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