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 8d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProjDirect_OWLQN(Vec d, Vec g) 9d71ae5a4SJacob Faibussowitsch { 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++) { 21ad540459SPierre Jolivet if (dptr[i] * gptr[i] <= 0.0) dptr[i] = 0.0; 22a7e14dcfSSatish Balay } 239566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(d, &dptr)); 249566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(g, &gptr)); 253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26a7e14dcfSSatish Balay } 27a7e14dcfSSatish Balay 28d71ae5a4SJacob Faibussowitsch static PetscErrorCode ComputePseudoGrad_OWLQN(Vec x, Vec gv, PetscReal lambda) 29d71ae5a4SJacob Faibussowitsch { 305e081366SBarry Smith const PetscReal *xptr; 315e081366SBarry Smith PetscReal *gptr; 32a7e14dcfSSatish Balay PetscInt low, high, low1, high1, i; 33a7e14dcfSSatish Balay 34a7e14dcfSSatish Balay PetscFunctionBegin; 359566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(x, &low, &high)); 369566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(gv, &low1, &high1)); 37a7e14dcfSSatish Balay 389566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xptr)); 399566063dSJacob Faibussowitsch PetscCall(VecGetArray(gv, &gptr)); 40a7e14dcfSSatish Balay for (i = 0; i < high - low; i++) { 4153506e15SBarry Smith if (xptr[i] < 0.0) gptr[i] = gptr[i] - lambda; 4253506e15SBarry Smith else if (xptr[i] > 0.0) gptr[i] = gptr[i] + lambda; 4353506e15SBarry Smith else if (gptr[i] + lambda < 0.0) gptr[i] = gptr[i] + lambda; 4453506e15SBarry Smith else if (gptr[i] - lambda > 0.0) gptr[i] = gptr[i] - lambda; 4553506e15SBarry Smith else gptr[i] = 0.0; 46a7e14dcfSSatish Balay } 479566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(gv, &gptr)); 489566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xptr)); 493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50a7e14dcfSSatish Balay } 51a7e14dcfSSatish Balay 52d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSolve_OWLQN(Tao tao) 53d71ae5a4SJacob Faibussowitsch { 54a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 55a7e14dcfSSatish Balay PetscReal f, fold, gdx, gnorm; 56a7e14dcfSSatish Balay PetscReal step = 1.0; 57a7e14dcfSSatish Balay PetscReal delta; 58a7e14dcfSSatish Balay PetscInt stepType; 59a7e14dcfSSatish Balay PetscInt iter = 0; 60e4cb33bbSBarry Smith TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; 61a7e14dcfSSatish Balay 62a7e14dcfSSatish Balay PetscFunctionBegin; 6348a46eb9SPierre 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")); 64a7e14dcfSSatish Balay 65a7e14dcfSSatish Balay /* Check convergence criteria */ 669566063dSJacob Faibussowitsch PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient)); 679566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 689566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution, lmP->GV, lmP->lambda)); 699566063dSJacob Faibussowitsch PetscCall(VecNorm(lmP->GV, NORM_2, &gnorm)); 703c859ba3SBarry Smith PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN"); 71a7e14dcfSSatish Balay 723ecd9318SAlp Dener tao->reason = TAO_CONTINUE_ITERATING; 739566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its)); 749566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao, iter, f, gnorm, 0.0, step)); 75dbbe0bcdSBarry Smith PetscUseTypeMethod(tao, convergencetest, tao->cnvP); 763ba16761SJacob Faibussowitsch if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(PETSC_SUCCESS); 77a7e14dcfSSatish Balay 78a7e14dcfSSatish Balay /* Set initial scaling for the function */ 79cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm * gnorm); 809566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 81a7e14dcfSSatish Balay 82a7e14dcfSSatish Balay /* Set counter for gradient/reset steps */ 83a7e14dcfSSatish Balay lmP->bfgs = 0; 84a7e14dcfSSatish Balay lmP->sgrad = 0; 85a7e14dcfSSatish Balay lmP->grad = 0; 86a7e14dcfSSatish Balay 87a7e14dcfSSatish Balay /* Have not converged; continue with Newton method */ 883ecd9318SAlp Dener while (tao->reason == TAO_CONTINUE_ITERATING) { 89e1e80dc8SAlp Dener /* Call general purpose update function */ 90dbbe0bcdSBarry Smith PetscTryTypeMethod(tao, update, tao->niter, tao->user_update); 91e1e80dc8SAlp Dener 92a7e14dcfSSatish Balay /* Compute direction */ 939566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 949566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 95a7e14dcfSSatish Balay 969566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D, lmP->GV)); 97a7e14dcfSSatish Balay 98a7e14dcfSSatish Balay ++lmP->bfgs; 99a7e14dcfSSatish Balay 100a7e14dcfSSatish Balay /* Check for success (descent direction) */ 1019566063dSJacob Faibussowitsch PetscCall(VecDot(lmP->D, lmP->GV, &gdx)); 102a7e14dcfSSatish Balay if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 103a7e14dcfSSatish Balay /* Step is not descent or direction produced not a number 104a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case because 105a7e14dcfSSatish Balay the first solve produces the scaled gradient direction, 106a7e14dcfSSatish Balay which is guaranteed to be descent 107a7e14dcfSSatish Balay 108a7e14dcfSSatish Balay Use steepest descent direction (scaled) */ 109a7e14dcfSSatish Balay ++lmP->grad; 110a7e14dcfSSatish Balay 111cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm * gnorm); 1129566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 1139566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1149566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1159566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 116a7e14dcfSSatish Balay 1179566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D, lmP->GV)); 118a7e14dcfSSatish Balay 119a7e14dcfSSatish Balay lmP->bfgs = 1; 120a7e14dcfSSatish Balay ++lmP->sgrad; 121a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 12253506e15SBarry Smith } else { 123a7e14dcfSSatish Balay if (1 == lmP->bfgs) { 124a7e14dcfSSatish Balay /* The first BFGS direction is always the scaled gradient */ 125a7e14dcfSSatish Balay ++lmP->sgrad; 126a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 12753506e15SBarry Smith } else { 128a7e14dcfSSatish Balay ++lmP->bfgs; 129a7e14dcfSSatish Balay stepType = OWLQN_BFGS; 130a7e14dcfSSatish Balay } 131a7e14dcfSSatish Balay } 132a7e14dcfSSatish Balay 1339566063dSJacob Faibussowitsch PetscCall(VecScale(lmP->D, -1.0)); 134a7e14dcfSSatish Balay 135a7e14dcfSSatish Balay /* Perform the linesearch */ 136a7e14dcfSSatish Balay fold = f; 1379566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, lmP->Xold)); 1389566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->Gold)); 139a7e14dcfSSatish Balay 1409566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step, &ls_status)); 1419566063dSJacob Faibussowitsch PetscCall(TaoAddLineSearchCounts(tao)); 142a7e14dcfSSatish Balay 143a7e14dcfSSatish Balay while (((int)ls_status < 0) && (stepType != OWLQN_GRADIENT)) { 144a7e14dcfSSatish Balay /* Reset factors and use scaled gradient step */ 145a7e14dcfSSatish Balay f = fold; 1469566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Xold, tao->solution)); 1479566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Gold, tao->gradient)); 1489566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 149a7e14dcfSSatish Balay 1509566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution, lmP->GV, lmP->lambda)); 151a7e14dcfSSatish Balay 152a7e14dcfSSatish Balay switch (stepType) { 153a7e14dcfSSatish Balay case OWLQN_BFGS: 154a7e14dcfSSatish Balay /* Failed to obtain acceptable iterate with BFGS step 155a7e14dcfSSatish Balay Attempt to use the scaled gradient direction */ 156a7e14dcfSSatish Balay 157cd929ea3SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(f)) / (gnorm * gnorm); 1589566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, delta)); 1599566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1609566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1619566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 162a7e14dcfSSatish Balay 1639566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D, lmP->GV)); 164a7e14dcfSSatish Balay 165a7e14dcfSSatish Balay lmP->bfgs = 1; 166a7e14dcfSSatish Balay ++lmP->sgrad; 167a7e14dcfSSatish Balay stepType = OWLQN_SCALED_GRADIENT; 168a7e14dcfSSatish Balay break; 169a7e14dcfSSatish Balay 170a7e14dcfSSatish Balay case OWLQN_SCALED_GRADIENT: 171a7e14dcfSSatish Balay /* The scaled gradient step did not produce a new iterate; 172a7e14dcfSSatish Balay attempt to use the gradient direction. 173a7e14dcfSSatish Balay Need to make sure we are not using a different diagonal scaling */ 1749566063dSJacob Faibussowitsch PetscCall(MatLMVMSetJ0Scale(lmP->M, 1.0)); 1759566063dSJacob Faibussowitsch PetscCall(MatLMVMReset(lmP->M, PETSC_FALSE)); 1769566063dSJacob Faibussowitsch PetscCall(MatLMVMUpdate(lmP->M, tao->solution, tao->gradient)); 1779566063dSJacob Faibussowitsch PetscCall(MatSolve(lmP->M, lmP->GV, lmP->D)); 178a7e14dcfSSatish Balay 1799566063dSJacob Faibussowitsch PetscCall(ProjDirect_OWLQN(lmP->D, lmP->GV)); 180a7e14dcfSSatish Balay 181a7e14dcfSSatish Balay lmP->bfgs = 1; 182a7e14dcfSSatish Balay ++lmP->grad; 183a7e14dcfSSatish Balay stepType = OWLQN_GRADIENT; 184a7e14dcfSSatish Balay break; 185a7e14dcfSSatish Balay } 1869566063dSJacob Faibussowitsch PetscCall(VecScale(lmP->D, -1.0)); 187a7e14dcfSSatish Balay 188a7e14dcfSSatish Balay /* Perform the linesearch */ 1899566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step, &ls_status)); 1909566063dSJacob Faibussowitsch PetscCall(TaoAddLineSearchCounts(tao)); 191a7e14dcfSSatish Balay } 192a7e14dcfSSatish Balay 193a7e14dcfSSatish Balay if ((int)ls_status < 0) { 194a7e14dcfSSatish Balay /* Failed to find an improving point*/ 195a7e14dcfSSatish Balay f = fold; 1969566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Xold, tao->solution)); 1979566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->Gold, tao->gradient)); 1989566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, lmP->GV)); 199a7e14dcfSSatish Balay step = 0.0; 20053506e15SBarry Smith } else { 201a7e14dcfSSatish Balay /* a little hack here, because that gv is used to store g */ 2029566063dSJacob Faibussowitsch PetscCall(VecCopy(lmP->GV, tao->gradient)); 203a7e14dcfSSatish Balay } 204a7e14dcfSSatish Balay 2059566063dSJacob Faibussowitsch PetscCall(ComputePseudoGrad_OWLQN(tao->solution, lmP->GV, lmP->lambda)); 206a7e14dcfSSatish Balay 207a7e14dcfSSatish Balay /* Check for termination */ 208a7e14dcfSSatish Balay 2099566063dSJacob Faibussowitsch PetscCall(VecNorm(lmP->GV, NORM_2, &gnorm)); 210a7e14dcfSSatish Balay 211a7e14dcfSSatish Balay iter++; 2129566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its)); 2139566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao, iter, f, gnorm, 0.0, step)); 214dbbe0bcdSBarry Smith PetscUseTypeMethod(tao, convergencetest, tao->cnvP); 215a7e14dcfSSatish Balay 21653506e15SBarry Smith if ((int)ls_status < 0) break; 217a7e14dcfSSatish Balay } 2183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 219a7e14dcfSSatish Balay } 220a7e14dcfSSatish Balay 221d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSetUp_OWLQN(Tao tao) 222d71ae5a4SJacob Faibussowitsch { 223a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 224a7e14dcfSSatish Balay PetscInt n, N; 225a7e14dcfSSatish Balay 226a7e14dcfSSatish Balay PetscFunctionBegin; 227441846f8SBarry Smith /* Existence of tao->solution checked in TaoSetUp() */ 2289566063dSJacob Faibussowitsch if (!tao->gradient) PetscCall(VecDuplicate(tao->solution, &tao->gradient)); 2299566063dSJacob Faibussowitsch if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution, &tao->stepdirection)); 2309566063dSJacob Faibussowitsch if (!lmP->D) PetscCall(VecDuplicate(tao->solution, &lmP->D)); 2319566063dSJacob Faibussowitsch if (!lmP->GV) PetscCall(VecDuplicate(tao->solution, &lmP->GV)); 2329566063dSJacob Faibussowitsch if (!lmP->Xold) PetscCall(VecDuplicate(tao->solution, &lmP->Xold)); 2339566063dSJacob Faibussowitsch if (!lmP->Gold) PetscCall(VecDuplicate(tao->solution, &lmP->Gold)); 234a7e14dcfSSatish Balay 235a7e14dcfSSatish Balay /* Create matrix for the limited memory approximation */ 2369566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(tao->solution, &n)); 2379566063dSJacob Faibussowitsch PetscCall(VecGetSize(tao->solution, &N)); 2389566063dSJacob Faibussowitsch PetscCall(MatCreateLMVMBFGS(((PetscObject)tao)->comm, n, N, &lmP->M)); 2399566063dSJacob Faibussowitsch PetscCall(MatLMVMAllocate(lmP->M, tao->solution, tao->gradient)); 2403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 241a7e14dcfSSatish Balay } 242a7e14dcfSSatish Balay 243a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 244d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoDestroy_OWLQN(Tao tao) 245d71ae5a4SJacob Faibussowitsch { 246a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 247a7e14dcfSSatish Balay 248a7e14dcfSSatish Balay PetscFunctionBegin; 249a7e14dcfSSatish Balay if (tao->setupcalled) { 2509566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->Xold)); 2519566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->Gold)); 2529566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->D)); 2539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&lmP->M)); 2549566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lmP->GV)); 255a7e14dcfSSatish Balay } 2569566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->data)); 2573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 258a7e14dcfSSatish Balay } 259a7e14dcfSSatish Balay 260a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 261d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSetFromOptions_OWLQN(Tao tao, PetscOptionItems *PetscOptionsObject) 262d71ae5a4SJacob Faibussowitsch { 263a7e14dcfSSatish Balay TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; 264a7e14dcfSSatish Balay 265a7e14dcfSSatish Balay PetscFunctionBegin; 266d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "Orthant-Wise Limited-memory method for Quasi-Newton unconstrained optimization"); 2679566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_owlqn_lambda", "regulariser weight", "", 100, &lmP->lambda, NULL)); 268d0609cedSBarry Smith PetscOptionsHeadEnd(); 2699566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetFromOptions(tao->linesearch)); 2703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 271a7e14dcfSSatish Balay } 272a7e14dcfSSatish Balay 273a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 274d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoView_OWLQN(Tao tao, PetscViewer viewer) 275d71ae5a4SJacob Faibussowitsch { 276a7e14dcfSSatish Balay TAO_OWLQN *lm = (TAO_OWLQN *)tao->data; 277a7e14dcfSSatish Balay PetscBool isascii; 278a7e14dcfSSatish Balay 279a7e14dcfSSatish Balay PetscFunctionBegin; 2809566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 281a7e14dcfSSatish Balay if (isascii) { 2829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 28363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "BFGS steps: %" PetscInt_FMT "\n", lm->bfgs)); 28463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %" PetscInt_FMT "\n", lm->sgrad)); 28563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Gradient steps: %" PetscInt_FMT "\n", lm->grad)); 2869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 287a7e14dcfSSatish Balay } 2883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 289a7e14dcfSSatish Balay } 290a7e14dcfSSatish Balay 291a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 2921522df2eSJason Sarich /*MC 2931522df2eSJason Sarich TAOOWLQN - orthant-wise limited memory quasi-newton algorithm 2941522df2eSJason Sarich 2951522df2eSJason Sarich . - tao_owlqn_lambda - regulariser weight 2961522df2eSJason Sarich 2971eb8069cSJason Sarich Level: beginner 2981522df2eSJason Sarich M*/ 2991522df2eSJason Sarich 300d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TaoCreate_OWLQN(Tao tao) 301d71ae5a4SJacob Faibussowitsch { 302a7e14dcfSSatish Balay TAO_OWLQN *lmP; 3038caf6e8cSBarry Smith const char *owarmijo_type = TAOLINESEARCHOWARMIJO; 304a7e14dcfSSatish Balay 305a7e14dcfSSatish Balay PetscFunctionBegin; 306a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_OWLQN; 307a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_OWLQN; 308a7e14dcfSSatish Balay tao->ops->view = TaoView_OWLQN; 309a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_OWLQN; 310a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_OWLQN; 311a7e14dcfSSatish Balay 3124dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&lmP)); 31383c8fe1dSLisandro Dalcin lmP->D = NULL; 31483c8fe1dSLisandro Dalcin lmP->M = NULL; 31583c8fe1dSLisandro Dalcin lmP->GV = NULL; 31683c8fe1dSLisandro Dalcin lmP->Xold = NULL; 31783c8fe1dSLisandro Dalcin lmP->Gold = NULL; 318a7e14dcfSSatish Balay lmP->lambda = 1.0; 319a7e14dcfSSatish Balay 320a7e14dcfSSatish Balay tao->data = (void *)lmP; 3216552cf8aSJason Sarich /* Override default settings (unless already changed) */ 322*606f75f6SBarry Smith PetscCall(TaoParametersInitialize(tao)); 323*606f75f6SBarry Smith PetscObjectParameterSetDefault(tao, max_it, 2000); 324*606f75f6SBarry Smith PetscObjectParameterSetDefault(tao, max_funcs, 4000); 325a7e14dcfSSatish Balay 3269566063dSJacob Faibussowitsch PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch)); 3279566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1)); 3289566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetType(tao->linesearch, owarmijo_type)); 3299566063dSJacob Faibussowitsch PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch, tao)); 3309566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch, tao->hdr.prefix)); 3313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 332a7e14dcfSSatish Balay } 333