xref: /petsc/src/tao/unconstrained/impls/lmvm/lmvm.c (revision 9515a40153b516acd9ba8e8514b436299c131326)
1ba92ff59SBarry Smith #include <petsctaolinesearch.h>
2aaa7dc30SBarry Smith #include <../src/tao/unconstrained/impls/lmvm/lmvm.h>
3a7e14dcfSSatish Balay 
4cd929ea3SAlp Dener #define LMVM_STEP_BFGS     0
5cd929ea3SAlp Dener #define LMVM_STEP_GRAD     1
6a7e14dcfSSatish Balay 
7441846f8SBarry Smith static PetscErrorCode TaoSolve_LMVM(Tao tao)
8a7e14dcfSSatish Balay {
9a7e14dcfSSatish Balay   TAO_LMVM                     *lmP = (TAO_LMVM *)tao->data;
10a7e14dcfSSatish Balay   PetscReal                    f, fold, gdx, gnorm;
11a7e14dcfSSatish Balay   PetscReal                    step = 1.0;
12a7e14dcfSSatish Balay   PetscErrorCode               ierr;
13cd929ea3SAlp Dener   PetscInt                     stepType = LMVM_STEP_GRAD, nupdates;
14e4cb33bbSBarry Smith   TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING;
15a7e14dcfSSatish Balay 
16a7e14dcfSSatish Balay   PetscFunctionBegin;
17a7e14dcfSSatish Balay 
18a7e14dcfSSatish Balay   if (tao->XL || tao->XU || tao->ops->computebounds) {
19a7e14dcfSSatish Balay     ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by lmvm algorithm\n");CHKERRQ(ierr);
20a7e14dcfSSatish Balay   }
21a7e14dcfSSatish Balay 
22a7e14dcfSSatish Balay   /*  Check convergence criteria */
23a7e14dcfSSatish Balay   ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient);CHKERRQ(ierr);
24a9603a14SPatrick Farrell   ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr);
25a9603a14SPatrick Farrell 
2687f595a5SBarry Smith   if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
27a7e14dcfSSatish Balay 
283ecd9318SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
293ecd9318SAlp Dener   ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr);
303ecd9318SAlp Dener   ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr);
313ecd9318SAlp Dener   ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr);
323ecd9318SAlp Dener   if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
33a7e14dcfSSatish Balay 
34a7e14dcfSSatish Balay   /*  Set counter for gradient/reset steps */
35cd929ea3SAlp Dener   if (!lmP->recycle) {
36a7e14dcfSSatish Balay     lmP->bfgs = 0;
37a7e14dcfSSatish Balay     lmP->grad = 0;
38cd929ea3SAlp Dener     ierr = MatLMVMReset(lmP->M, PETSC_FALSE); CHKERRQ(ierr);
39de6ffafeSAlp Dener   }
40a7e14dcfSSatish Balay 
41a7e14dcfSSatish Balay   /*  Have not converged; continue with Newton method */
423ecd9318SAlp Dener   while (tao->reason == TAO_CONTINUE_ITERATING) {
43a7e14dcfSSatish Balay     /*  Compute direction */
44cd929ea3SAlp Dener     if (lmP->H0) {
45cd929ea3SAlp Dener       ierr = MatLMVMSetJ0(lmP->M, lmP->H0);CHKERRQ(ierr);
46cd929ea3SAlp Dener       stepType = LMVM_STEP_BFGS;
47cd929ea3SAlp Dener     }
48a7e14dcfSSatish Balay     ierr = MatLMVMUpdate(lmP->M,tao->solution,tao->gradient);CHKERRQ(ierr);
49*9515a401SAlp Dener     ierr = MatSolve(lmP->M, tao->gradient, lmP->D);CHKERRQ(ierr);
50cd929ea3SAlp Dener     ierr = MatLMVMGetUpdateCount(lmP->M, &nupdates); CHKERRQ(ierr);
51cd929ea3SAlp Dener     if (nupdates > 0) stepType = LMVM_STEP_BFGS;
52a7e14dcfSSatish Balay 
53a7e14dcfSSatish Balay     /*  Check for success (descent direction) */
54a7e14dcfSSatish Balay     ierr = VecDot(lmP->D, tao->gradient, &gdx);CHKERRQ(ierr);
55a7e14dcfSSatish Balay     if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) {
56a7e14dcfSSatish Balay       /* Step is not descent or direction produced not a number
57a7e14dcfSSatish Balay          We can assert bfgsUpdates > 1 in this case because
58a7e14dcfSSatish Balay          the first solve produces the scaled gradient direction,
59a7e14dcfSSatish Balay          which is guaranteed to be descent
60a7e14dcfSSatish Balay 
61a7e14dcfSSatish Balay          Use steepest descent direction (scaled)
62a7e14dcfSSatish Balay       */
63a7e14dcfSSatish Balay 
64cd929ea3SAlp Dener       ierr = MatLMVMReset(lmP->M, PETSC_FALSE);CHKERRQ(ierr);
650ad3a497SAlp Dener       ierr = MatLMVMClearJ0(lmP->M);CHKERRQ(ierr);
66a7e14dcfSSatish Balay       ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
67*9515a401SAlp Dener       ierr = MatSolve(lmP->M,tao->gradient, lmP->D);CHKERRQ(ierr);
68a7e14dcfSSatish Balay 
69a7e14dcfSSatish Balay       /* On a reset, the direction cannot be not a number; it is a
70a7e14dcfSSatish Balay          scaled gradient step.  No need to check for this condition. */
71cd929ea3SAlp Dener       stepType = LMVM_STEP_GRAD;
72a7e14dcfSSatish Balay     }
73a7e14dcfSSatish Balay     ierr = VecScale(lmP->D, -1.0);CHKERRQ(ierr);
74a7e14dcfSSatish Balay 
75a7e14dcfSSatish Balay     /*  Perform the linesearch */
76a7e14dcfSSatish Balay     fold = f;
77a7e14dcfSSatish Balay     ierr = VecCopy(tao->solution, lmP->Xold);CHKERRQ(ierr);
78a7e14dcfSSatish Balay     ierr = VecCopy(tao->gradient, lmP->Gold);CHKERRQ(ierr);
79a7e14dcfSSatish Balay 
80a7e14dcfSSatish Balay     ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, lmP->D, &step,&ls_status);CHKERRQ(ierr);
81a7e14dcfSSatish Balay     ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
82a7e14dcfSSatish Balay 
83cd929ea3SAlp Dener     if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER && (stepType != LMVM_STEP_GRAD)) {
84a7e14dcfSSatish Balay       /*  Reset factors and use scaled gradient step */
85a7e14dcfSSatish Balay       f = fold;
86a7e14dcfSSatish Balay       ierr = VecCopy(lmP->Xold, tao->solution);CHKERRQ(ierr);
87a7e14dcfSSatish Balay       ierr = VecCopy(lmP->Gold, tao->gradient);CHKERRQ(ierr);
88a7e14dcfSSatish Balay 
89a7e14dcfSSatish Balay       /*  Failed to obtain acceptable iterate with BFGS step */
90a7e14dcfSSatish Balay       /*  Attempt to use the scaled gradient direction */
91a7e14dcfSSatish Balay 
92cd929ea3SAlp Dener       ierr = MatLMVMReset(lmP->M, PETSC_FALSE);CHKERRQ(ierr);
930ad3a497SAlp Dener       ierr = MatLMVMClearJ0(lmP->M);CHKERRQ(ierr);
94a7e14dcfSSatish Balay       ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
95*9515a401SAlp Dener       ierr = MatSolve(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
96a7e14dcfSSatish Balay 
97a7e14dcfSSatish Balay       /* On a reset, the direction cannot be not a number; it is a
98a7e14dcfSSatish Balay           scaled gradient step.  No need to check for this condition. */
99cd929ea3SAlp Dener       stepType = LMVM_STEP_GRAD;
100a7e14dcfSSatish Balay       ierr = VecScale(lmP->D, -1.0);CHKERRQ(ierr);
101a7e14dcfSSatish Balay 
102a7e14dcfSSatish Balay       /*  Perform the linesearch */
103a7e14dcfSSatish Balay       ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, lmP->D, &step, &ls_status);CHKERRQ(ierr);
104a7e14dcfSSatish Balay       ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
105a7e14dcfSSatish Balay     }
106a7e14dcfSSatish Balay 
10787f595a5SBarry Smith     if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
108a7e14dcfSSatish Balay       /*  Failed to find an improving point */
109a7e14dcfSSatish Balay       f = fold;
110a7e14dcfSSatish Balay       ierr = VecCopy(lmP->Xold, tao->solution);CHKERRQ(ierr);
111a7e14dcfSSatish Balay       ierr = VecCopy(lmP->Gold, tao->gradient);CHKERRQ(ierr);
112a7e14dcfSSatish Balay       step = 0.0;
113a7e14dcfSSatish Balay       tao->reason = TAO_DIVERGED_LS_FAILURE;
114cd929ea3SAlp Dener     } else {
115cd929ea3SAlp Dener       /* LS found valid step, so tally up step type */
116cd929ea3SAlp Dener       switch (stepType) {
117cd929ea3SAlp Dener       case LMVM_STEP_BFGS:
118cd929ea3SAlp Dener         ++lmP->bfgs;
119cd929ea3SAlp Dener         break;
120cd929ea3SAlp Dener       case LMVM_STEP_GRAD:
121cd929ea3SAlp Dener         ++lmP->grad;
122cd929ea3SAlp Dener         break;
123cd929ea3SAlp Dener       default:
124cd929ea3SAlp Dener         break;
125cd929ea3SAlp Dener       }
126cd929ea3SAlp Dener       /*  Compute new gradient norm */
127cd929ea3SAlp Dener       ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr);
128a7e14dcfSSatish Balay     }
129a9603a14SPatrick Farrell 
130cd929ea3SAlp Dener     /* Check convergence */
1318931d482SJason Sarich     tao->niter++;
1323ecd9318SAlp Dener     ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr);
1333ecd9318SAlp Dener     ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr);
1343ecd9318SAlp Dener     ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr);
135a7e14dcfSSatish Balay   }
136a7e14dcfSSatish Balay   PetscFunctionReturn(0);
137a7e14dcfSSatish Balay }
13887f595a5SBarry Smith 
139441846f8SBarry Smith static PetscErrorCode TaoSetUp_LMVM(Tao tao)
140a7e14dcfSSatish Balay {
141a7e14dcfSSatish Balay   TAO_LMVM       *lmP = (TAO_LMVM *)tao->data;
142a7e14dcfSSatish Balay   PetscInt       n,N;
143a7e14dcfSSatish Balay   PetscErrorCode ierr;
144d5ae2380SAlp Dener   PetscBool      is_spd;
145a7e14dcfSSatish Balay 
146a7e14dcfSSatish Balay   PetscFunctionBegin;
147a7e14dcfSSatish Balay   /* Existence of tao->solution checked in TaoSetUp() */
148a7e14dcfSSatish Balay   if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr);  }
149a7e14dcfSSatish Balay   if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr);  }
150a7e14dcfSSatish Balay   if (!lmP->D) {ierr = VecDuplicate(tao->solution,&lmP->D);CHKERRQ(ierr);  }
151a7e14dcfSSatish Balay   if (!lmP->Xold) {ierr = VecDuplicate(tao->solution,&lmP->Xold);CHKERRQ(ierr);  }
152a7e14dcfSSatish Balay   if (!lmP->Gold) {ierr = VecDuplicate(tao->solution,&lmP->Gold);CHKERRQ(ierr);  }
153a7e14dcfSSatish Balay 
154a7e14dcfSSatish Balay   /*  Create matrix for the limited memory approximation */
155a7e14dcfSSatish Balay   ierr = VecGetLocalSize(tao->solution,&n);CHKERRQ(ierr);
156a7e14dcfSSatish Balay   ierr = VecGetSize(tao->solution,&N);CHKERRQ(ierr);
157cd929ea3SAlp Dener   ierr = MatSetSizes(lmP->M, n, n, N, N);CHKERRQ(ierr);
158cd929ea3SAlp Dener   ierr = MatLMVMAllocate(lmP->M,tao->solution,tao->gradient);CHKERRQ(ierr);
1590ad3a497SAlp Dener   ierr = MatGetOption(lmP->M, MAT_SPD, &is_spd);CHKERRQ(ierr);
1600ad3a497SAlp Dener   if (!is_spd) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix is not symmetric positive-definite.");
161a9603a14SPatrick Farrell 
162a9603a14SPatrick Farrell   /* If the user has set a matrix to solve as the initial H0, set the options prefix here, and set up the KSP */
163a9603a14SPatrick Farrell   if (lmP->H0) {
164cd929ea3SAlp Dener     ierr = MatLMVMSetJ0(lmP->M, lmP->H0);CHKERRQ(ierr);
165a9603a14SPatrick Farrell   }
166a9603a14SPatrick Farrell 
167a7e14dcfSSatish Balay   PetscFunctionReturn(0);
168a7e14dcfSSatish Balay }
169a7e14dcfSSatish Balay 
170a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
171441846f8SBarry Smith static PetscErrorCode TaoDestroy_LMVM(Tao tao)
172a7e14dcfSSatish Balay {
173a7e14dcfSSatish Balay   TAO_LMVM       *lmP = (TAO_LMVM *)tao->data;
174a7e14dcfSSatish Balay   PetscErrorCode ierr;
175a7e14dcfSSatish Balay 
176a7e14dcfSSatish Balay   PetscFunctionBegin;
177a7e14dcfSSatish Balay   if (tao->setupcalled) {
178a7e14dcfSSatish Balay     ierr = VecDestroy(&lmP->Xold);CHKERRQ(ierr);
179a7e14dcfSSatish Balay     ierr = VecDestroy(&lmP->Gold);CHKERRQ(ierr);
180a7e14dcfSSatish Balay     ierr = VecDestroy(&lmP->D);CHKERRQ(ierr);
181a7e14dcfSSatish Balay   }
182cd929ea3SAlp Dener   ierr = MatDestroy(&lmP->M);CHKERRQ(ierr);
183a9603a14SPatrick Farrell   if (lmP->H0) {
184a9603a14SPatrick Farrell     ierr = PetscObjectDereference((PetscObject)lmP->H0);CHKERRQ(ierr);
185a9603a14SPatrick Farrell   }
186a7e14dcfSSatish Balay   ierr = PetscFree(tao->data);CHKERRQ(ierr);
187a9603a14SPatrick Farrell 
188a7e14dcfSSatish Balay   PetscFunctionReturn(0);
189a7e14dcfSSatish Balay }
190a7e14dcfSSatish Balay 
191a7e14dcfSSatish Balay /*------------------------------------------------------------*/
1924416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_LMVM(PetscOptionItems *PetscOptionsObject,Tao tao)
193a7e14dcfSSatish Balay {
194cd929ea3SAlp Dener   TAO_LMVM       *lm = (TAO_LMVM *)tao->data;
195a7e14dcfSSatish Balay   PetscErrorCode ierr;
196a7e14dcfSSatish Balay 
197a7e14dcfSSatish Balay   PetscFunctionBegin;
1981a1499c8SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Limited-memory variable-metric method for unconstrained optimization");CHKERRQ(ierr);
199cd929ea3SAlp Dener   ierr = PetscOptionsBool("-tao_lmvm_recycle","enable recycling of the BFGS matrix between subsequent TaoSolve() calls","",lm->recycle,&lm->recycle,NULL);CHKERRQ(ierr);
200114d2d62SAlp Dener   ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr);
201cd929ea3SAlp Dener   ierr = MatSetFromOptions(lm->M);CHKERRQ(ierr);
202288b7216SAlp Dener   ierr = PetscOptionsTail();CHKERRQ(ierr);
203a7e14dcfSSatish Balay   PetscFunctionReturn(0);
204a7e14dcfSSatish Balay }
205a7e14dcfSSatish Balay 
206a7e14dcfSSatish Balay /*------------------------------------------------------------*/
207441846f8SBarry Smith static PetscErrorCode TaoView_LMVM(Tao tao, PetscViewer viewer)
208a7e14dcfSSatish Balay {
209a7e14dcfSSatish Balay   TAO_LMVM       *lm = (TAO_LMVM *)tao->data;
210cd929ea3SAlp Dener   PetscBool      isascii;
2114d6623b4SAlp Dener   PetscInt       recycled_its;
212a7e14dcfSSatish Balay   PetscErrorCode ierr;
213a7e14dcfSSatish Balay 
214a7e14dcfSSatish Balay   PetscFunctionBegin;
215a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr);
216a7e14dcfSSatish Balay   if (isascii) {
217a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "  Gradient steps: %D\n", lm->grad);CHKERRQ(ierr);
218cd929ea3SAlp Dener     if (lm->recycle) {
219288b7216SAlp Dener       ierr = PetscViewerASCIIPrintf(viewer, "  Recycle: on\n");CHKERRQ(ierr);
220cd929ea3SAlp Dener       recycled_its = lm->bfgs + lm->grad;
2214d6623b4SAlp Dener       ierr = PetscViewerASCIIPrintf(viewer, "  Total recycled iterations: %D\n", recycled_its);CHKERRQ(ierr);
222a0bfee83SAlp Dener     }
223a7e14dcfSSatish Balay   }
224a7e14dcfSSatish Balay   PetscFunctionReturn(0);
225a7e14dcfSSatish Balay }
226a7e14dcfSSatish Balay 
227a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
228a7e14dcfSSatish Balay 
2294aa34175SJason Sarich /*MC
2304aa34175SJason Sarich   TAOLMVM - Limited Memory Variable Metric method is a quasi-Newton
2314aa34175SJason Sarich   optimization solver for unconstrained minimization. It solves
2324aa34175SJason Sarich   the Newton step
2334aa34175SJason Sarich           Hkdk = - gk
2344aa34175SJason Sarich 
2354aa34175SJason Sarich   using an approximation Bk in place of Hk, where Bk is composed using
2364aa34175SJason Sarich   the BFGS update formula. A More-Thuente line search is then used
2374aa34175SJason Sarich   to computed the steplength in the dk direction
2380ad3a497SAlp Dener 
2394aa34175SJason Sarich   Options Database Keys:
240cd929ea3SAlp Dener .   -tao_lmvm_recycle - enable recycling LMVM updates between TaoSolve() calls
2410ad3a497SAlp Dener .   -tao_lmvm_no_scale - (developer) disables diagonal Broyden scaling on the LMVM approximation
2424aa34175SJason Sarich 
2431eb8069cSJason Sarich   Level: beginner
2444aa34175SJason Sarich M*/
2454aa34175SJason Sarich 
246728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_LMVM(Tao tao)
247a7e14dcfSSatish Balay {
248a7e14dcfSSatish Balay   TAO_LMVM       *lmP;
2498caf6e8cSBarry Smith   const char     *morethuente_type = TAOLINESEARCHMT;
250a7e14dcfSSatish Balay   PetscErrorCode ierr;
251a7e14dcfSSatish Balay 
252a7e14dcfSSatish Balay   PetscFunctionBegin;
253a7e14dcfSSatish Balay   tao->ops->setup = TaoSetUp_LMVM;
254a7e14dcfSSatish Balay   tao->ops->solve = TaoSolve_LMVM;
255a7e14dcfSSatish Balay   tao->ops->view = TaoView_LMVM;
256a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_LMVM;
257a7e14dcfSSatish Balay   tao->ops->destroy = TaoDestroy_LMVM;
258a7e14dcfSSatish Balay 
2593c9e27cfSGeoffrey Irving   ierr = PetscNewLog(tao,&lmP);CHKERRQ(ierr);
260a7e14dcfSSatish Balay   lmP->D = 0;
261a7e14dcfSSatish Balay   lmP->M = 0;
262a7e14dcfSSatish Balay   lmP->Xold = 0;
263a7e14dcfSSatish Balay   lmP->Gold = 0;
264a9603a14SPatrick Farrell   lmP->H0   = NULL;
265cd929ea3SAlp Dener   lmP->recycle = PETSC_FALSE;
266a7e14dcfSSatish Balay 
267a7e14dcfSSatish Balay   tao->data = (void*)lmP;
2686552cf8aSJason Sarich   /* Override default settings (unless already changed) */
2696552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 2000;
2706552cf8aSJason Sarich   if (!tao->max_funcs_changed) tao->max_funcs = 4000;
271a7e14dcfSSatish Balay 
272a7e14dcfSSatish Balay   ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr);
27363b15415SAlp Dener   ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr);
274a7e14dcfSSatish Balay   ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr);
275441846f8SBarry Smith   ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr);
2765d527766SPatrick Farrell   ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr);
277cd929ea3SAlp Dener 
278cd929ea3SAlp Dener   ierr = KSPInitializePackage();CHKERRQ(ierr);
279cd929ea3SAlp Dener   ierr = MatCreate(((PetscObject)tao)->comm, &lmP->M);CHKERRQ(ierr);
280cd929ea3SAlp Dener   ierr = PetscObjectIncrementTabLevel((PetscObject)lmP->M, (PetscObject)tao, 1);CHKERRQ(ierr);
28178e4361aSAlp Dener   ierr = MatSetType(lmP->M, MATLMVMBFGS);CHKERRQ(ierr);
282cd929ea3SAlp Dener   ierr = MatSetOptionsPrefix(lmP->M, "tao_lmvm_");CHKERRQ(ierr);
283a7e14dcfSSatish Balay   PetscFunctionReturn(0);
284a7e14dcfSSatish Balay }
285