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: }