Actual source code: gpcglinesearch.c
2: #include "src/bound/impls/gpcg/gpcglinesearch.h" /*I "tao_solver.h" I*/
4: int TaoGPCGPrintHelpLineSearch(TAO_SOLVER,char*);
5: static int TaoGPCGSetOptionsLineSearch(TAO_SOLVER, void*linectx);
7: static int TaoGPCGDestroyLineSearch(TAO_SOLVER, void*linectx);
9: /* ---------------------------------------------------------- */
12: static int TaoGPCGDestroyLineSearch(TAO_SOLVER tao, void*lsctx)
13: {
14: int info;
15: TAO_GPCGLINESEARCH *ctx = (TAO_GPCGLINESEARCH *)lsctx;
17: TaoFunctionBegin;
18: if (ctx->setupcalled==1){
19: info = TaoVecDestroy(ctx->W2);CHKERRQ(info);
20: info = TaoVecDestroy(ctx->Gold);CHKERRQ(info);
21: }
22: info = TaoFree(ctx);CHKERRQ(info);
23: TaoFunctionReturn(0);
24: }
25: /*------------------------------------------------------------*/
28: static int TaoGPCGSetOptionsLineSearch(TAO_SOLVER tao, void*linectx)
29: {
30: TAO_GPCGLINESEARCH *ctx = (TAO_GPCGLINESEARCH *)linectx;
31: double tmp;
32: int itmp,info;
33: TaoTruth flg;
35: TaoFunctionBegin;
36: info = TaoOptionsHead("GPCG line search options");CHKERRQ(info);
38: info = TaoOptionInt("-tao_nls_maxfev","max function evals in line search",0,ctx->maxfev,&itmp,&flg);CHKERRQ(info);
39: if (flg) {ctx->maxfev = itmp;}
40: info = TaoOptionDouble("-tao_nls_ftol","tol for sufficient decrease",0,ctx->ftol,&tmp,&flg);CHKERRQ(info);
41: if (flg) {ctx->ftol = tmp;}
42: info = TaoOptionDouble("-tao_nls_gtol","tol for curvature condition",0,ctx->gtol,&tmp,&flg);CHKERRQ(info);
43: if (flg) {ctx->gtol = tmp;}
44: info = TaoOptionDouble("-tao_nls_rtol","relative tol for acceptable step",0,ctx->rtol,&tmp,&flg);CHKERRQ(info);
45: if (flg) {ctx->rtol = tmp;}
46: info = TaoOptionDouble("-tao_nls_stepmin","lower bound for step",0,ctx->stepmin,&tmp,&flg);CHKERRQ(info);
47: if (flg) {ctx->stepmin = tmp;}
48: info = TaoOptionDouble("-tao_nls_stepmax","upper bound for step",0,ctx->stepmax,&tmp,&flg);CHKERRQ(info);
49: if (flg) {ctx->stepmax = tmp;}
50: info = TaoOptionsTail();CHKERRQ(info);
52: TaoFunctionReturn(0);
53: }
56: /*------------------------------------------------------------*/
59: static int TaoGPCGViewLineSearch(TAO_SOLVER tao,void *ctx)
60: {
61: TAO_GPCGLINESEARCH *ls = (TAO_GPCGLINESEARCH *)ctx;
62: int info;
64: TaoFunctionBegin;
65: info = TaoPrintInt(tao," Line search: maxf=%d,",ls->maxfev);CHKERRQ(info);
66: info = TaoPrintDouble(tao," ftol=%g,",ls->ftol);CHKERRQ(info);
67: info = TaoPrintDouble(tao," rtol=%g,",ls->rtol);CHKERRQ(info);
68: info = TaoPrintDouble(tao," gtol=%g\n",ls->gtol);CHKERRQ(info);
69: TaoFunctionReturn(0);
70: }
72: /*------------------------------------------------------------*/
75: int TaoGPCGApplyLineSearch(TAO_SOLVER tao,TaoVec* X,
76: TaoVec* G,TaoVec* S,TaoVec* W,
77: double *f, double *step, int *info2,
78: void*ctx)
79: {
80: TAO_GPCGLINESEARCH *neP = (TAO_GPCGLINESEARCH *) ctx;
81: int info, i;
82: double zero=0.0;
83: double d1,finit,actred,prered,rho, gdx;
84: TaoVec* XL, *XU, *Xold=neP->W2,*Gold=neP->Gold;
85: TaoTruth flag;
87: TaoFunctionBegin;
88: /* neP->stepmin - lower bound for step */
89: /* neP->stepmax - upper bound for step */
90: /* neP->rtol - relative tolerance for an acceptable step */
91: /* neP->ftol - tolerance for sufficient decrease condition */
92: /* neP->gtol - tolerance for curvature condition */
93: /* neP->nfev - number of function evaluations */
94: /* neP->maxfev - maximum number of function evaluations */
96: /* Check input parameters for errors */
97: *info2=0;
98: if (neP->setupcalled){
99: info=X->Compatible(neP->W2,&flag); CHKERRQ(info);
100: if (flag==TAO_FALSE){
101: info=TaoVecDestroy(neP->W2); CHKERRQ(info);neP->W2=0;
102: info=TaoVecDestroy(neP->Gold); CHKERRQ(info);neP->Gold=0;
103: neP->setupcalled=0;
104: }
105: }
107: if (neP->setupcalled==0){
108: info = X->Clone(&neP->W2); CHKERRQ(info);
109: Xold=neP->W2;
110: info = X->Clone(&neP->Gold); CHKERRQ(info);
111: Gold=neP->Gold;
112: neP->setupcalled=1;
113: }
115: info = G->Dot(S,&gdx); CHKERRQ(info);
116: info = Xold->CopyFrom(X); CHKERRQ(info);
117: info = Gold->CopyFrom(G); CHKERRQ(info);
118: info = TaoGetVariableBounds(tao,&XL,&XU); CHKERRQ(info);
119: info = X->StepBoundInfo(XL,XU,S,&rho,&actred,&d1);CHKERRQ(info);
120: rho=0; actred=0;
121: *step = TaoMin(*step,d1);
123: if (*step < zero) {
124: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Line search error: step (%g) < 0\n",*step)); CHKERRQ(info);
125: *info2 = -1; TaoFunctionReturn(0);
126: } else if (neP->ftol < zero) {
127: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Line search error: ftol (%g) < 0\n",neP->ftol)); CHKERRQ(info);
128: *info2 = -2; TaoFunctionReturn(0);
129: } else if (neP->rtol < zero) {
130: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Line search error: rtol (%g) < 0\n",neP->rtol)); CHKERRQ(info);
131: *info2 = -3; TaoFunctionReturn(0);
132: } else if (neP->gtol < zero) {
133: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Line search error: gtol (%g) < 0\n",neP->gtol)); CHKERRQ(info);
134: *info2 = -4; TaoFunctionReturn(0);
135: } else if (neP->stepmin < zero) {
136: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Line search error: stepmin (%g) < 0\n",neP->stepmin)); CHKERRQ(info);
137: *info2 = -5; TaoFunctionReturn(0);
138: } else if (neP->stepmax < neP->stepmin) {
139: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Line search error: stepmax (%g) < stepmin (%g)\n",neP->stepmax,neP->stepmin)); CHKERRQ(info);
140: *info2 = -6; TaoFunctionReturn(0);
141: } else if (neP->maxfev < zero) {
142: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Line search error: maxfev (%d) < 0\n",neP->maxfev)); CHKERRQ(info);
143: *info2 = -7; TaoFunctionReturn(0);
144: }
147: /* Check that search direction is a descent direction */
148: /*
149: info = VecDot(G,S,&dginit);CHKERRQ(info); / * dginit = G^T S * /
150: if (dginit >= zero) {
151: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Search direction not a descent direction\n")); CHKERRQ(info);
152: *info2 = 7; return(0);
153: }
154: */
155: /* Initialization */
156: neP->nfev = 0;
157: finit = *f;
158: for (i=0; i< neP->maxfev; i++) {
159:
160: /* Force the step to be within the bounds */
161: *step = TaoMax(*step,neP->stepmin);
162: *step = TaoMin(*step,neP->stepmax);
163:
164: info = X->Waxpby(*step,S,1.0,Xold); CHKERRQ(info);
165: info = X->Median(XL,X,XU); CHKERRQ(info);
167: info = TaoGPCGComputeFunctionGradient(tao, X, f, G); CHKERRQ(info);
169: actred = *f - finit;
170: info = W->Waxpby(-1.0,Xold,1.0,X); CHKERRQ(info);
171: info = W->Dot(Gold,&prered); CHKERRQ(info);
172: if (fabs(prered)<1.0e-100) prered=1.0e-12;
173: rho = actred/prered;
174: /*
175: If sufficient progress has been obtained, accept the
176: point. Otherwise, backtrack.
177: */
179: if (rho > neP->ftol){
180: break;
181: } else{
182: *step = (*step)/2;
183: }
184: }
186: /* Convergence testing */
187:
188: if (*step <= neP->stepmin || *step >= neP->stepmax) {
189: *info2 = 6;
190: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Rounding errors may prevent further progress. May not be a step satisfying\n")); CHKERRQ(info);
191: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:sufficient decrease and curvature conditions. Tolerances may be too small.\n")); CHKERRQ(info);
192: }
193: if (*step == neP->stepmax) {
194: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Step is at the upper bound, stepmax (%g)\n",neP->stepmax)); CHKERRQ(info);
195: *info2 = 5;
196: }
197: if (*step == neP->stepmin) {
198: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Step is at the lower bound, stepmin (%g)\n",neP->stepmin)); CHKERRQ(info);
199: *info2 = 4;
200: }
201: if (neP->nfev >= neP->maxfev) {
202: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Number of line search function evals (%d) > maximum (%d)\n",neP->nfev,neP->maxfev)); CHKERRQ(info);
203: *info2 = 3;
204: }
205: if ((neP->bracket) && (neP->stepmax - neP->stepmin <= neP->rtol*neP->stepmax)){
206: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Relative width of interval of uncertainty is at most rtol (%g)\n",neP->rtol)); CHKERRQ(info);
207: *info2 = 2;
208: }
209: /*
210: if ((*f <= ftest1) && (PetscAbsDouble(dg) <= neP->gtol*(-dginit))) {
211: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:Line search success: Sufficient decrease and directional deriv conditions hold\n")); CHKERRQ(info);
212: *info2 = 1;
213: }
214: */
215:
216: /* Finish computations */
217: info = PetscLogInfo((tao,"TaoGPCGApplyLineSearch:%d function evals in line search, step = %10.4f\n",neP->nfev,*step)); CHKERRQ(info);
219: TaoFunctionReturn(0);
220: }
222: /* ---------------------------------------------------------- */
225: int TaoGPCGCreateLineSearch(TAO_SOLVER tao)
226: {
227: int info;
228: TAO_GPCGLINESEARCH *neP;
230: TaoFunctionBegin;
232: info = TaoNew(TAO_GPCGLINESEARCH,&neP);CHKERRQ(info);
233: info = PetscLogObjectMemory(tao,sizeof(TAO_GPCGLINESEARCH)); CHKERRQ(info);
234: neP->ftol = 0.05;
235: neP->rtol = 0.0;
236: neP->gtol = 0.0;
237: neP->stepmin = 1.0e-20;
238: neP->stepmax = 1.0e+20;
239: neP->nfev = 0;
240: neP->bracket = 0;
241: neP->infoc = 1;
242: neP->maxfev = 30;
243: neP->setupcalled = 0;
245: info = TaoSetLineSearch(tao,0,
246: TaoGPCGSetOptionsLineSearch,
247: TaoGPCGApplyLineSearch,
248: TaoGPCGViewLineSearch,
249: TaoGPCGDestroyLineSearch,
250: (void *) neP);CHKERRQ(info);
252: TaoFunctionReturn(0);
253: }