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)); 799566063dSJacob Faibussowitsch PetscCall((*tao->ops->convergencetest)(tao,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 */ 94e1e80dc8SAlp Dener if (tao->ops->update) { 959566063dSJacob Faibussowitsch PetscCall((*tao->ops->update)(tao, tao->niter, tao->user_update)); 96e1e80dc8SAlp Dener } 97e1e80dc8SAlp Dener 98a7e14dcfSSatish Balay /* Compute direction */ 999566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M,tao->solution,tao->gradient)); 1009566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 101a7e14dcfSSatish Balay 1029566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D,lmP->GV)); 103a7e14dcfSSatish Balay 104a7e14dcfSSatish Balay ++lmP->bfgs; 105a7e14dcfSSatish Balay 106a7e14dcfSSatish Balay /* Check for success (descent direction) */ 1079566063dSJacob Faibussowitsch PetscCall(VecDot(lmP->D, lmP->GV , &gdx)); 108a7e14dcfSSatish Balay if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 109a7e14dcfSSatish Balay 110a7e14dcfSSatish Balay /* Step is not descent or direction produced not a number 111a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case because 112a7e14dcfSSatish Balay the first solve produces the scaled gradient direction, 113a7e14dcfSSatish Balay which is guaranteed to be descent 114a7e14dcfSSatish Balay 115a7e14dcfSSatish Balay Use steepest descent direction (scaled) */ 116a7e14dcfSSatish Balay ++lmP->grad; 117a7e14dcfSSatish Balay 118cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm*gnorm); 1199566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 1209566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1219566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1229566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M,lmP->GV, lmP->D)); 123a7e14dcfSSatish Balay 1249566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D,lmP->GV)); 125a7e14dcfSSatish Balay 126a7e14dcfSSatish Balay lmP->bfgs = 1; 127a7e14dcfSSatish Balay ++lmP->sgrad; 128a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 12953506e15SBarry Smith } else { 130a7e14dcfSSatish Balay if (1 == lmP->bfgs) { 131a7e14dcfSSatish Balay /* The first BFGS direction is always the scaled gradient */ 132a7e14dcfSSatish Balay ++lmP->sgrad; 133a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 13453506e15SBarry Smith } else { 135a7e14dcfSSatish Balay ++lmP->bfgs; 136a7e14dcfSSatish Balay stepType = OWLQN_BFGS; 137a7e14dcfSSatish Balay } 138a7e14dcfSSatish Balay } 139a7e14dcfSSatish Balay 1409566063dSJacob Faibussowitsch PetscCall(VecScale(lmP->D, -1.0)); 141a7e14dcfSSatish Balay 142a7e14dcfSSatish Balay /* Perform the linesearch */ 143a7e14dcfSSatish Balay fold = f; 1449566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, lmP->Xold)); 1459566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->Gold)); 146a7e14dcfSSatish Balay 1479566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step,&ls_status)); 1489566063dSJacob Faibussowitsch PetscCall(TaoAddLineSearchCounts(tao)); 149a7e14dcfSSatish Balay 150a7e14dcfSSatish Balay while (((int)ls_status < 0) && (stepType != OWLQN_GRADIENT)) { 151a7e14dcfSSatish Balay 152a7e14dcfSSatish Balay /* Reset factors and use scaled gradient step */ 153a7e14dcfSSatish Balay f = fold; 1549566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Xold, tao->solution)); 1559566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Gold, tao->gradient)); 1569566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 157a7e14dcfSSatish Balay 1589566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution,lmP->GV,lmP->lambda)); 159a7e14dcfSSatish Balay 160a7e14dcfSSatish Balay switch(stepType) { 161a7e14dcfSSatish Balay case OWLQN_BFGS: 162a7e14dcfSSatish Balay /* Failed to obtain acceptable iterate with BFGS step 163a7e14dcfSSatish Balay Attempt to use the scaled gradient direction */ 164a7e14dcfSSatish Balay 165cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm*gnorm); 1669566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 1679566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1689566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1699566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 170a7e14dcfSSatish Balay 1719566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D,lmP->GV)); 172a7e14dcfSSatish Balay 173a7e14dcfSSatish Balay lmP->bfgs = 1; 174a7e14dcfSSatish Balay ++lmP->sgrad; 175a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 176a7e14dcfSSatish Balay break; 177a7e14dcfSSatish Balay 178a7e14dcfSSatish Balay case OWLQN_SCALED_GRADIENT: 179a7e14dcfSSatish Balay /* The scaled gradient step did not produce a new iterate; 180a7e14dcfSSatish Balay attempt to use the gradient direction. 181a7e14dcfSSatish Balay Need to make sure we are not using a different diagonal scaling */ 1829566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, 1.0)); 1839566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1849566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1859566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 186a7e14dcfSSatish Balay 1879566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D,lmP->GV)); 188a7e14dcfSSatish Balay 189a7e14dcfSSatish Balay lmP->bfgs = 1; 190a7e14dcfSSatish Balay ++lmP->grad; 191a7e14dcfSSatish Balay stepType = OWLQN_GRADIENT; 192a7e14dcfSSatish Balay break; 193a7e14dcfSSatish Balay } 1949566063dSJacob Faibussowitsch PetscCall(VecScale(lmP->D, -1.0)); 195a7e14dcfSSatish Balay 196a7e14dcfSSatish Balay /* Perform the linesearch */ 1979566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step, &ls_status)); 1989566063dSJacob Faibussowitsch PetscCall(TaoAddLineSearchCounts(tao)); 199a7e14dcfSSatish Balay } 200a7e14dcfSSatish Balay 201a7e14dcfSSatish Balay if ((int)ls_status < 0) { 202a7e14dcfSSatish Balay /* Failed to find an improving point*/ 203a7e14dcfSSatish Balay f = fold; 2049566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Xold, tao->solution)); 2059566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Gold, tao->gradient)); 2069566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 207a7e14dcfSSatish Balay step = 0.0; 20853506e15SBarry Smith } else { 209a7e14dcfSSatish Balay /* a little hack here, because that gv is used to store g */ 2109566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->GV, tao->gradient)); 211a7e14dcfSSatish Balay } 212a7e14dcfSSatish Balay 2139566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution,lmP->GV,lmP->lambda)); 214a7e14dcfSSatish Balay 215a7e14dcfSSatish Balay /* Check for termination */ 216a7e14dcfSSatish Balay 2179566063dSJacob Faibussowitsch PetscCall(VecNorm(lmP->GV,NORM_2,&gnorm)); 218a7e14dcfSSatish Balay 219a7e14dcfSSatish Balay iter++; 2209566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its)); 2219566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao,iter,f,gnorm,0.0,step)); 2229566063dSJacob Faibussowitsch PetscCall((*tao->ops->convergencetest)(tao,tao->cnvP)); 223a7e14dcfSSatish Balay 22453506e15SBarry Smith if ((int)ls_status < 0) break; 225a7e14dcfSSatish Balay } 226a7e14dcfSSatish Balay PetscFunctionReturn(0); 227a7e14dcfSSatish Balay } 228a7e14dcfSSatish Balay 229441846f8SBarry Smith static PetscErrorCode TaoSetUp_OWLQN(Tao tao) 230a7e14dcfSSatish Balay { 231a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 232a7e14dcfSSatish Balay PetscInt n,N; 233a7e14dcfSSatish Balay 234a7e14dcfSSatish Balay PetscFunctionBegin; 235441846f8SBarry Smith /* Existence of tao->solution checked in TaoSetUp() */ 2369566063dSJacob Faibussowitsch if (!tao->gradient) PetscCall(VecDuplicate(tao->solution,&tao->gradient)); 2379566063dSJacob Faibussowitsch if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution,&tao->stepdirection)); 2389566063dSJacob Faibussowitsch if (!lmP->D) PetscCall(VecDuplicate(tao->solution,&lmP->D)); 2399566063dSJacob Faibussowitsch if (!lmP->GV) PetscCall(VecDuplicate(tao->solution,&lmP->GV)); 2409566063dSJacob Faibussowitsch if (!lmP->Xold) PetscCall(VecDuplicate(tao->solution,&lmP->Xold)); 2419566063dSJacob Faibussowitsch if (!lmP->Gold) PetscCall(VecDuplicate(tao->solution,&lmP->Gold)); 242a7e14dcfSSatish Balay 243a7e14dcfSSatish Balay /* Create matrix for the limited memory approximation */ 2449566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(tao->solution,&n)); 2459566063dSJacob Faibussowitsch PetscCall(VecGetSize(tao->solution,&N)); 2469566063dSJacob Faibussowitsch PetscCall(MatCreateLMVMBFGS(((PetscObject)tao)->comm,n,N,&lmP->M)); 2479566063dSJacob Faibussowitsch PetscCall(MatLMVMAllocate(lmP->M,tao->solution,tao->gradient)); 248a7e14dcfSSatish Balay PetscFunctionReturn(0); 249a7e14dcfSSatish Balay } 250a7e14dcfSSatish Balay 251a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 252441846f8SBarry Smith static PetscErrorCode TaoDestroy_OWLQN(Tao tao) 253a7e14dcfSSatish Balay { 254a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 255a7e14dcfSSatish Balay 256a7e14dcfSSatish Balay PetscFunctionBegin; 257a7e14dcfSSatish Balay if (tao->setupcalled) { 2589566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->Xold)); 2599566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->Gold)); 2609566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->D)); 2619566063dSJacob Faibussowitsch PetscCall(MatDestroy(&lmP->M)); 2629566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->GV)); 263a7e14dcfSSatish Balay } 2649566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->data)); 265a7e14dcfSSatish Balay PetscFunctionReturn(0); 266a7e14dcfSSatish Balay } 267a7e14dcfSSatish Balay 268a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 2694416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_OWLQN(PetscOptionItems *PetscOptionsObject,Tao tao) 270a7e14dcfSSatish Balay { 271a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 272a7e14dcfSSatish Balay 273a7e14dcfSSatish Balay PetscFunctionBegin; 274d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"Orthant-Wise Limited-memory method for Quasi-Newton unconstrained optimization"); 2759566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_owlqn_lambda", "regulariser weight","", 100,&lmP->lambda,NULL)); 276d0609cedSBarry Smith PetscOptionsHeadEnd(); 2779566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetFromOptions(tao->linesearch)); 278a7e14dcfSSatish Balay PetscFunctionReturn(0); 279a7e14dcfSSatish Balay } 280a7e14dcfSSatish Balay 281a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 282441846f8SBarry Smith static PetscErrorCode TaoView_OWLQN(Tao tao, PetscViewer viewer) 283a7e14dcfSSatish Balay { 284a7e14dcfSSatish Balay TAO_OWLQN *lm = (TAO_OWLQN *)tao->data; 285a7e14dcfSSatish Balay PetscBool isascii; 286a7e14dcfSSatish Balay 287a7e14dcfSSatish Balay PetscFunctionBegin; 2889566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 289a7e14dcfSSatish Balay if (isascii) { 2909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 291*63a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "BFGS steps: %" PetscInt_FMT "\n", lm->bfgs)); 292*63a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %" PetscInt_FMT "\n", lm->sgrad)); 293*63a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Gradient steps: %" PetscInt_FMT "\n", lm->grad)); 2949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 295a7e14dcfSSatish Balay } 296a7e14dcfSSatish Balay PetscFunctionReturn(0); 297a7e14dcfSSatish Balay } 298a7e14dcfSSatish Balay 299a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 3001522df2eSJason Sarich /*MC 3011522df2eSJason Sarich TAOOWLQN - orthant-wise limited memory quasi-newton algorithm 3021522df2eSJason Sarich 3031522df2eSJason Sarich . - tao_owlqn_lambda - regulariser weight 3041522df2eSJason Sarich 3051eb8069cSJason Sarich Level: beginner 3061522df2eSJason Sarich M*/ 3071522df2eSJason Sarich 308728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_OWLQN(Tao tao) 309a7e14dcfSSatish Balay { 310a7e14dcfSSatish Balay TAO_OWLQN *lmP; 3118caf6e8cSBarry Smith const char *owarmijo_type = TAOLINESEARCHOWARMIJO; 312a7e14dcfSSatish Balay 313a7e14dcfSSatish Balay PetscFunctionBegin; 314a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_OWLQN; 315a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_OWLQN; 316a7e14dcfSSatish Balay tao->ops->view = TaoView_OWLQN; 317a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_OWLQN; 318a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_OWLQN; 319a7e14dcfSSatish Balay 3209566063dSJacob Faibussowitsch PetscCall(PetscNewLog(tao,&lmP)); 32183c8fe1dSLisandro Dalcin lmP->D = NULL; 32283c8fe1dSLisandro Dalcin lmP->M = NULL; 32383c8fe1dSLisandro Dalcin lmP->GV = NULL; 32483c8fe1dSLisandro Dalcin lmP->Xold = NULL; 32583c8fe1dSLisandro Dalcin lmP->Gold = NULL; 326a7e14dcfSSatish Balay lmP->lambda = 1.0; 327a7e14dcfSSatish Balay 328a7e14dcfSSatish Balay tao->data = (void*)lmP; 3296552cf8aSJason Sarich /* Override default settings (unless already changed) */ 3306552cf8aSJason Sarich if (!tao->max_it_changed) tao->max_it = 2000; 3316552cf8aSJason Sarich if (!tao->max_funcs_changed) tao->max_funcs = 4000; 332a7e14dcfSSatish Balay 3339566063dSJacob Faibussowitsch PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch)); 3349566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1)); 3359566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetType(tao->linesearch,owarmijo_type)); 3369566063dSJacob Faibussowitsch PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch,tao)); 3379566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix)); 338a7e14dcfSSatish Balay PetscFunctionReturn(0); 339a7e14dcfSSatish Balay } 340