File: | tao/linesearch/impls/morethuente/morethuente.c |
Warning: | line 210, column 52 The right operand of '>=' is a garbage value |
[?] Use j/k keys for keyboard navigation
1 | #include <petsc/private/taolinesearchimpl.h> | |||
2 | #include <../src/tao/linesearch/impls/morethuente/morethuente.h> | |||
3 | ||||
4 | /* | |||
5 | This algorithm is taken from More' and Thuente, "Line search algorithms | |||
6 | with guaranteed sufficient decrease", Argonne National Laboratory, | |||
7 | Technical Report MCS-P330-1092. | |||
8 | */ | |||
9 | ||||
10 | static PetscErrorCode Tao_mcstep(TaoLineSearch ls,PetscReal *stx,PetscReal *fx,PetscReal *dx,PetscReal *sty,PetscReal *fy,PetscReal *dy,PetscReal *stp,PetscReal *fp,PetscReal *dp); | |||
11 | ||||
12 | static PetscErrorCode TaoLineSearchDestroy_MT(TaoLineSearch ls) | |||
13 | { | |||
14 | PetscErrorCode ierr; | |||
15 | TaoLineSearch_MT *mt; | |||
16 | ||||
17 | PetscFunctionBegindo { do { ; if (petscstack && (petscstack->currentsize < 64)) { petscstack->function[petscstack->currentsize ] = __func__; petscstack->file[petscstack->currentsize] = "/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ; petscstack->line[petscstack->currentsize] = 17; petscstack ->petscroutine[petscstack->currentsize] = PETSC_TRUE; petscstack ->currentsize++; } if (petscstack) { petscstack->hotdepth += (PETSC_FALSE || petscstack->hotdepth); } ; } while (0) ; ; } while (0); | |||
18 | PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1)do { if (!ls) return PetscError(((MPI_Comm)0x44000001),18,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,85,PETSC_ERROR_INITIAL,"Null Object: Parameter # %d",1); if ( !PetscCheckPointer(ls,PETSC_OBJECT)) return PetscError(((MPI_Comm )0x44000001),18,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Invalid Pointer to Object: Parameter # %d" ,1); if (((PetscObject)(ls))->classid != TAOLINESEARCH_CLASSID ) { if (((PetscObject)(ls))->classid == -1) return PetscError (((MPI_Comm)0x44000001),18,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Object already free: Parameter # %d" ,1); else return PetscError(((MPI_Comm)0x44000001),18,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,62,PETSC_ERROR_INITIAL,"Wrong type of object: Parameter # %d" ,1); } } while (0); | |||
19 | mt = (TaoLineSearch_MT*)(ls->data); | |||
20 | if (mt->x) { | |||
21 | ierr = PetscObjectDereference((PetscObject)mt->x);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),21,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
22 | } | |||
23 | ierr = VecDestroy(&mt->work);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),23,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
24 | ierr = PetscFree(ls->data)((*PetscTrFree)((void*)(ls->data),24,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ) || ((ls->data) = 0,0));CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),24,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
25 | PetscFunctionReturn(0)do { do { ; if (petscstack && petscstack->currentsize > 0) { petscstack->currentsize--; petscstack->function [petscstack->currentsize] = 0; petscstack->file[petscstack ->currentsize] = 0; petscstack->line[petscstack->currentsize ] = 0; petscstack->petscroutine[petscstack->currentsize ] = PETSC_FALSE; } if (petscstack) { petscstack->hotdepth = (((petscstack->hotdepth-1)<(0)) ? (0) : (petscstack-> hotdepth-1)); } ; } while (0); return(0);} while (0); | |||
26 | } | |||
27 | ||||
28 | static PetscErrorCode TaoLineSearchSetFromOptions_MT(PetscOptionItems *PetscOptionsObject,TaoLineSearch ls) | |||
29 | { | |||
30 | PetscFunctionBegindo { do { ; if (petscstack && (petscstack->currentsize < 64)) { petscstack->function[petscstack->currentsize ] = __func__; petscstack->file[petscstack->currentsize] = "/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ; petscstack->line[petscstack->currentsize] = 30; petscstack ->petscroutine[petscstack->currentsize] = PETSC_TRUE; petscstack ->currentsize++; } if (petscstack) { petscstack->hotdepth += (PETSC_FALSE || petscstack->hotdepth); } ; } while (0) ; ; } while (0); | |||
31 | PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1)do { if (!ls) return PetscError(((MPI_Comm)0x44000001),31,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,85,PETSC_ERROR_INITIAL,"Null Object: Parameter # %d",1); if ( !PetscCheckPointer(ls,PETSC_OBJECT)) return PetscError(((MPI_Comm )0x44000001),31,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Invalid Pointer to Object: Parameter # %d" ,1); if (((PetscObject)(ls))->classid != TAOLINESEARCH_CLASSID ) { if (((PetscObject)(ls))->classid == -1) return PetscError (((MPI_Comm)0x44000001),31,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Object already free: Parameter # %d" ,1); else return PetscError(((MPI_Comm)0x44000001),31,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,62,PETSC_ERROR_INITIAL,"Wrong type of object: Parameter # %d" ,1); } } while (0); | |||
32 | PetscFunctionReturn(0)do { do { ; if (petscstack && petscstack->currentsize > 0) { petscstack->currentsize--; petscstack->function [petscstack->currentsize] = 0; petscstack->file[petscstack ->currentsize] = 0; petscstack->line[petscstack->currentsize ] = 0; petscstack->petscroutine[petscstack->currentsize ] = PETSC_FALSE; } if (petscstack) { petscstack->hotdepth = (((petscstack->hotdepth-1)<(0)) ? (0) : (petscstack-> hotdepth-1)); } ; } while (0); return(0);} while (0); | |||
33 | } | |||
34 | ||||
35 | static PetscErrorCode TaoLineSearchMonitor_MT(TaoLineSearch ls) | |||
36 | { | |||
37 | TaoLineSearch_MT *mt = (TaoLineSearch_MT*)ls->data; | |||
38 | PetscErrorCode ierr; | |||
39 | ||||
40 | PetscFunctionBegindo { do { ; if (petscstack && (petscstack->currentsize < 64)) { petscstack->function[petscstack->currentsize ] = __func__; petscstack->file[petscstack->currentsize] = "/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ; petscstack->line[petscstack->currentsize] = 40; petscstack ->petscroutine[petscstack->currentsize] = PETSC_TRUE; petscstack ->currentsize++; } if (petscstack) { petscstack->hotdepth += (PETSC_FALSE || petscstack->hotdepth); } ; } while (0) ; ; } while (0); | |||
41 | ierr = PetscViewerASCIIPrintf(ls->viewer, "stx: %g, fx: %g, dgx: %g\n", (double)mt->stx, (double)mt->fx, (double)mt->dgx);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),41,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
42 | ierr = PetscViewerASCIIPrintf(ls->viewer, "sty: %g, fy: %g, dgy: %g\n", (double)mt->sty, (double)mt->fy, (double)mt->dgy);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),42,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
43 | PetscFunctionReturn(0)do { do { ; if (petscstack && petscstack->currentsize > 0) { petscstack->currentsize--; petscstack->function [petscstack->currentsize] = 0; petscstack->file[petscstack ->currentsize] = 0; petscstack->line[petscstack->currentsize ] = 0; petscstack->petscroutine[petscstack->currentsize ] = PETSC_FALSE; } if (petscstack) { petscstack->hotdepth = (((petscstack->hotdepth-1)<(0)) ? (0) : (petscstack-> hotdepth-1)); } ; } while (0); return(0);} while (0); | |||
44 | } | |||
45 | ||||
46 | static PetscErrorCode TaoLineSearchApply_MT(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s) | |||
47 | { | |||
48 | PetscErrorCode ierr; | |||
49 | TaoLineSearch_MT *mt; | |||
50 | ||||
51 | PetscReal xtrapf = 4.0; | |||
52 | PetscReal finit, width, width1, dginit, fm, fxm, fym, dgm, dgxm, dgym; | |||
53 | PetscReal dgx, dgy, dg, dg2, fx, fy, stx, sty, dgtest; | |||
54 | PetscReal ftest1=0.0, ftest2=0.0; | |||
55 | PetscInt i, stage1,n1,n2,nn1,nn2; | |||
56 | PetscReal bstepmin1, bstepmin2, bstepmax; | |||
| ||||
57 | PetscBool g_computed=PETSC_FALSE; /* to prevent extra gradient computation */ | |||
58 | ||||
59 | PetscFunctionBegindo { do { ; if (petscstack && (petscstack->currentsize < 64)) { petscstack->function[petscstack->currentsize ] = __func__; petscstack->file[petscstack->currentsize] = "/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ; petscstack->line[petscstack->currentsize] = 59; petscstack ->petscroutine[petscstack->currentsize] = PETSC_TRUE; petscstack ->currentsize++; } if (petscstack) { petscstack->hotdepth += (PETSC_FALSE || petscstack->hotdepth); } ; } while (0) ; ; } while (0); | |||
60 | PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1)do { if (!ls) return PetscError(((MPI_Comm)0x44000001),60,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,85,PETSC_ERROR_INITIAL,"Null Object: Parameter # %d",1); if ( !PetscCheckPointer(ls,PETSC_OBJECT)) return PetscError(((MPI_Comm )0x44000001),60,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Invalid Pointer to Object: Parameter # %d" ,1); if (((PetscObject)(ls))->classid != TAOLINESEARCH_CLASSID ) { if (((PetscObject)(ls))->classid == -1) return PetscError (((MPI_Comm)0x44000001),60,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Object already free: Parameter # %d" ,1); else return PetscError(((MPI_Comm)0x44000001),60,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,62,PETSC_ERROR_INITIAL,"Wrong type of object: Parameter # %d" ,1); } } while (0); | |||
61 | PetscValidHeaderSpecific(x,VEC_CLASSID,2)do { if (!x) return PetscError(((MPI_Comm)0x44000001),61,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,85,PETSC_ERROR_INITIAL,"Null Object: Parameter # %d",2); if ( !PetscCheckPointer(x,PETSC_OBJECT)) return PetscError(((MPI_Comm )0x44000001),61,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Invalid Pointer to Object: Parameter # %d" ,2); if (((PetscObject)(x))->classid != VEC_CLASSID) { if ( ((PetscObject)(x))->classid == -1) return PetscError(((MPI_Comm )0x44000001),61,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Object already free: Parameter # %d" ,2); else return PetscError(((MPI_Comm)0x44000001),61,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,62,PETSC_ERROR_INITIAL,"Wrong type of object: Parameter # %d" ,2); } } while (0); | |||
62 | PetscValidScalarPointer(f,3)do { if (!f) return PetscError(((MPI_Comm)0x44000001),62,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,85,PETSC_ERROR_INITIAL,"Null Pointer: Parameter # %d",3); if (!PetscCheckPointer(f,PETSC_DOUBLE)) return PetscError(((MPI_Comm )0x44000001),62,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,68,PETSC_ERROR_INITIAL,"Invalid Pointer to PetscScalar: Parameter # %d" ,3); } while (0); | |||
63 | PetscValidHeaderSpecific(g,VEC_CLASSID,4)do { if (!g) return PetscError(((MPI_Comm)0x44000001),63,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,85,PETSC_ERROR_INITIAL,"Null Object: Parameter # %d",4); if ( !PetscCheckPointer(g,PETSC_OBJECT)) return PetscError(((MPI_Comm )0x44000001),63,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Invalid Pointer to Object: Parameter # %d" ,4); if (((PetscObject)(g))->classid != VEC_CLASSID) { if ( ((PetscObject)(g))->classid == -1) return PetscError(((MPI_Comm )0x44000001),63,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Object already free: Parameter # %d" ,4); else return PetscError(((MPI_Comm)0x44000001),63,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,62,PETSC_ERROR_INITIAL,"Wrong type of object: Parameter # %d" ,4); } } while (0); | |||
64 | PetscValidHeaderSpecific(s,VEC_CLASSID,5)do { if (!s) return PetscError(((MPI_Comm)0x44000001),64,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,85,PETSC_ERROR_INITIAL,"Null Object: Parameter # %d",5); if ( !PetscCheckPointer(s,PETSC_OBJECT)) return PetscError(((MPI_Comm )0x44000001),64,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Invalid Pointer to Object: Parameter # %d" ,5); if (((PetscObject)(s))->classid != VEC_CLASSID) { if ( ((PetscObject)(s))->classid == -1) return PetscError(((MPI_Comm )0x44000001),64,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Object already free: Parameter # %d" ,5); else return PetscError(((MPI_Comm)0x44000001),64,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,62,PETSC_ERROR_INITIAL,"Wrong type of object: Parameter # %d" ,5); } } while (0); | |||
65 | ||||
66 | ierr = TaoLineSearchMonitor(ls, 0, *f, 0.0);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),66,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
67 | ||||
68 | /* comm,type,size checks are done in interface TaoLineSearchApply */ | |||
69 | mt = (TaoLineSearch_MT*)(ls->data); | |||
70 | ls->reason = TAOLINESEARCH_CONTINUE_ITERATING; | |||
71 | ||||
72 | /* Check work vector */ | |||
73 | if (!mt->work) { | |||
74 | ierr = VecDuplicate(x,&mt->work);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),74,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
75 | mt->x = x; | |||
76 | ierr = PetscObjectReference((PetscObject)mt->x);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),76,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
77 | } else if (x != mt->x) { | |||
78 | ierr = VecDestroy(&mt->work);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),78,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
79 | ierr = VecDuplicate(x,&mt->work);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),79,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
80 | ierr = PetscObjectDereference((PetscObject)mt->x);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),80,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
81 | mt->x = x; | |||
82 | ierr = PetscObjectReference((PetscObject)mt->x);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),82,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
83 | } | |||
84 | ||||
85 | if (ls->bounded) { | |||
86 | /* Compute step length needed to make all variables equal a bound */ | |||
87 | /* Compute the smallest steplength that will make one nonbinding variable | |||
88 | equal the bound */ | |||
89 | ierr = VecGetLocalSize(ls->upper,&n1);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),89,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
90 | ierr = VecGetLocalSize(mt->x, &n2);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),90,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
91 | ierr = VecGetSize(ls->upper,&nn1);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),91,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
92 | ierr = VecGetSize(mt->x,&nn2);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),92,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
93 | if (n1 != n2 || nn1 != nn2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Variable vector not compatible with bounds vector")return PetscError(((MPI_Comm)0x44000001),93,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,60,PETSC_ERROR_INITIAL,"Variable vector not compatible with bounds vector" ); | |||
94 | ierr = VecScale(s,-1.0);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),94,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
95 | ierr = VecBoundGradientProjection(s,x,ls->lower,ls->upper,s);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),95,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
96 | ierr = VecScale(s,-1.0);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),96,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
97 | ierr = VecStepBoundInfo(x,s,ls->lower,ls->upper,&bstepmin1,&bstepmin2,&bstepmax);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),97,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
98 | ls->stepmax = PetscMin(bstepmax,1.0e15)(((bstepmax)<(1.0e15)) ? (bstepmax) : (1.0e15)); | |||
99 | } | |||
100 | ||||
101 | ierr = VecDot(g,s,&dginit);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),101,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
102 | if (PetscIsInfOrNanReal(dginit)) { | |||
103 | ierr = PetscInfo1(ls,"Initial Line Search step * g is Inf or Nan (%g)\n",(double)dginit)PetscInfo_Private(__func__,ls,"Initial Line Search step * g is Inf or Nan (%g)\n" ,(double)dginit);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),103,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
104 | ls->reason=TAOLINESEARCH_FAILED_INFORNAN; | |||
105 | PetscFunctionReturn(0)do { do { ; if (petscstack && petscstack->currentsize > 0) { petscstack->currentsize--; petscstack->function [petscstack->currentsize] = 0; petscstack->file[petscstack ->currentsize] = 0; petscstack->line[petscstack->currentsize ] = 0; petscstack->petscroutine[petscstack->currentsize ] = PETSC_FALSE; } if (petscstack) { petscstack->hotdepth = (((petscstack->hotdepth-1)<(0)) ? (0) : (petscstack-> hotdepth-1)); } ; } while (0); return(0);} while (0); | |||
106 | } | |||
107 | if (dginit >= 0.0) { | |||
108 | ierr = PetscInfo1(ls,"Initial Line Search step * g is not descent direction (%g)\n",(double)dginit)PetscInfo_Private(__func__,ls,"Initial Line Search step * g is not descent direction (%g)\n" ,(double)dginit);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),108,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
109 | ls->reason = TAOLINESEARCH_FAILED_ASCENT; | |||
110 | PetscFunctionReturn(0)do { do { ; if (petscstack && petscstack->currentsize > 0) { petscstack->currentsize--; petscstack->function [petscstack->currentsize] = 0; petscstack->file[petscstack ->currentsize] = 0; petscstack->line[petscstack->currentsize ] = 0; petscstack->petscroutine[petscstack->currentsize ] = PETSC_FALSE; } if (petscstack) { petscstack->hotdepth = (((petscstack->hotdepth-1)<(0)) ? (0) : (petscstack-> hotdepth-1)); } ; } while (0); return(0);} while (0); | |||
111 | } | |||
112 | ||||
113 | /* Initialization */ | |||
114 | mt->bracket = 0; | |||
115 | stage1 = 1; | |||
116 | finit = *f; | |||
117 | dgtest = ls->ftol * dginit; | |||
118 | width = ls->stepmax - ls->stepmin; | |||
119 | width1 = width * 2.0; | |||
120 | ierr = VecCopy(x,mt->work);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),120,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
121 | /* Variable dictionary: | |||
122 | stx, fx, dgx - the step, function, and derivative at the best step | |||
123 | sty, fy, dgy - the step, function, and derivative at the other endpoint | |||
124 | of the interval of uncertainty | |||
125 | step, f, dg - the step, function, and derivative at the current step */ | |||
126 | ||||
127 | stx = 0.0; | |||
128 | fx = finit; | |||
129 | dgx = dginit; | |||
130 | sty = 0.0; | |||
131 | fy = finit; | |||
132 | dgy = dginit; | |||
133 | ||||
134 | ls->step=ls->initstep; | |||
135 | for (i=0; i< ls->max_funcs; i++) { | |||
136 | /* Set min and max steps to correspond to the interval of uncertainty */ | |||
137 | if (mt->bracket) { | |||
138 | ls->stepmin = PetscMin(stx,sty)(((stx)<(sty)) ? (stx) : (sty)); | |||
139 | ls->stepmax = PetscMax(stx,sty)(((stx)<(sty)) ? (sty) : (stx)); | |||
140 | } else { | |||
141 | ls->stepmin = stx; | |||
142 | ls->stepmax = ls->step + xtrapf * (ls->step - stx); | |||
143 | } | |||
144 | ||||
145 | /* Force the step to be within the bounds */ | |||
146 | ls->step = PetscMax(ls->step,ls->stepmin)(((ls->step)<(ls->stepmin)) ? (ls->stepmin) : (ls ->step)); | |||
147 | ls->step = PetscMin(ls->step,ls->stepmax)(((ls->step)<(ls->stepmax)) ? (ls->step) : (ls-> stepmax)); | |||
148 | ||||
149 | /* If an unusual termination is to occur, then let step be the lowest | |||
150 | point obtained thus far */ | |||
151 | if ((stx!=0) && (((mt->bracket) && (ls->step <= ls->stepmin || ls->step >= ls->stepmax)) || ((mt->bracket) && (ls->stepmax - ls->stepmin <= ls->rtol * ls->stepmax)) || | |||
152 | ((ls->nfeval+ls->nfgeval) >= ls->max_funcs - 1) || (mt->infoc == 0))) { | |||
153 | ls->step = stx; | |||
154 | } | |||
155 | ||||
156 | ierr = VecCopy(x,mt->work);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),156,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
157 | ierr = VecAXPY(mt->work,ls->step,s);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),157,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); /* W = X + step*S */ | |||
158 | ||||
159 | if (ls->bounded) { | |||
160 | ierr = VecMedian(ls->lower, mt->work, ls->upper, mt->work);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),160,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
161 | } | |||
162 | if (ls->usegts) { | |||
163 | ierr = TaoLineSearchComputeObjectiveAndGTS(ls,mt->work,f,&dg);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),163,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
164 | g_computed=PETSC_FALSE; | |||
165 | } else { | |||
166 | ierr = TaoLineSearchComputeObjectiveAndGradient(ls,mt->work,f,g);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),166,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
167 | g_computed=PETSC_TRUE; | |||
168 | if (ls->bounded) { | |||
169 | ierr = VecDot(g,x,&dg);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),169,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
170 | ierr = VecDot(g,mt->work,&dg2);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),170,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
171 | dg = (dg2 - dg)/ls->step; | |||
172 | } else { | |||
173 | ierr = VecDot(g,s,&dg);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),173,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
174 | } | |||
175 | } | |||
176 | ||||
177 | /* update bracketing parameters in the MT context for printouts in monitor */ | |||
178 | mt->stx = stx; | |||
179 | mt->fx = fx; | |||
180 | mt->dgx = dgx; | |||
181 | mt->sty = sty; | |||
182 | mt->fy = fy; | |||
183 | mt->dgy = dgy; | |||
184 | ierr = TaoLineSearchMonitor(ls, i+1, *f, ls->step);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),184,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
185 | ||||
186 | if (0 == i) { | |||
187 | ls->f_fullstep=*f; | |||
188 | } | |||
189 | ||||
190 | if (PetscIsInfOrNanReal(*f) || PetscIsInfOrNanReal(dg)) { | |||
191 | /* User provided compute function generated Not-a-Number, assume | |||
192 | domain violation and set function value and directional | |||
193 | derivative to infinity. */ | |||
194 | *f = PETSC_INFINITY(1.7976931348623157e+308/4); | |||
195 | dg = PETSC_INFINITY(1.7976931348623157e+308/4); | |||
196 | } | |||
197 | ||||
198 | ftest1 = finit + ls->step * dgtest; | |||
199 | if (ls->bounded) { | |||
200 | ftest2 = finit + ls->step * dgtest * ls->ftol; | |||
201 | } | |||
202 | /* Convergence testing */ | |||
203 | if (((*f - ftest1 <= 1.0e-10 * PetscAbsReal(finit)fabs(finit)) && (PetscAbsReal(dg)fabs(dg) + ls->gtol*dginit <= 0.0))) { | |||
204 | ierr = PetscInfo(ls, "Line search success: Sufficient decrease and directional deriv conditions hold\n")PetscInfo_Private(__func__,ls,"Line search success: Sufficient decrease and directional deriv conditions hold\n" );CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),204,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
205 | ls->reason = TAOLINESEARCH_SUCCESS; | |||
206 | break; | |||
207 | } | |||
208 | ||||
209 | /* Check Armijo if beyond the first breakpoint */ | |||
210 | if (ls->bounded && (*f <= ftest2) && (ls->step >= bstepmin2)) { | |||
| ||||
211 | ierr = PetscInfo(ls,"Line search success: Sufficient decrease.\n")PetscInfo_Private(__func__,ls,"Line search success: Sufficient decrease.\n" );CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),211,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
212 | ls->reason = TAOLINESEARCH_SUCCESS; | |||
213 | break; | |||
214 | } | |||
215 | ||||
216 | /* Checks for bad cases */ | |||
217 | if (((mt->bracket) && (ls->step <= ls->stepmin||ls->step >= ls->stepmax)) || (!mt->infoc)) { | |||
218 | ierr = PetscInfo(ls,"Rounding errors may prevent further progress. May not be a step satisfying\n")PetscInfo_Private(__func__,ls,"Rounding errors may prevent further progress. May not be a step satisfying\n" );CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),218,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
219 | ierr = PetscInfo(ls,"sufficient decrease and curvature conditions. Tolerances may be too small.\n")PetscInfo_Private(__func__,ls,"sufficient decrease and curvature conditions. Tolerances may be too small.\n" );CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),219,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
220 | ls->reason = TAOLINESEARCH_HALTED_OTHER; | |||
221 | break; | |||
222 | } | |||
223 | if ((ls->step == ls->stepmax) && (*f <= ftest1) && (dg <= dgtest)) { | |||
224 | ierr = PetscInfo1(ls,"Step is at the upper bound, stepmax (%g)\n",(double)ls->stepmax)PetscInfo_Private(__func__,ls,"Step is at the upper bound, stepmax (%g)\n" ,(double)ls->stepmax);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),224,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
225 | ls->reason = TAOLINESEARCH_HALTED_UPPERBOUND; | |||
226 | break; | |||
227 | } | |||
228 | if ((ls->step == ls->stepmin) && (*f >= ftest1) && (dg >= dgtest)) { | |||
229 | ierr = PetscInfo1(ls,"Step is at the lower bound, stepmin (%g)\n",(double)ls->stepmin)PetscInfo_Private(__func__,ls,"Step is at the lower bound, stepmin (%g)\n" ,(double)ls->stepmin);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),229,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
230 | ls->reason = TAOLINESEARCH_HALTED_LOWERBOUND; | |||
231 | break; | |||
232 | } | |||
233 | if ((mt->bracket) && (ls->stepmax - ls->stepmin <= ls->rtol*ls->stepmax)){ | |||
234 | ierr = PetscInfo1(ls,"Relative width of interval of uncertainty is at most rtol (%g)\n",(double)ls->rtol)PetscInfo_Private(__func__,ls,"Relative width of interval of uncertainty is at most rtol (%g)\n" ,(double)ls->rtol);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),234,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
235 | ls->reason = TAOLINESEARCH_HALTED_RTOL; | |||
236 | break; | |||
237 | } | |||
238 | ||||
239 | /* In the first stage, we seek a step for which the modified function | |||
240 | has a nonpositive value and nonnegative derivative */ | |||
241 | if ((stage1) && (*f <= ftest1) && (dg >= dginit * PetscMin(ls->ftol, ls->gtol)(((ls->ftol)<(ls->gtol)) ? (ls->ftol) : (ls->gtol )))) { | |||
242 | stage1 = 0; | |||
243 | } | |||
244 | ||||
245 | /* A modified function is used to predict the step only if we | |||
246 | have not obtained a step for which the modified function has a | |||
247 | nonpositive function value and nonnegative derivative, and if a | |||
248 | lower function value has been obtained but the decrease is not | |||
249 | sufficient */ | |||
250 | ||||
251 | if ((stage1) && (*f <= fx) && (*f > ftest1)) { | |||
252 | fm = *f - ls->step * dgtest; /* Define modified function */ | |||
253 | fxm = fx - stx * dgtest; /* and derivatives */ | |||
254 | fym = fy - sty * dgtest; | |||
255 | dgm = dg - dgtest; | |||
256 | dgxm = dgx - dgtest; | |||
257 | dgym = dgy - dgtest; | |||
258 | ||||
259 | /* if (dgxm * (ls->step - stx) >= 0.0) */ | |||
260 | /* Update the interval of uncertainty and compute the new step */ | |||
261 | ierr = Tao_mcstep(ls,&stx,&fxm,&dgxm,&sty,&fym,&dgym,&ls->step,&fm,&dgm);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),261,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
262 | ||||
263 | fx = fxm + stx * dgtest; /* Reset the function and */ | |||
264 | fy = fym + sty * dgtest; /* gradient values */ | |||
265 | dgx = dgxm + dgtest; | |||
266 | dgy = dgym + dgtest; | |||
267 | } else { | |||
268 | /* Update the interval of uncertainty and compute the new step */ | |||
269 | ierr = Tao_mcstep(ls,&stx,&fx,&dgx,&sty,&fy,&dgy,&ls->step,f,&dg);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),269,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
270 | } | |||
271 | ||||
272 | /* Force a sufficient decrease in the interval of uncertainty */ | |||
273 | if (mt->bracket) { | |||
274 | if (PetscAbsReal(sty - stx)fabs(sty - stx) >= 0.66 * width1) ls->step = stx + 0.5*(sty - stx); | |||
275 | width1 = width; | |||
276 | width = PetscAbsReal(sty - stx)fabs(sty - stx); | |||
277 | } | |||
278 | } | |||
279 | if ((ls->nfeval+ls->nfgeval) > ls->max_funcs) { | |||
280 | ierr = PetscInfo2(ls,"Number of line search function evals (%D) > maximum (%D)\n",(ls->nfeval+ls->nfgeval),ls->max_funcs)PetscInfo_Private(__func__,ls,"Number of line search function evals (%D) > maximum (%D)\n" ,(ls->nfeval+ls->nfgeval),ls->max_funcs);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),280,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
281 | ls->reason = TAOLINESEARCH_HALTED_MAXFCN; | |||
282 | } | |||
283 | ||||
284 | /* Finish computations */ | |||
285 | ierr = PetscInfo2(ls,"%D function evals in line search, step = %g\n",(ls->nfeval+ls->nfgeval),(double)ls->step)PetscInfo_Private(__func__,ls,"%D function evals in line search, step = %g\n" ,(ls->nfeval+ls->nfgeval),(double)ls->step);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),285,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
286 | ||||
287 | /* Set new solution vector and compute gradient if needed */ | |||
288 | ierr = VecCopy(mt->work,x);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),288,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
289 | if (!g_computed) { | |||
290 | ierr = TaoLineSearchComputeGradient(ls,mt->work,g);CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),290,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
291 | } | |||
292 | PetscFunctionReturn(0)do { do { ; if (petscstack && petscstack->currentsize > 0) { petscstack->currentsize--; petscstack->function [petscstack->currentsize] = 0; petscstack->file[petscstack ->currentsize] = 0; petscstack->line[petscstack->currentsize ] = 0; petscstack->petscroutine[petscstack->currentsize ] = PETSC_FALSE; } if (petscstack) { petscstack->hotdepth = (((petscstack->hotdepth-1)<(0)) ? (0) : (petscstack-> hotdepth-1)); } ; } while (0); return(0);} while (0); | |||
293 | } | |||
294 | ||||
295 | /*MC | |||
296 | TAOLINESEARCHMT - Line-search type with cubic interpolation that satisfies both the sufficient decrease and | |||
297 | curvature conditions. This method can take step lengths greater than 1. | |||
298 | ||||
299 | More-Thuente line-search can be selected with "-tao_ls_type more-thuente". | |||
300 | ||||
301 | References: | |||
302 | . 1. - JORGE J. MORE AND DAVID J. THUENTE, LINE SEARCH ALGORITHMS WITH GUARANTEED SUFFICIENT DECREASE. | |||
303 | ACM Trans. Math. Software 20, no. 3 (1994): 286-307. | |||
304 | ||||
305 | Level: developer | |||
306 | ||||
307 | .seealso: TaoLineSearchCreate(), TaoLineSearchSetType(), TaoLineSearchApply() | |||
308 | ||||
309 | .keywords: Tao, linesearch | |||
310 | M*/ | |||
311 | PETSC_EXTERNextern __attribute__((visibility ("default"))) PetscErrorCode TaoLineSearchCreate_MT(TaoLineSearch ls) | |||
312 | { | |||
313 | PetscErrorCode ierr; | |||
314 | TaoLineSearch_MT *ctx; | |||
315 | ||||
316 | PetscFunctionBegindo { do { ; if (petscstack && (petscstack->currentsize < 64)) { petscstack->function[petscstack->currentsize ] = __func__; petscstack->file[petscstack->currentsize] = "/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ; petscstack->line[petscstack->currentsize] = 316; petscstack ->petscroutine[petscstack->currentsize] = PETSC_TRUE; petscstack ->currentsize++; } if (petscstack) { petscstack->hotdepth += (PETSC_FALSE || petscstack->hotdepth); } ; } while (0) ; ; } while (0); | |||
317 | PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1)do { if (!ls) return PetscError(((MPI_Comm)0x44000001),317,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,85,PETSC_ERROR_INITIAL,"Null Object: Parameter # %d",1); if ( !PetscCheckPointer(ls,PETSC_OBJECT)) return PetscError(((MPI_Comm )0x44000001),317,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Invalid Pointer to Object: Parameter # %d" ,1); if (((PetscObject)(ls))->classid != TAOLINESEARCH_CLASSID ) { if (((PetscObject)(ls))->classid == -1) return PetscError (((MPI_Comm)0x44000001),317,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,64,PETSC_ERROR_INITIAL,"Object already free: Parameter # %d" ,1); else return PetscError(((MPI_Comm)0x44000001),317,__func__ ,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,62,PETSC_ERROR_INITIAL,"Wrong type of object: Parameter # %d" ,1); } } while (0); | |||
318 | ierr = PetscNewLog(ls,&ctx)(PetscMallocA(1,PETSC_TRUE,318,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,(size_t)(1)*sizeof(**(((&ctx)))),(((&ctx)))) || PetscLogObjectMemory ((PetscObject)ls,sizeof(**(&ctx))));CHKERRQ(ierr)do {if (__builtin_expect(!!(ierr),0)) return PetscError(((MPI_Comm )0x44000001),318,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,ierr,PETSC_ERROR_REPEAT," ");} while (0); | |||
319 | ctx->bracket=0; | |||
320 | ctx->infoc=1; | |||
321 | ls->data = (void*)ctx; | |||
322 | ls->initstep = 1.0; | |||
323 | ls->ops->setup=0; | |||
324 | ls->ops->reset=0; | |||
325 | ls->ops->apply=TaoLineSearchApply_MT; | |||
326 | ls->ops->destroy=TaoLineSearchDestroy_MT; | |||
327 | ls->ops->setfromoptions=TaoLineSearchSetFromOptions_MT; | |||
328 | ls->ops->monitor=TaoLineSearchMonitor_MT; | |||
329 | PetscFunctionReturn(0)do { do { ; if (petscstack && petscstack->currentsize > 0) { petscstack->currentsize--; petscstack->function [petscstack->currentsize] = 0; petscstack->file[petscstack ->currentsize] = 0; petscstack->line[petscstack->currentsize ] = 0; petscstack->petscroutine[petscstack->currentsize ] = PETSC_FALSE; } if (petscstack) { petscstack->hotdepth = (((petscstack->hotdepth-1)<(0)) ? (0) : (petscstack-> hotdepth-1)); } ; } while (0); return(0);} while (0); | |||
330 | } | |||
331 | ||||
332 | /* | |||
333 | The subroutine mcstep is taken from the work of Jorge Nocedal. | |||
334 | this is a variant of More' and Thuente's routine. | |||
335 | ||||
336 | subroutine mcstep | |||
337 | ||||
338 | the purpose of mcstep is to compute a safeguarded step for | |||
339 | a linesearch and to update an interval of uncertainty for | |||
340 | a minimizer of the function. | |||
341 | ||||
342 | the parameter stx contains the step with the least function | |||
343 | value. the parameter stp contains the current step. it is | |||
344 | assumed that the derivative at stx is negative in the | |||
345 | direction of the step. if bracket is set true then a | |||
346 | minimizer has been bracketed in an interval of uncertainty | |||
347 | with endpoints stx and sty. | |||
348 | ||||
349 | the subroutine statement is | |||
350 | ||||
351 | subroutine mcstep(stx,fx,dx,sty,fy,dy,stp,fp,dp,bracket, | |||
352 | stpmin,stpmax,info) | |||
353 | ||||
354 | where | |||
355 | ||||
356 | stx, fx, and dx are variables which specify the step, | |||
357 | the function, and the derivative at the best step obtained | |||
358 | so far. The derivative must be negative in the direction | |||
359 | of the step, that is, dx and stp-stx must have opposite | |||
360 | signs. On output these parameters are updated appropriately. | |||
361 | ||||
362 | sty, fy, and dy are variables which specify the step, | |||
363 | the function, and the derivative at the other endpoint of | |||
364 | the interval of uncertainty. On output these parameters are | |||
365 | updated appropriately. | |||
366 | ||||
367 | stp, fp, and dp are variables which specify the step, | |||
368 | the function, and the derivative at the current step. | |||
369 | If bracket is set true then on input stp must be | |||
370 | between stx and sty. On output stp is set to the new step. | |||
371 | ||||
372 | bracket is a logical variable which specifies if a minimizer | |||
373 | has been bracketed. If the minimizer has not been bracketed | |||
374 | then on input bracket must be set false. If the minimizer | |||
375 | is bracketed then on output bracket is set true. | |||
376 | ||||
377 | stpmin and stpmax are input variables which specify lower | |||
378 | and upper bounds for the step. | |||
379 | ||||
380 | info is an integer output variable set as follows: | |||
381 | if info = 1,2,3,4,5, then the step has been computed | |||
382 | according to one of the five cases below. otherwise | |||
383 | info = 0, and this indicates improper input parameters. | |||
384 | ||||
385 | subprograms called | |||
386 | ||||
387 | fortran-supplied ... abs,max,min,sqrt | |||
388 | ||||
389 | argonne national laboratory. minpack project. june 1983 | |||
390 | jorge j. more', david j. thuente | |||
391 | ||||
392 | */ | |||
393 | ||||
394 | static PetscErrorCode Tao_mcstep(TaoLineSearch ls,PetscReal *stx,PetscReal *fx,PetscReal *dx,PetscReal *sty,PetscReal *fy,PetscReal *dy,PetscReal *stp,PetscReal *fp,PetscReal *dp) | |||
395 | { | |||
396 | TaoLineSearch_MT *mtP = (TaoLineSearch_MT *) ls->data; | |||
397 | PetscReal gamma1, p, q, r, s, sgnd, stpc, stpf, stpq, theta; | |||
398 | PetscInt bound; | |||
399 | ||||
400 | PetscFunctionBegindo { do { ; if (petscstack && (petscstack->currentsize < 64)) { petscstack->function[petscstack->currentsize ] = __func__; petscstack->file[petscstack->currentsize] = "/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ; petscstack->line[petscstack->currentsize] = 400; petscstack ->petscroutine[petscstack->currentsize] = PETSC_TRUE; petscstack ->currentsize++; } if (petscstack) { petscstack->hotdepth += (PETSC_FALSE || petscstack->hotdepth); } ; } while (0) ; ; } while (0); | |||
401 | /* Check the input parameters for errors */ | |||
402 | mtP->infoc = 0; | |||
403 | if (mtP->bracket && (*stp <= PetscMin(*stx,*sty)(((*stx)<(*sty)) ? (*stx) : (*sty)) || (*stp >= PetscMax(*stx,*sty)(((*stx)<(*sty)) ? (*sty) : (*stx))))) SETERRQ(PETSC_COMM_SELF,1,"bad stp in bracket")return PetscError(((MPI_Comm)0x44000001),403,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,1,PETSC_ERROR_INITIAL,"bad stp in bracket"); | |||
404 | if (*dx * (*stp-*stx) >= 0.0) SETERRQ(PETSC_COMM_SELF,1,"dx * (stp-stx) >= 0.0")return PetscError(((MPI_Comm)0x44000001),404,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,1,PETSC_ERROR_INITIAL,"dx * (stp-stx) >= 0.0"); | |||
405 | if (ls->stepmax < ls->stepmin) SETERRQ(PETSC_COMM_SELF,1,"stepmax > stepmin")return PetscError(((MPI_Comm)0x44000001),405,__func__,"/sandbox/petsc/petsc.next/src/tao/linesearch/impls/morethuente/morethuente.c" ,1,PETSC_ERROR_INITIAL,"stepmax > stepmin"); | |||
406 | ||||
407 | /* Determine if the derivatives have opposite sign */ | |||
408 | sgnd = *dp * (*dx / PetscAbsReal(*dx)fabs(*dx)); | |||
409 | ||||
410 | if (*fp > *fx) { | |||
411 | /* Case 1: a higher function value. | |||
412 | The minimum is bracketed. If the cubic step is closer | |||
413 | to stx than the quadratic step, the cubic step is taken, | |||
414 | else the average of the cubic and quadratic steps is taken. */ | |||
415 | ||||
416 | mtP->infoc = 1; | |||
417 | bound = 1; | |||
418 | theta = 3 * (*fx - *fp) / (*stp - *stx) + *dx + *dp; | |||
419 | s = PetscMax(PetscAbsReal(theta),PetscAbsReal(*dx))(((fabs(theta))<(fabs(*dx))) ? (fabs(*dx)) : (fabs(theta)) ); | |||
420 | s = PetscMax(s,PetscAbsReal(*dp))(((s)<(fabs(*dp))) ? (fabs(*dp)) : (s)); | |||
421 | gamma1 = s*PetscSqrtScalar(PetscPowScalar(theta/s,2.0) - (*dx/s)*(*dp/s))sqrt(pow(theta/s,2.0) - (*dx/s)*(*dp/s)); | |||
422 | if (*stp < *stx) gamma1 = -gamma1; | |||
423 | /* Can p be 0? Check */ | |||
424 | p = (gamma1 - *dx) + theta; | |||
425 | q = ((gamma1 - *dx) + gamma1) + *dp; | |||
426 | r = p/q; | |||
427 | stpc = *stx + r*(*stp - *stx); | |||
428 | stpq = *stx + ((*dx/((*fx-*fp)/(*stp-*stx)+*dx))*0.5) * (*stp - *stx); | |||
429 | ||||
430 | if (PetscAbsReal(stpc-*stx)fabs(stpc-*stx) < PetscAbsReal(stpq-*stx)fabs(stpq-*stx)) { | |||
431 | stpf = stpc; | |||
432 | } else { | |||
433 | stpf = stpc + 0.5*(stpq - stpc); | |||
434 | } | |||
435 | mtP->bracket = 1; | |||
436 | } else if (sgnd < 0.0) { | |||
437 | /* Case 2: A lower function value and derivatives of | |||
438 | opposite sign. The minimum is bracketed. If the cubic | |||
439 | step is closer to stx than the quadratic (secant) step, | |||
440 | the cubic step is taken, else the quadratic step is taken. */ | |||
441 | ||||
442 | mtP->infoc = 2; | |||
443 | bound = 0; | |||
444 | theta = 3*(*fx - *fp)/(*stp - *stx) + *dx + *dp; | |||
445 | s = PetscMax(PetscAbsReal(theta),PetscAbsReal(*dx))(((fabs(theta))<(fabs(*dx))) ? (fabs(*dx)) : (fabs(theta)) ); | |||
446 | s = PetscMax(s,PetscAbsReal(*dp))(((s)<(fabs(*dp))) ? (fabs(*dp)) : (s)); | |||
447 | gamma1 = s*PetscSqrtScalar(PetscPowScalar(theta/s,2.0) - (*dx/s)*(*dp/s))sqrt(pow(theta/s,2.0) - (*dx/s)*(*dp/s)); | |||
448 | if (*stp > *stx) gamma1 = -gamma1; | |||
449 | p = (gamma1 - *dp) + theta; | |||
450 | q = ((gamma1 - *dp) + gamma1) + *dx; | |||
451 | r = p/q; | |||
452 | stpc = *stp + r*(*stx - *stp); | |||
453 | stpq = *stp + (*dp/(*dp-*dx))*(*stx - *stp); | |||
454 | ||||
455 | if (PetscAbsReal(stpc-*stp)fabs(stpc-*stp) > PetscAbsReal(stpq-*stp)fabs(stpq-*stp)) { | |||
456 | stpf = stpc; | |||
457 | } else { | |||
458 | stpf = stpq; | |||
459 | } | |||
460 | mtP->bracket = 1; | |||
461 | } else if (PetscAbsReal(*dp)fabs(*dp) < PetscAbsReal(*dx)fabs(*dx)) { | |||
462 | /* Case 3: A lower function value, derivatives of the | |||
463 | same sign, and the magnitude of the derivative decreases. | |||
464 | The cubic step is only used if the cubic tends to infinity | |||
465 | in the direction of the step or if the minimum of the cubic | |||
466 | is beyond stp. Otherwise the cubic step is defined to be | |||
467 | either stepmin or stepmax. The quadratic (secant) step is also | |||
468 | computed and if the minimum is bracketed then the step | |||
469 | closest to stx is taken, else the step farthest away is taken. */ | |||
470 | ||||
471 | mtP->infoc = 3; | |||
472 | bound = 1; | |||
473 | theta = 3*(*fx - *fp)/(*stp - *stx) + *dx + *dp; | |||
474 | s = PetscMax(PetscAbsReal(theta),PetscAbsReal(*dx))(((fabs(theta))<(fabs(*dx))) ? (fabs(*dx)) : (fabs(theta)) ); | |||
475 | s = PetscMax(s,PetscAbsReal(*dp))(((s)<(fabs(*dp))) ? (fabs(*dp)) : (s)); | |||
476 | ||||
477 | /* The case gamma1 = 0 only arises if the cubic does not tend | |||
478 | to infinity in the direction of the step. */ | |||
479 | gamma1 = s*PetscSqrtScalar(PetscMax(0.0,PetscPowScalar(theta/s,2.0) - (*dx/s)*(*dp/s)))sqrt((((0.0)<(pow(theta/s,2.0) - (*dx/s)*(*dp/s))) ? (pow( theta/s,2.0) - (*dx/s)*(*dp/s)) : (0.0))); | |||
480 | if (*stp > *stx) gamma1 = -gamma1; | |||
481 | p = (gamma1 - *dp) + theta; | |||
482 | q = (gamma1 + (*dx - *dp)) + gamma1; | |||
483 | r = p/q; | |||
484 | if (r < 0.0 && gamma1 != 0.0) stpc = *stp + r*(*stx - *stp); | |||
485 | else if (*stp > *stx) stpc = ls->stepmax; | |||
486 | else stpc = ls->stepmin; | |||
487 | stpq = *stp + (*dp/(*dp-*dx)) * (*stx - *stp); | |||
488 | ||||
489 | if (mtP->bracket) { | |||
490 | if (PetscAbsReal(*stp-stpc)fabs(*stp-stpc) < PetscAbsReal(*stp-stpq)fabs(*stp-stpq)) { | |||
491 | stpf = stpc; | |||
492 | } else { | |||
493 | stpf = stpq; | |||
494 | } | |||
495 | } else { | |||
496 | if (PetscAbsReal(*stp-stpc)fabs(*stp-stpc) > PetscAbsReal(*stp-stpq)fabs(*stp-stpq)) { | |||
497 | stpf = stpc; | |||
498 | } else { | |||
499 | stpf = stpq; | |||
500 | } | |||
501 | } | |||
502 | } else { | |||
503 | /* Case 4: A lower function value, derivatives of the | |||
504 | same sign, and the magnitude of the derivative does | |||
505 | not decrease. If the minimum is not bracketed, the step | |||
506 | is either stpmin or stpmax, else the cubic step is taken. */ | |||
507 | ||||
508 | mtP->infoc = 4; | |||
509 | bound = 0; | |||
510 | if (mtP->bracket) { | |||
511 | theta = 3*(*fp - *fy)/(*sty - *stp) + *dy + *dp; | |||
512 | s = PetscMax(PetscAbsReal(theta),PetscAbsReal(*dy))(((fabs(theta))<(fabs(*dy))) ? (fabs(*dy)) : (fabs(theta)) ); | |||
513 | s = PetscMax(s,PetscAbsReal(*dp))(((s)<(fabs(*dp))) ? (fabs(*dp)) : (s)); | |||
514 | gamma1 = s*PetscSqrtScalar(PetscPowScalar(theta/s,2.0) - (*dy/s)*(*dp/s))sqrt(pow(theta/s,2.0) - (*dy/s)*(*dp/s)); | |||
515 | if (*stp > *sty) gamma1 = -gamma1; | |||
516 | p = (gamma1 - *dp) + theta; | |||
517 | q = ((gamma1 - *dp) + gamma1) + *dy; | |||
518 | r = p/q; | |||
519 | stpc = *stp + r*(*sty - *stp); | |||
520 | stpf = stpc; | |||
521 | } else if (*stp > *stx) { | |||
522 | stpf = ls->stepmax; | |||
523 | } else { | |||
524 | stpf = ls->stepmin; | |||
525 | } | |||
526 | } | |||
527 | ||||
528 | /* Update the interval of uncertainty. This update does not | |||
529 | depend on the new step or the case analysis above. */ | |||
530 | ||||
531 | if (*fp > *fx) { | |||
532 | *sty = *stp; | |||
533 | *fy = *fp; | |||
534 | *dy = *dp; | |||
535 | } else { | |||
536 | if (sgnd < 0.0) { | |||
537 | *sty = *stx; | |||
538 | *fy = *fx; | |||
539 | *dy = *dx; | |||
540 | } | |||
541 | *stx = *stp; | |||
542 | *fx = *fp; | |||
543 | *dx = *dp; | |||
544 | } | |||
545 | ||||
546 | /* Compute the new step and safeguard it. */ | |||
547 | stpf = PetscMin(ls->stepmax,stpf)(((ls->stepmax)<(stpf)) ? (ls->stepmax) : (stpf)); | |||
548 | stpf = PetscMax(ls->stepmin,stpf)(((ls->stepmin)<(stpf)) ? (stpf) : (ls->stepmin)); | |||
549 | *stp = stpf; | |||
550 | if (mtP->bracket && bound) { | |||
551 | if (*sty > *stx) { | |||
552 | *stp = PetscMin(*stx+0.66*(*sty-*stx),*stp)(((*stx+0.66*(*sty-*stx))<(*stp)) ? (*stx+0.66*(*sty-*stx) ) : (*stp)); | |||
553 | } else { | |||
554 | *stp = PetscMax(*stx+0.66*(*sty-*stx),*stp)(((*stx+0.66*(*sty-*stx))<(*stp)) ? (*stp) : (*stx+0.66*(* sty-*stx))); | |||
555 | } | |||
556 | } | |||
557 | PetscFunctionReturn(0)do { do { ; if (petscstack && petscstack->currentsize > 0) { petscstack->currentsize--; petscstack->function [petscstack->currentsize] = 0; petscstack->file[petscstack ->currentsize] = 0; petscstack->line[petscstack->currentsize ] = 0; petscstack->petscroutine[petscstack->currentsize ] = PETSC_FALSE; } if (petscstack) { petscstack->hotdepth = (((petscstack->hotdepth-1)<(0)) ? (0) : (petscstack-> hotdepth-1)); } ; } while (0); return(0);} while (0); | |||
558 | } |