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