1ba92ff59SBarry Smith #include <petsctaolinesearch.h> 2aaa7dc30SBarry Smith #include <../src/tao/unconstrained/impls/owlqn/owlqn.h> 3a7e14dcfSSatish Balay 4a7e14dcfSSatish Balay #define OWLQN_BFGS 0 5a7e14dcfSSatish Balay #define OWLQN_SCALED_GRADIENT 1 6a7e14dcfSSatish Balay #define OWLQN_GRADIENT 2 7a7e14dcfSSatish Balay 89371c9d4SSatish Balay static PetscErrorCode ProjDirect_OWLQN(Vec d, Vec g) { 95e081366SBarry Smith const PetscReal *gptr; 105e081366SBarry Smith PetscReal *dptr; 11a7e14dcfSSatish Balay PetscInt low, high, low1, high1, i; 12a7e14dcfSSatish Balay 13a7e14dcfSSatish Balay PetscFunctionBegin; 149566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(d, &low, &high)); 159566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(g, &low1, &high1)); 16a7e14dcfSSatish Balay 179566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(g, &gptr)); 189566063dSJacob Faibussowitsch PetscCall(VecGetArray(d, &dptr)); 19a7e14dcfSSatish Balay for (i = 0; i < high - low; i++) { 20*ad540459SPierre Jolivet if (dptr[i] * gptr[i] <= 0.0) dptr[i] = 0.0; 21a7e14dcfSSatish Balay } 229566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(d, &dptr)); 239566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(g, &gptr)); 24a7e14dcfSSatish Balay PetscFunctionReturn(0); 25a7e14dcfSSatish Balay } 26a7e14dcfSSatish Balay 279371c9d4SSatish Balay static PetscErrorCode ComputePseudoGrad_OWLQN(Vec x, Vec gv, PetscReal lambda) { 285e081366SBarry Smith const PetscReal *xptr; 295e081366SBarry Smith PetscReal *gptr; 30a7e14dcfSSatish Balay PetscInt low, high, low1, high1, i; 31a7e14dcfSSatish Balay 32a7e14dcfSSatish Balay PetscFunctionBegin; 339566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(x, &low, &high)); 349566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(gv, &low1, &high1)); 35a7e14dcfSSatish Balay 369566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xptr)); 379566063dSJacob Faibussowitsch PetscCall(VecGetArray(gv, &gptr)); 38a7e14dcfSSatish Balay for (i = 0; i < high - low; i++) { 3953506e15SBarry Smith if (xptr[i] < 0.0) gptr[i] = gptr[i] - lambda; 4053506e15SBarry Smith else if (xptr[i] > 0.0) gptr[i] = gptr[i] + lambda; 4153506e15SBarry Smith else if (gptr[i] + lambda < 0.0) gptr[i] = gptr[i] + lambda; 4253506e15SBarry Smith else if (gptr[i] - lambda > 0.0) gptr[i] = gptr[i] - lambda; 4353506e15SBarry Smith else gptr[i] = 0.0; 44a7e14dcfSSatish Balay } 459566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(gv, &gptr)); 469566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xptr)); 47a7e14dcfSSatish Balay PetscFunctionReturn(0); 48a7e14dcfSSatish Balay } 49a7e14dcfSSatish Balay 509371c9d4SSatish Balay static PetscErrorCode TaoSolve_OWLQN(Tao tao) { 51a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 52a7e14dcfSSatish Balay PetscReal f, fold, gdx, gnorm; 53a7e14dcfSSatish Balay PetscReal step = 1.0; 54a7e14dcfSSatish Balay PetscReal delta; 55a7e14dcfSSatish Balay PetscInt stepType; 56a7e14dcfSSatish Balay PetscInt iter = 0; 57e4cb33bbSBarry Smith TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; 58a7e14dcfSSatish Balay 59a7e14dcfSSatish Balay PetscFunctionBegin; 6048a46eb9SPierre Jolivet if (tao->XL || tao->XU || tao->ops->computebounds) PetscCall(PetscInfo(tao, "WARNING: Variable bounds have been set but will be ignored by owlqn algorithm\n")); 61a7e14dcfSSatish Balay 62a7e14dcfSSatish Balay /* Check convergence criteria */ 639566063dSJacob Faibussowitsch PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient)); 649566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 659566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution, lmP->GV, lmP->lambda)); 669566063dSJacob Faibussowitsch PetscCall(VecNorm(lmP->GV, NORM_2, &gnorm)); 673c859ba3SBarry Smith PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN"); 68a7e14dcfSSatish Balay 693ecd9318SAlp Dener tao->reason = TAO_CONTINUE_ITERATING; 709566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its)); 719566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao, iter, f, gnorm, 0.0, step)); 72dbbe0bcdSBarry Smith PetscUseTypeMethod(tao, convergencetest, tao->cnvP); 733ecd9318SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 74a7e14dcfSSatish Balay 75a7e14dcfSSatish Balay /* Set initial scaling for the function */ 76cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm * gnorm); 779566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 78a7e14dcfSSatish Balay 79a7e14dcfSSatish Balay /* Set counter for gradient/reset steps */ 80a7e14dcfSSatish Balay lmP->bfgs = 0; 81a7e14dcfSSatish Balay lmP->sgrad = 0; 82a7e14dcfSSatish Balay lmP->grad = 0; 83a7e14dcfSSatish Balay 84a7e14dcfSSatish Balay /* Have not converged; continue with Newton method */ 853ecd9318SAlp Dener while (tao->reason == TAO_CONTINUE_ITERATING) { 86e1e80dc8SAlp Dener /* Call general purpose update function */ 87dbbe0bcdSBarry Smith PetscTryTypeMethod(tao, update, tao->niter, tao->user_update); 88e1e80dc8SAlp Dener 89a7e14dcfSSatish Balay /* Compute direction */ 909566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 919566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 92a7e14dcfSSatish Balay 939566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D, lmP->GV)); 94a7e14dcfSSatish Balay 95a7e14dcfSSatish Balay ++lmP->bfgs; 96a7e14dcfSSatish Balay 97a7e14dcfSSatish Balay /* Check for success (descent direction) */ 989566063dSJacob Faibussowitsch PetscCall(VecDot(lmP->D, lmP->GV, &gdx)); 99a7e14dcfSSatish Balay if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 100a7e14dcfSSatish Balay /* Step is not descent or direction produced not a number 101a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case because 102a7e14dcfSSatish Balay the first solve produces the scaled gradient direction, 103a7e14dcfSSatish Balay which is guaranteed to be descent 104a7e14dcfSSatish Balay 105a7e14dcfSSatish Balay Use steepest descent direction (scaled) */ 106a7e14dcfSSatish Balay ++lmP->grad; 107a7e14dcfSSatish Balay 108cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm * gnorm); 1099566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 1109566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1119566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1129566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 113a7e14dcfSSatish Balay 1149566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D, lmP->GV)); 115a7e14dcfSSatish Balay 116a7e14dcfSSatish Balay lmP->bfgs = 1; 117a7e14dcfSSatish Balay ++lmP->sgrad; 118a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 11953506e15SBarry Smith } else { 120a7e14dcfSSatish Balay if (1 == lmP->bfgs) { 121a7e14dcfSSatish Balay /* The first BFGS direction is always the scaled gradient */ 122a7e14dcfSSatish Balay ++lmP->sgrad; 123a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 12453506e15SBarry Smith } else { 125a7e14dcfSSatish Balay ++lmP->bfgs; 126a7e14dcfSSatish Balay stepType = OWLQN_BFGS; 127a7e14dcfSSatish Balay } 128a7e14dcfSSatish Balay } 129a7e14dcfSSatish Balay 1309566063dSJacob Faibussowitsch PetscCall(VecScale(lmP->D, -1.0)); 131a7e14dcfSSatish Balay 132a7e14dcfSSatish Balay /* Perform the linesearch */ 133a7e14dcfSSatish Balay fold = f; 1349566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, lmP->Xold)); 1359566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->Gold)); 136a7e14dcfSSatish Balay 1379566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step, &ls_status)); 1389566063dSJacob Faibussowitsch PetscCall(TaoAddLineSearchCounts(tao)); 139a7e14dcfSSatish Balay 140a7e14dcfSSatish Balay while (((int)ls_status < 0) && (stepType != OWLQN_GRADIENT)) { 141a7e14dcfSSatish Balay /* Reset factors and use scaled gradient step */ 142a7e14dcfSSatish Balay f = fold; 1439566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Xold, tao->solution)); 1449566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Gold, tao->gradient)); 1459566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 146a7e14dcfSSatish Balay 1479566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution, lmP->GV, lmP->lambda)); 148a7e14dcfSSatish Balay 149a7e14dcfSSatish Balay switch (stepType) { 150a7e14dcfSSatish Balay case OWLQN_BFGS: 151a7e14dcfSSatish Balay /* Failed to obtain acceptable iterate with BFGS step 152a7e14dcfSSatish Balay Attempt to use the scaled gradient direction */ 153a7e14dcfSSatish Balay 154cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm * gnorm); 1559566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 1569566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1579566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1589566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 159a7e14dcfSSatish Balay 1609566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D, lmP->GV)); 161a7e14dcfSSatish Balay 162a7e14dcfSSatish Balay lmP->bfgs = 1; 163a7e14dcfSSatish Balay ++lmP->sgrad; 164a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 165a7e14dcfSSatish Balay break; 166a7e14dcfSSatish Balay 167a7e14dcfSSatish Balay case OWLQN_SCALED_GRADIENT: 168a7e14dcfSSatish Balay /* The scaled gradient step did not produce a new iterate; 169a7e14dcfSSatish Balay attempt to use the gradient direction. 170a7e14dcfSSatish Balay Need to make sure we are not using a different diagonal scaling */ 1719566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, 1.0)); 1729566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1739566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1749566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 175a7e14dcfSSatish Balay 1769566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D, lmP->GV)); 177a7e14dcfSSatish Balay 178a7e14dcfSSatish Balay lmP->bfgs = 1; 179a7e14dcfSSatish Balay ++lmP->grad; 180a7e14dcfSSatish Balay stepType = OWLQN_GRADIENT; 181a7e14dcfSSatish Balay break; 182a7e14dcfSSatish Balay } 1839566063dSJacob Faibussowitsch PetscCall(VecScale(lmP->D, -1.0)); 184a7e14dcfSSatish Balay 185a7e14dcfSSatish Balay /* Perform the linesearch */ 1869566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step, &ls_status)); 1879566063dSJacob Faibussowitsch PetscCall(TaoAddLineSearchCounts(tao)); 188a7e14dcfSSatish Balay } 189a7e14dcfSSatish Balay 190a7e14dcfSSatish Balay if ((int)ls_status < 0) { 191a7e14dcfSSatish Balay /* Failed to find an improving point*/ 192a7e14dcfSSatish Balay f = fold; 1939566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Xold, tao->solution)); 1949566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Gold, tao->gradient)); 1959566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 196a7e14dcfSSatish Balay step = 0.0; 19753506e15SBarry Smith } else { 198a7e14dcfSSatish Balay /* a little hack here, because that gv is used to store g */ 1999566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->GV, tao->gradient)); 200a7e14dcfSSatish Balay } 201a7e14dcfSSatish Balay 2029566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution, lmP->GV, lmP->lambda)); 203a7e14dcfSSatish Balay 204a7e14dcfSSatish Balay /* Check for termination */ 205a7e14dcfSSatish Balay 2069566063dSJacob Faibussowitsch PetscCall(VecNorm(lmP->GV, NORM_2, &gnorm)); 207a7e14dcfSSatish Balay 208a7e14dcfSSatish Balay iter++; 2099566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its)); 2109566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao, iter, f, gnorm, 0.0, step)); 211dbbe0bcdSBarry Smith PetscUseTypeMethod(tao, convergencetest, tao->cnvP); 212a7e14dcfSSatish Balay 21353506e15SBarry Smith if ((int)ls_status < 0) break; 214a7e14dcfSSatish Balay } 215a7e14dcfSSatish Balay PetscFunctionReturn(0); 216a7e14dcfSSatish Balay } 217a7e14dcfSSatish Balay 2189371c9d4SSatish Balay static PetscErrorCode TaoSetUp_OWLQN(Tao tao) { 219a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 220a7e14dcfSSatish Balay PetscInt n, N; 221a7e14dcfSSatish Balay 222a7e14dcfSSatish Balay PetscFunctionBegin; 223441846f8SBarry Smith /* Existence of tao->solution checked in TaoSetUp() */ 2249566063dSJacob Faibussowitsch if (!tao->gradient) PetscCall(VecDuplicate(tao->solution, &tao->gradient)); 2259566063dSJacob Faibussowitsch if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution, &tao->stepdirection)); 2269566063dSJacob Faibussowitsch if (!lmP->D) PetscCall(VecDuplicate(tao->solution, &lmP->D)); 2279566063dSJacob Faibussowitsch if (!lmP->GV) PetscCall(VecDuplicate(tao->solution, &lmP->GV)); 2289566063dSJacob Faibussowitsch if (!lmP->Xold) PetscCall(VecDuplicate(tao->solution, &lmP->Xold)); 2299566063dSJacob Faibussowitsch if (!lmP->Gold) PetscCall(VecDuplicate(tao->solution, &lmP->Gold)); 230a7e14dcfSSatish Balay 231a7e14dcfSSatish Balay /* Create matrix for the limited memory approximation */ 2329566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(tao->solution, &n)); 2339566063dSJacob Faibussowitsch PetscCall(VecGetSize(tao->solution, &N)); 2349566063dSJacob Faibussowitsch PetscCall(MatCreateLMVMBFGS(((PetscObject)tao)->comm, n, N, &lmP->M)); 2359566063dSJacob Faibussowitsch PetscCall(MatLMVMAllocate(lmP->M, tao->solution, tao->gradient)); 236a7e14dcfSSatish Balay PetscFunctionReturn(0); 237a7e14dcfSSatish Balay } 238a7e14dcfSSatish Balay 239a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 2409371c9d4SSatish Balay static PetscErrorCode TaoDestroy_OWLQN(Tao tao) { 241a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 242a7e14dcfSSatish Balay 243a7e14dcfSSatish Balay PetscFunctionBegin; 244a7e14dcfSSatish Balay if (tao->setupcalled) { 2459566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->Xold)); 2469566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->Gold)); 2479566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->D)); 2489566063dSJacob Faibussowitsch PetscCall(MatDestroy(&lmP->M)); 2499566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->GV)); 250a7e14dcfSSatish Balay } 2519566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->data)); 252a7e14dcfSSatish Balay PetscFunctionReturn(0); 253a7e14dcfSSatish Balay } 254a7e14dcfSSatish Balay 255a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 2569371c9d4SSatish Balay static PetscErrorCode TaoSetFromOptions_OWLQN(Tao tao, PetscOptionItems *PetscOptionsObject) { 257a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 258a7e14dcfSSatish Balay 259a7e14dcfSSatish Balay PetscFunctionBegin; 260d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "Orthant-Wise Limited-memory method for Quasi-Newton unconstrained optimization"); 2619566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_owlqn_lambda", "regulariser weight", "", 100, &lmP->lambda, NULL)); 262d0609cedSBarry Smith PetscOptionsHeadEnd(); 2639566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetFromOptions(tao->linesearch)); 264a7e14dcfSSatish Balay PetscFunctionReturn(0); 265a7e14dcfSSatish Balay } 266a7e14dcfSSatish Balay 267a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 2689371c9d4SSatish Balay static PetscErrorCode TaoView_OWLQN(Tao tao, PetscViewer viewer) { 269a7e14dcfSSatish Balay TAO_OWLQN *lm = (TAO_OWLQN *)tao->data; 270a7e14dcfSSatish Balay PetscBool isascii; 271a7e14dcfSSatish Balay 272a7e14dcfSSatish Balay PetscFunctionBegin; 2739566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 274a7e14dcfSSatish Balay if (isascii) { 2759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 27663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "BFGS steps: %" PetscInt_FMT "\n", lm->bfgs)); 27763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %" PetscInt_FMT "\n", lm->sgrad)); 27863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Gradient steps: %" PetscInt_FMT "\n", lm->grad)); 2799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 280a7e14dcfSSatish Balay } 281a7e14dcfSSatish Balay PetscFunctionReturn(0); 282a7e14dcfSSatish Balay } 283a7e14dcfSSatish Balay 284a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 2851522df2eSJason Sarich /*MC 2861522df2eSJason Sarich TAOOWLQN - orthant-wise limited memory quasi-newton algorithm 2871522df2eSJason Sarich 2881522df2eSJason Sarich . - tao_owlqn_lambda - regulariser weight 2891522df2eSJason Sarich 2901eb8069cSJason Sarich Level: beginner 2911522df2eSJason Sarich M*/ 2921522df2eSJason Sarich 2939371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode TaoCreate_OWLQN(Tao tao) { 294a7e14dcfSSatish Balay TAO_OWLQN *lmP; 2958caf6e8cSBarry Smith const char *owarmijo_type = TAOLINESEARCHOWARMIJO; 296a7e14dcfSSatish Balay 297a7e14dcfSSatish Balay PetscFunctionBegin; 298a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_OWLQN; 299a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_OWLQN; 300a7e14dcfSSatish Balay tao->ops->view = TaoView_OWLQN; 301a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_OWLQN; 302a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_OWLQN; 303a7e14dcfSSatish Balay 3049566063dSJacob Faibussowitsch PetscCall(PetscNewLog(tao, &lmP)); 30583c8fe1dSLisandro Dalcin lmP->D = NULL; 30683c8fe1dSLisandro Dalcin lmP->M = NULL; 30783c8fe1dSLisandro Dalcin lmP->GV = NULL; 30883c8fe1dSLisandro Dalcin lmP->Xold = NULL; 30983c8fe1dSLisandro Dalcin lmP->Gold = NULL; 310a7e14dcfSSatish Balay lmP->lambda = 1.0; 311a7e14dcfSSatish Balay 312a7e14dcfSSatish Balay tao->data = (void *)lmP; 3136552cf8aSJason Sarich /* Override default settings (unless already changed) */ 3146552cf8aSJason Sarich if (!tao->max_it_changed) tao->max_it = 2000; 3156552cf8aSJason Sarich if (!tao->max_funcs_changed) tao->max_funcs = 4000; 316a7e14dcfSSatish Balay 3179566063dSJacob Faibussowitsch PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch)); 3189566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1)); 3199566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetType(tao->linesearch, owarmijo_type)); 3209566063dSJacob Faibussowitsch PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch, tao)); 3219566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch, tao->hdr.prefix)); 322a7e14dcfSSatish Balay PetscFunctionReturn(0); 323a7e14dcfSSatish Balay } 324