1*ac9112b8SAlp Dener #include <petsctaolinesearch.h> 2*ac9112b8SAlp Dener #include <../src/tao/bound/impls/bncg/bncg.h> 3*ac9112b8SAlp Dener 4*ac9112b8SAlp Dener #define CG_FletcherReeves 0 5*ac9112b8SAlp Dener #define CG_PolakRibiere 1 6*ac9112b8SAlp Dener #define CG_PolakRibierePlus 2 7*ac9112b8SAlp Dener #define CG_HestenesStiefel 3 8*ac9112b8SAlp Dener #define CG_DaiYuan 4 9*ac9112b8SAlp Dener #define CG_Types 5 10*ac9112b8SAlp Dener 11*ac9112b8SAlp Dener static const char *CG_Table[64] = {"fr", "pr", "prp", "hs", "dy"}; 12*ac9112b8SAlp Dener 13*ac9112b8SAlp Dener PetscErrorCode TaoBNCGResetStepForNewInactives(Tao tao, Vec step) 14*ac9112b8SAlp Dener { 15*ac9112b8SAlp Dener TAO_BNCG *cg = (TAO_BNCG*)tao->data; 16*ac9112b8SAlp Dener PetscErrorCode ierr; 17*ac9112b8SAlp Dener const PetscScalar *xl, *xo, *xn, *xu, *gn, *go; 18*ac9112b8SAlp Dener PetscInt size, i; 19*ac9112b8SAlp Dener PetscScalar *s; 20*ac9112b8SAlp Dener 21*ac9112b8SAlp Dener PetscFunctionBegin; 22*ac9112b8SAlp Dener ierr = VecGetLocalSize(tao->solution, &size);CHKERRQ(ierr); 23*ac9112b8SAlp Dener ierr = VecGetArrayRead(cg->unprojected_gradient_old, &go);CHKERRQ(ierr); 24*ac9112b8SAlp Dener ierr = VecGetArrayRead(cg->unprojected_gradient, &gn);CHKERRQ(ierr); 25*ac9112b8SAlp Dener ierr = VecGetArrayRead(cg->X_old, &xo);CHKERRQ(ierr); 26*ac9112b8SAlp Dener ierr = VecGetArrayRead(tao->solution, &xn);CHKERRQ(ierr); 27*ac9112b8SAlp Dener ierr = VecGetArrayRead(tao->XL, &xl);CHKERRQ(ierr); 28*ac9112b8SAlp Dener ierr = VecGetArrayRead(tao->XU, &xu);CHKERRQ(ierr); 29*ac9112b8SAlp Dener ierr = VecGetArray(step, &s);CHKERRQ(ierr); 30*ac9112b8SAlp Dener for (i=0; i<size; i++) { 31*ac9112b8SAlp Dener if (xl[i] == xu[i]) { 32*ac9112b8SAlp Dener s[i] = 0.0; 33*ac9112b8SAlp Dener } else { 34*ac9112b8SAlp Dener if (xl[i] > PETSC_NINFINITY) { 35*ac9112b8SAlp Dener if ((xn[i] == xl[i] && gn[i] < 0.0) && (xo[i] == xl[i] && go[i] >= 0.0)) { 36*ac9112b8SAlp Dener s[i] = -gn[i]; 37*ac9112b8SAlp Dener } 38*ac9112b8SAlp Dener } 39*ac9112b8SAlp Dener if (xu[i] < PETSC_NINFINITY) { 40*ac9112b8SAlp Dener if ((xn[i] == xu[i] && gn[i] > 0.0) && (xo[i] == xu[i] && go[i] <= 0.0)) { 41*ac9112b8SAlp Dener s[i] = -gn[i]; 42*ac9112b8SAlp Dener } 43*ac9112b8SAlp Dener } 44*ac9112b8SAlp Dener } 45*ac9112b8SAlp Dener } 46*ac9112b8SAlp Dener ierr = VecRestoreArrayRead(cg->unprojected_gradient_old, &go);CHKERRQ(ierr); 47*ac9112b8SAlp Dener ierr = VecRestoreArrayRead(cg->unprojected_gradient, &gn);CHKERRQ(ierr); 48*ac9112b8SAlp Dener ierr = VecRestoreArrayRead(cg->X_old, &xo);CHKERRQ(ierr); 49*ac9112b8SAlp Dener ierr = VecRestoreArrayRead(tao->solution, &xn);CHKERRQ(ierr); 50*ac9112b8SAlp Dener ierr = VecRestoreArrayRead(tao->XL, &xl);CHKERRQ(ierr); 51*ac9112b8SAlp Dener ierr = VecRestoreArrayRead(tao->XU, &xu);CHKERRQ(ierr); 52*ac9112b8SAlp Dener ierr = VecRestoreArray(step, &s);CHKERRQ(ierr); 53*ac9112b8SAlp Dener PetscFunctionReturn(0); 54*ac9112b8SAlp Dener } 55*ac9112b8SAlp Dener 56*ac9112b8SAlp Dener static PetscErrorCode TaoSolve_BNCG(Tao tao) 57*ac9112b8SAlp Dener { 58*ac9112b8SAlp Dener TAO_BNCG *cg = (TAO_BNCG*)tao->data; 59*ac9112b8SAlp Dener PetscErrorCode ierr; 60*ac9112b8SAlp Dener TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; 61*ac9112b8SAlp Dener PetscReal step=1.0,f,gnorm,gnorm2,delta,gd,ginner,beta,dnorm; 62*ac9112b8SAlp Dener PetscReal gd_old,gnorm2_old,f_old; 63*ac9112b8SAlp Dener PetscBool cg_restart; 64*ac9112b8SAlp Dener 65*ac9112b8SAlp Dener PetscFunctionBegin; 66*ac9112b8SAlp Dener /* Project the current point onto the feasible set */ 67*ac9112b8SAlp Dener ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 68*ac9112b8SAlp Dener ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); 69*ac9112b8SAlp Dener 70*ac9112b8SAlp Dener /* Project the initial point onto the feasible region */ 71*ac9112b8SAlp Dener ierr = VecMedian(tao->XL,tao->solution,tao->XU,tao->solution);CHKERRQ(ierr); 72*ac9112b8SAlp Dener 73*ac9112b8SAlp Dener /* Compute the objective function and criteria */ 74*ac9112b8SAlp Dener ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, cg->unprojected_gradient);CHKERRQ(ierr); 75*ac9112b8SAlp Dener ierr = VecNorm(cg->unprojected_gradient,NORM_2,&gnorm);CHKERRQ(ierr); 76*ac9112b8SAlp Dener if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 77*ac9112b8SAlp Dener 78*ac9112b8SAlp Dener /* Project the gradient and calculate the norm */ 79*ac9112b8SAlp Dener ierr = VecBoundGradientProjection(cg->unprojected_gradient,tao->solution,tao->XL,tao->XU,tao->gradient);CHKERRQ(ierr); 80*ac9112b8SAlp Dener ierr = VecNorm(tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 81*ac9112b8SAlp Dener gnorm2 = gnorm*gnorm; 82*ac9112b8SAlp Dener 83*ac9112b8SAlp Dener /* Convergence check */ 84*ac9112b8SAlp Dener tao->reason = TAO_CONTINUE_ITERATING; 85*ac9112b8SAlp Dener ierr = TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its);CHKERRQ(ierr); 86*ac9112b8SAlp Dener ierr = TaoMonitor(tao, tao->niter, f, gnorm, 0.0, step);CHKERRQ(ierr); 87*ac9112b8SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 88*ac9112b8SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 89*ac9112b8SAlp Dener 90*ac9112b8SAlp Dener /* Start optimization iterations */ 91*ac9112b8SAlp Dener f_old = f; 92*ac9112b8SAlp Dener gnorm2_old = gnorm2; 93*ac9112b8SAlp Dener ierr = VecCopy(tao->solution, cg->X_old);CHKERRQ(ierr); 94*ac9112b8SAlp Dener ierr = VecCopy(tao->gradient, cg->G_old);CHKERRQ(ierr); 95*ac9112b8SAlp Dener ierr = VecCopy(cg->unprojected_gradient, cg->unprojected_gradient_old);CHKERRQ(ierr); 96*ac9112b8SAlp Dener tao->niter = cg->ls_fails = cg->broken_ortho = cg->descent_error = 0; 97*ac9112b8SAlp Dener cg->resets = -1; 98*ac9112b8SAlp Dener while (tao->reason == TAO_CONTINUE_ITERATING) { 99*ac9112b8SAlp Dener /* Check restart conditions for using steepest descent */ 100*ac9112b8SAlp Dener cg_restart = PETSC_FALSE; 101*ac9112b8SAlp Dener ierr = VecDot(tao->gradient, cg->G_old, &ginner);CHKERRQ(ierr); 102*ac9112b8SAlp Dener if (tao->niter == 0) { 103*ac9112b8SAlp Dener /* 1) First iteration */ 104*ac9112b8SAlp Dener cg_restart = PETSC_TRUE; 105*ac9112b8SAlp Dener } else if (PetscAbsScalar(ginner) >= cg->eta * gnorm2) { 106*ac9112b8SAlp Dener /* 2) Gradients are far from orthogonal */ 107*ac9112b8SAlp Dener cg_restart = PETSC_TRUE; 108*ac9112b8SAlp Dener cg->broken_ortho++; 109*ac9112b8SAlp Dener } 110*ac9112b8SAlp Dener 111*ac9112b8SAlp Dener /* Compute CG step */ 112*ac9112b8SAlp Dener if (cg_restart) { 113*ac9112b8SAlp Dener beta = 0.0; 114*ac9112b8SAlp Dener cg->resets++; 115*ac9112b8SAlp Dener } else { 116*ac9112b8SAlp Dener switch (cg->cg_type) { 117*ac9112b8SAlp Dener case CG_FletcherReeves: 118*ac9112b8SAlp Dener beta = gnorm2 / gnorm2_old; 119*ac9112b8SAlp Dener break; 120*ac9112b8SAlp Dener 121*ac9112b8SAlp Dener case CG_PolakRibiere: 122*ac9112b8SAlp Dener beta = (gnorm2 - ginner) / gnorm2_old; 123*ac9112b8SAlp Dener break; 124*ac9112b8SAlp Dener 125*ac9112b8SAlp Dener case CG_PolakRibierePlus: 126*ac9112b8SAlp Dener beta = PetscMax((gnorm2-ginner)/gnorm2_old, 0.0); 127*ac9112b8SAlp Dener break; 128*ac9112b8SAlp Dener 129*ac9112b8SAlp Dener case CG_HestenesStiefel: 130*ac9112b8SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gd);CHKERRQ(ierr); 131*ac9112b8SAlp Dener ierr = VecDot(cg->G_old, tao->stepdirection, &gd_old);CHKERRQ(ierr); 132*ac9112b8SAlp Dener beta = (gnorm2 - ginner) / (gd - gd_old); 133*ac9112b8SAlp Dener break; 134*ac9112b8SAlp Dener 135*ac9112b8SAlp Dener case CG_DaiYuan: 136*ac9112b8SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gd);CHKERRQ(ierr); 137*ac9112b8SAlp Dener ierr = VecDot(cg->G_old, tao->stepdirection, &gd_old);CHKERRQ(ierr); 138*ac9112b8SAlp Dener beta = gnorm2 / (gd - gd_old); 139*ac9112b8SAlp Dener break; 140*ac9112b8SAlp Dener 141*ac9112b8SAlp Dener default: 142*ac9112b8SAlp Dener beta = 0.0; 143*ac9112b8SAlp Dener break; 144*ac9112b8SAlp Dener } 145*ac9112b8SAlp Dener } 146*ac9112b8SAlp Dener 147*ac9112b8SAlp Dener /* Compute the direction d=-g + beta*d */ 148*ac9112b8SAlp Dener ierr = VecAXPBY(tao->stepdirection, -1.0, beta, tao->gradient);CHKERRQ(ierr); 149*ac9112b8SAlp Dener ierr = TaoBNCGResetStepForNewInactives(tao, tao->stepdirection);CHKERRQ(ierr); 150*ac9112b8SAlp Dener 151*ac9112b8SAlp Dener /* Verify that this is a descent direction */ 152*ac9112b8SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gd);CHKERRQ(ierr); 153*ac9112b8SAlp Dener ierr = VecNorm(tao->stepdirection, NORM_2, &dnorm); 154*ac9112b8SAlp Dener if (gd > -cg->rho*PetscPowReal(dnorm, cg->pow)) { 155*ac9112b8SAlp Dener /* Not a descent direction, so we reset back to projected gradient descent */ 156*ac9112b8SAlp Dener ierr = VecAXPBY(tao->stepdirection, -1.0, 0.0, tao->gradient);CHKERRQ(ierr); 157*ac9112b8SAlp Dener cg->resets++; 158*ac9112b8SAlp Dener cg->descent_error++; 159*ac9112b8SAlp Dener } 160*ac9112b8SAlp Dener 161*ac9112b8SAlp Dener /* update initial steplength choice */ 162*ac9112b8SAlp Dener delta = 1.0; 163*ac9112b8SAlp Dener delta = PetscMax(delta, cg->delta_min); 164*ac9112b8SAlp Dener delta = PetscMin(delta, cg->delta_max); 165*ac9112b8SAlp Dener 166*ac9112b8SAlp Dener /* Store solution and gradient info before it changes */ 167*ac9112b8SAlp Dener ierr = VecCopy(tao->solution, cg->X_old);CHKERRQ(ierr); 168*ac9112b8SAlp Dener ierr = VecCopy(tao->gradient, cg->G_old);CHKERRQ(ierr); 169*ac9112b8SAlp Dener ierr = VecCopy(cg->unprojected_gradient, cg->unprojected_gradient_old);CHKERRQ(ierr); 170*ac9112b8SAlp Dener gnorm2_old = gnorm2; 171*ac9112b8SAlp Dener f_old = f; 172*ac9112b8SAlp Dener 173*ac9112b8SAlp Dener /* Perform bounded line search */ 174*ac9112b8SAlp Dener ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,delta);CHKERRQ(ierr); 175*ac9112b8SAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, cg->unprojected_gradient, tao->stepdirection, &step, &ls_status);CHKERRQ(ierr); 176*ac9112b8SAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 177*ac9112b8SAlp Dener 178*ac9112b8SAlp Dener /* Check linesearch failure */ 179*ac9112b8SAlp Dener if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) { 180*ac9112b8SAlp Dener cg->ls_fails++; 181*ac9112b8SAlp Dener /* Restore previous point */ 182*ac9112b8SAlp Dener gnorm2 = gnorm2_old; 183*ac9112b8SAlp Dener f = f_old; 184*ac9112b8SAlp Dener ierr = VecCopy(cg->X_old, tao->solution);CHKERRQ(ierr); 185*ac9112b8SAlp Dener ierr = VecCopy(cg->G_old, tao->gradient);CHKERRQ(ierr); 186*ac9112b8SAlp Dener ierr = VecCopy(cg->unprojected_gradient_old, cg->unprojected_gradient);CHKERRQ(ierr); 187*ac9112b8SAlp Dener 188*ac9112b8SAlp Dener /* Fall back on the unscaled gradient step */ 189*ac9112b8SAlp Dener delta = 1.0; 190*ac9112b8SAlp Dener ierr = VecCopy(tao->solution, tao->stepdirection);CHKERRQ(ierr); 191*ac9112b8SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 192*ac9112b8SAlp Dener 193*ac9112b8SAlp Dener ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,delta);CHKERRQ(ierr); 194*ac9112b8SAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, cg->unprojected_gradient, tao->stepdirection, &step, &ls_status);CHKERRQ(ierr); 195*ac9112b8SAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 196*ac9112b8SAlp Dener 197*ac9112b8SAlp Dener if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER){ 198*ac9112b8SAlp Dener cg->ls_fails++; 199*ac9112b8SAlp Dener /* Restore previous point */ 200*ac9112b8SAlp Dener gnorm2 = gnorm2_old; 201*ac9112b8SAlp Dener f = f_old; 202*ac9112b8SAlp Dener ierr = VecCopy(cg->X_old, tao->solution);CHKERRQ(ierr); 203*ac9112b8SAlp Dener ierr = VecCopy(cg->G_old, tao->gradient);CHKERRQ(ierr); 204*ac9112b8SAlp Dener ierr = VecCopy(cg->unprojected_gradient_old, cg->unprojected_gradient);CHKERRQ(ierr); 205*ac9112b8SAlp Dener 206*ac9112b8SAlp Dener /* Nothing left to do but fail out of the optimization */ 207*ac9112b8SAlp Dener step = 0.0; 208*ac9112b8SAlp Dener tao->reason = TAO_DIVERGED_LS_FAILURE; 209*ac9112b8SAlp Dener } 210*ac9112b8SAlp Dener } 211*ac9112b8SAlp Dener 212*ac9112b8SAlp Dener /* Compute the projected gradient and its norm */ 213*ac9112b8SAlp Dener ierr = VecBoundGradientProjection(cg->unprojected_gradient,tao->solution,tao->XL,tao->XU,tao->gradient);CHKERRQ(ierr); 214*ac9112b8SAlp Dener ierr = VecNorm(tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 215*ac9112b8SAlp Dener gnorm2 = gnorm*gnorm; 216*ac9112b8SAlp Dener 217*ac9112b8SAlp Dener /* Convergence test */ 218*ac9112b8SAlp Dener tao->niter++; 219*ac9112b8SAlp Dener ierr = TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its);CHKERRQ(ierr); 220*ac9112b8SAlp Dener ierr = TaoMonitor(tao, tao->niter, f, gnorm, 0.0, step);CHKERRQ(ierr); 221*ac9112b8SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 222*ac9112b8SAlp Dener } 223*ac9112b8SAlp Dener PetscFunctionReturn(0); 224*ac9112b8SAlp Dener } 225*ac9112b8SAlp Dener 226*ac9112b8SAlp Dener static PetscErrorCode TaoSetUp_BNCG(Tao tao) 227*ac9112b8SAlp Dener { 228*ac9112b8SAlp Dener TAO_BNCG *cg = (TAO_BNCG*)tao->data; 229*ac9112b8SAlp Dener PetscErrorCode ierr; 230*ac9112b8SAlp Dener 231*ac9112b8SAlp Dener PetscFunctionBegin; 232*ac9112b8SAlp Dener if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr);} 233*ac9112b8SAlp Dener if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); } 234*ac9112b8SAlp Dener if (!cg->X_old) {ierr = VecDuplicate(tao->solution,&cg->X_old);CHKERRQ(ierr);} 235*ac9112b8SAlp Dener if (!cg->G_old) {ierr = VecDuplicate(tao->gradient,&cg->G_old);CHKERRQ(ierr); } 236*ac9112b8SAlp Dener if (!cg->unprojected_gradient) {ierr = VecDuplicate(tao->gradient,&cg->unprojected_gradient);CHKERRQ(ierr);} 237*ac9112b8SAlp Dener if (!cg->unprojected_gradient_old) {ierr = VecDuplicate(tao->gradient,&cg->unprojected_gradient_old);CHKERRQ(ierr);} 238*ac9112b8SAlp Dener PetscFunctionReturn(0); 239*ac9112b8SAlp Dener } 240*ac9112b8SAlp Dener 241*ac9112b8SAlp Dener static PetscErrorCode TaoDestroy_BNCG(Tao tao) 242*ac9112b8SAlp Dener { 243*ac9112b8SAlp Dener TAO_BNCG *cg = (TAO_BNCG*) tao->data; 244*ac9112b8SAlp Dener PetscErrorCode ierr; 245*ac9112b8SAlp Dener 246*ac9112b8SAlp Dener PetscFunctionBegin; 247*ac9112b8SAlp Dener if (tao->setupcalled) { 248*ac9112b8SAlp Dener ierr = VecDestroy(&cg->X_old);CHKERRQ(ierr); 249*ac9112b8SAlp Dener ierr = VecDestroy(&cg->G_old);CHKERRQ(ierr); 250*ac9112b8SAlp Dener ierr = VecDestroy(&cg->unprojected_gradient);CHKERRQ(ierr); 251*ac9112b8SAlp Dener ierr = VecDestroy(&cg->unprojected_gradient_old);CHKERRQ(ierr); 252*ac9112b8SAlp Dener } 253*ac9112b8SAlp Dener ierr = TaoLineSearchDestroy(&tao->linesearch);CHKERRQ(ierr); 254*ac9112b8SAlp Dener ierr = PetscFree(tao->data);CHKERRQ(ierr); 255*ac9112b8SAlp Dener PetscFunctionReturn(0); 256*ac9112b8SAlp Dener } 257*ac9112b8SAlp Dener 258*ac9112b8SAlp Dener static PetscErrorCode TaoSetFromOptions_BNCG(PetscOptionItems *PetscOptionsObject,Tao tao) 259*ac9112b8SAlp Dener { 260*ac9112b8SAlp Dener TAO_BNCG *cg = (TAO_BNCG*)tao->data; 261*ac9112b8SAlp Dener PetscErrorCode ierr; 262*ac9112b8SAlp Dener 263*ac9112b8SAlp Dener PetscFunctionBegin; 264*ac9112b8SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 265*ac9112b8SAlp Dener ierr = PetscOptionsHead(PetscOptionsObject,"Nonlinear Conjugate Gradient method for unconstrained optimization");CHKERRQ(ierr); 266*ac9112b8SAlp Dener ierr = PetscOptionsReal("-tao_BNCG_eta","restart tolerance", "", cg->eta,&cg->eta,NULL);CHKERRQ(ierr); 267*ac9112b8SAlp Dener ierr = PetscOptionsReal("-tao_BNCG_rho","descent direction tolerance", "", cg->rho,&cg->rho,NULL);CHKERRQ(ierr); 268*ac9112b8SAlp Dener ierr = PetscOptionsReal("-tao_BNCG_pow","descent direction exponent", "", cg->pow,&cg->pow,NULL);CHKERRQ(ierr); 269*ac9112b8SAlp Dener ierr = PetscOptionsEList("-tao_BNCG_type","cg formula", "", CG_Table, CG_Types, CG_Table[cg->cg_type], &cg->cg_type,NULL);CHKERRQ(ierr); 270*ac9112b8SAlp Dener ierr = PetscOptionsReal("-tao_BNCG_delta_min","minimum delta value", "", cg->delta_min,&cg->delta_min,NULL);CHKERRQ(ierr); 271*ac9112b8SAlp Dener ierr = PetscOptionsReal("-tao_BNCG_delta_max","maximum delta value", "", cg->delta_max,&cg->delta_max,NULL);CHKERRQ(ierr); 272*ac9112b8SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 273*ac9112b8SAlp Dener PetscFunctionReturn(0); 274*ac9112b8SAlp Dener } 275*ac9112b8SAlp Dener 276*ac9112b8SAlp Dener static PetscErrorCode TaoView_BNCG(Tao tao, PetscViewer viewer) 277*ac9112b8SAlp Dener { 278*ac9112b8SAlp Dener PetscBool isascii; 279*ac9112b8SAlp Dener TAO_BNCG *cg = (TAO_BNCG*)tao->data; 280*ac9112b8SAlp Dener PetscErrorCode ierr; 281*ac9112b8SAlp Dener 282*ac9112b8SAlp Dener PetscFunctionBegin; 283*ac9112b8SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr); 284*ac9112b8SAlp Dener if (isascii) { 285*ac9112b8SAlp Dener ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 286*ac9112b8SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "CG Type: %s\n", CG_Table[cg->cg_type]);CHKERRQ(ierr); 287*ac9112b8SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Resets: %i\n", cg->resets);CHKERRQ(ierr); 288*ac9112b8SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " Broken ortho: %i\n", cg->broken_ortho);CHKERRQ(ierr); 289*ac9112b8SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " Not a descent dir.: %i\n", cg->descent_error);CHKERRQ(ierr); 290*ac9112b8SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Line search fails: %i\n", cg->ls_fails);CHKERRQ(ierr); 291*ac9112b8SAlp Dener ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 292*ac9112b8SAlp Dener } 293*ac9112b8SAlp Dener PetscFunctionReturn(0); 294*ac9112b8SAlp Dener } 295*ac9112b8SAlp Dener 296*ac9112b8SAlp Dener /*MC 297*ac9112b8SAlp Dener TAOBNCG - Bound-constrained Nonlinear Conjugate Gradient method. 298*ac9112b8SAlp Dener 299*ac9112b8SAlp Dener Options Database Keys: 300*ac9112b8SAlp Dener + -tao_BNCG_eta <r> - restart tolerance 301*ac9112b8SAlp Dener . -tao_BNCG_type <taocg_type> - cg formula 302*ac9112b8SAlp Dener . -tao_BNCG_delta_min <r> - minimum delta value 303*ac9112b8SAlp Dener - -tao_BNCG_delta_max <r> - maximum delta value 304*ac9112b8SAlp Dener 305*ac9112b8SAlp Dener Notes: 306*ac9112b8SAlp Dener CG formulas are: 307*ac9112b8SAlp Dener "fr" - Fletcher-Reeves 308*ac9112b8SAlp Dener "pr" - Polak-Ribiere 309*ac9112b8SAlp Dener "prp" - Polak-Ribiere-Plus 310*ac9112b8SAlp Dener "hs" - Hestenes-Steifel 311*ac9112b8SAlp Dener "dy" - Dai-Yuan 312*ac9112b8SAlp Dener Level: beginner 313*ac9112b8SAlp Dener M*/ 314*ac9112b8SAlp Dener 315*ac9112b8SAlp Dener 316*ac9112b8SAlp Dener PETSC_EXTERN PetscErrorCode TaoCreate_BNCG(Tao tao) 317*ac9112b8SAlp Dener { 318*ac9112b8SAlp Dener TAO_BNCG *cg; 319*ac9112b8SAlp Dener const char *morethuente_type = TAOLINESEARCHMT; 320*ac9112b8SAlp Dener PetscErrorCode ierr; 321*ac9112b8SAlp Dener 322*ac9112b8SAlp Dener PetscFunctionBegin; 323*ac9112b8SAlp Dener tao->ops->setup = TaoSetUp_BNCG; 324*ac9112b8SAlp Dener tao->ops->solve = TaoSolve_BNCG; 325*ac9112b8SAlp Dener tao->ops->view = TaoView_BNCG; 326*ac9112b8SAlp Dener tao->ops->setfromoptions = TaoSetFromOptions_BNCG; 327*ac9112b8SAlp Dener tao->ops->destroy = TaoDestroy_BNCG; 328*ac9112b8SAlp Dener 329*ac9112b8SAlp Dener /* Override default settings (unless already changed) */ 330*ac9112b8SAlp Dener if (!tao->max_it_changed) tao->max_it = 2000; 331*ac9112b8SAlp Dener if (!tao->max_funcs_changed) tao->max_funcs = 4000; 332*ac9112b8SAlp Dener 333*ac9112b8SAlp Dener /* Note: nondefault values should be used for nonlinear conjugate gradient */ 334*ac9112b8SAlp Dener /* method. In particular, gtol should be less that 0.5; the value used in */ 335*ac9112b8SAlp Dener /* Nocedal and Wright is 0.10. We use the default values for the */ 336*ac9112b8SAlp Dener /* linesearch because it seems to work better. */ 337*ac9112b8SAlp Dener ierr = TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch);CHKERRQ(ierr); 338*ac9112b8SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 339*ac9112b8SAlp Dener ierr = TaoLineSearchSetType(tao->linesearch, morethuente_type);CHKERRQ(ierr); 340*ac9112b8SAlp Dener ierr = TaoLineSearchUseTaoRoutines(tao->linesearch, tao);CHKERRQ(ierr); 341*ac9112b8SAlp Dener ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 342*ac9112b8SAlp Dener 343*ac9112b8SAlp Dener ierr = PetscNewLog(tao,&cg);CHKERRQ(ierr); 344*ac9112b8SAlp Dener tao->data = (void*)cg; 345*ac9112b8SAlp Dener cg->rho = 1e-4; 346*ac9112b8SAlp Dener cg->pow = 2.1; 347*ac9112b8SAlp Dener cg->eta = 0.5; 348*ac9112b8SAlp Dener cg->delta_min = 1e-7; 349*ac9112b8SAlp Dener cg->delta_max = 100; 350*ac9112b8SAlp Dener cg->cg_type = CG_DaiYuan; 351*ac9112b8SAlp Dener PetscFunctionReturn(0); 352*ac9112b8SAlp Dener } 353