xref: /petsc/src/tao/unconstrained/impls/cg/taocg.c (revision 6c23d07575f07c9a033c9cb13c1a90726fd2593a)
15e1affc2SSatish Balay #include "taolinesearch.h"
25e1affc2SSatish Balay #include "taocg.h"
35e1affc2SSatish Balay 
45e1affc2SSatish Balay #define CG_FletcherReeves       0
55e1affc2SSatish Balay #define CG_PolakRibiere         1
65e1affc2SSatish Balay #define CG_PolakRibierePlus     2
75e1affc2SSatish Balay #define CG_HestenesStiefel      3
85e1affc2SSatish Balay #define CG_DaiYuan              4
95e1affc2SSatish Balay #define CG_Types                5
105e1affc2SSatish Balay 
115e1affc2SSatish Balay static const char *CG_Table[64] = {
125e1affc2SSatish Balay   "fr", "pr", "prp", "hs", "dy"
135e1affc2SSatish Balay };
145e1affc2SSatish Balay 
155e1affc2SSatish Balay 
165e1affc2SSatish Balay #undef __FUNCT__
175e1affc2SSatish Balay #define __FUNCT__ "TaoSolve_CG"
185e1affc2SSatish Balay static PetscErrorCode TaoSolve_CG(TaoSolver tao)
195e1affc2SSatish Balay {
205e1affc2SSatish Balay     TAO_CG *cgP = (TAO_CG*)tao->data;
215e1affc2SSatish Balay     PetscErrorCode ierr;
225e1affc2SSatish Balay     TaoSolverTerminationReason reason = TAO_CONTINUE_ITERATING;
235e1affc2SSatish Balay     TaoLineSearchTerminationReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING;
245e1affc2SSatish Balay     PetscReal step=1.0,f,gnorm,gnorm2,delta,gd,ginner,beta;
255e1affc2SSatish Balay     PetscReal gd_old,gnorm2_old,f_old;
265e1affc2SSatish Balay     PetscInt iter=0;
275e1affc2SSatish Balay 
285e1affc2SSatish Balay 
295e1affc2SSatish Balay     PetscFunctionBegin;
305e1affc2SSatish Balay 
315e1affc2SSatish Balay     if (tao->XL || tao->XU || tao->ops->computebounds) {
325e1affc2SSatish Balay       ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by cg algorithm\n"); CHKERRQ(ierr);
335e1affc2SSatish Balay     }
345e1affc2SSatish Balay 
355e1affc2SSatish Balay     /*  Check convergence criteria */
365e1affc2SSatish Balay     ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient); CHKERRQ(ierr);
375e1affc2SSatish Balay     ierr = VecNorm(tao->gradient,NORM_2,&gnorm); CHKERRQ(ierr);
385e1affc2SSatish Balay     if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) {
395e1affc2SSatish Balay 	SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
405e1affc2SSatish Balay     }
415e1affc2SSatish Balay 
425e1affc2SSatish Balay     ierr = TaoMonitor(tao, iter, f, gnorm, 0.0, step, &reason); CHKERRQ(ierr);
435e1affc2SSatish Balay     if (reason != TAO_CONTINUE_ITERATING) {
445e1affc2SSatish Balay 	PetscFunctionReturn(0);
455e1affc2SSatish Balay     }
465e1affc2SSatish Balay 
475e1affc2SSatish Balay 
485e1affc2SSatish Balay     /*  Set initial direction to -gradient */
495e1affc2SSatish Balay     ierr = VecCopy(tao->gradient, tao->stepdirection); CHKERRQ(ierr);
505e1affc2SSatish Balay     ierr = VecScale(tao->stepdirection, -1.0); CHKERRQ(ierr);
515e1affc2SSatish Balay     gnorm2 = gnorm*gnorm;
525e1affc2SSatish Balay 
535e1affc2SSatish Balay     /*  Set initial scaling for the function */
545e1affc2SSatish Balay     if (f != 0.0) {
555e1affc2SSatish Balay 	delta = 2.0*PetscAbsScalar(f) / gnorm2;
565e1affc2SSatish Balay 	delta = PetscMax(delta,cgP->delta_min);
575e1affc2SSatish Balay 	delta = PetscMin(delta,cgP->delta_max);
585e1affc2SSatish Balay     } else {
595e1affc2SSatish Balay 	delta = 2.0 / gnorm2;
605e1affc2SSatish Balay 	delta = PetscMax(delta,cgP->delta_min);
615e1affc2SSatish Balay 	delta = PetscMin(delta,cgP->delta_max);
625e1affc2SSatish Balay     }
635e1affc2SSatish Balay     /*  Set counter for gradient and reset steps */
645e1affc2SSatish Balay     cgP->ngradsteps = 0;
655e1affc2SSatish Balay     cgP->nresetsteps = 0;
665e1affc2SSatish Balay 
675e1affc2SSatish Balay     while (1) {
685e1affc2SSatish Balay 	/*  Save the current gradient information */
695e1affc2SSatish Balay 	f_old = f;
705e1affc2SSatish Balay 	gnorm2_old = gnorm2;
715e1affc2SSatish Balay 	ierr = VecCopy(tao->solution, cgP->X_old); CHKERRQ(ierr);
725e1affc2SSatish Balay 	ierr = VecCopy(tao->gradient, cgP->G_old); CHKERRQ(ierr);
735e1affc2SSatish Balay 	ierr = VecDot(tao->gradient, tao->stepdirection, &gd); CHKERRQ(ierr);
745e1affc2SSatish Balay 	if ((gd >= 0) || PetscIsInfOrNanReal(gd)) {
755e1affc2SSatish Balay 	    ++cgP->ngradsteps;
765e1affc2SSatish Balay 	    if (f != 0.0) {
775e1affc2SSatish Balay 		delta = 2.0*PetscAbsScalar(f) / gnorm2;
785e1affc2SSatish Balay 		delta = PetscMax(delta,cgP->delta_min);
795e1affc2SSatish Balay 		delta = PetscMin(delta,cgP->delta_max);
805e1affc2SSatish Balay 	    } else {
815e1affc2SSatish Balay 		delta = 2.0 / gnorm2;
825e1affc2SSatish Balay 		delta = PetscMax(delta,cgP->delta_min);
835e1affc2SSatish Balay 		delta = PetscMin(delta,cgP->delta_max);
845e1affc2SSatish Balay 	    }
855e1affc2SSatish Balay 
865e1affc2SSatish Balay 	    ierr = VecCopy(tao->gradient, tao->stepdirection); CHKERRQ(ierr);
875e1affc2SSatish Balay 	    ierr = VecScale(tao->stepdirection, -1.0); CHKERRQ(ierr);
885e1affc2SSatish Balay 	}
895e1affc2SSatish Balay 
905e1affc2SSatish Balay 	/*  Search direction for improving point */
915e1affc2SSatish Balay 	ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,delta);
925e1affc2SSatish Balay 	ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status); CHKERRQ(ierr);
935e1affc2SSatish Balay 	ierr = TaoAddLineSearchCounts(tao); CHKERRQ(ierr);
945e1affc2SSatish Balay 	if (ls_status != TAOLINESEARCH_SUCCESS &&
955e1affc2SSatish Balay 	    ls_status != TAOLINESEARCH_SUCCESS_USER) {
965e1affc2SSatish Balay 	    /*  Linesearch failed */
975e1affc2SSatish Balay 	    /*  Reset factors and use scaled gradient step */
985e1affc2SSatish Balay 	    ++cgP->nresetsteps;
995e1affc2SSatish Balay 	    f = f_old;
1005e1affc2SSatish Balay 	    gnorm2 = gnorm2_old;
1015e1affc2SSatish Balay 	    ierr = VecCopy(cgP->X_old, tao->solution); CHKERRQ(ierr);
1025e1affc2SSatish Balay 	    ierr = VecCopy(cgP->G_old, tao->gradient); CHKERRQ(ierr);
1035e1affc2SSatish Balay 
1045e1affc2SSatish Balay 	    if (f != 0.0) {
1055e1affc2SSatish Balay 		delta = 2.0*PetscAbsScalar(f) / gnorm2;
1065e1affc2SSatish Balay 		delta = PetscMax(delta,cgP->delta_min);
1075e1affc2SSatish Balay 		delta = PetscMin(delta,cgP->delta_max);
1085e1affc2SSatish Balay 	    } else {
1095e1affc2SSatish Balay 		delta = 2.0 / gnorm2;
1105e1affc2SSatish Balay 		delta = PetscMax(delta,cgP->delta_min);
1115e1affc2SSatish Balay 		delta = PetscMin(delta,cgP->delta_max);
1125e1affc2SSatish Balay 	    }
1135e1affc2SSatish Balay 
1145e1affc2SSatish Balay 	    ierr = VecCopy(tao->gradient, tao->stepdirection); CHKERRQ(ierr);
1155e1affc2SSatish Balay 	    ierr = VecScale(tao->stepdirection, -1.0); CHKERRQ(ierr);
1165e1affc2SSatish Balay 
1175e1affc2SSatish Balay 	    ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,delta);
1185e1affc2SSatish Balay 	    ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status); CHKERRQ(ierr);
1195e1affc2SSatish Balay 	    ierr = TaoAddLineSearchCounts(tao); CHKERRQ(ierr);
1205e1affc2SSatish Balay 
1215e1affc2SSatish Balay 	    if (ls_status != TAOLINESEARCH_SUCCESS &&
1225e1affc2SSatish Balay 		ls_status != TAOLINESEARCH_SUCCESS_USER) {
1235e1affc2SSatish Balay 		/*  Linesearch failed again */
1245e1affc2SSatish Balay 		/*  switch to unscaled gradient */
1255e1affc2SSatish Balay 		f = f_old;
1265e1affc2SSatish Balay 		gnorm2 = gnorm2_old;
1275e1affc2SSatish Balay 		ierr = VecCopy(cgP->X_old, tao->solution); CHKERRQ(ierr);
1285e1affc2SSatish Balay 		ierr = VecCopy(cgP->G_old, tao->gradient); CHKERRQ(ierr);
1295e1affc2SSatish Balay 		delta = 1.0;
1305e1affc2SSatish Balay 		ierr = VecCopy(tao->solution, tao->stepdirection); CHKERRQ(ierr);
1315e1affc2SSatish Balay 		ierr = VecScale(tao->stepdirection, -1.0); CHKERRQ(ierr);
1325e1affc2SSatish Balay 
1335e1affc2SSatish Balay 		ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,delta);
1345e1affc2SSatish Balay 		ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status); CHKERRQ(ierr);
1355e1affc2SSatish Balay 		ierr = TaoAddLineSearchCounts(tao); CHKERRQ(ierr);
1365e1affc2SSatish Balay 		if (ls_status != TAOLINESEARCH_SUCCESS &&
1375e1affc2SSatish Balay 		    ls_status != TAOLINESEARCH_SUCCESS_USER) {
1385e1affc2SSatish Balay 
1395e1affc2SSatish Balay 		  /*  Line search failed for last time -- give up */
1405e1affc2SSatish Balay 		  f = f_old;
1415e1affc2SSatish Balay 		  gnorm2 = gnorm2_old;
1425e1affc2SSatish Balay 		  ierr = VecCopy(cgP->X_old, tao->solution); CHKERRQ(ierr);
1435e1affc2SSatish Balay 		  ierr = VecCopy(cgP->G_old, tao->gradient); CHKERRQ(ierr);
1445e1affc2SSatish Balay 		  step = 0.0;
1455e1affc2SSatish Balay 		  reason = TAO_DIVERGED_LS_FAILURE;
1465e1affc2SSatish Balay 		  tao->reason = TAO_DIVERGED_LS_FAILURE;
1475e1affc2SSatish Balay 		}
1485e1affc2SSatish Balay 	    }
1495e1affc2SSatish Balay 	}
1505e1affc2SSatish Balay 
1515e1affc2SSatish Balay 	/*  Check for bad value */
1525e1affc2SSatish Balay 	ierr = VecNorm(tao->gradient,NORM_2,&gnorm); CHKERRQ(ierr);
1535e1affc2SSatish Balay 	if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) {
1545e1affc2SSatish Balay 	    SETERRQ(PETSC_COMM_SELF,1,"User-provided compute function generated Inf or NaN");
1555e1affc2SSatish Balay 	}
1565e1affc2SSatish Balay 
1575e1affc2SSatish Balay 	/*  Check for termination */
1585e1affc2SSatish Balay 	gnorm2 =gnorm * gnorm;
1595e1affc2SSatish Balay 	iter++;
1605e1affc2SSatish Balay 	ierr = TaoMonitor(tao, iter, f, gnorm, 0.0, step, &reason); CHKERRQ(ierr);
1615e1affc2SSatish Balay 	if (reason != TAO_CONTINUE_ITERATING) {
1625e1affc2SSatish Balay 	    break;
1635e1affc2SSatish Balay 	}
1645e1affc2SSatish Balay 
1655e1affc2SSatish Balay 	/*  Check for restart condition */
1665e1affc2SSatish Balay 	ierr = VecDot(tao->gradient, cgP->G_old, &ginner); CHKERRQ(ierr);
1675e1affc2SSatish Balay 	if (PetscAbsScalar(ginner) >= cgP->eta * gnorm2) {
1685e1affc2SSatish Balay 	    /*  Gradients far from orthognal; use steepest descent direction */
1695e1affc2SSatish Balay 	    beta = 0.0;
1705e1affc2SSatish Balay 	} else {
1715e1affc2SSatish Balay 	    /*  Gradients close to orthogonal; use conjugate gradient formula */
1725e1affc2SSatish Balay 	    switch (cgP->cg_type) {
1735e1affc2SSatish Balay 		case CG_FletcherReeves:
1745e1affc2SSatish Balay 		    beta = gnorm2 / gnorm2_old;
1755e1affc2SSatish Balay 		    break;
1765e1affc2SSatish Balay 
1775e1affc2SSatish Balay 		case CG_PolakRibiere:
1785e1affc2SSatish Balay 		    beta = (gnorm2 - ginner) / gnorm2_old;
1795e1affc2SSatish Balay 		    break;
1805e1affc2SSatish Balay 
1815e1affc2SSatish Balay 		case CG_PolakRibierePlus:
1825e1affc2SSatish Balay 		    beta = PetscMax((gnorm2-ginner)/gnorm2_old, 0.0);
1835e1affc2SSatish Balay 		    break;
1845e1affc2SSatish Balay 
1855e1affc2SSatish Balay 		case CG_HestenesStiefel:
1865e1affc2SSatish Balay 		    ierr = VecDot(tao->gradient, tao->stepdirection, &gd); CHKERRQ(ierr);
1875e1affc2SSatish Balay 		    ierr = VecDot(cgP->G_old, tao->stepdirection, &gd_old); CHKERRQ(ierr);
1885e1affc2SSatish Balay 		    beta = (gnorm2 - ginner) / (gd - gd_old);
1895e1affc2SSatish Balay 		    break;
1905e1affc2SSatish Balay 
1915e1affc2SSatish Balay 		case CG_DaiYuan:
1925e1affc2SSatish Balay 		    ierr = VecDot(tao->gradient, tao->stepdirection, &gd); CHKERRQ(ierr);
1935e1affc2SSatish Balay 		    ierr = VecDot(cgP->G_old, tao->stepdirection, &gd_old); CHKERRQ(ierr);
1945e1affc2SSatish Balay 		    beta = gnorm2 / (gd - gd_old);
1955e1affc2SSatish Balay 		    break;
1965e1affc2SSatish Balay 
1975e1affc2SSatish Balay 		default:
1985e1affc2SSatish Balay 		    beta = 0.0;
1995e1affc2SSatish Balay 		    break;
2005e1affc2SSatish Balay 	    }
2015e1affc2SSatish Balay 	}
2025e1affc2SSatish Balay 
2035e1affc2SSatish Balay 	/*  Compute the direction d=-g + beta*d */
2045e1affc2SSatish Balay 	ierr = VecAXPBY(tao->stepdirection, -1.0, beta, tao->gradient); CHKERRQ(ierr);
2055e1affc2SSatish Balay 
2065e1affc2SSatish Balay 	/*  update initial steplength choice */
2075e1affc2SSatish Balay 	delta = 1.0;
2085e1affc2SSatish Balay 	delta = PetscMax(delta, cgP->delta_min);
2095e1affc2SSatish Balay 	delta = PetscMin(delta, cgP->delta_max);
2105e1affc2SSatish Balay     }
2115e1affc2SSatish Balay     PetscFunctionReturn(0);
2125e1affc2SSatish Balay }
2135e1affc2SSatish Balay 
2145e1affc2SSatish Balay #undef __FUNCT__
2155e1affc2SSatish Balay #define __FUNCT__ "TaoSetUp_CG"
2165e1affc2SSatish Balay static PetscErrorCode TaoSetUp_CG(TaoSolver tao)
2175e1affc2SSatish Balay {
2185e1affc2SSatish Balay     TAO_CG *cgP = (TAO_CG*)tao->data;
2195e1affc2SSatish Balay     PetscErrorCode ierr;
2205e1affc2SSatish Balay 
2215e1affc2SSatish Balay     PetscFunctionBegin;
2225e1affc2SSatish Balay     if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient); CHKERRQ(ierr);}
2235e1affc2SSatish Balay     if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection); CHKERRQ(ierr); }
2245e1affc2SSatish Balay     if (!cgP->X_old) {ierr = VecDuplicate(tao->solution,&cgP->X_old); CHKERRQ(ierr);}
2255e1affc2SSatish Balay     if (!cgP->G_old) {ierr = VecDuplicate(tao->gradient,&cgP->G_old); CHKERRQ(ierr); }
2265e1affc2SSatish Balay 
2275e1affc2SSatish Balay     PetscFunctionReturn(0);
2285e1affc2SSatish Balay }
2295e1affc2SSatish Balay 
2305e1affc2SSatish Balay 
2315e1affc2SSatish Balay #undef __FUNCT__
2325e1affc2SSatish Balay #define __FUNCT__ "TaoDestroy_CG"
2335e1affc2SSatish Balay static PetscErrorCode TaoDestroy_CG(TaoSolver tao)
2345e1affc2SSatish Balay {
2355e1affc2SSatish Balay   TAO_CG         *cgP = (TAO_CG*) tao->data;
2365e1affc2SSatish Balay   PetscErrorCode ierr;
2375e1affc2SSatish Balay 
2385e1affc2SSatish Balay   PetscFunctionBegin;
2395e1affc2SSatish Balay   if (tao->setupcalled) {
2405e1affc2SSatish Balay     ierr = VecDestroy(&cgP->X_old); CHKERRQ(ierr);
2415e1affc2SSatish Balay     ierr = VecDestroy(&cgP->G_old); CHKERRQ(ierr);
2425e1affc2SSatish Balay   }
2435e1affc2SSatish Balay   ierr = TaoLineSearchDestroy(&tao->linesearch); CHKERRQ(ierr);
2445e1affc2SSatish Balay   ierr = PetscFree(tao->data); CHKERRQ(ierr);
2455e1affc2SSatish Balay   PetscFunctionReturn(0);
2465e1affc2SSatish Balay }
2475e1affc2SSatish Balay 
2485e1affc2SSatish Balay #undef __FUNCT__
2495e1affc2SSatish Balay #define __FUNCT__ "TaoSetFromOptions_CG"
2505e1affc2SSatish Balay static PetscErrorCode TaoSetFromOptions_CG(TaoSolver tao)
2515e1affc2SSatish Balay {
2525e1affc2SSatish Balay     TAO_CG *cgP = (TAO_CG*)tao->data;
2535e1affc2SSatish Balay     PetscErrorCode ierr;
2545e1affc2SSatish Balay 
2555e1affc2SSatish Balay     PetscFunctionBegin;
2565e1affc2SSatish Balay     ierr = TaoLineSearchSetFromOptions(tao->linesearch); CHKERRQ(ierr);
2575e1affc2SSatish Balay     ierr = PetscOptionsHead("Nonlinear Conjugate Gradient method for unconstrained optimization"); CHKERRQ(ierr);
2585e1affc2SSatish Balay     ierr = PetscOptionsReal("-tao_cg_eta","restart tolerance", "", cgP->eta,&cgP->eta,0);CHKERRQ(ierr);
2595e1affc2SSatish Balay     ierr = PetscOptionsEList("-tao_cg_type","cg formula", "", CG_Table, CG_Types, CG_Table[cgP->cg_type], &cgP->cg_type, 0); CHKERRQ(ierr);
260*6c23d075SBarry Smith     ierr = PetscOptionsReal("-tao_cg_delta_min","minimum delta value", "", cgP->delta_min,&cgP->delta_min,0); CHKERRQ(ierr);
261*6c23d075SBarry Smith     ierr = PetscOptionsReal("-tao_cg_delta_max","maximum delta value", "", cgP->delta_max,&cgP->delta_max,0); CHKERRQ(ierr);
2625e1affc2SSatish Balay     ierr = PetscOptionsTail(); CHKERRQ(ierr);
2635e1affc2SSatish Balay     PetscFunctionReturn(0);
2645e1affc2SSatish Balay }
2655e1affc2SSatish Balay 
2665e1affc2SSatish Balay #undef __FUNCT__
2675e1affc2SSatish Balay #define __FUNCT__ "TaoView_CG"
2685e1affc2SSatish Balay static PetscErrorCode TaoView_CG(TaoSolver tao, PetscViewer viewer)
2695e1affc2SSatish Balay {
2705e1affc2SSatish Balay     PetscBool isascii;
2715e1affc2SSatish Balay     TAO_CG *cgP = (TAO_CG*)tao->data;
2725e1affc2SSatish Balay     PetscErrorCode ierr;
2735e1affc2SSatish Balay 
2745e1affc2SSatish Balay     PetscFunctionBegin;
2755e1affc2SSatish Balay     ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii); CHKERRQ(ierr);
2765e1affc2SSatish Balay     if (isascii) {
2775e1affc2SSatish Balay         ierr = PetscViewerASCIIPushTab(viewer); CHKERRQ(ierr);
2785e1affc2SSatish Balay 	ierr = PetscViewerASCIIPrintf(viewer, "CG Type: %s\n", CG_Table[cgP->cg_type]); CHKERRQ(ierr);
2795e1affc2SSatish Balay 	ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", cgP->ngradsteps); CHKERRQ(ierr);
2805e1affc2SSatish Balay 	ierr= PetscViewerASCIIPrintf(viewer, "Reset steps: %D\n", cgP->nresetsteps); CHKERRQ(ierr);
2815e1affc2SSatish Balay         ierr = PetscViewerASCIIPopTab(viewer); CHKERRQ(ierr);
2825e1affc2SSatish Balay     } else {
2835e1affc2SSatish Balay       SETERRQ1(((PetscObject)tao)->comm,PETSC_ERR_SUP,"Viewer type %s not supported for TAO CG",((PetscObject)viewer)->type_name);
2845e1affc2SSatish Balay     }
2855e1affc2SSatish Balay     PetscFunctionReturn(0);
2865e1affc2SSatish Balay }
2875e1affc2SSatish Balay 
2885e1affc2SSatish Balay 
2895e1affc2SSatish Balay EXTERN_C_BEGIN
2905e1affc2SSatish Balay #undef __FUNCT__
2915e1affc2SSatish Balay #define __FUNCT__ "TaoCreate_CG"
2925e1affc2SSatish Balay PetscErrorCode TaoCreate_CG(TaoSolver tao)
2935e1affc2SSatish Balay {
2945e1affc2SSatish Balay     TAO_CG *cgP;
2955e1affc2SSatish Balay     const char *morethuente_type = TAOLINESEARCH_MT;
2965e1affc2SSatish Balay     PetscErrorCode ierr;
2975e1affc2SSatish Balay     PetscFunctionBegin;
2985e1affc2SSatish Balay     tao->ops->setup = TaoSetUp_CG;
2995e1affc2SSatish Balay     tao->ops->solve = TaoSolve_CG;
3005e1affc2SSatish Balay     tao->ops->view = TaoView_CG;
3015e1affc2SSatish Balay     tao->ops->setfromoptions = TaoSetFromOptions_CG;
3025e1affc2SSatish Balay     tao->ops->destroy = TaoDestroy_CG;
3035e1affc2SSatish Balay 
3045e1affc2SSatish Balay     tao->max_it = 2000;
3055e1affc2SSatish Balay     tao->max_funcs = 4000;
3065e1affc2SSatish Balay     tao->fatol = 1e-4;
3075e1affc2SSatish Balay     tao->frtol = 1e-4;
3085e1affc2SSatish Balay 
3095e1affc2SSatish Balay     /*  Note: nondefault values should be used for nonlinear conjugate gradient  */
3105e1affc2SSatish Balay     /*  method.  In particular, gtol should be less that 0.5; the value used in  */
3115e1affc2SSatish Balay     /*  Nocedal and Wright is 0.10.  We use the default values for the  */
3125e1affc2SSatish Balay     /*  linesearch because it seems to work better. */
3135e1affc2SSatish Balay     ierr = TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch); CHKERRQ(ierr);
3145e1affc2SSatish Balay     ierr = TaoLineSearchSetType(tao->linesearch, morethuente_type); CHKERRQ(ierr);
3155e1affc2SSatish Balay     ierr = TaoLineSearchUseTaoSolverRoutines(tao->linesearch, tao); CHKERRQ(ierr);
3165e1affc2SSatish Balay 
3175e1affc2SSatish Balay 
3185e1affc2SSatish Balay     ierr = PetscNewLog(tao,&cgP); CHKERRQ(ierr);
3195e1affc2SSatish Balay     tao->data = (void*)cgP;
3205e1affc2SSatish Balay     cgP->eta = 0.1;
3215e1affc2SSatish Balay     cgP->delta_min = 1e-7;
3225e1affc2SSatish Balay     cgP->delta_max = 100;
3235e1affc2SSatish Balay     cgP->cg_type = CG_PolakRibierePlus;
3245e1affc2SSatish Balay 
3255e1affc2SSatish Balay     PetscFunctionReturn(0);
3265e1affc2SSatish Balay }
3275e1affc2SSatish Balay 
3285e1affc2SSatish Balay EXTERN_C_END
3295e1affc2SSatish Balay 
3305e1affc2SSatish Balay 
3315e1affc2SSatish Balay 
3325e1affc2SSatish Balay 
3335e1affc2SSatish Balay 
334