xref: /petsc/src/tao/unconstrained/tutorials/rosenbrock1.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
1c4762a1bSJed Brown /* Program usage: mpiexec -n 1 rosenbrock1 [-help] [all TAO options] */
2c4762a1bSJed Brown 
3c4762a1bSJed Brown /*  Include "petsctao.h" so we can use TAO solvers.  */
4c4762a1bSJed Brown #include <petsctao.h>
5c4762a1bSJed Brown 
6c4762a1bSJed Brown static  char help[] = "This example demonstrates use of the TAO package to \n\
7c4762a1bSJed Brown solve an unconstrained minimization problem on a single processor.  We \n\
8c4762a1bSJed Brown minimize the extended Rosenbrock function: \n\
9c4762a1bSJed Brown    sum_{i=0}^{n/2-1} (alpha*(x_{2i+1}-x_{2i}^2)^2 + (1-x_{2i})^2) \n\
10c4762a1bSJed Brown or the chained Rosenbrock function:\n\
11c4762a1bSJed Brown    sum_{i=0}^{n-1} alpha*(x_{i+1} - x_i^2)^2 + (1 - x_i)^2\n";
12c4762a1bSJed Brown 
13c4762a1bSJed Brown /*T
14c4762a1bSJed Brown    Concepts: TAO^Solving an unconstrained minimization problem
15c4762a1bSJed Brown    Routines: TaoCreate();
16a82e8c82SStefano Zampini    Routines: TaoSetType(); TaoSetObjectiveAndGradient();
17a82e8c82SStefano Zampini    Routines: TaoSetHessian();
18a82e8c82SStefano Zampini    Routines: TaoSetSolution();
19c4762a1bSJed Brown    Routines: TaoSetFromOptions();
20c4762a1bSJed Brown    Routines: TaoSolve();
21c4762a1bSJed Brown    Routines: TaoDestroy();
22c4762a1bSJed Brown    Processors: 1
23c4762a1bSJed Brown T*/
24c4762a1bSJed Brown 
25c4762a1bSJed Brown /*
26c4762a1bSJed Brown    User-defined application context - contains data needed by the
27c4762a1bSJed Brown    application-provided call-back routines that evaluate the function,
28c4762a1bSJed Brown    gradient, and hessian.
29c4762a1bSJed Brown */
30c4762a1bSJed Brown typedef struct {
31c4762a1bSJed Brown   PetscInt  n;          /* dimension */
32c4762a1bSJed Brown   PetscReal alpha;   /* condition parameter */
33c4762a1bSJed Brown   PetscBool chained;
34c4762a1bSJed Brown } AppCtx;
35c4762a1bSJed Brown 
36c4762a1bSJed Brown /* -------------- User-defined routines ---------- */
37c4762a1bSJed Brown PetscErrorCode FormFunctionGradient(Tao,Vec,PetscReal*,Vec,void*);
38c4762a1bSJed Brown PetscErrorCode FormHessian(Tao,Vec,Mat,Mat,void*);
39c4762a1bSJed Brown 
40c4762a1bSJed Brown int main(int argc,char **argv)
41c4762a1bSJed Brown {
42c4762a1bSJed Brown   PetscErrorCode     ierr;                  /* used to check for functions returning nonzeros */
43c4762a1bSJed Brown   PetscReal          zero=0.0;
44c4762a1bSJed Brown   Vec                x;                     /* solution vector */
45c4762a1bSJed Brown   Mat                H;
46c4762a1bSJed Brown   Tao                tao;                   /* Tao solver context */
47c4762a1bSJed Brown   PetscBool          flg, test_lmvm = PETSC_FALSE;
48c4762a1bSJed Brown   PetscMPIInt        size;                  /* number of processes running */
49c4762a1bSJed Brown   AppCtx             user;                  /* user-defined application context */
50c4762a1bSJed Brown   KSP                ksp;
51c4762a1bSJed Brown   PC                 pc;
52c4762a1bSJed Brown   Mat                M;
53c4762a1bSJed Brown   Vec                in, out, out2;
54c4762a1bSJed Brown   PetscReal          mult_solve_dist;
55c4762a1bSJed Brown 
56c4762a1bSJed Brown   /* Initialize TAO and PETSc */
57c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
58*5f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size));
593c859ba3SBarry Smith   PetscCheck(size == 1,PETSC_COMM_WORLD,PETSC_ERR_WRONG_MPI_SIZE,"Incorrect number of processors");
60c4762a1bSJed Brown 
61c4762a1bSJed Brown   /* Initialize problem parameters */
62c4762a1bSJed Brown   user.n = 2; user.alpha = 99.0; user.chained = PETSC_FALSE;
63c4762a1bSJed Brown   /* Check for command line arguments to override defaults */
64*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-n",&user.n,&flg));
65*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-alpha",&user.alpha,&flg));
66*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-chained",&user.chained,&flg));
67*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_lmvm",&test_lmvm,&flg));
68c4762a1bSJed Brown 
69c4762a1bSJed Brown   /* Allocate vectors for the solution and gradient */
70*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCreateSeq(PETSC_COMM_SELF,user.n,&x));
71*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateSeqBAIJ(PETSC_COMM_SELF,2,user.n,user.n,1,NULL,&H));
72c4762a1bSJed Brown 
73c4762a1bSJed Brown   /* The TAO code begins here */
74c4762a1bSJed Brown 
75c4762a1bSJed Brown   /* Create TAO solver with desired solution method */
76*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TaoCreate(PETSC_COMM_SELF,&tao));
77*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TaoSetType(tao,TAOLMVM));
78c4762a1bSJed Brown 
79c4762a1bSJed Brown   /* Set solution vec and an initial guess */
80*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(x, zero));
81*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TaoSetSolution(tao,x));
82c4762a1bSJed Brown 
83c4762a1bSJed Brown   /* Set routines for function, gradient, hessian evaluation */
84*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TaoSetObjectiveAndGradient(tao,NULL,FormFunctionGradient,&user));
85*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TaoSetHessian(tao,H,H,FormHessian,&user));
86c4762a1bSJed Brown 
87c4762a1bSJed Brown   /* Test the LMVM matrix */
88c4762a1bSJed Brown   if (test_lmvm) {
89*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsSetValue(NULL, "-tao_type", "bqnktr"));
90c4762a1bSJed Brown   }
91c4762a1bSJed Brown 
92c4762a1bSJed Brown   /* Check for TAO command line options */
93*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TaoSetFromOptions(tao));
94c4762a1bSJed Brown 
95c4762a1bSJed Brown   /* SOLVE THE APPLICATION */
96*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TaoSolve(tao));
97c4762a1bSJed Brown 
98c4762a1bSJed Brown   /* Test the LMVM matrix */
99c4762a1bSJed Brown   if (test_lmvm) {
100*5f80ce2aSJacob Faibussowitsch     CHKERRQ(TaoGetKSP(tao, &ksp));
101*5f80ce2aSJacob Faibussowitsch     CHKERRQ(KSPGetPC(ksp, &pc));
102*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PCLMVMGetMatLMVM(pc, &M));
103*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDuplicate(x, &in));
104*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDuplicate(x, &out));
105*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDuplicate(x, &out2));
106*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecSet(in, 1.0));
107*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMult(M, in, out));
108*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSolve(M, out, out2));
109*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecAXPY(out2, -1.0, in));
110*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecNorm(out2, NORM_2, &mult_solve_dist));
111c4762a1bSJed Brown     if (mult_solve_dist < 1.e-11) {
112*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject)tao), "error between LMVM MatMult and MatSolve: < 1.e-11\n"));
113c4762a1bSJed Brown     } else if (mult_solve_dist < 1.e-6) {
114*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject)tao), "error between LMVM MatMult and MatSolve: < 1.e-6\n"));
115c4762a1bSJed Brown     } else {
116*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject)tao), "error between LMVM MatMult and MatSolve: %e\n", (double)mult_solve_dist));
117c4762a1bSJed Brown     }
118*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&in));
119*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&out));
120*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&out2));
121c4762a1bSJed Brown   }
122c4762a1bSJed Brown 
123*5f80ce2aSJacob Faibussowitsch   CHKERRQ(TaoDestroy(&tao));
124*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&x));
125*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&H));
126c4762a1bSJed Brown 
127c4762a1bSJed Brown   ierr = PetscFinalize();
128c4762a1bSJed Brown   return ierr;
129c4762a1bSJed Brown }
130c4762a1bSJed Brown 
131c4762a1bSJed Brown /* -------------------------------------------------------------------- */
132c4762a1bSJed Brown /*
133c4762a1bSJed Brown     FormFunctionGradient - Evaluates the function, f(X), and gradient, G(X).
134c4762a1bSJed Brown 
135c4762a1bSJed Brown     Input Parameters:
136c4762a1bSJed Brown .   tao  - the Tao context
137c4762a1bSJed Brown .   X    - input vector
138c4762a1bSJed Brown .   ptr  - optional user-defined context, as set by TaoSetFunctionGradient()
139c4762a1bSJed Brown 
140c4762a1bSJed Brown     Output Parameters:
141c4762a1bSJed Brown .   G - vector containing the newly evaluated gradient
142c4762a1bSJed Brown .   f - function value
143c4762a1bSJed Brown 
144c4762a1bSJed Brown     Note:
145c4762a1bSJed Brown     Some optimization methods ask for the function and the gradient evaluation
146c4762a1bSJed Brown     at the same time.  Evaluating both at once may be more efficient that
147c4762a1bSJed Brown     evaluating each separately.
148c4762a1bSJed Brown */
149c4762a1bSJed Brown PetscErrorCode FormFunctionGradient(Tao tao,Vec X,PetscReal *f, Vec G,void *ptr)
150c4762a1bSJed Brown {
151c4762a1bSJed Brown   AppCtx            *user = (AppCtx *) ptr;
152c4762a1bSJed Brown   PetscInt          i,nn=user->n/2;
153c4762a1bSJed Brown   PetscReal         ff=0,t1,t2,alpha=user->alpha;
154c4762a1bSJed Brown   PetscScalar       *g;
155c4762a1bSJed Brown   const PetscScalar *x;
156c4762a1bSJed Brown 
157c4762a1bSJed Brown   PetscFunctionBeginUser;
158c4762a1bSJed Brown   /* Get pointers to vector data */
159*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(X,&x));
160*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArray(G,&g));
161c4762a1bSJed Brown 
162c4762a1bSJed Brown   /* Compute G(X) */
163c4762a1bSJed Brown   if (user->chained) {
164c4762a1bSJed Brown     g[0] = 0;
165c4762a1bSJed Brown     for (i=0; i<user->n-1; i++) {
166c4762a1bSJed Brown       t1 = x[i+1] - x[i]*x[i];
167c4762a1bSJed Brown       ff += PetscSqr(1 - x[i]) + alpha*t1*t1;
168c4762a1bSJed Brown       g[i] += -2*(1 - x[i]) + 2*alpha*t1*(-2*x[i]);
169c4762a1bSJed Brown       g[i+1] = 2*alpha*t1;
170c4762a1bSJed Brown     }
171c4762a1bSJed Brown   } else {
172c4762a1bSJed Brown     for (i=0; i<nn; i++) {
173c4762a1bSJed Brown       t1 = x[2*i+1]-x[2*i]*x[2*i]; t2= 1-x[2*i];
174c4762a1bSJed Brown       ff += alpha*t1*t1 + t2*t2;
175c4762a1bSJed Brown       g[2*i] = -4*alpha*t1*x[2*i]-2.0*t2;
176c4762a1bSJed Brown       g[2*i+1] = 2*alpha*t1;
177c4762a1bSJed Brown     }
178c4762a1bSJed Brown   }
179c4762a1bSJed Brown 
180c4762a1bSJed Brown   /* Restore vectors */
181*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(X,&x));
182*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArray(G,&g));
183c4762a1bSJed Brown   *f   = ff;
184c4762a1bSJed Brown 
185*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLogFlops(15.0*nn));
186c4762a1bSJed Brown   PetscFunctionReturn(0);
187c4762a1bSJed Brown }
188c4762a1bSJed Brown 
189c4762a1bSJed Brown /* ------------------------------------------------------------------- */
190c4762a1bSJed Brown /*
191c4762a1bSJed Brown    FormHessian - Evaluates Hessian matrix.
192c4762a1bSJed Brown 
193c4762a1bSJed Brown    Input Parameters:
194c4762a1bSJed Brown .  tao   - the Tao context
195c4762a1bSJed Brown .  x     - input vector
196c4762a1bSJed Brown .  ptr   - optional user-defined context, as set by TaoSetHessian()
197c4762a1bSJed Brown 
198c4762a1bSJed Brown    Output Parameters:
199c4762a1bSJed Brown .  H     - Hessian matrix
200c4762a1bSJed Brown 
201c4762a1bSJed Brown    Note:  Providing the Hessian may not be necessary.  Only some solvers
202c4762a1bSJed Brown    require this matrix.
203c4762a1bSJed Brown */
204c4762a1bSJed Brown PetscErrorCode FormHessian(Tao tao,Vec X,Mat H, Mat Hpre, void *ptr)
205c4762a1bSJed Brown {
206c4762a1bSJed Brown   AppCtx            *user = (AppCtx*)ptr;
207c4762a1bSJed Brown   PetscInt          i, ind[2];
208c4762a1bSJed Brown   PetscReal         alpha=user->alpha;
209c4762a1bSJed Brown   PetscReal         v[2][2];
210c4762a1bSJed Brown   const PetscScalar *x;
211c4762a1bSJed Brown   PetscBool         assembled;
212c4762a1bSJed Brown 
213c4762a1bSJed Brown   PetscFunctionBeginUser;
214c4762a1bSJed Brown   /* Zero existing matrix entries */
215*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssembled(H,&assembled));
216*5f80ce2aSJacob Faibussowitsch   if (assembled) CHKERRQ(MatZeroEntries(H));
217c4762a1bSJed Brown 
218c4762a1bSJed Brown   /* Get a pointer to vector data */
219*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(X,&x));
220c4762a1bSJed Brown 
221c4762a1bSJed Brown   /* Compute H(X) entries */
222c4762a1bSJed Brown   if (user->chained) {
223*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatZeroEntries(H));
224c4762a1bSJed Brown     for (i=0; i<user->n-1; i++) {
225c4762a1bSJed Brown       PetscScalar t1 = x[i+1] - x[i]*x[i];
226c4762a1bSJed Brown       v[0][0] = 2 + 2*alpha*(t1*(-2) - 2*x[i]);
227c4762a1bSJed Brown       v[0][1] = 2*alpha*(-2*x[i]);
228c4762a1bSJed Brown       v[1][0] = 2*alpha*(-2*x[i]);
229c4762a1bSJed Brown       v[1][1] = 2*alpha*t1;
230c4762a1bSJed Brown       ind[0] = i; ind[1] = i+1;
231*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSetValues(H,2,ind,2,ind,v[0],ADD_VALUES));
232c4762a1bSJed Brown     }
233c4762a1bSJed Brown   } else {
234c4762a1bSJed Brown     for (i=0; i<user->n/2; i++) {
235c4762a1bSJed Brown       v[1][1] = 2*alpha;
236c4762a1bSJed Brown       v[0][0] = -4*alpha*(x[2*i+1]-3*x[2*i]*x[2*i]) + 2;
237c4762a1bSJed Brown       v[1][0] = v[0][1] = -4.0*alpha*x[2*i];
238c4762a1bSJed Brown       ind[0]=2*i; ind[1]=2*i+1;
239*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSetValues(H,2,ind,2,ind,v[0],INSERT_VALUES));
240c4762a1bSJed Brown     }
241c4762a1bSJed Brown   }
242*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(X,&x));
243c4762a1bSJed Brown 
244c4762a1bSJed Brown   /* Assemble matrix */
245*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyBegin(H,MAT_FINAL_ASSEMBLY));
246*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyEnd(H,MAT_FINAL_ASSEMBLY));
247*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLogFlops(9.0*user->n/2.0));
248c4762a1bSJed Brown   PetscFunctionReturn(0);
249c4762a1bSJed Brown }
250c4762a1bSJed Brown 
251c4762a1bSJed Brown /*TEST
252c4762a1bSJed Brown 
253c4762a1bSJed Brown    build:
254c4762a1bSJed Brown       requires: !complex
255c4762a1bSJed Brown 
256c4762a1bSJed Brown    test:
257c4762a1bSJed Brown       args: -tao_smonitor -tao_type nls -tao_gatol 1.e-4
258c4762a1bSJed Brown       requires: !single
259c4762a1bSJed Brown 
260c4762a1bSJed Brown    test:
261c4762a1bSJed Brown       suffix: 2
262c4762a1bSJed Brown       args: -tao_smonitor -tao_type lmvm -tao_gatol 1.e-3
263c4762a1bSJed Brown 
264c4762a1bSJed Brown    test:
265c4762a1bSJed Brown       suffix: 3
266c4762a1bSJed Brown       args: -tao_smonitor -tao_type ntr -tao_gatol 1.e-4
267c4762a1bSJed Brown       requires: !single
268c4762a1bSJed Brown 
269c4762a1bSJed Brown    test:
270c4762a1bSJed Brown       suffix: 4
271c4762a1bSJed Brown       args: -tao_smonitor -tao_type ntr -tao_mf_hessian -tao_ntr_pc_type none -tao_gatol 1.e-4
272c4762a1bSJed Brown 
273c4762a1bSJed Brown    test:
274c4762a1bSJed Brown       suffix: 5
275c4762a1bSJed Brown       args: -tao_smonitor -tao_type bntr -tao_gatol 1.e-4
276c4762a1bSJed Brown 
277c4762a1bSJed Brown    test:
278c4762a1bSJed Brown       suffix: 6
279c4762a1bSJed Brown       args: -tao_smonitor -tao_type bntl -tao_gatol 1.e-4
280c4762a1bSJed Brown 
281c4762a1bSJed Brown    test:
282c4762a1bSJed Brown       suffix: 7
283c4762a1bSJed Brown       args: -tao_smonitor -tao_type bnls -tao_gatol 1.e-4
284c4762a1bSJed Brown 
285c4762a1bSJed Brown    test:
286c4762a1bSJed Brown       suffix: 8
287c4762a1bSJed Brown       args: -tao_smonitor -tao_type bntr -tao_bnk_max_cg_its 3 -tao_gatol 1.e-4
288c4762a1bSJed Brown 
289c4762a1bSJed Brown    test:
290c4762a1bSJed Brown       suffix: 9
291c4762a1bSJed Brown       args: -tao_smonitor -tao_type bntl -tao_bnk_max_cg_its 3 -tao_gatol 1.e-4
292c4762a1bSJed Brown 
293c4762a1bSJed Brown    test:
294c4762a1bSJed Brown       suffix: 10
295c4762a1bSJed Brown       args: -tao_smonitor -tao_type bnls -tao_bnk_max_cg_its 3 -tao_gatol 1.e-4
296c4762a1bSJed Brown 
297c4762a1bSJed Brown    test:
298c4762a1bSJed Brown       suffix: 11
299864588a7SAlp Dener       args: -test_lmvm -tao_max_it 10 -tao_bqnk_mat_type lmvmbroyden
300c4762a1bSJed Brown 
301c4762a1bSJed Brown    test:
302c4762a1bSJed Brown       suffix: 12
303864588a7SAlp Dener       args: -test_lmvm -tao_max_it 10 -tao_bqnk_mat_type lmvmbadbroyden
304c4762a1bSJed Brown 
305c4762a1bSJed Brown    test:
306c4762a1bSJed Brown      suffix: 13
307864588a7SAlp Dener      args: -test_lmvm -tao_max_it 10 -tao_bqnk_mat_type lmvmsymbroyden
308c4762a1bSJed Brown 
309c4762a1bSJed Brown    test:
310c4762a1bSJed Brown      suffix: 14
311c4762a1bSJed Brown      args: -test_lmvm -tao_max_it 10 -tao_bqnk_mat_type lmvmbfgs
312c4762a1bSJed Brown 
313c4762a1bSJed Brown    test:
314c4762a1bSJed Brown      suffix: 15
315c4762a1bSJed Brown      args: -test_lmvm -tao_max_it 10 -tao_bqnk_mat_type lmvmdfp
316c4762a1bSJed Brown 
317c4762a1bSJed Brown    test:
318c4762a1bSJed Brown      suffix: 16
319c4762a1bSJed Brown      args: -test_lmvm -tao_max_it 10 -tao_bqnk_mat_type lmvmsr1
320c4762a1bSJed Brown 
321c4762a1bSJed Brown    test:
322c4762a1bSJed Brown      suffix: 17
323c4762a1bSJed Brown      args: -tao_smonitor -tao_gatol 1e-4 -tao_type bqnls
324c4762a1bSJed Brown 
325c4762a1bSJed Brown    test:
326c4762a1bSJed Brown      suffix: 18
327c4762a1bSJed Brown      args: -tao_smonitor -tao_gatol 1e-4 -tao_type blmvm
328c4762a1bSJed Brown 
329c4762a1bSJed Brown    test:
330c4762a1bSJed Brown      suffix: 19
331c4762a1bSJed Brown      args: -tao_smonitor -tao_gatol 1e-4 -tao_type bqnktr -tao_bqnk_mat_type lmvmsr1
332c4762a1bSJed Brown 
333c4762a1bSJed Brown    test:
334c4762a1bSJed Brown      suffix: 20
335c4762a1bSJed Brown      args: -tao_monitor -tao_gatol 1e-4 -tao_type blmvm -tao_ls_monitor
336c4762a1bSJed Brown 
337c4762a1bSJed Brown    test:
338c4762a1bSJed Brown      suffix: 21
339864588a7SAlp Dener      args: -test_lmvm -tao_max_it 10 -tao_bqnk_mat_type lmvmsymbadbroyden
340c4762a1bSJed Brown 
34105579b36STristan Konolige    test:
34205579b36STristan Konolige      suffix: 22
34305579b36STristan Konolige      args: -tao_max_it 1 -tao_converged_reason
34405579b36STristan Konolige 
34505579b36STristan Konolige    test:
34605579b36STristan Konolige      suffix: 23
34705579b36STristan Konolige      args: -tao_max_funcs 0 -tao_converged_reason
34805579b36STristan Konolige 
34905579b36STristan Konolige    test:
35005579b36STristan Konolige      suffix: 24
35105579b36STristan Konolige      args: -tao_gatol 10 -tao_converged_reason
35205579b36STristan Konolige 
35305579b36STristan Konolige    test:
35405579b36STristan Konolige      suffix: 25
35505579b36STristan Konolige      args: -tao_grtol 10 -tao_converged_reason
35605579b36STristan Konolige 
35705579b36STristan Konolige    test:
35805579b36STristan Konolige      suffix: 26
35905579b36STristan Konolige      args: -tao_gttol 10 -tao_converged_reason
36005579b36STristan Konolige 
36105579b36STristan Konolige    test:
36205579b36STristan Konolige      suffix: 27
36305579b36STristan Konolige      args: -tao_steptol 10 -tao_converged_reason
36405579b36STristan Konolige 
36505579b36STristan Konolige    test:
36605579b36STristan Konolige      suffix: 28
36705579b36STristan Konolige      args: -tao_fmin 10 -tao_converged_reason
36805579b36STristan Konolige 
369c4762a1bSJed Brown TEST*/
370