1*a7e14dcfSSatish Balay #include "petscvec.h" 2*a7e14dcfSSatish Balay #include "taosolver.h" 3*a7e14dcfSSatish Balay #include "tao-private/taolinesearch_impl.h" 4*a7e14dcfSSatish Balay #include "owarmijo.h" 5*a7e14dcfSSatish Balay 6*a7e14dcfSSatish Balay #define REPLACE_FIFO 1 7*a7e14dcfSSatish Balay #define REPLACE_MRU 2 8*a7e14dcfSSatish Balay 9*a7e14dcfSSatish Balay #define REFERENCE_MAX 1 10*a7e14dcfSSatish Balay #define REFERENCE_AVE 2 11*a7e14dcfSSatish Balay #define REFERENCE_MEAN 3 12*a7e14dcfSSatish Balay 13*a7e14dcfSSatish Balay 14*a7e14dcfSSatish Balay 15*a7e14dcfSSatish Balay static PetscErrorCode ProjWork_OWLQN(Vec w,Vec x,Vec gv,PetscReal *gdx) 16*a7e14dcfSSatish Balay { 17*a7e14dcfSSatish Balay PetscReal *xptr,*wptr,*gptr; 18*a7e14dcfSSatish Balay PetscErrorCode ierr; 19*a7e14dcfSSatish Balay PetscInt low,high,low1,high1,low2,high2,i; 20*a7e14dcfSSatish Balay 21*a7e14dcfSSatish Balay PetscFunctionBegin; 22*a7e14dcfSSatish Balay 23*a7e14dcfSSatish Balay ierr=VecGetOwnershipRange(w,&low,&high);CHKERRQ(ierr); 24*a7e14dcfSSatish Balay ierr=VecGetOwnershipRange(x,&low1,&high1);CHKERRQ(ierr); 25*a7e14dcfSSatish Balay ierr=VecGetOwnershipRange(gv,&low2,&high2);CHKERRQ(ierr); 26*a7e14dcfSSatish Balay 27*a7e14dcfSSatish Balay *gdx=0.0; 28*a7e14dcfSSatish Balay ierr = VecGetArray(x,&xptr);CHKERRQ(ierr); 29*a7e14dcfSSatish Balay ierr = VecGetArray(w,&wptr);CHKERRQ(ierr); 30*a7e14dcfSSatish Balay ierr = VecGetArray(gv,&gptr);CHKERRQ(ierr); 31*a7e14dcfSSatish Balay 32*a7e14dcfSSatish Balay for (i=0;i<high-low;i++) 33*a7e14dcfSSatish Balay { 34*a7e14dcfSSatish Balay if (xptr[i]*wptr[i]<0.0) 35*a7e14dcfSSatish Balay wptr[i]=0.0; 36*a7e14dcfSSatish Balay 37*a7e14dcfSSatish Balay *gdx = *gdx + gptr[i]*(wptr[i]-xptr[i]); 38*a7e14dcfSSatish Balay } 39*a7e14dcfSSatish Balay ierr = VecRestoreArray(w,&wptr);CHKERRQ(ierr); 40*a7e14dcfSSatish Balay ierr = VecRestoreArray(x,&xptr);CHKERRQ(ierr); 41*a7e14dcfSSatish Balay ierr = VecRestoreArray(gv,&gptr);CHKERRQ(ierr); 42*a7e14dcfSSatish Balay 43*a7e14dcfSSatish Balay PetscFunctionReturn(0); 44*a7e14dcfSSatish Balay } 45*a7e14dcfSSatish Balay 46*a7e14dcfSSatish Balay #undef __FUNCT__ 47*a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchDestroy_OWArmijo" 48*a7e14dcfSSatish Balay static PetscErrorCode TaoLineSearchDestroy_OWArmijo(TaoLineSearch ls) 49*a7e14dcfSSatish Balay { 50*a7e14dcfSSatish Balay TAOLINESEARCH_OWARMIJO_CTX *armP = (TAOLINESEARCH_OWARMIJO_CTX *)ls->data; 51*a7e14dcfSSatish Balay PetscErrorCode ierr; 52*a7e14dcfSSatish Balay 53*a7e14dcfSSatish Balay PetscFunctionBegin; 54*a7e14dcfSSatish Balay 55*a7e14dcfSSatish Balay if (armP->memory != PETSC_NULL) { 56*a7e14dcfSSatish Balay ierr = PetscFree(armP->memory); CHKERRQ(ierr); 57*a7e14dcfSSatish Balay armP->memory = PETSC_NULL; 58*a7e14dcfSSatish Balay } 59*a7e14dcfSSatish Balay if (armP->x) { 60*a7e14dcfSSatish Balay ierr = PetscObjectDereference((PetscObject)armP->x); CHKERRQ(ierr); 61*a7e14dcfSSatish Balay } 62*a7e14dcfSSatish Balay ierr = VecDestroy(&armP->work); CHKERRQ(ierr); 63*a7e14dcfSSatish Balay ierr = PetscFree(ls->data); CHKERRQ(ierr); 64*a7e14dcfSSatish Balay ls->data = PETSC_NULL; 65*a7e14dcfSSatish Balay PetscFunctionReturn(0); 66*a7e14dcfSSatish Balay } 67*a7e14dcfSSatish Balay 68*a7e14dcfSSatish Balay #undef __FUNCT__ 69*a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchSetFromOptions_OWArmijo" 70*a7e14dcfSSatish Balay static PetscErrorCode TaoLineSearchSetFromOptions_OWArmijo(TaoLineSearch ls) 71*a7e14dcfSSatish Balay { 72*a7e14dcfSSatish Balay TAOLINESEARCH_OWARMIJO_CTX *armP = (TAOLINESEARCH_OWARMIJO_CTX *)ls->data; 73*a7e14dcfSSatish Balay PetscErrorCode ierr; 74*a7e14dcfSSatish Balay 75*a7e14dcfSSatish Balay PetscFunctionBegin; 76*a7e14dcfSSatish Balay ierr = PetscOptionsHead("OWArmijo linesearch options");CHKERRQ(ierr); 77*a7e14dcfSSatish Balay ierr = PetscOptionsReal("-tao_ls_OWArmijo_alpha", "initial reference constant", "", armP->alpha, &armP->alpha, 0); CHKERRQ(ierr); 78*a7e14dcfSSatish Balay ierr = PetscOptionsReal("-tao_ls_OWArmijo_beta_inf", "decrease constant one", "", armP->beta_inf, &armP->beta_inf, 0); CHKERRQ(ierr); 79*a7e14dcfSSatish Balay ierr = PetscOptionsReal("-tao_ls_OWArmijo_beta", "decrease constant", "", armP->beta, &armP->beta, 0); CHKERRQ(ierr); 80*a7e14dcfSSatish Balay ierr = PetscOptionsReal("-tao_ls_OWArmijo_sigma", "acceptance constant", "", armP->sigma, &armP->sigma, 0); CHKERRQ(ierr); 81*a7e14dcfSSatish Balay ierr = PetscOptionsInt("-tao_ls_OWArmijo_memory_size", "number of historical elements", "", armP->memorySize, &armP->memorySize, 0); CHKERRQ(ierr); 82*a7e14dcfSSatish Balay ierr = PetscOptionsInt("-tao_ls_OWArmijo_reference_policy", "policy for updating reference value", "", armP->referencePolicy, &armP->referencePolicy, 0); CHKERRQ(ierr); 83*a7e14dcfSSatish Balay ierr = PetscOptionsInt("-tao_ls_OWArmijo_replacement_policy", "policy for updating memory", "", armP->replacementPolicy, &armP->replacementPolicy, 0); CHKERRQ(ierr); 84*a7e14dcfSSatish Balay ierr = PetscOptionsBool("-tao_ls_OWArmijo_nondescending","Use nondescending OWArmijo algorithm","",armP->nondescending,&armP->nondescending, 0); CHKERRQ(ierr); 85*a7e14dcfSSatish Balay ierr = PetscOptionsTail();CHKERRQ(ierr); 86*a7e14dcfSSatish Balay PetscFunctionReturn(0); 87*a7e14dcfSSatish Balay } 88*a7e14dcfSSatish Balay 89*a7e14dcfSSatish Balay #undef __FUNCT__ 90*a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchView_OWArmijo" 91*a7e14dcfSSatish Balay static PetscErrorCode TaoLineSearchView_OWArmijo(TaoLineSearch ls, PetscViewer pv) 92*a7e14dcfSSatish Balay { 93*a7e14dcfSSatish Balay TAOLINESEARCH_OWARMIJO_CTX *armP = (TAOLINESEARCH_OWARMIJO_CTX *)ls->data; 94*a7e14dcfSSatish Balay PetscBool isascii; 95*a7e14dcfSSatish Balay PetscErrorCode ierr; 96*a7e14dcfSSatish Balay 97*a7e14dcfSSatish Balay PetscFunctionBegin; 98*a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)pv, PETSCVIEWERASCII, &isascii); CHKERRQ(ierr); 99*a7e14dcfSSatish Balay if (isascii) { 100*a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(pv," maxf=%d, ftol=%g, gtol=%g\n",ls->max_funcs, ls->rtol, ls->ftol); CHKERRQ(ierr); 101*a7e14dcfSSatish Balay ierr=PetscViewerASCIIPrintf(pv," OWArmijo linesearch",armP->alpha);CHKERRQ(ierr); 102*a7e14dcfSSatish Balay if (armP->nondescending) { 103*a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(pv, " (nondescending)"); CHKERRQ(ierr); 104*a7e14dcfSSatish Balay } 105*a7e14dcfSSatish Balay ierr=PetscViewerASCIIPrintf(pv,": alpha=%g beta=%g ",armP->alpha,armP->beta);CHKERRQ(ierr); 106*a7e14dcfSSatish Balay ierr=PetscViewerASCIIPrintf(pv,"sigma=%g ",armP->sigma);CHKERRQ(ierr); 107*a7e14dcfSSatish Balay ierr=PetscViewerASCIIPrintf(pv,"memsize=%d\n",armP->memorySize);CHKERRQ(ierr); 108*a7e14dcfSSatish Balay } else { 109*a7e14dcfSSatish Balay SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for OWArmijo TaoLineSearch",((PetscObject)pv)->type_name); 110*a7e14dcfSSatish Balay } 111*a7e14dcfSSatish Balay PetscFunctionReturn(0); 112*a7e14dcfSSatish Balay } 113*a7e14dcfSSatish Balay 114*a7e14dcfSSatish Balay #undef __FUNCT__ 115*a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchApply_OWArmijo" 116*a7e14dcfSSatish Balay /* @ TaoApply_OWArmijo - This routine performs a linesearch. It 117*a7e14dcfSSatish Balay backtracks until the (nonmonotone) OWArmijo conditions are satisfied. 118*a7e14dcfSSatish Balay 119*a7e14dcfSSatish Balay Input Parameters: 120*a7e14dcfSSatish Balay + tao - TAO_SOLVER context 121*a7e14dcfSSatish Balay . X - current iterate (on output X contains new iterate, X + step*S) 122*a7e14dcfSSatish Balay . S - search direction 123*a7e14dcfSSatish Balay . f - merit function evaluated at X 124*a7e14dcfSSatish Balay . G - gradient of merit function evaluated at X 125*a7e14dcfSSatish Balay . W - work vector 126*a7e14dcfSSatish Balay - step - initial estimate of step length 127*a7e14dcfSSatish Balay 128*a7e14dcfSSatish Balay Output parameters: 129*a7e14dcfSSatish Balay + f - merit function evaluated at new iterate, X + step*S 130*a7e14dcfSSatish Balay . G - gradient of merit function evaluated at new iterate, X + step*S 131*a7e14dcfSSatish Balay . X - new iterate 132*a7e14dcfSSatish Balay - step - final step length 133*a7e14dcfSSatish Balay 134*a7e14dcfSSatish Balay Info is set to one of: 135*a7e14dcfSSatish Balay . 0 - the line search succeeds; the sufficient decrease 136*a7e14dcfSSatish Balay condition and the directional derivative condition hold 137*a7e14dcfSSatish Balay 138*a7e14dcfSSatish Balay negative number if an input parameter is invalid 139*a7e14dcfSSatish Balay - -1 - step < 0 140*a7e14dcfSSatish Balay 141*a7e14dcfSSatish Balay positive number > 1 if the line search otherwise terminates 142*a7e14dcfSSatish Balay + 1 - Step is at the lower bound, stepmin. 143*a7e14dcfSSatish Balay @ */ 144*a7e14dcfSSatish Balay static PetscErrorCode TaoLineSearchApply_OWArmijo(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s) 145*a7e14dcfSSatish Balay { 146*a7e14dcfSSatish Balay TAOLINESEARCH_OWARMIJO_CTX *armP = (TAOLINESEARCH_OWARMIJO_CTX *)ls->data; 147*a7e14dcfSSatish Balay PetscErrorCode ierr; 148*a7e14dcfSSatish Balay PetscInt i; 149*a7e14dcfSSatish Balay PetscReal fact, ref, gdx; 150*a7e14dcfSSatish Balay PetscInt idx; 151*a7e14dcfSSatish Balay PetscBool g_computed=PETSC_FALSE; /* to prevent extra gradient computation */ 152*a7e14dcfSSatish Balay 153*a7e14dcfSSatish Balay Vec g_old; 154*a7e14dcfSSatish Balay PetscReal owlqn_minstep=0.005; 155*a7e14dcfSSatish Balay PetscReal partgdx; 156*a7e14dcfSSatish Balay 157*a7e14dcfSSatish Balay PetscFunctionBegin; 158*a7e14dcfSSatish Balay 159*a7e14dcfSSatish Balay fact = 0.0; 160*a7e14dcfSSatish Balay ls->nfeval=0; 161*a7e14dcfSSatish Balay ls->reason = TAOLINESEARCH_CONTINUE_ITERATING; 162*a7e14dcfSSatish Balay if (!armP->work) { 163*a7e14dcfSSatish Balay ierr = VecDuplicate(x,&armP->work); CHKERRQ(ierr); 164*a7e14dcfSSatish Balay armP->x = x; 165*a7e14dcfSSatish Balay ierr = PetscObjectReference((PetscObject)armP->x); CHKERRQ(ierr); 166*a7e14dcfSSatish Balay } 167*a7e14dcfSSatish Balay /* If x has changed, then recreate work */ 168*a7e14dcfSSatish Balay else if (x != armP->x) { 169*a7e14dcfSSatish Balay ierr = VecDestroy(&armP->work); CHKERRQ(ierr); 170*a7e14dcfSSatish Balay ierr = VecDuplicate(x,&armP->work); CHKERRQ(ierr); 171*a7e14dcfSSatish Balay ierr = PetscObjectDereference((PetscObject)armP->x); CHKERRQ(ierr); 172*a7e14dcfSSatish Balay armP->x = x; 173*a7e14dcfSSatish Balay ierr = PetscObjectReference((PetscObject)armP->x); CHKERRQ(ierr); 174*a7e14dcfSSatish Balay } 175*a7e14dcfSSatish Balay 176*a7e14dcfSSatish Balay /* Check linesearch parameters */ 177*a7e14dcfSSatish Balay if (armP->alpha < 1) { 178*a7e14dcfSSatish Balay ierr = PetscInfo1(ls,"OWArmijo line search error: alpha (%g) < 1\n", armP->alpha); CHKERRQ(ierr); 179*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER; 180*a7e14dcfSSatish Balay } 181*a7e14dcfSSatish Balay 182*a7e14dcfSSatish Balay else if ((armP->beta <= 0) || (armP->beta >= 1)) { 183*a7e14dcfSSatish Balay ierr = PetscInfo1(ls,"OWArmijo line search error: beta (%g) invalid\n", armP->beta); CHKERRQ(ierr); 184*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER; 185*a7e14dcfSSatish Balay 186*a7e14dcfSSatish Balay } 187*a7e14dcfSSatish Balay 188*a7e14dcfSSatish Balay else if ((armP->beta_inf <= 0) || (armP->beta_inf >= 1)) { 189*a7e14dcfSSatish Balay ierr = PetscInfo1(ls,"OWArmijo line search error: beta_inf (%g) invalid\n", armP->beta_inf); CHKERRQ(ierr); 190*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER; 191*a7e14dcfSSatish Balay } 192*a7e14dcfSSatish Balay 193*a7e14dcfSSatish Balay else if ((armP->sigma <= 0) || (armP->sigma >= 0.5)) { 194*a7e14dcfSSatish Balay ierr = PetscInfo1(ls,"OWArmijo line search error: sigma (%g) invalid\n", armP->sigma); CHKERRQ(ierr); 195*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER; 196*a7e14dcfSSatish Balay } 197*a7e14dcfSSatish Balay 198*a7e14dcfSSatish Balay else if (armP->memorySize < 1) { 199*a7e14dcfSSatish Balay ierr = PetscInfo1(ls,"OWArmijo line search error: memory_size (%d) < 1\n", armP->memorySize); CHKERRQ(ierr); 200*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER; 201*a7e14dcfSSatish Balay } 202*a7e14dcfSSatish Balay 203*a7e14dcfSSatish Balay else if ((armP->referencePolicy != REFERENCE_MAX) && 204*a7e14dcfSSatish Balay (armP->referencePolicy != REFERENCE_AVE) && 205*a7e14dcfSSatish Balay (armP->referencePolicy != REFERENCE_MEAN)) { 206*a7e14dcfSSatish Balay ierr = PetscInfo(ls,"OWArmijo line search error: reference_policy invalid\n"); CHKERRQ(ierr); 207*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER; 208*a7e14dcfSSatish Balay 209*a7e14dcfSSatish Balay } 210*a7e14dcfSSatish Balay 211*a7e14dcfSSatish Balay else if ((armP->replacementPolicy != REPLACE_FIFO) && 212*a7e14dcfSSatish Balay (armP->replacementPolicy != REPLACE_MRU)) { 213*a7e14dcfSSatish Balay ierr = PetscInfo(ls,"OWArmijo line search error: replacement_policy invalid\n"); CHKERRQ(ierr); 214*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER; 215*a7e14dcfSSatish Balay } 216*a7e14dcfSSatish Balay 217*a7e14dcfSSatish Balay else if (PetscIsInfOrNanReal(*f)) { 218*a7e14dcfSSatish Balay ierr = PetscInfo(ls,"OWArmijo line search error: initial function inf or nan\n"); CHKERRQ(ierr); 219*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER; 220*a7e14dcfSSatish Balay } 221*a7e14dcfSSatish Balay 222*a7e14dcfSSatish Balay if (ls->reason != TAOLINESEARCH_CONTINUE_ITERATING) { 223*a7e14dcfSSatish Balay PetscFunctionReturn(0); 224*a7e14dcfSSatish Balay } 225*a7e14dcfSSatish Balay 226*a7e14dcfSSatish Balay /* Check to see of the memory has been allocated. If not, allocate 227*a7e14dcfSSatish Balay the historical array and populate it with the initial function 228*a7e14dcfSSatish Balay values. */ 229*a7e14dcfSSatish Balay if (armP->memory == PETSC_NULL) { 230*a7e14dcfSSatish Balay ierr = PetscMalloc(sizeof(PetscReal)*armP->memorySize, &armP->memory ); CHKERRQ(ierr); 231*a7e14dcfSSatish Balay } 232*a7e14dcfSSatish Balay 233*a7e14dcfSSatish Balay if (!armP->memorySetup) { 234*a7e14dcfSSatish Balay for (i = 0; i < armP->memorySize; i++) { 235*a7e14dcfSSatish Balay armP->memory[i] = armP->alpha*(*f); 236*a7e14dcfSSatish Balay } 237*a7e14dcfSSatish Balay 238*a7e14dcfSSatish Balay armP->current = 0; 239*a7e14dcfSSatish Balay armP->lastReference = armP->memory[0]; 240*a7e14dcfSSatish Balay armP->memorySetup=PETSC_TRUE; 241*a7e14dcfSSatish Balay } 242*a7e14dcfSSatish Balay 243*a7e14dcfSSatish Balay /* Calculate reference value (MAX) */ 244*a7e14dcfSSatish Balay ref = armP->memory[0]; 245*a7e14dcfSSatish Balay idx = 0; 246*a7e14dcfSSatish Balay 247*a7e14dcfSSatish Balay for (i = 1; i < armP->memorySize; i++) { 248*a7e14dcfSSatish Balay if (armP->memory[i] > ref) { 249*a7e14dcfSSatish Balay ref = armP->memory[i]; 250*a7e14dcfSSatish Balay idx = i; 251*a7e14dcfSSatish Balay } 252*a7e14dcfSSatish Balay } 253*a7e14dcfSSatish Balay 254*a7e14dcfSSatish Balay if (armP->referencePolicy == REFERENCE_AVE) { 255*a7e14dcfSSatish Balay ref = 0; 256*a7e14dcfSSatish Balay for (i = 0; i < armP->memorySize; i++) { 257*a7e14dcfSSatish Balay ref += armP->memory[i]; 258*a7e14dcfSSatish Balay } 259*a7e14dcfSSatish Balay ref = ref / armP->memorySize; 260*a7e14dcfSSatish Balay ref = PetscMax(ref, armP->memory[armP->current]); 261*a7e14dcfSSatish Balay } 262*a7e14dcfSSatish Balay else if (armP->referencePolicy == REFERENCE_MEAN) { 263*a7e14dcfSSatish Balay ref = PetscMin(ref, 0.5*(armP->lastReference + armP->memory[armP->current])); 264*a7e14dcfSSatish Balay } 265*a7e14dcfSSatish Balay 266*a7e14dcfSSatish Balay 267*a7e14dcfSSatish Balay if (armP->nondescending) { 268*a7e14dcfSSatish Balay fact = armP->sigma; 269*a7e14dcfSSatish Balay } 270*a7e14dcfSSatish Balay 271*a7e14dcfSSatish Balay VecDuplicate(g,&g_old); 272*a7e14dcfSSatish Balay VecCopy(g,g_old); 273*a7e14dcfSSatish Balay 274*a7e14dcfSSatish Balay ls->step = ls->initstep; 275*a7e14dcfSSatish Balay 276*a7e14dcfSSatish Balay while (ls->step >= owlqn_minstep && ls->nfeval < ls->max_funcs) { 277*a7e14dcfSSatish Balay /* Calculate iterate */ 278*a7e14dcfSSatish Balay ierr = VecCopy(x,armP->work); CHKERRQ(ierr); 279*a7e14dcfSSatish Balay ierr = VecAXPY(armP->work,ls->step,s); CHKERRQ(ierr); 280*a7e14dcfSSatish Balay 281*a7e14dcfSSatish Balay partgdx=0.0; 282*a7e14dcfSSatish Balay ierr = ProjWork_OWLQN(armP->work,x,g_old,&partgdx); 283*a7e14dcfSSatish Balay ierr = (PetscErrorCode)MPI_Allreduce(&partgdx,&gdx,1,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD); CHKERRQ(ierr); 284*a7e14dcfSSatish Balay 285*a7e14dcfSSatish Balay /* Check the condition of gdx */ 286*a7e14dcfSSatish Balay if (PetscIsInfOrNanReal(gdx)) { 287*a7e14dcfSSatish Balay ierr = PetscInfo1(ls,"Initial Line Search step * g is Inf or Nan (%g)\n",gdx); CHKERRQ(ierr); 288*a7e14dcfSSatish Balay ls->reason=TAOLINESEARCH_FAILED_INFORNAN; 289*a7e14dcfSSatish Balay PetscFunctionReturn(0); 290*a7e14dcfSSatish Balay } 291*a7e14dcfSSatish Balay if (gdx >= 0.0) { 292*a7e14dcfSSatish Balay ierr = PetscInfo1(ls,"Initial Line Search step is not descent direction (g's=%g)\n",gdx); CHKERRQ(ierr); 293*a7e14dcfSSatish Balay ls->reason = TAOLINESEARCH_FAILED_ASCENT; 294*a7e14dcfSSatish Balay PetscFunctionReturn(0); 295*a7e14dcfSSatish Balay } 296*a7e14dcfSSatish Balay 297*a7e14dcfSSatish Balay /* Calculate function at new iterate */ 298*a7e14dcfSSatish Balay ierr = TaoLineSearchComputeObjectiveAndGradient(ls,armP->work,f,g); CHKERRQ(ierr); 299*a7e14dcfSSatish Balay g_computed=PETSC_TRUE; 300*a7e14dcfSSatish Balay 301*a7e14dcfSSatish Balay 302*a7e14dcfSSatish Balay if (ls->step == ls->initstep) { 303*a7e14dcfSSatish Balay ls->f_fullstep = *f; 304*a7e14dcfSSatish Balay } 305*a7e14dcfSSatish Balay 306*a7e14dcfSSatish Balay if (PetscIsInfOrNanReal(*f)) { 307*a7e14dcfSSatish Balay ls->step *= armP->beta_inf; 308*a7e14dcfSSatish Balay } 309*a7e14dcfSSatish Balay else { 310*a7e14dcfSSatish Balay /* Check descent condition */ 311*a7e14dcfSSatish Balay if (armP->nondescending && *f <= ref - ls->step*fact*ref) 312*a7e14dcfSSatish Balay break; 313*a7e14dcfSSatish Balay if (!armP->nondescending && *f <= ref + armP->sigma * gdx) { 314*a7e14dcfSSatish Balay break; 315*a7e14dcfSSatish Balay } 316*a7e14dcfSSatish Balay 317*a7e14dcfSSatish Balay ls->step *= armP->beta; 318*a7e14dcfSSatish Balay } 319*a7e14dcfSSatish Balay } 320*a7e14dcfSSatish Balay 321*a7e14dcfSSatish Balay VecDestroy(&g_old); 322*a7e14dcfSSatish Balay 323*a7e14dcfSSatish Balay /* Check termination */ 324*a7e14dcfSSatish Balay if (PetscIsInfOrNanReal(*f)) { 325*a7e14dcfSSatish Balay ierr = PetscInfo(ls, "Function is inf or nan.\n"); CHKERRQ(ierr); 326*a7e14dcfSSatish Balay ls->reason = TAOLINESEARCH_FAILED_BADPARAMETER; 327*a7e14dcfSSatish Balay } else if (ls->step < owlqn_minstep) { 328*a7e14dcfSSatish Balay ierr = PetscInfo(ls, "Step length is below tolerance.\n"); CHKERRQ(ierr); 329*a7e14dcfSSatish Balay ls->reason = TAOLINESEARCH_HALTED_RTOL; 330*a7e14dcfSSatish Balay } else if (ls->nfeval >= ls->max_funcs) { 331*a7e14dcfSSatish Balay ierr = PetscInfo2(ls, "Number of line search function evals (%d) > maximum allowed (%d)\n",ls->nfeval, ls->max_funcs); CHKERRQ(ierr); 332*a7e14dcfSSatish Balay ls->reason = TAOLINESEARCH_HALTED_MAXFCN; 333*a7e14dcfSSatish Balay } 334*a7e14dcfSSatish Balay if (ls->reason) { 335*a7e14dcfSSatish Balay PetscFunctionReturn(0); 336*a7e14dcfSSatish Balay } 337*a7e14dcfSSatish Balay 338*a7e14dcfSSatish Balay /* Successful termination, update memory */ 339*a7e14dcfSSatish Balay armP->lastReference = ref; 340*a7e14dcfSSatish Balay if (armP->replacementPolicy == REPLACE_FIFO) { 341*a7e14dcfSSatish Balay armP->memory[armP->current++] = *f; 342*a7e14dcfSSatish Balay if (armP->current >= armP->memorySize) { 343*a7e14dcfSSatish Balay armP->current = 0; 344*a7e14dcfSSatish Balay } 345*a7e14dcfSSatish Balay } else { 346*a7e14dcfSSatish Balay armP->current = idx; 347*a7e14dcfSSatish Balay armP->memory[idx] = *f; 348*a7e14dcfSSatish Balay } 349*a7e14dcfSSatish Balay 350*a7e14dcfSSatish Balay /* Update iterate and compute gradient */ 351*a7e14dcfSSatish Balay ierr = VecCopy(armP->work,x); CHKERRQ(ierr); 352*a7e14dcfSSatish Balay if (!g_computed) { 353*a7e14dcfSSatish Balay ierr = TaoLineSearchComputeGradient(ls, x, g); CHKERRQ(ierr); 354*a7e14dcfSSatish Balay } 355*a7e14dcfSSatish Balay 356*a7e14dcfSSatish Balay /* Finish computations */ 357*a7e14dcfSSatish Balay ierr = PetscInfo2(ls, "%d function evals in line search, step = %10.4f\n",ls->nfeval, ls->step); CHKERRQ(ierr); 358*a7e14dcfSSatish Balay 359*a7e14dcfSSatish Balay PetscFunctionReturn(0); 360*a7e14dcfSSatish Balay } 361*a7e14dcfSSatish Balay 362*a7e14dcfSSatish Balay EXTERN_C_BEGIN 363*a7e14dcfSSatish Balay #undef __FUNCT__ 364*a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchCreate_OWArmijo" 365*a7e14dcfSSatish Balay PetscErrorCode TaoLineSearchCreate_OWArmijo(TaoLineSearch ls) 366*a7e14dcfSSatish Balay { 367*a7e14dcfSSatish Balay TAOLINESEARCH_OWARMIJO_CTX *armP; 368*a7e14dcfSSatish Balay PetscErrorCode ierr; 369*a7e14dcfSSatish Balay 370*a7e14dcfSSatish Balay PetscFunctionBegin; 371*a7e14dcfSSatish Balay PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 372*a7e14dcfSSatish Balay ierr = PetscNewLog(ls,TAOLINESEARCH_OWARMIJO_CTX, &armP);CHKERRQ(ierr); 373*a7e14dcfSSatish Balay 374*a7e14dcfSSatish Balay armP->memory = PETSC_NULL; 375*a7e14dcfSSatish Balay armP->alpha = 1.0; 376*a7e14dcfSSatish Balay armP->beta = 0.25; 377*a7e14dcfSSatish Balay armP->beta_inf = 0.25; 378*a7e14dcfSSatish Balay armP->sigma = 1e-4; 379*a7e14dcfSSatish Balay armP->memorySize = 1; 380*a7e14dcfSSatish Balay armP->referencePolicy = REFERENCE_MAX; 381*a7e14dcfSSatish Balay armP->replacementPolicy = REPLACE_MRU; 382*a7e14dcfSSatish Balay armP->nondescending=PETSC_FALSE; 383*a7e14dcfSSatish Balay ls->data = (void*)armP; 384*a7e14dcfSSatish Balay ls->initstep=0.1; 385*a7e14dcfSSatish Balay ls->ops->setup=0; 386*a7e14dcfSSatish Balay ls->ops->apply=TaoLineSearchApply_OWArmijo; 387*a7e14dcfSSatish Balay ls->ops->view = TaoLineSearchView_OWArmijo; 388*a7e14dcfSSatish Balay ls->ops->destroy = TaoLineSearchDestroy_OWArmijo; 389*a7e14dcfSSatish Balay ls->ops->setfromoptions = TaoLineSearchSetFromOptions_OWArmijo; 390*a7e14dcfSSatish Balay 391*a7e14dcfSSatish Balay PetscFunctionReturn(0); 392*a7e14dcfSSatish Balay } 393*a7e14dcfSSatish Balay EXTERN_C_END 394