1*a7e14dcfSSatish Balay #include "taolinesearch.h" 2*a7e14dcfSSatish Balay #include "src/matrix/lmvmmat.h" 3*a7e14dcfSSatish Balay #include "lmvm.h" 4*a7e14dcfSSatish Balay 5*a7e14dcfSSatish Balay #define LMVM_BFGS 0 6*a7e14dcfSSatish Balay #define LMVM_SCALED_GRADIENT 1 7*a7e14dcfSSatish Balay #define LMVM_GRADIENT 2 8*a7e14dcfSSatish Balay 9*a7e14dcfSSatish Balay #undef __FUNCT__ 10*a7e14dcfSSatish Balay #define __FUNCT__ "TaoSolve_LMVM" 11*a7e14dcfSSatish Balay static PetscErrorCode TaoSolve_LMVM(TaoSolver tao) 12*a7e14dcfSSatish Balay { 13*a7e14dcfSSatish Balay 14*a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 15*a7e14dcfSSatish Balay 16*a7e14dcfSSatish Balay PetscReal f, fold, gdx, gnorm; 17*a7e14dcfSSatish Balay PetscReal step = 1.0; 18*a7e14dcfSSatish Balay 19*a7e14dcfSSatish Balay PetscReal delta; 20*a7e14dcfSSatish Balay 21*a7e14dcfSSatish Balay PetscErrorCode ierr; 22*a7e14dcfSSatish Balay PetscInt stepType; 23*a7e14dcfSSatish Balay PetscInt iter = 0; 24*a7e14dcfSSatish Balay TaoSolverTerminationReason reason = TAO_CONTINUE_ITERATING; 25*a7e14dcfSSatish Balay TaoLineSearchTerminationReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; 26*a7e14dcfSSatish Balay 27*a7e14dcfSSatish Balay PetscFunctionBegin; 28*a7e14dcfSSatish Balay 29*a7e14dcfSSatish Balay if (tao->XL || tao->XU || tao->ops->computebounds) { 30*a7e14dcfSSatish Balay ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by lmvm algorithm\n"); CHKERRQ(ierr); 31*a7e14dcfSSatish Balay } 32*a7e14dcfSSatish Balay 33*a7e14dcfSSatish Balay /* Check convergence criteria */ 34*a7e14dcfSSatish Balay ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient); CHKERRQ(ierr); 35*a7e14dcfSSatish Balay ierr = VecNorm(tao->gradient,NORM_2,&gnorm); CHKERRQ(ierr); 36*a7e14dcfSSatish Balay if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) { 37*a7e14dcfSSatish Balay SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 38*a7e14dcfSSatish Balay } 39*a7e14dcfSSatish Balay 40*a7e14dcfSSatish Balay ierr = TaoMonitor(tao, iter, f, gnorm, 0.0, step, &reason); CHKERRQ(ierr); 41*a7e14dcfSSatish Balay if (reason != TAO_CONTINUE_ITERATING) { 42*a7e14dcfSSatish Balay PetscFunctionReturn(0); 43*a7e14dcfSSatish Balay } 44*a7e14dcfSSatish Balay 45*a7e14dcfSSatish Balay /* Set initial scaling for the function */ 46*a7e14dcfSSatish Balay if (f != 0.0) { 47*a7e14dcfSSatish Balay delta = 2.0 * PetscAbsScalar(f) / (gnorm*gnorm); 48*a7e14dcfSSatish Balay } 49*a7e14dcfSSatish Balay else { 50*a7e14dcfSSatish Balay delta = 2.0 / (gnorm*gnorm); 51*a7e14dcfSSatish Balay } 52*a7e14dcfSSatish Balay ierr = MatLMVMSetDelta(lmP->M,delta); CHKERRQ(ierr); 53*a7e14dcfSSatish Balay 54*a7e14dcfSSatish Balay /* Set counter for gradient/reset steps */ 55*a7e14dcfSSatish Balay lmP->bfgs = 0; 56*a7e14dcfSSatish Balay lmP->sgrad = 0; 57*a7e14dcfSSatish Balay lmP->grad = 0; 58*a7e14dcfSSatish Balay 59*a7e14dcfSSatish Balay /* Have not converged; continue with Newton method */ 60*a7e14dcfSSatish Balay while (reason == TAO_CONTINUE_ITERATING) { 61*a7e14dcfSSatish Balay /* Compute direction */ 62*a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M,tao->solution,tao->gradient); CHKERRQ(ierr); 63*a7e14dcfSSatish Balay ierr = MatLMVMSolve(lmP->M, tao->gradient, lmP->D); CHKERRQ(ierr); 64*a7e14dcfSSatish Balay ++lmP->bfgs; 65*a7e14dcfSSatish Balay 66*a7e14dcfSSatish Balay /* Check for success (descent direction) */ 67*a7e14dcfSSatish Balay ierr = VecDot(lmP->D, tao->gradient, &gdx); CHKERRQ(ierr); 68*a7e14dcfSSatish Balay if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 69*a7e14dcfSSatish Balay /* Step is not descent or direction produced not a number 70*a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case because 71*a7e14dcfSSatish Balay the first solve produces the scaled gradient direction, 72*a7e14dcfSSatish Balay which is guaranteed to be descent 73*a7e14dcfSSatish Balay 74*a7e14dcfSSatish Balay Use steepest descent direction (scaled) 75*a7e14dcfSSatish Balay */ 76*a7e14dcfSSatish Balay 77*a7e14dcfSSatish Balay ++lmP->grad; 78*a7e14dcfSSatish Balay 79*a7e14dcfSSatish Balay if (f != 0.0) { 80*a7e14dcfSSatish Balay delta = 2.0 * PetscAbsScalar(f) / (gnorm*gnorm); 81*a7e14dcfSSatish Balay } 82*a7e14dcfSSatish Balay else { 83*a7e14dcfSSatish Balay delta = 2.0 / (gnorm*gnorm); 84*a7e14dcfSSatish Balay } 85*a7e14dcfSSatish Balay ierr = MatLMVMSetDelta(lmP->M, delta); CHKERRQ(ierr); 86*a7e14dcfSSatish Balay ierr = MatLMVMReset(lmP->M); CHKERRQ(ierr); 87*a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient); CHKERRQ(ierr); 88*a7e14dcfSSatish Balay ierr = MatLMVMSolve(lmP->M,tao->gradient, lmP->D); CHKERRQ(ierr); 89*a7e14dcfSSatish Balay 90*a7e14dcfSSatish Balay /* On a reset, the direction cannot be not a number; it is a 91*a7e14dcfSSatish Balay scaled gradient step. No need to check for this condition. */ 92*a7e14dcfSSatish Balay 93*a7e14dcfSSatish Balay lmP->bfgs = 1; 94*a7e14dcfSSatish Balay ++lmP->sgrad; 95*a7e14dcfSSatish Balay stepType = LMVM_SCALED_GRADIENT; 96*a7e14dcfSSatish Balay } 97*a7e14dcfSSatish Balay else { 98*a7e14dcfSSatish Balay if (1 == lmP->bfgs) { 99*a7e14dcfSSatish Balay /* The first BFGS direction is always the scaled gradient */ 100*a7e14dcfSSatish Balay ++lmP->sgrad; 101*a7e14dcfSSatish Balay stepType = LMVM_SCALED_GRADIENT; 102*a7e14dcfSSatish Balay } 103*a7e14dcfSSatish Balay else { 104*a7e14dcfSSatish Balay ++lmP->bfgs; 105*a7e14dcfSSatish Balay stepType = LMVM_BFGS; 106*a7e14dcfSSatish Balay } 107*a7e14dcfSSatish Balay } 108*a7e14dcfSSatish Balay ierr = VecScale(lmP->D, -1.0); CHKERRQ(ierr); 109*a7e14dcfSSatish Balay 110*a7e14dcfSSatish Balay /* Perform the linesearch */ 111*a7e14dcfSSatish Balay fold = f; 112*a7e14dcfSSatish Balay ierr = VecCopy(tao->solution, lmP->Xold); CHKERRQ(ierr); 113*a7e14dcfSSatish Balay ierr = VecCopy(tao->gradient, lmP->Gold); CHKERRQ(ierr); 114*a7e14dcfSSatish Balay 115*a7e14dcfSSatish Balay ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, lmP->D, &step,&ls_status); CHKERRQ(ierr); 116*a7e14dcfSSatish Balay ierr = TaoAddLineSearchCounts(tao); CHKERRQ(ierr); 117*a7e14dcfSSatish Balay 118*a7e14dcfSSatish Balay 119*a7e14dcfSSatish Balay while (ls_status != TAOLINESEARCH_SUCCESS && 120*a7e14dcfSSatish Balay ls_status != TAOLINESEARCH_SUCCESS_USER 121*a7e14dcfSSatish Balay && (stepType != LMVM_GRADIENT)) { 122*a7e14dcfSSatish Balay /* Linesearch failed */ 123*a7e14dcfSSatish Balay /* Reset factors and use scaled gradient step */ 124*a7e14dcfSSatish Balay f = fold; 125*a7e14dcfSSatish Balay ierr = VecCopy(lmP->Xold, tao->solution); CHKERRQ(ierr); 126*a7e14dcfSSatish Balay ierr = VecCopy(lmP->Gold, tao->gradient); CHKERRQ(ierr); 127*a7e14dcfSSatish Balay 128*a7e14dcfSSatish Balay switch(stepType) { 129*a7e14dcfSSatish Balay case LMVM_BFGS: 130*a7e14dcfSSatish Balay /* Failed to obtain acceptable iterate with BFGS step */ 131*a7e14dcfSSatish Balay /* Attempt to use the scaled gradient direction */ 132*a7e14dcfSSatish Balay 133*a7e14dcfSSatish Balay if (f != 0.0) { 134*a7e14dcfSSatish Balay delta = 2.0 * PetscAbsScalar(f) / (gnorm*gnorm); 135*a7e14dcfSSatish Balay } 136*a7e14dcfSSatish Balay else { 137*a7e14dcfSSatish Balay delta = 2.0 / (gnorm*gnorm); 138*a7e14dcfSSatish Balay } 139*a7e14dcfSSatish Balay ierr = MatLMVMSetDelta(lmP->M, delta); CHKERRQ(ierr); 140*a7e14dcfSSatish Balay ierr = MatLMVMReset(lmP->M); CHKERRQ(ierr); 141*a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient); CHKERRQ(ierr); 142*a7e14dcfSSatish Balay ierr = MatLMVMSolve(lmP->M, tao->gradient, lmP->D); CHKERRQ(ierr); 143*a7e14dcfSSatish Balay 144*a7e14dcfSSatish Balay /* On a reset, the direction cannot be not a number; it is a 145*a7e14dcfSSatish Balay scaled gradient step. No need to check for this condition. */ 146*a7e14dcfSSatish Balay 147*a7e14dcfSSatish Balay lmP->bfgs = 1; 148*a7e14dcfSSatish Balay ++lmP->sgrad; 149*a7e14dcfSSatish Balay stepType = LMVM_SCALED_GRADIENT; 150*a7e14dcfSSatish Balay break; 151*a7e14dcfSSatish Balay 152*a7e14dcfSSatish Balay case LMVM_SCALED_GRADIENT: 153*a7e14dcfSSatish Balay /* The scaled gradient step did not produce a new iterate; 154*a7e14dcfSSatish Balay attempt to use the gradient direction. 155*a7e14dcfSSatish Balay Need to make sure we are not using a different diagonal scaling */ 156*a7e14dcfSSatish Balay ierr = MatLMVMSetDelta(lmP->M, 1.0); CHKERRQ(ierr); 157*a7e14dcfSSatish Balay ierr = MatLMVMReset(lmP->M); CHKERRQ(ierr); 158*a7e14dcfSSatish Balay ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient); CHKERRQ(ierr); 159*a7e14dcfSSatish Balay ierr = MatLMVMSolve(lmP->M, tao->gradient, lmP->D); CHKERRQ(ierr); 160*a7e14dcfSSatish Balay 161*a7e14dcfSSatish Balay lmP->bfgs = 1; 162*a7e14dcfSSatish Balay ++lmP->grad; 163*a7e14dcfSSatish Balay stepType = LMVM_GRADIENT; 164*a7e14dcfSSatish Balay break; 165*a7e14dcfSSatish Balay } 166*a7e14dcfSSatish Balay ierr = VecScale(lmP->D, -1.0); CHKERRQ(ierr); 167*a7e14dcfSSatish Balay 168*a7e14dcfSSatish Balay /* Perform the linesearch */ 169*a7e14dcfSSatish Balay ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, lmP->D, &step, &ls_status); CHKERRQ(ierr); 170*a7e14dcfSSatish Balay ierr = TaoAddLineSearchCounts(tao); CHKERRQ(ierr); 171*a7e14dcfSSatish Balay 172*a7e14dcfSSatish Balay } 173*a7e14dcfSSatish Balay 174*a7e14dcfSSatish Balay if (ls_status != TAOLINESEARCH_SUCCESS && 175*a7e14dcfSSatish Balay ls_status != TAOLINESEARCH_SUCCESS_USER) { 176*a7e14dcfSSatish Balay /* Failed to find an improving point */ 177*a7e14dcfSSatish Balay f = fold; 178*a7e14dcfSSatish Balay ierr = VecCopy(lmP->Xold, tao->solution); CHKERRQ(ierr); 179*a7e14dcfSSatish Balay ierr = VecCopy(lmP->Gold, tao->gradient); CHKERRQ(ierr); 180*a7e14dcfSSatish Balay step = 0.0; 181*a7e14dcfSSatish Balay reason = TAO_DIVERGED_LS_FAILURE; 182*a7e14dcfSSatish Balay tao->reason = TAO_DIVERGED_LS_FAILURE; 183*a7e14dcfSSatish Balay } 184*a7e14dcfSSatish Balay /* Check for termination */ 185*a7e14dcfSSatish Balay ierr = VecNorm(tao->gradient, NORM_2, &gnorm); CHKERRQ(ierr); 186*a7e14dcfSSatish Balay iter++; 187*a7e14dcfSSatish Balay ierr = TaoMonitor(tao,iter,f,gnorm,0.0,step,&reason); CHKERRQ(ierr); 188*a7e14dcfSSatish Balay } 189*a7e14dcfSSatish Balay PetscFunctionReturn(0); 190*a7e14dcfSSatish Balay } 191*a7e14dcfSSatish Balay #undef __FUNCT__ 192*a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetUp_LMVM" 193*a7e14dcfSSatish Balay static PetscErrorCode TaoSetUp_LMVM(TaoSolver tao) 194*a7e14dcfSSatish Balay { 195*a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 196*a7e14dcfSSatish Balay PetscInt n,N; 197*a7e14dcfSSatish Balay PetscErrorCode ierr; 198*a7e14dcfSSatish Balay 199*a7e14dcfSSatish Balay PetscFunctionBegin; 200*a7e14dcfSSatish Balay /* Existence of tao->solution checked in TaoSetUp() */ 201*a7e14dcfSSatish Balay if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient); CHKERRQ(ierr); } 202*a7e14dcfSSatish Balay if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection); CHKERRQ(ierr); } 203*a7e14dcfSSatish Balay if (!lmP->D) {ierr = VecDuplicate(tao->solution,&lmP->D); CHKERRQ(ierr); } 204*a7e14dcfSSatish Balay if (!lmP->Xold) {ierr = VecDuplicate(tao->solution,&lmP->Xold); CHKERRQ(ierr); } 205*a7e14dcfSSatish Balay if (!lmP->Gold) {ierr = VecDuplicate(tao->solution,&lmP->Gold); CHKERRQ(ierr); } 206*a7e14dcfSSatish Balay 207*a7e14dcfSSatish Balay /* Create matrix for the limited memory approximation */ 208*a7e14dcfSSatish Balay ierr = VecGetLocalSize(tao->solution,&n); CHKERRQ(ierr); 209*a7e14dcfSSatish Balay ierr = VecGetSize(tao->solution,&N); CHKERRQ(ierr); 210*a7e14dcfSSatish Balay ierr = MatCreateLMVM(((PetscObject)tao)->comm,n,N,&lmP->M); CHKERRQ(ierr); 211*a7e14dcfSSatish Balay ierr = MatLMVMAllocateVectors(lmP->M,tao->solution); CHKERRQ(ierr); 212*a7e14dcfSSatish Balay 213*a7e14dcfSSatish Balay 214*a7e14dcfSSatish Balay PetscFunctionReturn(0); 215*a7e14dcfSSatish Balay } 216*a7e14dcfSSatish Balay 217*a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 218*a7e14dcfSSatish Balay #undef __FUNCT__ 219*a7e14dcfSSatish Balay #define __FUNCT__ "TaoDestroy_LMVM" 220*a7e14dcfSSatish Balay static PetscErrorCode TaoDestroy_LMVM(TaoSolver tao) 221*a7e14dcfSSatish Balay { 222*a7e14dcfSSatish Balay 223*a7e14dcfSSatish Balay TAO_LMVM *lmP = (TAO_LMVM *)tao->data; 224*a7e14dcfSSatish Balay PetscErrorCode ierr; 225*a7e14dcfSSatish Balay 226*a7e14dcfSSatish Balay PetscFunctionBegin; 227*a7e14dcfSSatish Balay if (tao->setupcalled) { 228*a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->Xold); CHKERRQ(ierr); 229*a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->Gold); CHKERRQ(ierr); 230*a7e14dcfSSatish Balay ierr = VecDestroy(&lmP->D); CHKERRQ(ierr); 231*a7e14dcfSSatish Balay ierr = MatDestroy(&lmP->M); CHKERRQ(ierr); 232*a7e14dcfSSatish Balay } 233*a7e14dcfSSatish Balay ierr = PetscFree(tao->data); CHKERRQ(ierr); 234*a7e14dcfSSatish Balay tao->data = PETSC_NULL; 235*a7e14dcfSSatish Balay 236*a7e14dcfSSatish Balay PetscFunctionReturn(0); 237*a7e14dcfSSatish Balay } 238*a7e14dcfSSatish Balay 239*a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 240*a7e14dcfSSatish Balay #undef __FUNCT__ 241*a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetFromOptions_LMVM" 242*a7e14dcfSSatish Balay static PetscErrorCode TaoSetFromOptions_LMVM(TaoSolver tao) 243*a7e14dcfSSatish Balay { 244*a7e14dcfSSatish Balay 245*a7e14dcfSSatish Balay PetscErrorCode ierr; 246*a7e14dcfSSatish Balay 247*a7e14dcfSSatish Balay PetscFunctionBegin; 248*a7e14dcfSSatish Balay ierr = PetscOptionsHead("Limited-memory variable-metric method for unconstrained optimization"); CHKERRQ(ierr); 249*a7e14dcfSSatish Balay ierr = TaoLineSearchSetFromOptions(tao->linesearch); CHKERRQ(ierr); 250*a7e14dcfSSatish Balay ierr = PetscOptionsTail(); CHKERRQ(ierr); 251*a7e14dcfSSatish Balay PetscFunctionReturn(0); 252*a7e14dcfSSatish Balay 253*a7e14dcfSSatish Balay PetscFunctionReturn(0); 254*a7e14dcfSSatish Balay } 255*a7e14dcfSSatish Balay 256*a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 257*a7e14dcfSSatish Balay #undef __FUNCT__ 258*a7e14dcfSSatish Balay #define __FUNCT__ "TaoView_LMVM" 259*a7e14dcfSSatish Balay static PetscErrorCode TaoView_LMVM(TaoSolver tao, PetscViewer viewer) 260*a7e14dcfSSatish Balay { 261*a7e14dcfSSatish Balay 262*a7e14dcfSSatish Balay TAO_LMVM *lm = (TAO_LMVM *)tao->data; 263*a7e14dcfSSatish Balay PetscBool isascii; 264*a7e14dcfSSatish Balay PetscErrorCode ierr; 265*a7e14dcfSSatish Balay 266*a7e14dcfSSatish Balay 267*a7e14dcfSSatish Balay PetscFunctionBegin; 268*a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii); CHKERRQ(ierr); 269*a7e14dcfSSatish Balay if (isascii) { 270*a7e14dcfSSatish Balay 271*a7e14dcfSSatish Balay ierr = PetscViewerASCIIPushTab(viewer); CHKERRQ(ierr); 272*a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "BFGS steps: %D\n", lm->bfgs); CHKERRQ(ierr); 273*a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %D\n", lm->sgrad); CHKERRQ(ierr); 274*a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", lm->grad); CHKERRQ(ierr); 275*a7e14dcfSSatish Balay ierr = PetscViewerASCIIPopTab(viewer); CHKERRQ(ierr); 276*a7e14dcfSSatish Balay } else { 277*a7e14dcfSSatish Balay SETERRQ1(((PetscObject)tao)->comm,PETSC_ERR_SUP,"Viewer type %s not supported for TAO LMVM",((PetscObject)viewer)->type_name); 278*a7e14dcfSSatish Balay } 279*a7e14dcfSSatish Balay PetscFunctionReturn(0); 280*a7e14dcfSSatish Balay } 281*a7e14dcfSSatish Balay 282*a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 283*a7e14dcfSSatish Balay 284*a7e14dcfSSatish Balay EXTERN_C_BEGIN 285*a7e14dcfSSatish Balay #undef __FUNCT__ 286*a7e14dcfSSatish Balay #define __FUNCT__ "TaoCreate_LMVM" 287*a7e14dcfSSatish Balay PetscErrorCode TaoCreate_LMVM(TaoSolver tao) 288*a7e14dcfSSatish Balay { 289*a7e14dcfSSatish Balay 290*a7e14dcfSSatish Balay TAO_LMVM *lmP; 291*a7e14dcfSSatish Balay const char *morethuente_type = TAOLINESEARCH_MT; 292*a7e14dcfSSatish Balay PetscErrorCode ierr; 293*a7e14dcfSSatish Balay 294*a7e14dcfSSatish Balay PetscFunctionBegin; 295*a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_LMVM; 296*a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_LMVM; 297*a7e14dcfSSatish Balay tao->ops->view = TaoView_LMVM; 298*a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_LMVM; 299*a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_LMVM; 300*a7e14dcfSSatish Balay 301*a7e14dcfSSatish Balay ierr = PetscNewLog(tao,TAO_LMVM, &lmP); CHKERRQ(ierr); 302*a7e14dcfSSatish Balay lmP->D = 0; 303*a7e14dcfSSatish Balay lmP->M = 0; 304*a7e14dcfSSatish Balay lmP->Xold = 0; 305*a7e14dcfSSatish Balay lmP->Gold = 0; 306*a7e14dcfSSatish Balay 307*a7e14dcfSSatish Balay tao->data = (void*)lmP; 308*a7e14dcfSSatish Balay tao->max_it = 2000; 309*a7e14dcfSSatish Balay tao->max_funcs = 4000; 310*a7e14dcfSSatish Balay tao->fatol = 1e-4; 311*a7e14dcfSSatish Balay tao->frtol = 1e-4; 312*a7e14dcfSSatish Balay 313*a7e14dcfSSatish Balay ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch); CHKERRQ(ierr); 314*a7e14dcfSSatish Balay ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type); CHKERRQ(ierr); 315*a7e14dcfSSatish Balay ierr = TaoLineSearchUseTaoSolverRoutines(tao->linesearch,tao); CHKERRQ(ierr); 316*a7e14dcfSSatish Balay 317*a7e14dcfSSatish Balay PetscFunctionReturn(0); 318*a7e14dcfSSatish Balay } 319*a7e14dcfSSatish Balay EXTERN_C_END 320