xref: /petsc/src/tao/unconstrained/impls/owlqn/owlqn.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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++) {
209371c9d4SSatish Balay     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;
60*48a46eb9SPierre 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