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 8a7e14dcfSSatish Balay static PetscErrorCode ProjDirect_OWLQN(Vec d, Vec g) 9a7e14dcfSSatish Balay { 105e081366SBarry Smith const PetscReal *gptr; 115e081366SBarry Smith PetscReal *dptr; 12a7e14dcfSSatish Balay PetscInt low,high,low1,high1,i; 13a7e14dcfSSatish Balay 14a7e14dcfSSatish Balay PetscFunctionBegin; 159566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(d,&low,&high)); 169566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(g,&low1,&high1)); 17a7e14dcfSSatish Balay 189566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(g,&gptr)); 199566063dSJacob Faibussowitsch PetscCall(VecGetArray(d,&dptr)); 20a7e14dcfSSatish Balay for (i = 0; i < high-low; i++) { 2153506e15SBarry Smith if (dptr[i] * gptr[i] <= 0.0) { 22a7e14dcfSSatish Balay dptr[i] = 0.0; 23a7e14dcfSSatish Balay } 24a7e14dcfSSatish Balay } 259566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(d,&dptr)); 269566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(g,&gptr)); 27a7e14dcfSSatish Balay PetscFunctionReturn(0); 28a7e14dcfSSatish Balay } 29a7e14dcfSSatish Balay 30a7e14dcfSSatish Balay static PetscErrorCode ComputePseudoGrad_OWLQN(Vec x, Vec gv, PetscReal lambda) 31a7e14dcfSSatish Balay { 325e081366SBarry Smith const PetscReal *xptr; 335e081366SBarry Smith PetscReal *gptr; 34a7e14dcfSSatish Balay PetscInt low,high,low1,high1,i; 35a7e14dcfSSatish Balay 36a7e14dcfSSatish Balay PetscFunctionBegin; 379566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(x,&low,&high)); 389566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(gv,&low1,&high1)); 39a7e14dcfSSatish Balay 409566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xptr)); 419566063dSJacob Faibussowitsch PetscCall(VecGetArray(gv,&gptr)); 42a7e14dcfSSatish Balay for (i = 0; i < high-low; i++) { 4353506e15SBarry Smith if (xptr[i] < 0.0) gptr[i] = gptr[i] - lambda; 4453506e15SBarry Smith else if (xptr[i] > 0.0) gptr[i] = gptr[i] + lambda; 4553506e15SBarry Smith else if (gptr[i] + lambda < 0.0) gptr[i] = gptr[i] + lambda; 4653506e15SBarry Smith else if (gptr[i] - lambda > 0.0) gptr[i] = gptr[i] - lambda; 4753506e15SBarry Smith else gptr[i] = 0.0; 48a7e14dcfSSatish Balay } 499566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(gv,&gptr)); 509566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xptr)); 51a7e14dcfSSatish Balay PetscFunctionReturn(0); 52a7e14dcfSSatish Balay } 53a7e14dcfSSatish Balay 54441846f8SBarry Smith static PetscErrorCode TaoSolve_OWLQN(Tao tao) 55a7e14dcfSSatish Balay { 56a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 57a7e14dcfSSatish Balay PetscReal f, fold, gdx, gnorm; 58a7e14dcfSSatish Balay PetscReal step = 1.0; 59a7e14dcfSSatish Balay PetscReal delta; 60a7e14dcfSSatish Balay PetscInt stepType; 61a7e14dcfSSatish Balay PetscInt iter = 0; 62e4cb33bbSBarry Smith TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; 63a7e14dcfSSatish Balay 64a7e14dcfSSatish Balay PetscFunctionBegin; 65a7e14dcfSSatish Balay if (tao->XL || tao->XU || tao->ops->computebounds) { 669566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"WARNING: Variable bounds have been set but will be ignored by owlqn algorithm\n")); 67a7e14dcfSSatish Balay } 68a7e14dcfSSatish Balay 69a7e14dcfSSatish Balay /* Check convergence criteria */ 709566063dSJacob Faibussowitsch PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient)); 719566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 729566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution,lmP->GV,lmP->lambda)); 739566063dSJacob Faibussowitsch PetscCall(VecNorm(lmP->GV,NORM_2,&gnorm)); 743c859ba3SBarry Smith PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm),PetscObjectComm((PetscObject)tao),PETSC_ERR_USER, "User provided compute function generated Inf or NaN"); 75a7e14dcfSSatish Balay 763ecd9318SAlp Dener tao->reason = TAO_CONTINUE_ITERATING; 779566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its)); 789566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao,iter,f,gnorm,0.0,step)); 79*dbbe0bcdSBarry Smith PetscUseTypeMethod(tao,convergencetest ,tao->cnvP); 803ecd9318SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 81a7e14dcfSSatish Balay 82a7e14dcfSSatish Balay /* Set initial scaling for the function */ 83cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm*gnorm); 849566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 85a7e14dcfSSatish Balay 86a7e14dcfSSatish Balay /* Set counter for gradient/reset steps */ 87a7e14dcfSSatish Balay lmP->bfgs = 0; 88a7e14dcfSSatish Balay lmP->sgrad = 0; 89a7e14dcfSSatish Balay lmP->grad = 0; 90a7e14dcfSSatish Balay 91a7e14dcfSSatish Balay /* Have not converged; continue with Newton method */ 923ecd9318SAlp Dener while (tao->reason == TAO_CONTINUE_ITERATING) { 93e1e80dc8SAlp Dener /* Call general purpose update function */ 94*dbbe0bcdSBarry Smith PetscTryTypeMethod(tao,update, tao->niter, tao->user_update); 95e1e80dc8SAlp Dener 96a7e14dcfSSatish Balay /* Compute direction */ 979566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M,tao->solution,tao->gradient)); 989566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 99a7e14dcfSSatish Balay 1009566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D,lmP->GV)); 101a7e14dcfSSatish Balay 102a7e14dcfSSatish Balay ++lmP->bfgs; 103a7e14dcfSSatish Balay 104a7e14dcfSSatish Balay /* Check for success (descent direction) */ 1059566063dSJacob Faibussowitsch PetscCall(VecDot(lmP->D, lmP->GV , &gdx)); 106a7e14dcfSSatish Balay if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 107a7e14dcfSSatish Balay 108a7e14dcfSSatish Balay /* Step is not descent or direction produced not a number 109a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case because 110a7e14dcfSSatish Balay the first solve produces the scaled gradient direction, 111a7e14dcfSSatish Balay which is guaranteed to be descent 112a7e14dcfSSatish Balay 113a7e14dcfSSatish Balay Use steepest descent direction (scaled) */ 114a7e14dcfSSatish Balay ++lmP->grad; 115a7e14dcfSSatish Balay 116cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm*gnorm); 1179566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 1189566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1199566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1209566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M,lmP->GV, lmP->D)); 121a7e14dcfSSatish Balay 1229566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D,lmP->GV)); 123a7e14dcfSSatish Balay 124a7e14dcfSSatish Balay lmP->bfgs = 1; 125a7e14dcfSSatish Balay ++lmP->sgrad; 126a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 12753506e15SBarry Smith } else { 128a7e14dcfSSatish Balay if (1 == lmP->bfgs) { 129a7e14dcfSSatish Balay /* The first BFGS direction is always the scaled gradient */ 130a7e14dcfSSatish Balay ++lmP->sgrad; 131a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 13253506e15SBarry Smith } else { 133a7e14dcfSSatish Balay ++lmP->bfgs; 134a7e14dcfSSatish Balay stepType = OWLQN_BFGS; 135a7e14dcfSSatish Balay } 136a7e14dcfSSatish Balay } 137a7e14dcfSSatish Balay 1389566063dSJacob Faibussowitsch PetscCall(VecScale(lmP->D, -1.0)); 139a7e14dcfSSatish Balay 140a7e14dcfSSatish Balay /* Perform the linesearch */ 141a7e14dcfSSatish Balay fold = f; 1429566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, lmP->Xold)); 1439566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->Gold)); 144a7e14dcfSSatish Balay 1459566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step,&ls_status)); 1469566063dSJacob Faibussowitsch PetscCall(TaoAddLineSearchCounts(tao)); 147a7e14dcfSSatish Balay 148a7e14dcfSSatish Balay while (((int)ls_status < 0) && (stepType != OWLQN_GRADIENT)) { 149a7e14dcfSSatish Balay 150a7e14dcfSSatish Balay /* Reset factors and use scaled gradient step */ 151a7e14dcfSSatish Balay f = fold; 1529566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Xold, tao->solution)); 1539566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Gold, tao->gradient)); 1549566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 155a7e14dcfSSatish Balay 1569566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution,lmP->GV,lmP->lambda)); 157a7e14dcfSSatish Balay 158a7e14dcfSSatish Balay switch(stepType) { 159a7e14dcfSSatish Balay case OWLQN_BFGS: 160a7e14dcfSSatish Balay /* Failed to obtain acceptable iterate with BFGS step 161a7e14dcfSSatish Balay Attempt to use the scaled gradient direction */ 162a7e14dcfSSatish Balay 163cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm*gnorm); 1649566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 1659566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1669566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1679566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 168a7e14dcfSSatish Balay 1699566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D,lmP->GV)); 170a7e14dcfSSatish Balay 171a7e14dcfSSatish Balay lmP->bfgs = 1; 172a7e14dcfSSatish Balay ++lmP->sgrad; 173a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 174a7e14dcfSSatish Balay break; 175a7e14dcfSSatish Balay 176a7e14dcfSSatish Balay case OWLQN_SCALED_GRADIENT: 177a7e14dcfSSatish Balay /* The scaled gradient step did not produce a new iterate; 178a7e14dcfSSatish Balay attempt to use the gradient direction. 179a7e14dcfSSatish Balay Need to make sure we are not using a different diagonal scaling */ 1809566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, 1.0)); 1819566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1829566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1839566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 184a7e14dcfSSatish Balay 1859566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D,lmP->GV)); 186a7e14dcfSSatish Balay 187a7e14dcfSSatish Balay lmP->bfgs = 1; 188a7e14dcfSSatish Balay ++lmP->grad; 189a7e14dcfSSatish Balay stepType = OWLQN_GRADIENT; 190a7e14dcfSSatish Balay break; 191a7e14dcfSSatish Balay } 1929566063dSJacob Faibussowitsch PetscCall(VecScale(lmP->D, -1.0)); 193a7e14dcfSSatish Balay 194a7e14dcfSSatish Balay /* Perform the linesearch */ 1959566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step, &ls_status)); 1969566063dSJacob Faibussowitsch PetscCall(TaoAddLineSearchCounts(tao)); 197a7e14dcfSSatish Balay } 198a7e14dcfSSatish Balay 199a7e14dcfSSatish Balay if ((int)ls_status < 0) { 200a7e14dcfSSatish Balay /* Failed to find an improving point*/ 201a7e14dcfSSatish Balay f = fold; 2029566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Xold, tao->solution)); 2039566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Gold, tao->gradient)); 2049566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 205a7e14dcfSSatish Balay step = 0.0; 20653506e15SBarry Smith } else { 207a7e14dcfSSatish Balay /* a little hack here, because that gv is used to store g */ 2089566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->GV, tao->gradient)); 209a7e14dcfSSatish Balay } 210a7e14dcfSSatish Balay 2119566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution,lmP->GV,lmP->lambda)); 212a7e14dcfSSatish Balay 213a7e14dcfSSatish Balay /* Check for termination */ 214a7e14dcfSSatish Balay 2159566063dSJacob Faibussowitsch PetscCall(VecNorm(lmP->GV,NORM_2,&gnorm)); 216a7e14dcfSSatish Balay 217a7e14dcfSSatish Balay iter++; 2189566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its)); 2199566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao,iter,f,gnorm,0.0,step)); 220*dbbe0bcdSBarry Smith PetscUseTypeMethod(tao,convergencetest ,tao->cnvP); 221a7e14dcfSSatish Balay 22253506e15SBarry Smith if ((int)ls_status < 0) break; 223a7e14dcfSSatish Balay } 224a7e14dcfSSatish Balay PetscFunctionReturn(0); 225a7e14dcfSSatish Balay } 226a7e14dcfSSatish Balay 227441846f8SBarry Smith static PetscErrorCode TaoSetUp_OWLQN(Tao tao) 228a7e14dcfSSatish Balay { 229a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 230a7e14dcfSSatish Balay PetscInt n,N; 231a7e14dcfSSatish Balay 232a7e14dcfSSatish Balay PetscFunctionBegin; 233441846f8SBarry Smith /* Existence of tao->solution checked in TaoSetUp() */ 2349566063dSJacob Faibussowitsch if (!tao->gradient) PetscCall(VecDuplicate(tao->solution,&tao->gradient)); 2359566063dSJacob Faibussowitsch if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution,&tao->stepdirection)); 2369566063dSJacob Faibussowitsch if (!lmP->D) PetscCall(VecDuplicate(tao->solution,&lmP->D)); 2379566063dSJacob Faibussowitsch if (!lmP->GV) PetscCall(VecDuplicate(tao->solution,&lmP->GV)); 2389566063dSJacob Faibussowitsch if (!lmP->Xold) PetscCall(VecDuplicate(tao->solution,&lmP->Xold)); 2399566063dSJacob Faibussowitsch if (!lmP->Gold) PetscCall(VecDuplicate(tao->solution,&lmP->Gold)); 240a7e14dcfSSatish Balay 241a7e14dcfSSatish Balay /* Create matrix for the limited memory approximation */ 2429566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(tao->solution,&n)); 2439566063dSJacob Faibussowitsch PetscCall(VecGetSize(tao->solution,&N)); 2449566063dSJacob Faibussowitsch PetscCall(MatCreateLMVMBFGS(((PetscObject)tao)->comm,n,N,&lmP->M)); 2459566063dSJacob Faibussowitsch PetscCall(MatLMVMAllocate(lmP->M,tao->solution,tao->gradient)); 246a7e14dcfSSatish Balay PetscFunctionReturn(0); 247a7e14dcfSSatish Balay } 248a7e14dcfSSatish Balay 249a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 250441846f8SBarry Smith static PetscErrorCode TaoDestroy_OWLQN(Tao tao) 251a7e14dcfSSatish Balay { 252a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 253a7e14dcfSSatish Balay 254a7e14dcfSSatish Balay PetscFunctionBegin; 255a7e14dcfSSatish Balay if (tao->setupcalled) { 2569566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->Xold)); 2579566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->Gold)); 2589566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->D)); 2599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&lmP->M)); 2609566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->GV)); 261a7e14dcfSSatish Balay } 2629566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->data)); 263a7e14dcfSSatish Balay PetscFunctionReturn(0); 264a7e14dcfSSatish Balay } 265a7e14dcfSSatish Balay 266a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 267*dbbe0bcdSBarry Smith static PetscErrorCode TaoSetFromOptions_OWLQN(Tao tao,PetscOptionItems *PetscOptionsObject) 268a7e14dcfSSatish Balay { 269a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 270a7e14dcfSSatish Balay 271a7e14dcfSSatish Balay PetscFunctionBegin; 272d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"Orthant-Wise Limited-memory method for Quasi-Newton unconstrained optimization"); 2739566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_owlqn_lambda", "regulariser weight","", 100,&lmP->lambda,NULL)); 274d0609cedSBarry Smith PetscOptionsHeadEnd(); 2759566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetFromOptions(tao->linesearch)); 276a7e14dcfSSatish Balay PetscFunctionReturn(0); 277a7e14dcfSSatish Balay } 278a7e14dcfSSatish Balay 279a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 280441846f8SBarry Smith static PetscErrorCode TaoView_OWLQN(Tao tao, PetscViewer viewer) 281a7e14dcfSSatish Balay { 282a7e14dcfSSatish Balay TAO_OWLQN *lm = (TAO_OWLQN *)tao->data; 283a7e14dcfSSatish Balay PetscBool isascii; 284a7e14dcfSSatish Balay 285a7e14dcfSSatish Balay PetscFunctionBegin; 2869566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 287a7e14dcfSSatish Balay if (isascii) { 2889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 28963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "BFGS steps: %" PetscInt_FMT "\n", lm->bfgs)); 29063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %" PetscInt_FMT "\n", lm->sgrad)); 29163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Gradient steps: %" PetscInt_FMT "\n", lm->grad)); 2929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 293a7e14dcfSSatish Balay } 294a7e14dcfSSatish Balay PetscFunctionReturn(0); 295a7e14dcfSSatish Balay } 296a7e14dcfSSatish Balay 297a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 2981522df2eSJason Sarich /*MC 2991522df2eSJason Sarich TAOOWLQN - orthant-wise limited memory quasi-newton algorithm 3001522df2eSJason Sarich 3011522df2eSJason Sarich . - tao_owlqn_lambda - regulariser weight 3021522df2eSJason Sarich 3031eb8069cSJason Sarich Level: beginner 3041522df2eSJason Sarich M*/ 3051522df2eSJason Sarich 306728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_OWLQN(Tao tao) 307a7e14dcfSSatish Balay { 308a7e14dcfSSatish Balay TAO_OWLQN *lmP; 3098caf6e8cSBarry Smith const char *owarmijo_type = TAOLINESEARCHOWARMIJO; 310a7e14dcfSSatish Balay 311a7e14dcfSSatish Balay PetscFunctionBegin; 312a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_OWLQN; 313a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_OWLQN; 314a7e14dcfSSatish Balay tao->ops->view = TaoView_OWLQN; 315a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_OWLQN; 316a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_OWLQN; 317a7e14dcfSSatish Balay 3189566063dSJacob Faibussowitsch PetscCall(PetscNewLog(tao,&lmP)); 31983c8fe1dSLisandro Dalcin lmP->D = NULL; 32083c8fe1dSLisandro Dalcin lmP->M = NULL; 32183c8fe1dSLisandro Dalcin lmP->GV = NULL; 32283c8fe1dSLisandro Dalcin lmP->Xold = NULL; 32383c8fe1dSLisandro Dalcin lmP->Gold = NULL; 324a7e14dcfSSatish Balay lmP->lambda = 1.0; 325a7e14dcfSSatish Balay 326a7e14dcfSSatish Balay tao->data = (void*)lmP; 3276552cf8aSJason Sarich /* Override default settings (unless already changed) */ 3286552cf8aSJason Sarich if (!tao->max_it_changed) tao->max_it = 2000; 3296552cf8aSJason Sarich if (!tao->max_funcs_changed) tao->max_funcs = 4000; 330a7e14dcfSSatish Balay 3319566063dSJacob Faibussowitsch PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch)); 3329566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1)); 3339566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetType(tao->linesearch,owarmijo_type)); 3349566063dSJacob Faibussowitsch PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch,tao)); 3359566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix)); 336a7e14dcfSSatish Balay PetscFunctionReturn(0); 337a7e14dcfSSatish Balay } 338