Actual source code: taosolver.c

petsc-3.8.4 2018-03-24
Report Typos and Errors
  1: #define TAO_DLL

  3:  #include <petsc/private/taoimpl.h>

  5: PetscBool TaoRegisterAllCalled = PETSC_FALSE;
  6: PetscFunctionList TaoList = NULL;

  8: PetscClassId TAO_CLASSID;
  9: PetscLogEvent Tao_Solve, Tao_ObjectiveEval, Tao_GradientEval, Tao_ObjGradientEval, Tao_HessianEval, Tao_ConstraintsEval, Tao_JacobianEval;

 11: const char *TaoSubSetTypes[] = {  "subvec","mask","matrixfree","TaoSubSetType","TAO_SUBSET_",0};

 13: struct _n_TaoMonitorDrawCtx {
 14:   PetscViewer viewer;
 15:   PetscInt    howoften;  /* when > 0 uses iteration % howoften, when negative only final solution plotted */
 16: };

 18: /*@
 19:   TaoCreate - Creates a TAO solver

 21:   Collective on MPI_Comm

 23:   Input Parameter:
 24: . comm - MPI communicator

 26:   Output Parameter:
 27: . newtao - the new Tao context

 29:   Available methods include:
 30: +    nls - Newton's method with line search for unconstrained minimization
 31: .    ntr - Newton's method with trust region for unconstrained minimization
 32: .    ntl - Newton's method with trust region, line search for unconstrained minimization
 33: .    lmvm - Limited memory variable metric method for unconstrained minimization
 34: .    cg - Nonlinear conjugate gradient method for unconstrained minimization
 35: .    nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
 36: .    tron - Newton Trust Region method for bound constrained minimization
 37: .    gpcg - Newton Trust Region method for quadratic bound constrained minimization
 38: .    blmvm - Limited memory variable metric method for bound constrained minimization
 39: .    lcl - Linearly constrained Lagrangian method for pde-constrained minimization
 40: -    pounders - Model-based algorithm for nonlinear least squares

 42:    Options Database Keys:
 43: .   -tao_type - select which method TAO should use

 45:    Level: beginner

 47: .seealso: TaoSolve(), TaoDestroy()
 48: @*/
 49: PetscErrorCode TaoCreate(MPI_Comm comm, Tao *newtao)
 50: {
 52:   Tao            tao;

 56:   *newtao = NULL;

 58:   TaoInitializePackage();
 59:   TaoLineSearchInitializePackage();

 61:   PetscHeaderCreate(tao,TAO_CLASSID,"Tao","Optimization solver","Tao",comm,TaoDestroy,TaoView);
 62:   tao->ops->computeobjective=0;
 63:   tao->ops->computeobjectiveandgradient=0;
 64:   tao->ops->computegradient=0;
 65:   tao->ops->computehessian=0;
 66:   tao->ops->computeseparableobjective=0;
 67:   tao->ops->computeconstraints=0;
 68:   tao->ops->computejacobian=0;
 69:   tao->ops->computejacobianequality=0;
 70:   tao->ops->computejacobianinequality=0;
 71:   tao->ops->computeequalityconstraints=0;
 72:   tao->ops->computeinequalityconstraints=0;
 73:   tao->ops->convergencetest=TaoDefaultConvergenceTest;
 74:   tao->ops->convergencedestroy=0;
 75:   tao->ops->computedual=0;
 76:   tao->ops->setup=0;
 77:   tao->ops->solve=0;
 78:   tao->ops->view=0;
 79:   tao->ops->setfromoptions=0;
 80:   tao->ops->destroy=0;

 82:   tao->solution=NULL;
 83:   tao->gradient=NULL;
 84:   tao->sep_objective = NULL;
 85:   tao->constraints=NULL;
 86:   tao->constraints_equality=NULL;
 87:   tao->constraints_inequality=NULL;
 88:   tao->sep_weights_v=NULL;
 89:   tao->sep_weights_w=NULL;
 90:   tao->stepdirection=NULL;
 91:   tao->niter=0;
 92:   tao->ntotalits=0;
 93:   tao->XL = NULL;
 94:   tao->XU = NULL;
 95:   tao->IL = NULL;
 96:   tao->IU = NULL;
 97:   tao->DI = NULL;
 98:   tao->DE = NULL;
 99:   tao->gradient_norm = NULL;
100:   tao->gradient_norm_tmp = NULL;
101:   tao->hessian = NULL;
102:   tao->hessian_pre = NULL;
103:   tao->jacobian = NULL;
104:   tao->jacobian_pre = NULL;
105:   tao->jacobian_state = NULL;
106:   tao->jacobian_state_pre = NULL;
107:   tao->jacobian_state_inv = NULL;
108:   tao->jacobian_design = NULL;
109:   tao->jacobian_design_pre = NULL;
110:   tao->jacobian_equality = NULL;
111:   tao->jacobian_equality_pre = NULL;
112:   tao->jacobian_inequality = NULL;
113:   tao->jacobian_inequality_pre = NULL;
114:   tao->state_is = NULL;
115:   tao->design_is = NULL;

117:   tao->max_it     = 10000;
118:   tao->max_funcs   = 10000;
119: #if defined(PETSC_USE_REAL_SINGLE)
120:   tao->gatol       = 1e-5;
121:   tao->grtol       = 1e-5;
122: #else
123:   tao->gatol       = 1e-8;
124:   tao->grtol       = 1e-8;
125: #endif
126:   tao->crtol       = 0.0;
127:   tao->catol       = 0.0;
128:   tao->gttol       = 0.0;
129:   tao->steptol     = 0.0;
130:   tao->trust0      = PETSC_INFINITY;
131:   tao->fmin        = PETSC_NINFINITY;
132:   tao->hist_malloc = PETSC_FALSE;
133:   tao->hist_reset = PETSC_TRUE;
134:   tao->hist_max = 0;
135:   tao->hist_len = 0;
136:   tao->hist_obj = NULL;
137:   tao->hist_resid = NULL;
138:   tao->hist_cnorm = NULL;
139:   tao->hist_lits = NULL;

141:   tao->numbermonitors=0;
142:   tao->viewsolution=PETSC_FALSE;
143:   tao->viewhessian=PETSC_FALSE;
144:   tao->viewgradient=PETSC_FALSE;
145:   tao->viewjacobian=PETSC_FALSE;
146:   tao->viewconstraints = PETSC_FALSE;

148:   /* These flags prevents algorithms from overriding user options */
149:   tao->max_it_changed   =PETSC_FALSE;
150:   tao->max_funcs_changed=PETSC_FALSE;
151:   tao->gatol_changed    =PETSC_FALSE;
152:   tao->grtol_changed    =PETSC_FALSE;
153:   tao->gttol_changed    =PETSC_FALSE;
154:   tao->steptol_changed  =PETSC_FALSE;
155:   tao->trust0_changed   =PETSC_FALSE;
156:   tao->fmin_changed     =PETSC_FALSE;
157:   tao->catol_changed    =PETSC_FALSE;
158:   tao->crtol_changed    =PETSC_FALSE;
159:   TaoResetStatistics(tao);
160:   *newtao = tao;
161:   return(0);
162: }

164: /*@
165:   TaoSolve - Solves an optimization problem min F(x) s.t. l <= x <= u

167:   Collective on Tao

169:   Input Parameters:
170: . tao - the Tao context

172:   Notes:
173:   The user must set up the Tao with calls to TaoSetInitialVector(),
174:   TaoSetObjectiveRoutine(),
175:   TaoSetGradientRoutine(), and (if using 2nd order method) TaoSetHessianRoutine().

177:   You should call TaoGetConvergedReason() or run with -tao_converged_reason to determine if the optimization algorithm actually succeeded or
178:   why it failed.

180:   Level: beginner

182: .seealso: TaoCreate(), TaoSetObjectiveRoutine(), TaoSetGradientRoutine(), TaoSetHessianRoutine(), TaoGetConvergedReason()
183:  @*/
184: PetscErrorCode TaoSolve(Tao tao)
185: {
186:   PetscErrorCode   ierr;
187:   static PetscBool set = PETSC_FALSE;

191:   PetscCitationsRegister("@TechReport{tao-user-ref,\n"
192:                                 "title   = {Toolkit for Advanced Optimization (TAO) Users Manual},\n"
193:                                 "author  = {Todd Munson and Jason Sarich and Stefan Wild and Steve Benson and Lois Curfman McInnes},\n"
194:                                 "Institution = {Argonne National Laboratory},\n"
195:                                 "Year   = 2014,\n"
196:                                 "Number = {ANL/MCS-TM-322 - Revision 3.5},\n"
197:                                 "url    = {http://www.mcs.anl.gov/tao}\n}\n",&set);

199:   TaoSetUp(tao);
200:   TaoResetStatistics(tao);
201:   if (tao->linesearch) {
202:     TaoLineSearchReset(tao->linesearch);
203:   }

205:   PetscLogEventBegin(Tao_Solve,tao,0,0,0);
206:   if (tao->ops->solve){ (*tao->ops->solve)(tao); }
207:   PetscLogEventEnd(Tao_Solve,tao,0,0,0);

209:   tao->ntotalits += tao->niter;
210:   TaoViewFromOptions(tao,NULL,"-tao_view");

212:   if (tao->printreason) {
213:     if (tao->reason > 0) {
214:       PetscPrintf(((PetscObject)tao)->comm,"TAO solve converged due to %s iterations %D\n",TaoConvergedReasons[tao->reason],tao->niter);
215:     } else {
216:       PetscPrintf(((PetscObject)tao)->comm,"TAO solve did not converge due to %s iteration %D\n",TaoConvergedReasons[tao->reason],tao->niter);
217:     }
218:   }
219:   return(0);
220: }

222: /*@
223:   TaoSetUp - Sets up the internal data structures for the later use
224:   of a Tao solver

226:   Collective on tao

228:   Input Parameters:
229: . tao - the TAO context

231:   Notes:
232:   The user will not need to explicitly call TaoSetUp(), as it will
233:   automatically be called in TaoSolve().  However, if the user
234:   desires to call it explicitly, it should come after TaoCreate()
235:   and any TaoSetSomething() routines, but before TaoSolve().

237:   Level: advanced

239: .seealso: TaoCreate(), TaoSolve()
240: @*/
241: PetscErrorCode TaoSetUp(Tao tao)
242: {

247:   if (tao->setupcalled) return(0);

249:   if (!tao->solution) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetInitialVector");
250:   if (tao->ops->setup) {
251:     (*tao->ops->setup)(tao);
252:   }
253:   tao->setupcalled = PETSC_TRUE;
254:   return(0);
255: }

257: /*@
258:   TaoDestroy - Destroys the TAO context that was created with
259:   TaoCreate()

261:   Collective on Tao

263:   Input Parameter:
264: . tao - the Tao context

266:   Level: beginner

268: .seealso: TaoCreate(), TaoSolve()
269: @*/
270: PetscErrorCode TaoDestroy(Tao *tao)
271: {

275:   if (!*tao) return(0);
277:   if (--((PetscObject)*tao)->refct > 0) {*tao=0;return(0);}

279:   if ((*tao)->ops->destroy) {
280:     (*((*tao))->ops->destroy)(*tao);
281:   }
282:   KSPDestroy(&(*tao)->ksp);
283:   TaoLineSearchDestroy(&(*tao)->linesearch);

285:   if ((*tao)->ops->convergencedestroy) {
286:     (*(*tao)->ops->convergencedestroy)((*tao)->cnvP);
287:     if ((*tao)->jacobian_state_inv) {
288:       MatDestroy(&(*tao)->jacobian_state_inv);
289:     }
290:   }
291:   VecDestroy(&(*tao)->solution);
292:   VecDestroy(&(*tao)->gradient);

294:   if ((*tao)->gradient_norm) {
295:     PetscObjectDereference((PetscObject)(*tao)->gradient_norm);
296:     VecDestroy(&(*tao)->gradient_norm_tmp);
297:   }

299:   VecDestroy(&(*tao)->XL);
300:   VecDestroy(&(*tao)->XU);
301:   VecDestroy(&(*tao)->IL);
302:   VecDestroy(&(*tao)->IU);
303:   VecDestroy(&(*tao)->DE);
304:   VecDestroy(&(*tao)->DI);
305:   VecDestroy(&(*tao)->constraints_equality);
306:   VecDestroy(&(*tao)->constraints_inequality);
307:   VecDestroy(&(*tao)->stepdirection);
308:   MatDestroy(&(*tao)->hessian_pre);
309:   MatDestroy(&(*tao)->hessian);
310:   MatDestroy(&(*tao)->jacobian_pre);
311:   MatDestroy(&(*tao)->jacobian);
312:   MatDestroy(&(*tao)->jacobian_state_pre);
313:   MatDestroy(&(*tao)->jacobian_state);
314:   MatDestroy(&(*tao)->jacobian_state_inv);
315:   MatDestroy(&(*tao)->jacobian_design);
316:   MatDestroy(&(*tao)->jacobian_equality);
317:   MatDestroy(&(*tao)->jacobian_equality_pre);
318:   MatDestroy(&(*tao)->jacobian_inequality);
319:   MatDestroy(&(*tao)->jacobian_inequality_pre);
320:   ISDestroy(&(*tao)->state_is);
321:   ISDestroy(&(*tao)->design_is);
322:   VecDestroy(&(*tao)->sep_weights_v);
323:   TaoCancelMonitors(*tao);
324:   if ((*tao)->hist_malloc) {
325:     PetscFree((*tao)->hist_obj);
326:     PetscFree((*tao)->hist_resid);
327:     PetscFree((*tao)->hist_cnorm);
328:     PetscFree((*tao)->hist_lits);
329:   }
330:   if ((*tao)->sep_weights_n) {
331:     PetscFree((*tao)->sep_weights_rows);
332:     PetscFree((*tao)->sep_weights_cols);
333:     PetscFree((*tao)->sep_weights_w);
334:   }
335:   PetscHeaderDestroy(tao);
336:   return(0);
337: }

339: /*@
340:   TaoSetFromOptions - Sets various Tao parameters from user
341:   options.

343:   Collective on Tao

345:   Input Paremeter:
346: . tao - the Tao solver context

348:   options Database Keys:
349: + -tao_type <type> - The algorithm that TAO uses (lmvm, nls, etc.)
350: . -tao_gatol <gatol> - absolute error tolerance for ||gradient||
351: . -tao_grtol <grtol> - relative error tolerance for ||gradient||
352: . -tao_gttol <gttol> - reduction of ||gradient|| relative to initial gradient
353: . -tao_max_it <max> - sets maximum number of iterations
354: . -tao_max_funcs <max> - sets maximum number of function evaluations
355: . -tao_fmin <fmin> - stop if function value reaches fmin
356: . -tao_steptol <tol> - stop if trust region radius less than <tol>
357: . -tao_trust0 <t> - initial trust region radius
358: . -tao_monitor - prints function value and residual at each iteration
359: . -tao_smonitor - same as tao_monitor, but truncates very small values
360: . -tao_cmonitor - prints function value, residual, and constraint norm at each iteration
361: . -tao_view_solution - prints solution vector at each iteration
362: . -tao_view_separableobjective - prints separable objective vector at each iteration
363: . -tao_view_step - prints step direction vector at each iteration
364: . -tao_view_gradient - prints gradient vector at each iteration
365: . -tao_draw_solution - graphically view solution vector at each iteration
366: . -tao_draw_step - graphically view step vector at each iteration
367: . -tao_draw_gradient - graphically view gradient at each iteration
368: . -tao_fd_gradient - use gradient computed with finite differences
369: . -tao_cancelmonitors - cancels all monitors (except those set with command line)
370: . -tao_view - prints information about the Tao after solving
371: - -tao_converged_reason - prints the reason TAO stopped iterating

373:   Notes:
374:   To see all options, run your program with the -help option or consult the
375:   user's manual. Should be called after TaoCreate() but before TaoSolve()

377:   Level: beginner
378: @*/
379: PetscErrorCode TaoSetFromOptions(Tao tao)
380: {
382:   const TaoType  default_type = TAOLMVM;
383:   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
384:   PetscViewer    monviewer;
385:   PetscBool      flg;
386:   MPI_Comm       comm;

390:   PetscObjectGetComm((PetscObject)tao,&comm);

392:   /* So no warnings are given about unused options */
393:   PetscOptionsHasName(((PetscObject)tao)->options,((PetscObject)tao)->prefix,"-tao_ls_type",&flg);

395:   PetscObjectOptionsBegin((PetscObject)tao);
396:   {
397:     TaoRegisterAll();
398:     if (((PetscObject)tao)->type_name) {
399:       default_type = ((PetscObject)tao)->type_name;
400:     }
401:     /* Check for type from options */
402:     PetscOptionsFList("-tao_type","Tao Solver type","TaoSetType",TaoList,default_type,type,256,&flg);
403:     if (flg) {
404:       TaoSetType(tao,type);
405:     } else if (!((PetscObject)tao)->type_name) {
406:       TaoSetType(tao,default_type);
407:     }

409:     PetscOptionsReal("-tao_catol","Stop if constraints violations within","TaoSetConstraintTolerances",tao->catol,&tao->catol,&flg);
410:     if (flg) tao->catol_changed=PETSC_TRUE;
411:     PetscOptionsReal("-tao_crtol","Stop if relative contraint violations within","TaoSetConstraintTolerances",tao->crtol,&tao->crtol,&flg);
412:     if (flg) tao->crtol_changed=PETSC_TRUE;
413:     PetscOptionsReal("-tao_gatol","Stop if norm of gradient less than","TaoSetTolerances",tao->gatol,&tao->gatol,&flg);
414:     if (flg) tao->gatol_changed=PETSC_TRUE;
415:     PetscOptionsReal("-tao_grtol","Stop if norm of gradient divided by the function value is less than","TaoSetTolerances",tao->grtol,&tao->grtol,&flg);
416:     if (flg) tao->grtol_changed=PETSC_TRUE;
417:     PetscOptionsReal("-tao_gttol","Stop if the norm of the gradient is less than the norm of the initial gradient times tol","TaoSetTolerances",tao->gttol,&tao->gttol,&flg);
418:     if (flg) tao->gttol_changed=PETSC_TRUE;
419:     PetscOptionsInt("-tao_max_it","Stop if iteration number exceeds","TaoSetMaximumIterations",tao->max_it,&tao->max_it,&flg);
420:     if (flg) tao->max_it_changed=PETSC_TRUE;
421:     PetscOptionsInt("-tao_max_funcs","Stop if number of function evaluations exceeds","TaoSetMaximumFunctionEvaluations",tao->max_funcs,&tao->max_funcs,&flg);
422:     if (flg) tao->max_funcs_changed=PETSC_TRUE;
423:     PetscOptionsReal("-tao_fmin","Stop if function less than","TaoSetFunctionLowerBound",tao->fmin,&tao->fmin,&flg);
424:     if (flg) tao->fmin_changed=PETSC_TRUE;
425:     PetscOptionsReal("-tao_steptol","Stop if step size or trust region radius less than","",tao->steptol,&tao->steptol,&flg);
426:     if (flg) tao->steptol_changed=PETSC_TRUE;
427:     PetscOptionsReal("-tao_trust0","Initial trust region radius","TaoSetTrustRegionRadius",tao->trust0,&tao->trust0,&flg);
428:     if (flg) tao->trust0_changed=PETSC_TRUE;
429:     PetscOptionsString("-tao_view_solution","view solution vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
430:     if (flg) {
431:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
432:       TaoSetMonitor(tao,TaoSolutionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
433:     }

435:     PetscOptionsBool("-tao_converged_reason","Print reason for TAO converged","TaoSolve",tao->printreason,&tao->printreason,NULL);
436:     PetscOptionsString("-tao_view_gradient","view gradient vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
437:     if (flg) {
438:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
439:       TaoSetMonitor(tao,TaoGradientMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
440:     }

442:     PetscOptionsString("-tao_view_stepdirection","view step direction vector after each iteration","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
443:     if (flg) {
444:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
445:       TaoSetMonitor(tao,TaoStepDirectionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
446:     }

448:     PetscOptionsString("-tao_view_separableobjective","view separable objective vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
449:     if (flg) {
450:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
451:       TaoSetMonitor(tao,TaoSeparableObjectiveMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
452:     }

454:     PetscOptionsString("-tao_monitor","Use the default convergence monitor","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
455:     if (flg) {
456:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
457:       TaoSetMonitor(tao,TaoDefaultMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
458:     }

460:     PetscOptionsString("-tao_smonitor","Use the short convergence monitor","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
461:     if (flg) {
462:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
463:       TaoSetMonitor(tao,TaoDefaultSMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
464:     }

466:     PetscOptionsString("-tao_cmonitor","Use the default convergence monitor with constraint norm","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
467:     if (flg) {
468:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
469:       TaoSetMonitor(tao,TaoDefaultCMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
470:     }


473:     flg = PETSC_FALSE;
474:     PetscOptionsBool("-tao_cancelmonitors","cancel all monitors and call any registered destroy routines","TaoCancelMonitors",flg,&flg,NULL);
475:     if (flg) {TaoCancelMonitors(tao);}

477:     flg = PETSC_FALSE;
478:     PetscOptionsBool("-tao_draw_solution","Plot solution vector at each iteration","TaoSetMonitor",flg,&flg,NULL);
479:     if (flg) {
480:       TaoMonitorDrawCtx drawctx;
481:       PetscInt          howoften = 1;
482:       TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx);
483:       TaoSetMonitor(tao,TaoDrawSolutionMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy);
484:     }

486:     flg = PETSC_FALSE;
487:     PetscOptionsBool("-tao_draw_step","plots step direction at each iteration","TaoSetMonitor",flg,&flg,NULL);
488:     if (flg) {
489:       TaoSetMonitor(tao,TaoDrawStepMonitor,NULL,NULL);
490:     }

492:     flg = PETSC_FALSE;
493:     PetscOptionsBool("-tao_draw_gradient","plots gradient at each iteration","TaoSetMonitor",flg,&flg,NULL);
494:     if (flg) {
495:       TaoMonitorDrawCtx drawctx;
496:       PetscInt          howoften = 1;
497:       TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx);
498:       TaoSetMonitor(tao,TaoDrawGradientMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy);
499:     }
500:     flg = PETSC_FALSE;
501:     PetscOptionsBool("-tao_fd_gradient","compute gradient using finite differences","TaoDefaultComputeGradient",flg,&flg,NULL);
502:     if (flg) {
503:       TaoSetGradientRoutine(tao,TaoDefaultComputeGradient,NULL);
504:     }
505:     PetscOptionsEnum("-tao_subset_type","subset type", "", TaoSubSetTypes,(PetscEnum)tao->subset_type, (PetscEnum*)&tao->subset_type, 0);

507:     if (tao->ops->setfromoptions) {
508:       (*tao->ops->setfromoptions)(PetscOptionsObject,tao);
509:     }
510:   }
511:   PetscOptionsEnd();
512:   return(0);
513: }

515: /*@C
516:   TaoView - Prints information about the Tao

518:   Collective on Tao

520:   InputParameters:
521: + tao - the Tao context
522: - viewer - visualization context

524:   Options Database Key:
525: . -tao_view - Calls TaoView() at the end of TaoSolve()

527:   Notes:
528:   The available visualization contexts include
529: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
530: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
531:          output where only the first processor opens
532:          the file.  All other processors send their
533:          data to the first processor to print.

535:   Level: beginner

537: .seealso: PetscViewerASCIIOpen()
538: @*/
539: PetscErrorCode TaoView(Tao tao, PetscViewer viewer)
540: {
541:   PetscErrorCode      ierr;
542:   PetscBool           isascii,isstring;
543:   const TaoType type;

547:   if (!viewer) {
548:     PetscViewerASCIIGetStdout(((PetscObject)tao)->comm,&viewer);
549:   }

553:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
554:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
555:   if (isascii) {
556:     PetscObjectPrintClassNamePrefixType((PetscObject)tao,viewer);
557:     PetscViewerASCIIPushTab(viewer);

559:     if (tao->ops->view) {
560:       PetscViewerASCIIPushTab(viewer);
561:       (*tao->ops->view)(tao,viewer);
562:       PetscViewerASCIIPopTab(viewer);
563:     }
564:     if (tao->linesearch) {
565:       PetscObjectPrintClassNamePrefixType((PetscObject)(tao->linesearch),viewer);
566:     }
567:     if (tao->ksp) {
568:       PetscObjectPrintClassNamePrefixType((PetscObject)(tao->ksp),viewer);
569:       PetscViewerASCIIPrintf(viewer,"total KSP iterations: %D\n",tao->ksp_tot_its);
570:     }
571:     if (tao->XL || tao->XU) {
572:       PetscViewerASCIIPrintf(viewer,"Active Set subset type: %s\n",TaoSubSetTypes[tao->subset_type]);
573:     }

575:     ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: gatol=%g,",(double)tao->gatol);
576:     ierr=PetscViewerASCIIPrintf(viewer," steptol=%g,",(double)tao->steptol);
577:     ierr=PetscViewerASCIIPrintf(viewer," gttol=%g\n",(double)tao->gttol);

579:     PetscViewerASCIIPrintf(viewer,"Residual in Function/Gradient:=%g\n",(double)tao->residual);

581:     if (tao->cnorm>0 || tao->catol>0 || tao->crtol>0){
582:       ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances:");
583:       ierr=PetscViewerASCIIPrintf(viewer," catol=%g,",(double)tao->catol);
584:       ierr=PetscViewerASCIIPrintf(viewer," crtol=%g\n",(double)tao->crtol);
585:       PetscViewerASCIIPrintf(viewer,"Residual in Constraints:=%g\n",(double)tao->cnorm);
586:     }

588:     if (tao->trust < tao->steptol){
589:       ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: steptol=%g\n",(double)tao->steptol);
590:       ierr=PetscViewerASCIIPrintf(viewer,"Final trust region radius:=%g\n",(double)tao->trust);
591:     }

593:     if (tao->fmin>-1.e25){
594:       ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: function minimum=%g\n",(double)tao->fmin);
595:     }
596:     PetscViewerASCIIPrintf(viewer,"Objective value=%g\n",(double)tao->fc);

598:     PetscViewerASCIIPrintf(viewer,"total number of iterations=%D,          ",tao->niter);
599:     PetscViewerASCIIPrintf(viewer,"              (max: %D)\n",tao->max_it);

601:     if (tao->nfuncs>0){
602:       PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%D,",tao->nfuncs);
603:       PetscViewerASCIIPrintf(viewer,"                max: %D\n",tao->max_funcs);
604:     }
605:     if (tao->ngrads>0){
606:       PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%D,",tao->ngrads);
607:       PetscViewerASCIIPrintf(viewer,"                max: %D\n",tao->max_funcs);
608:     }
609:     if (tao->nfuncgrads>0){
610:       PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%D,",tao->nfuncgrads);
611:       PetscViewerASCIIPrintf(viewer,"    (max: %D)\n",tao->max_funcs);
612:     }
613:     if (tao->nhess>0){
614:       PetscViewerASCIIPrintf(viewer,"total number of Hessian evaluations=%D\n",tao->nhess);
615:     }
616:     /*  if (tao->linear_its>0){
617:      PetscViewerASCIIPrintf(viewer,"  total Krylov method iterations=%D\n",tao->linear_its);
618:      }*/
619:     if (tao->nconstraints>0){
620:       PetscViewerASCIIPrintf(viewer,"total number of constraint function evaluations=%D\n",tao->nconstraints);
621:     }
622:     if (tao->njac>0){
623:       PetscViewerASCIIPrintf(viewer,"total number of Jacobian evaluations=%D\n",tao->njac);
624:     }

626:     if (tao->reason>0){
627:       PetscViewerASCIIPrintf(viewer,    "Solution converged: ");
628:       switch (tao->reason) {
629:       case TAO_CONVERGED_GATOL:
630:         PetscViewerASCIIPrintf(viewer," ||g(X)|| <= gatol\n");
631:         break;
632:       case TAO_CONVERGED_GRTOL:
633:         PetscViewerASCIIPrintf(viewer," ||g(X)||/|f(X)| <= grtol\n");
634:         break;
635:       case TAO_CONVERGED_GTTOL:
636:         PetscViewerASCIIPrintf(viewer," ||g(X)||/||g(X0)|| <= gttol\n");
637:         break;
638:       case TAO_CONVERGED_STEPTOL:
639:         PetscViewerASCIIPrintf(viewer," Steptol -- step size small\n");
640:         break;
641:       case TAO_CONVERGED_MINF:
642:         PetscViewerASCIIPrintf(viewer," Minf --  f < fmin\n");
643:         break;
644:       case TAO_CONVERGED_USER:
645:         PetscViewerASCIIPrintf(viewer," User Terminated\n");
646:         break;
647:       default:
648:         PetscViewerASCIIPrintf(viewer,"\n");
649:         break;
650:       }

652:     } else {
653:       PetscViewerASCIIPrintf(viewer,"Solver terminated: %d",tao->reason);
654:       switch (tao->reason) {
655:       case TAO_DIVERGED_MAXITS:
656:         PetscViewerASCIIPrintf(viewer," Maximum Iterations\n");
657:         break;
658:       case TAO_DIVERGED_NAN:
659:         PetscViewerASCIIPrintf(viewer," NAN or Inf encountered\n");
660:         break;
661:       case TAO_DIVERGED_MAXFCN:
662:         PetscViewerASCIIPrintf(viewer," Maximum Function Evaluations\n");
663:         break;
664:       case TAO_DIVERGED_LS_FAILURE:
665:         PetscViewerASCIIPrintf(viewer," Line Search Failure\n");
666:         break;
667:       case TAO_DIVERGED_TR_REDUCTION:
668:         PetscViewerASCIIPrintf(viewer," Trust Region too small\n");
669:         break;
670:       case TAO_DIVERGED_USER:
671:         PetscViewerASCIIPrintf(viewer," User Terminated\n");
672:         break;
673:       default:
674:         PetscViewerASCIIPrintf(viewer,"\n");
675:         break;
676:       }
677:     }
678:     PetscViewerASCIIPopTab(viewer);
679:   } else if (isstring) {
680:     TaoGetType(tao,&type);
681:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
682:   }
683:   return(0);
684: }

686: /*@
687:   TaoSetTolerances - Sets parameters used in TAO convergence tests

689:   Logically collective on Tao

691:   Input Parameters:
692: + tao - the Tao context
693: . gatol - stop if norm of gradient is less than this
694: . grtol - stop if relative norm of gradient is less than this
695: - gttol - stop if norm of gradient is reduced by this factor

697:   Options Database Keys:
698: + -tao_gatol <gatol> - Sets gatol
699: . -tao_grtol <grtol> - Sets grtol
700: - -tao_gttol <gttol> - Sets gttol

702:   Stopping Criteria:
703: $ ||g(X)||                            <= gatol
704: $ ||g(X)|| / |f(X)|                   <= grtol
705: $ ||g(X)|| / ||g(X0)||                <= gttol

707:   Notes:
708:   Use PETSC_DEFAULT to leave one or more tolerances unchanged.

710:   Level: beginner

712: .seealso: TaoGetTolerances()

714: @*/
715: PetscErrorCode TaoSetTolerances(Tao tao, PetscReal gatol, PetscReal grtol, PetscReal gttol)
716: {


722:   if (gatol != PETSC_DEFAULT) {
723:     if (gatol<0) {
724:       PetscInfo(tao,"Tried to set negative gatol -- ignored.\n");
725:     } else {
726:       tao->gatol = PetscMax(0,gatol);
727:       tao->gatol_changed=PETSC_TRUE;
728:     }
729:   }

731:   if (grtol != PETSC_DEFAULT) {
732:     if (grtol<0) {
733:       PetscInfo(tao,"Tried to set negative grtol -- ignored.\n");
734:     } else {
735:       tao->grtol = PetscMax(0,grtol);
736:       tao->grtol_changed=PETSC_TRUE;
737:     }
738:   }

740:   if (gttol != PETSC_DEFAULT) {
741:     if (gttol<0) {
742:       PetscInfo(tao,"Tried to set negative gttol -- ignored.\n");
743:     } else {
744:       tao->gttol = PetscMax(0,gttol);
745:       tao->gttol_changed=PETSC_TRUE;
746:     }
747:   }
748:   return(0);
749: }

751: /*@
752:   TaoSetConstraintTolerances - Sets constraint tolerance parameters used in TAO  convergence tests

754:   Logically collective on Tao

756:   Input Parameters:
757: + tao - the Tao context
758: . catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
759: - crtol - relative contraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria

761:   Options Database Keys:
762: + -tao_catol <catol> - Sets catol
763: - -tao_crtol <crtol> - Sets crtol

765:   Notes:
766:   Use PETSC_DEFAULT to leave any tolerance unchanged.

768:   Level: intermediate

770: .seealso: TaoGetTolerances(), TaoGetConstraintTolerances(), TaoSetTolerances()

772: @*/
773: PetscErrorCode TaoSetConstraintTolerances(Tao tao, PetscReal catol, PetscReal crtol)
774: {


780:   if (catol != PETSC_DEFAULT) {
781:     if (catol<0) {
782:       PetscInfo(tao,"Tried to set negative catol -- ignored.\n");
783:     } else {
784:       tao->catol = PetscMax(0,catol);
785:       tao->catol_changed=PETSC_TRUE;
786:     }
787:   }

789:   if (crtol != PETSC_DEFAULT) {
790:     if (crtol<0) {
791:       PetscInfo(tao,"Tried to set negative crtol -- ignored.\n");
792:     } else {
793:       tao->crtol = PetscMax(0,crtol);
794:       tao->crtol_changed=PETSC_TRUE;
795:     }
796:   }
797:   return(0);
798: }

800: /*@
801:   TaoGetConstraintTolerances - Gets constraint tolerance parameters used in TAO  convergence tests

803:   Not ollective

805:   Input Parameter:
806: . tao - the Tao context

808:   Output Parameter:
809: + catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
810: - crtol - relative contraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria

812:   Level: intermediate

814: .seealso: TaoGetTolerances(), TaoSetTolerances(), TaoSetConstraintTolerances()

816: @*/
817: PetscErrorCode TaoGetConstraintTolerances(Tao tao, PetscReal *catol, PetscReal *crtol)
818: {
821:   if (catol) *catol = tao->catol;
822:   if (crtol) *crtol = tao->crtol;
823:   return(0);
824: }

826: /*@
827:    TaoSetFunctionLowerBound - Sets a bound on the solution objective value.
828:    When an approximate solution with an objective value below this number
829:    has been found, the solver will terminate.

831:    Logically Collective on Tao

833:    Input Parameters:
834: +  tao - the Tao solver context
835: -  fmin - the tolerance

837:    Options Database Keys:
838: .    -tao_fmin <fmin> - sets the minimum function value

840:    Level: intermediate

842: .seealso: TaoSetTolerances()
843: @*/
844: PetscErrorCode TaoSetFunctionLowerBound(Tao tao,PetscReal fmin)
845: {
848:   tao->fmin = fmin;
849:   tao->fmin_changed=PETSC_TRUE;
850:   return(0);
851: }

853: /*@
854:    TaoGetFunctionLowerBound - Gets the bound on the solution objective value.
855:    When an approximate solution with an objective value below this number
856:    has been found, the solver will terminate.

858:    Not collective on Tao

860:    Input Parameters:
861: .  tao - the Tao solver context

863:    OutputParameters:
864: .  fmin - the minimum function value

866:    Level: intermediate

868: .seealso: TaoSetFunctionLowerBound()
869: @*/
870: PetscErrorCode TaoGetFunctionLowerBound(Tao tao,PetscReal *fmin)
871: {
874:   *fmin = tao->fmin;
875:   return(0);
876: }

878: /*@
879:    TaoSetMaximumFunctionEvaluations - Sets a maximum number of
880:    function evaluations.

882:    Logically Collective on Tao

884:    Input Parameters:
885: +  tao - the Tao solver context
886: -  nfcn - the maximum number of function evaluations (>=0)

888:    Options Database Keys:
889: .    -tao_max_funcs <nfcn> - sets the maximum number of function evaluations

891:    Level: intermediate

893: .seealso: TaoSetTolerances(), TaoSetMaximumIterations()
894: @*/

896: PetscErrorCode TaoSetMaximumFunctionEvaluations(Tao tao,PetscInt nfcn)
897: {
900:   tao->max_funcs = PetscMax(0,nfcn);
901:   tao->max_funcs_changed=PETSC_TRUE;
902:   return(0);
903: }

905: /*@
906:    TaoGetMaximumFunctionEvaluations - Sets a maximum number of
907:    function evaluations.

909:    Not Collective

911:    Input Parameters:
912: .  tao - the Tao solver context

914:    Output Parameters:
915: .  nfcn - the maximum number of function evaluations

917:    Level: intermediate

919: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
920: @*/

922: PetscErrorCode TaoGetMaximumFunctionEvaluations(Tao tao,PetscInt *nfcn)
923: {
926:   *nfcn = tao->max_funcs;
927:   return(0);
928: }

930: /*@
931:    TaoGetCurrentFunctionEvaluations - Get current number of
932:    function evaluations.

934:    Not Collective

936:    Input Parameters:
937: .  tao - the Tao solver context

939:    Output Parameters:
940: .  nfuncs - the current number of function evaluations

942:    Level: intermediate

944: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
945: @*/

947: PetscErrorCode TaoGetCurrentFunctionEvaluations(Tao tao,PetscInt *nfuncs)
948: {
951:   *nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
952:   return(0);
953: }

955: /*@
956:    TaoSetMaximumIterations - Sets a maximum number of iterates.

958:    Logically Collective on Tao

960:    Input Parameters:
961: +  tao - the Tao solver context
962: -  maxits - the maximum number of iterates (>=0)

964:    Options Database Keys:
965: .    -tao_max_it <its> - sets the maximum number of iterations

967:    Level: intermediate

969: .seealso: TaoSetTolerances(), TaoSetMaximumFunctionEvaluations()
970: @*/
971: PetscErrorCode TaoSetMaximumIterations(Tao tao,PetscInt maxits)
972: {
975:   tao->max_it = PetscMax(0,maxits);
976:   tao->max_it_changed=PETSC_TRUE;
977:   return(0);
978: }

980: /*@
981:    TaoGetMaximumIterations - Sets a maximum number of iterates.

983:    Not Collective

985:    Input Parameters:
986: .  tao - the Tao solver context

988:    Output Parameters:
989: .  maxits - the maximum number of iterates

991:    Level: intermediate

993: .seealso: TaoSetMaximumIterations(), TaoGetMaximumFunctionEvaluations()
994: @*/
995: PetscErrorCode TaoGetMaximumIterations(Tao tao,PetscInt *maxits)
996: {
999:   *maxits = tao->max_it;
1000:   return(0);
1001: }

1003: /*@
1004:    TaoSetInitialTrustRegionRadius - Sets the initial trust region radius.

1006:    Logically collective on Tao

1008:    Input Parameter:
1009: +  tao - a TAO optimization solver
1010: -  radius - the trust region radius

1012:    Level: intermediate

1014:    Options Database Key:
1015: .  -tao_trust0 <t0> - sets initial trust region radius

1017: .seealso: TaoGetTrustRegionRadius(), TaoSetTrustRegionTolerance()
1018: @*/
1019: PetscErrorCode TaoSetInitialTrustRegionRadius(Tao tao, PetscReal radius)
1020: {
1023:   tao->trust0 = PetscMax(0.0,radius);
1024:   tao->trust0_changed=PETSC_TRUE;
1025:   return(0);
1026: }

1028: /*@
1029:    TaoGetInitialTrustRegionRadius - Sets the initial trust region radius.

1031:    Not Collective

1033:    Input Parameter:
1034: .  tao - a TAO optimization solver

1036:    Output Parameter:
1037: .  radius - the trust region radius

1039:    Level: intermediate

1041: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetCurrentTrustRegionRadius()
1042: @*/
1043: PetscErrorCode TaoGetInitialTrustRegionRadius(Tao tao, PetscReal *radius)
1044: {
1047:   *radius = tao->trust0;
1048:   return(0);
1049: }

1051: /*@
1052:    TaoGetCurrentTrustRegionRadius - Gets the current trust region radius.

1054:    Not Collective

1056:    Input Parameter:
1057: .  tao - a TAO optimization solver

1059:    Output Parameter:
1060: .  radius - the trust region radius

1062:    Level: intermediate

1064: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetInitialTrustRegionRadius()
1065: @*/
1066: PetscErrorCode TaoGetCurrentTrustRegionRadius(Tao tao, PetscReal *radius)
1067: {
1070:   *radius = tao->trust;
1071:   return(0);
1072: }

1074: /*@
1075:   TaoGetTolerances - gets the current values of tolerances

1077:   Not Collective

1079:   Input Parameters:
1080: . tao - the Tao context

1082:   Output Parameters:
1083: + gatol - stop if norm of gradient is less than this
1084: . grtol - stop if relative norm of gradient is less than this
1085: - gttol - stop if norm of gradient is reduced by a this factor

1087:   Note: NULL can be used as an argument if not all tolerances values are needed

1089: .seealso TaoSetTolerances()

1091:   Level: intermediate
1092: @*/
1093: PetscErrorCode TaoGetTolerances(Tao tao, PetscReal *gatol, PetscReal *grtol, PetscReal *gttol)
1094: {
1097:   if (gatol) *gatol=tao->gatol;
1098:   if (grtol) *grtol=tao->grtol;
1099:   if (gttol) *gttol=tao->gttol;
1100:   return(0);
1101: }

1103: /*@
1104:   TaoGetKSP - Gets the linear solver used by the optimization solver.
1105:   Application writers should use TaoGetKSP if they need direct access
1106:   to the PETSc KSP object.

1108:   Not Collective

1110:    Input Parameters:
1111: .  tao - the TAO solver

1113:    Output Parameters:
1114: .  ksp - the KSP linear solver used in the optimization solver

1116:    Level: intermediate

1118: @*/
1119: PetscErrorCode TaoGetKSP(Tao tao, KSP *ksp)
1120: {
1122:   *ksp = tao->ksp;
1123:   return(0);
1124: }

1126: /*@
1127:    TaoGetLinearSolveIterations - Gets the total number of linear iterations
1128:    used by the TAO solver

1130:    Not Collective

1132:    Input Parameter:
1133: .  tao - TAO context

1135:    Output Parameter:
1136: .  lits - number of linear iterations

1138:    Notes:
1139:    This counter is reset to zero for each successive call to TaoSolve()

1141:    Level: intermediate

1143: .keywords: TAO

1145: .seealso:  TaoGetKSP()
1146: @*/
1147: PetscErrorCode  TaoGetLinearSolveIterations(Tao tao,PetscInt *lits)
1148: {
1152:   *lits = tao->ksp_tot_its;
1153:   return(0);
1154: }

1156: /*@
1157:   TaoGetLineSearch - Gets the line search used by the optimization solver.
1158:   Application writers should use TaoGetLineSearch if they need direct access
1159:   to the TaoLineSearch object.

1161:   Not Collective

1163:    Input Parameters:
1164: .  tao - the TAO solver

1166:    Output Parameters:
1167: .  ls - the line search used in the optimization solver

1169:    Level: intermediate

1171: @*/
1172: PetscErrorCode TaoGetLineSearch(Tao tao, TaoLineSearch *ls)
1173: {
1175:   *ls = tao->linesearch;
1176:   return(0);
1177: }

1179: /*@
1180:   TaoAddLineSearchCounts - Adds the number of function evaluations spent
1181:   in the line search to the running total.

1183:    Input Parameters:
1184: +  tao - the TAO solver
1185: -  ls - the line search used in the optimization solver

1187:    Level: developer

1189: .seealso: TaoLineSearchApply()
1190: @*/
1191: PetscErrorCode TaoAddLineSearchCounts(Tao tao)
1192: {
1194:   PetscBool      flg;
1195:   PetscInt       nfeval,ngeval,nfgeval;

1199:   if (tao->linesearch) {
1200:     TaoLineSearchIsUsingTaoRoutines(tao->linesearch,&flg);
1201:     if (!flg) {
1202:       TaoLineSearchGetNumberFunctionEvaluations(tao->linesearch,&nfeval,&ngeval,&nfgeval);
1203:       tao->nfuncs+=nfeval;
1204:       tao->ngrads+=ngeval;
1205:       tao->nfuncgrads+=nfgeval;
1206:     }
1207:   }
1208:   return(0);
1209: }

1211: /*@
1212:   TaoGetSolutionVector - Returns the vector with the current TAO solution

1214:   Not Collective

1216:   Input Parameter:
1217: . tao - the Tao context

1219:   Output Parameter:
1220: . X - the current solution

1222:   Level: intermediate

1224:   Note:  The returned vector will be the same object that was passed into TaoSetInitialVector()
1225: @*/
1226: PetscErrorCode TaoGetSolutionVector(Tao tao, Vec *X)
1227: {
1230:   *X = tao->solution;
1231:   return(0);
1232: }

1234: /*@
1235:   TaoGetGradientVector - Returns the vector with the current TAO gradient

1237:   Not Collective

1239:   Input Parameter:
1240: . tao - the Tao context

1242:   Output Parameter:
1243: . G - the current solution

1245:   Level: intermediate
1246: @*/
1247: PetscErrorCode TaoGetGradientVector(Tao tao, Vec *G)
1248: {
1251:   *G = tao->gradient;
1252:   return(0);
1253: }

1255: /*@
1256:    TaoResetStatistics - Initialize the statistics used by TAO for all of the solvers.
1257:    These statistics include the iteration number, residual norms, and convergence status.
1258:    This routine gets called before solving each optimization problem.

1260:    Collective on Tao

1262:    Input Parameters:
1263: .  solver - the Tao context

1265:    Level: developer

1267: .seealso: TaoCreate(), TaoSolve()
1268: @*/
1269: PetscErrorCode TaoResetStatistics(Tao tao)
1270: {
1273:   tao->niter        = 0;
1274:   tao->nfuncs       = 0;
1275:   tao->nfuncgrads   = 0;
1276:   tao->ngrads       = 0;
1277:   tao->nhess        = 0;
1278:   tao->njac         = 0;
1279:   tao->nconstraints = 0;
1280:   tao->ksp_its      = 0;
1281:   tao->ksp_tot_its  = 0;
1282:   tao->reason       = TAO_CONTINUE_ITERATING;
1283:   tao->residual     = 0.0;
1284:   tao->cnorm        = 0.0;
1285:   tao->step         = 0.0;
1286:   tao->lsflag       = PETSC_FALSE;
1287:   if (tao->hist_reset) tao->hist_len=0;
1288:   return(0);
1289: }

1291: /*@C
1292:   TaoSetConvergenceTest - Sets the function that is to be used to test
1293:   for convergence o fthe iterative minimization solution.  The new convergence
1294:   testing routine will replace TAO's default convergence test.

1296:   Logically Collective on Tao

1298:   Input Parameters:
1299: + tao - the Tao object
1300: . conv - the routine to test for convergence
1301: - ctx - [optional] context for private data for the convergence routine
1302:         (may be NULL)

1304:   Calling sequence of conv:
1305: $   PetscErrorCode conv(Tao tao, void *ctx)

1307: + tao - the Tao object
1308: - ctx - [optional] convergence context

1310:   Note: The new convergence testing routine should call TaoSetConvergedReason().

1312:   Level: advanced

1314: .seealso: TaoSetConvergedReason(), TaoGetSolutionStatus(), TaoGetTolerances(), TaoSetMonitor

1316: @*/
1317: PetscErrorCode TaoSetConvergenceTest(Tao tao, PetscErrorCode (*conv)(Tao,void*), void *ctx)
1318: {
1321:   (tao)->ops->convergencetest = conv;
1322:   (tao)->cnvP = ctx;
1323:   return(0);
1324: }

1326: /*@C
1327:    TaoSetMonitor - Sets an ADDITIONAL function that is to be used at every
1328:    iteration of the solver to display the iteration's
1329:    progress.

1331:    Logically Collective on Tao

1333:    Input Parameters:
1334: +  tao - the Tao solver context
1335: .  mymonitor - monitoring routine
1336: -  mctx - [optional] user-defined context for private data for the
1337:           monitor routine (may be NULL)

1339:    Calling sequence of mymonitor:
1340: $     int mymonitor(Tao tao,void *mctx)

1342: +    tao - the Tao solver context
1343: -    mctx - [optional] monitoring context


1346:    Options Database Keys:
1347: +    -tao_monitor        - sets TaoDefaultMonitor()
1348: .    -tao_smonitor       - sets short monitor
1349: .    -tao_cmonitor       - same as smonitor plus constraint norm
1350: .    -tao_view_solution   - view solution at each iteration
1351: .    -tao_view_gradient   - view gradient at each iteration
1352: .    -tao_view_separableobjective - view separable objective function at each iteration
1353: -    -tao_cancelmonitors - cancels all monitors that have been hardwired into a code by calls to TaoSetMonitor(), but does not cancel those set via the options database.


1356:    Notes:
1357:    Several different monitoring routines may be set by calling
1358:    TaoSetMonitor() multiple times; all will be called in the
1359:    order in which they were set.

1361:    Fortran Notes: Only one monitor function may be set

1363:    Level: intermediate

1365: .seealso: TaoDefaultMonitor(), TaoCancelMonitors(),  TaoSetDestroyRoutine()
1366: @*/
1367: PetscErrorCode TaoSetMonitor(Tao tao, PetscErrorCode (*func)(Tao, void*), void *ctx,PetscErrorCode (*dest)(void**))
1368: {
1370:   PetscInt       i;

1374:   if (tao->numbermonitors >= MAXTAOMONITORS) SETERRQ1(PETSC_COMM_SELF,1,"Cannot attach another monitor -- max=",MAXTAOMONITORS);

1376:   for (i=0; i<tao->numbermonitors;i++) {
1377:     if (func == tao->monitor[i] && dest == tao->monitordestroy[i] && ctx == tao->monitorcontext[i]) {
1378:       if (dest) {
1379:         (*dest)(&ctx);
1380:       }
1381:       return(0);
1382:     }
1383:   }
1384:   tao->monitor[tao->numbermonitors] = func;
1385:   tao->monitorcontext[tao->numbermonitors] = ctx;
1386:   tao->monitordestroy[tao->numbermonitors] = dest;
1387:   ++tao->numbermonitors;
1388:   return(0);
1389: }

1391: /*@
1392:    TaoCancelMonitors - Clears all the monitor functions for a Tao object.

1394:    Logically Collective on Tao

1396:    Input Parameters:
1397: .  tao - the Tao solver context

1399:    Options Database:
1400: .  -tao_cancelmonitors - cancels all monitors that have been hardwired
1401:     into a code by calls to TaoSetMonitor(), but does not cancel those
1402:     set via the options database

1404:    Notes:
1405:    There is no way to clear one specific monitor from a Tao object.

1407:    Level: advanced

1409: .seealso: TaoDefaultMonitor(), TaoSetMonitor()
1410: @*/
1411: PetscErrorCode TaoCancelMonitors(Tao tao)
1412: {
1413:   PetscInt       i;

1418:   for (i=0;i<tao->numbermonitors;i++) {
1419:     if (tao->monitordestroy[i]) {
1420:       (*tao->monitordestroy[i])(&tao->monitorcontext[i]);
1421:     }
1422:   }
1423:   tao->numbermonitors=0;
1424:   return(0);
1425: }

1427: /*@
1428:    TaoDefaultMonitor - Default routine for monitoring progress of the
1429:    Tao solvers (default).  This monitor prints the function value and gradient
1430:    norm at each iteration.  It can be turned on from the command line using the
1431:    -tao_monitor option

1433:    Collective on Tao

1435:    Input Parameters:
1436: +  tao - the Tao context
1437: -  ctx - PetscViewer context or NULL

1439:    Options Database Keys:
1440: .  -tao_monitor

1442:    Level: advanced

1444: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1445: @*/
1446: PetscErrorCode TaoDefaultMonitor(Tao tao, void *ctx)
1447: {
1449:   PetscInt       its;
1450:   PetscReal      fct,gnorm;
1451:   PetscViewer    viewer = (PetscViewer)ctx;

1455:   its=tao->niter;
1456:   fct=tao->fc;
1457:   gnorm=tao->residual;
1458:   ierr=PetscViewerASCIIPrintf(viewer,"iter = %3D,",its);
1459:   ierr=PetscViewerASCIIPrintf(viewer," Function value: %g,",(double)fct);
1460:   if (gnorm >= PETSC_INFINITY) {
1461:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: Inf \n");
1462:   } else {
1463:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: %g \n",(double)gnorm);
1464:   }
1465:   return(0);
1466: }

1468: /*@
1469:    TaoDefaultSMonitor - Default routine for monitoring progress of the
1470:    solver. Same as TaoDefaultMonitor() except
1471:    it prints fewer digits of the residual as the residual gets smaller.
1472:    This is because the later digits are meaningless and are often
1473:    different on different machines; by using this routine different
1474:    machines will usually generate the same output. It can be turned on
1475:    by using the -tao_smonitor option

1477:    Collective on Tao

1479:    Input Parameters:
1480: +  tao - the Tao context
1481: -  ctx - PetscViewer context of type ASCII

1483:    Options Database Keys:
1484: .  -tao_smonitor

1486:    Level: advanced

1488: .seealso: TaoDefaultMonitor(), TaoSetMonitor()
1489: @*/
1490: PetscErrorCode TaoDefaultSMonitor(Tao tao, void *ctx)
1491: {
1493:   PetscInt       its;
1494:   PetscReal      fct,gnorm;
1495:   PetscViewer    viewer = (PetscViewer)ctx;

1499:   its=tao->niter;
1500:   fct=tao->fc;
1501:   gnorm=tao->residual;
1502:   ierr=PetscViewerASCIIPrintf(viewer,"iter = %3D,",its);
1503:   ierr=PetscViewerASCIIPrintf(viewer," Function value %g,",(double)fct);
1504:   if (gnorm >= PETSC_INFINITY) {
1505:     ierr=PetscViewerASCIIPrintf(viewer," Residual: Inf \n");
1506:   } else if (gnorm > 1.e-6) {
1507:     ierr=PetscViewerASCIIPrintf(viewer," Residual: %g \n",(double)gnorm);
1508:   } else if (gnorm > 1.e-11) {
1509:     ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-6 \n");
1510:   } else {
1511:     ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-11 \n");
1512:   }
1513:   return(0);
1514: }

1516: /*@
1517:    TaoDefaultCMonitor - same as TaoDefaultMonitor() except
1518:    it prints the norm of the constraints function. It can be turned on
1519:    from the command line using the -tao_cmonitor option

1521:    Collective on Tao

1523:    Input Parameters:
1524: +  tao - the Tao context
1525: -  ctx - PetscViewer context or NULL

1527:    Options Database Keys:
1528: .  -tao_cmonitor

1530:    Level: advanced

1532: .seealso: TaoDefaultMonitor(), TaoSetMonitor()
1533: @*/
1534: PetscErrorCode TaoDefaultCMonitor(Tao tao, void *ctx)
1535: {
1537:   PetscInt       its;
1538:   PetscReal      fct,gnorm;
1539:   PetscViewer    viewer = (PetscViewer)ctx;

1543:   its=tao->niter;
1544:   fct=tao->fc;
1545:   gnorm=tao->residual;
1546:   ierr=PetscViewerASCIIPrintf(viewer,"iter = %D,",its);
1547:   ierr=PetscViewerASCIIPrintf(viewer," Function value: %g,",(double)fct);
1548:   ierr=PetscViewerASCIIPrintf(viewer,"  Residual: %g ",(double)gnorm);
1549:   PetscViewerASCIIPrintf(viewer,"  Constraint: %g \n",(double)tao->cnorm);
1550:   return(0);
1551: }

1553: /*@C
1554:    TaoSolutionMonitor - Views the solution at each iteration
1555:    It can be turned on from the command line using the
1556:    -tao_view_solution option

1558:    Collective on Tao

1560:    Input Parameters:
1561: +  tao - the Tao context
1562: -  ctx - PetscViewer context or NULL

1564:    Options Database Keys:
1565: .  -tao_view_solution

1567:    Level: advanced

1569: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1570: @*/
1571: PetscErrorCode TaoSolutionMonitor(Tao tao, void *ctx)
1572: {
1574:   PetscViewer    viewer  = (PetscViewer)ctx;;

1578:   VecView(tao->solution, viewer);
1579:   return(0);
1580: }

1582: /*@C
1583:    TaoGradientMonitor - Views the gradient at each iteration
1584:    It can be turned on from the command line using the
1585:    -tao_view_gradient option

1587:    Collective on Tao

1589:    Input Parameters:
1590: +  tao - the Tao context
1591: -  ctx - PetscViewer context or NULL

1593:    Options Database Keys:
1594: .  -tao_view_gradient

1596:    Level: advanced

1598: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1599: @*/
1600: PetscErrorCode TaoGradientMonitor(Tao tao, void *ctx)
1601: {
1603:   PetscViewer    viewer = (PetscViewer)ctx;

1607:   VecView(tao->gradient, viewer);
1608:   return(0);
1609: }

1611: /*@C
1612:    TaoStepDirectionMonitor - Views the gradient at each iteration
1613:    It can be turned on from the command line using the
1614:    -tao_view_gradient option

1616:    Collective on Tao

1618:    Input Parameters:
1619: +  tao - the Tao context
1620: -  ctx - PetscViewer context or NULL

1622:    Options Database Keys:
1623: .  -tao_view_gradient

1625:    Level: advanced

1627: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1628: @*/
1629: PetscErrorCode TaoStepDirectionMonitor(Tao tao, void *ctx)
1630: {
1632:   PetscViewer    viewer = (PetscViewer)ctx;

1636:   VecView(tao->stepdirection, viewer);
1637:   return(0);
1638: }

1640: /*@C
1641:    TaoDrawSolutionMonitor - Plots the solution at each iteration
1642:    It can be turned on from the command line using the
1643:    -tao_draw_solution option

1645:    Collective on Tao

1647:    Input Parameters:
1648: +  tao - the Tao context
1649: -  ctx - TaoMonitorDraw context

1651:    Options Database Keys:
1652: .  -tao_draw_solution

1654:    Level: advanced

1656: .seealso: TaoSolutionMonitor(), TaoSetMonitor(), TaoDrawGradientMonitor
1657: @*/
1658: PetscErrorCode TaoDrawSolutionMonitor(Tao tao, void *ctx)
1659: {
1660:   PetscErrorCode    ierr;
1661:   TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;

1664:   if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return(0);
1665:   VecView(tao->solution,ictx->viewer);
1666:   return(0);
1667: }

1669: /*@C
1670:    TaoDrawGradientMonitor - Plots the gradient at each iteration
1671:    It can be turned on from the command line using the
1672:    -tao_draw_gradient option

1674:    Collective on Tao

1676:    Input Parameters:
1677: +  tao - the Tao context
1678: -  ctx - PetscViewer context

1680:    Options Database Keys:
1681: .  -tao_draw_gradient

1683:    Level: advanced

1685: .seealso: TaoGradientMonitor(), TaoSetMonitor(), TaoDrawSolutionMonitor
1686: @*/
1687: PetscErrorCode TaoDrawGradientMonitor(Tao tao, void *ctx)
1688: {
1689:   PetscErrorCode    ierr;
1690:   TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;

1693:   if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return(0);
1694:   VecView(tao->gradient,ictx->viewer);
1695:   return(0);
1696: }

1698: /*@C
1699:    TaoDrawStepMonitor - Plots the step direction at each iteration
1700:    It can be turned on from the command line using the
1701:    -tao_draw_step option

1703:    Collective on Tao

1705:    Input Parameters:
1706: +  tao - the Tao context
1707: -  ctx - PetscViewer context

1709:    Options Database Keys:
1710: .  -tao_draw_step

1712:    Level: advanced

1714: .seealso: TaoSetMonitor(), TaoDrawSolutionMonitor
1715: @*/
1716: PetscErrorCode TaoDrawStepMonitor(Tao tao, void *ctx)
1717: {
1719:   PetscViewer    viewer = (PetscViewer)(ctx);

1722:   VecView(tao->stepdirection, viewer);
1723:   return(0);
1724: }

1726: /*@C
1727:    TaoSeparableObjectiveMonitor - Views the separable objective function at each iteration
1728:    It can be turned on from the command line using the
1729:    -tao_view_separableobjective option

1731:    Collective on Tao

1733:    Input Parameters:
1734: +  tao - the Tao context
1735: -  ctx - PetscViewer context or NULL

1737:    Options Database Keys:
1738: .  -tao_view_separableobjective

1740:    Level: advanced

1742: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1743: @*/
1744: PetscErrorCode TaoSeparableObjectiveMonitor(Tao tao, void *ctx)
1745: {
1747:   PetscViewer    viewer  = (PetscViewer)ctx;

1751:   VecView(tao->sep_objective,viewer);
1752:   return(0);
1753: }

1755: /*@
1756:    TaoDefaultConvergenceTest - Determines whether the solver should continue iterating
1757:    or terminate.

1759:    Collective on Tao

1761:    Input Parameters:
1762: +  tao - the Tao context
1763: -  dummy - unused dummy context

1765:    Output Parameter:
1766: .  reason - for terminating

1768:    Notes:
1769:    This routine checks the residual in the optimality conditions, the
1770:    relative residual in the optimity conditions, the number of function
1771:    evaluations, and the function value to test convergence.  Some
1772:    solvers may use different convergence routines.

1774:    Level: developer

1776: .seealso: TaoSetTolerances(),TaoGetConvergedReason(),TaoSetConvergedReason()
1777: @*/

1779: PetscErrorCode TaoDefaultConvergenceTest(Tao tao,void *dummy)
1780: {
1781:   PetscInt           niter=tao->niter, nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
1782:   PetscInt           max_funcs=tao->max_funcs;
1783:   PetscReal          gnorm=tao->residual, gnorm0=tao->gnorm0;
1784:   PetscReal          f=tao->fc, steptol=tao->steptol,trradius=tao->step;
1785:   PetscReal          gatol=tao->gatol,grtol=tao->grtol,gttol=tao->gttol;
1786:   PetscReal          catol=tao->catol,crtol=tao->crtol;
1787:   PetscReal          fmin=tao->fmin, cnorm=tao->cnorm;
1788:   TaoConvergedReason reason=tao->reason;
1789:   PetscErrorCode     ierr;

1793:   if (reason != TAO_CONTINUE_ITERATING) {
1794:     return(0);
1795:   }

1797:   if (PetscIsInfOrNanReal(f)) {
1798:     PetscInfo(tao,"Failed to converged, function value is Inf or NaN\n");
1799:     reason = TAO_DIVERGED_NAN;
1800:   } else if (f <= fmin && cnorm <=catol) {
1801:     PetscInfo2(tao,"Converged due to function value %g < minimum function value %g\n", (double)f,(double)fmin);
1802:     reason = TAO_CONVERGED_MINF;
1803:   } else if (gnorm<= gatol && cnorm <=catol) {
1804:     PetscInfo2(tao,"Converged due to residual norm ||g(X)||=%g < %g\n",(double)gnorm,(double)gatol);
1805:     reason = TAO_CONVERGED_GATOL;
1806:   } else if ( f!=0 && PetscAbsReal(gnorm/f) <= grtol && cnorm <= crtol) {
1807:     PetscInfo2(tao,"Converged due to residual ||g(X)||/|f(X)| =%g < %g\n",(double)(gnorm/f),(double)grtol);
1808:     reason = TAO_CONVERGED_GRTOL;
1809:   } else if (gnorm0 != 0 && ((gttol == 0 && gnorm == 0) || gnorm/gnorm0 < gttol) && cnorm <= crtol) {
1810:     PetscInfo2(tao,"Converged due to relative residual norm ||g(X)||/||g(X0)|| = %g < %g\n",(double)(gnorm/gnorm0),(double)gttol);
1811:     reason = TAO_CONVERGED_GTTOL;
1812:   } else if (nfuncs > max_funcs){
1813:     PetscInfo2(tao,"Exceeded maximum number of function evaluations: %D > %D\n", nfuncs,max_funcs);
1814:     reason = TAO_DIVERGED_MAXFCN;
1815:   } else if ( tao->lsflag != 0 ){
1816:     PetscInfo(tao,"Tao Line Search failure.\n");
1817:     reason = TAO_DIVERGED_LS_FAILURE;
1818:   } else if (trradius < steptol && niter > 0){
1819:     PetscInfo2(tao,"Trust region/step size too small: %g < %g\n", (double)trradius,(double)steptol);
1820:     reason = TAO_CONVERGED_STEPTOL;
1821:   } else if (niter > tao->max_it) {
1822:     PetscInfo2(tao,"Exceeded maximum number of iterations: %D > %D\n",niter,tao->max_it);
1823:     reason = TAO_DIVERGED_MAXITS;
1824:   } else {
1825:     reason = TAO_CONTINUE_ITERATING;
1826:   }
1827:   tao->reason = reason;
1828:   return(0);
1829: }

1831: /*@C
1832:    TaoSetOptionsPrefix - Sets the prefix used for searching for all
1833:    TAO options in the database.


1836:    Logically Collective on Tao

1838:    Input Parameters:
1839: +  tao - the Tao context
1840: -  prefix - the prefix string to prepend to all TAO option requests

1842:    Notes:
1843:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1844:    The first character of all runtime options is AUTOMATICALLY the hyphen.

1846:    For example, to distinguish between the runtime options for two
1847:    different TAO solvers, one could call
1848: .vb
1849:       TaoSetOptionsPrefix(tao1,"sys1_")
1850:       TaoSetOptionsPrefix(tao2,"sys2_")
1851: .ve

1853:    This would enable use of different options for each system, such as
1854: .vb
1855:       -sys1_tao_method blmvm -sys1_tao_gtol 1.e-3
1856:       -sys2_tao_method lmvm  -sys2_tao_gtol 1.e-4
1857: .ve


1860:    Level: advanced

1862: .seealso: TaoAppendOptionsPrefix(), TaoGetOptionsPrefix()
1863: @*/

1865: PetscErrorCode TaoSetOptionsPrefix(Tao tao, const char p[])
1866: {

1870:   PetscObjectSetOptionsPrefix((PetscObject)tao,p);
1871:   if (tao->linesearch) {
1872:     TaoLineSearchSetOptionsPrefix(tao->linesearch,p);
1873:   }
1874:   if (tao->ksp) {
1875:     KSPSetOptionsPrefix(tao->ksp,p);
1876:   }
1877:   return(0);
1878: }

1880: /*@C
1881:    TaoAppendOptionsPrefix - Appends to the prefix used for searching for all
1882:    TAO options in the database.


1885:    Logically Collective on Tao

1887:    Input Parameters:
1888: +  tao - the Tao solver context
1889: -  prefix - the prefix string to prepend to all TAO option requests

1891:    Notes:
1892:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1893:    The first character of all runtime options is AUTOMATICALLY the hyphen.


1896:    Level: advanced

1898: .seealso: TaoSetOptionsPrefix(), TaoGetOptionsPrefix()
1899: @*/
1900: PetscErrorCode TaoAppendOptionsPrefix(Tao tao, const char p[])
1901: {

1905:   PetscObjectAppendOptionsPrefix((PetscObject)tao,p);
1906:   if (tao->linesearch) {
1907:     TaoLineSearchSetOptionsPrefix(tao->linesearch,p);
1908:   }
1909:   if (tao->ksp) {
1910:     KSPSetOptionsPrefix(tao->ksp,p);
1911:   }
1912:   return(0);
1913: }

1915: /*@C
1916:   TaoGetOptionsPrefix - Gets the prefix used for searching for all
1917:   TAO options in the database

1919:   Not Collective

1921:   Input Parameters:
1922: . tao - the Tao context

1924:   Output Parameters:
1925: . prefix - pointer to the prefix string used is returned

1927:   Notes: On the fortran side, the user should pass in a string 'prefix' of
1928:   sufficient length to hold the prefix.

1930:   Level: advanced

1932: .seealso: TaoSetOptionsPrefix(), TaoAppendOptionsPrefix()
1933: @*/
1934: PetscErrorCode TaoGetOptionsPrefix(Tao tao, const char *p[])
1935: {
1936:    return PetscObjectGetOptionsPrefix((PetscObject)tao,p);
1937: }

1939: /*@C
1940:    TaoSetType - Sets the method for the unconstrained minimization solver.

1942:    Collective on Tao

1944:    Input Parameters:
1945: +  solver - the Tao solver context
1946: -  type - a known method

1948:    Options Database Key:
1949: .  -tao_type <type> - Sets the method; use -help for a list
1950:    of available methods (for instance, "-tao_type lmvm" or "-tao_type tron")

1952:    Available methods include:
1953: +    nls - Newton's method with line search for unconstrained minimization
1954: .    ntr - Newton's method with trust region for unconstrained minimization
1955: .    ntl - Newton's method with trust region, line search for unconstrained minimization
1956: .    lmvm - Limited memory variable metric method for unconstrained minimization
1957: .    cg - Nonlinear conjugate gradient method for unconstrained minimization
1958: .    nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
1959: .    tron - Newton Trust Region method for bound constrained minimization
1960: .    gpcg - Newton Trust Region method for quadratic bound constrained minimization
1961: .    blmvm - Limited memory variable metric method for bound constrained minimization
1962: -    pounders - Model-based algorithm pounder extended for nonlinear least squares

1964:   Level: intermediate

1966: .seealso: TaoCreate(), TaoGetType(), TaoType

1968: @*/
1969: PetscErrorCode TaoSetType(Tao tao, const TaoType type)
1970: {
1972:   PetscErrorCode (*create_xxx)(Tao);
1973:   PetscBool      issame;


1978:   PetscObjectTypeCompare((PetscObject)tao,type,&issame);
1979:   if (issame) return(0);

1981:   PetscFunctionListFind(TaoList, type, (void(**)(void))&create_xxx);
1982:   if (!create_xxx) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Tao type %s",type);

1984:   /* Destroy the existing solver information */
1985:   if (tao->ops->destroy) {
1986:     (*tao->ops->destroy)(tao);
1987:   }
1988:   KSPDestroy(&tao->ksp);
1989:   TaoLineSearchDestroy(&tao->linesearch);
1990:   VecDestroy(&tao->gradient);
1991:   VecDestroy(&tao->stepdirection);

1993:   tao->ops->setup = 0;
1994:   tao->ops->solve = 0;
1995:   tao->ops->view  = 0;
1996:   tao->ops->setfromoptions = 0;
1997:   tao->ops->destroy = 0;

1999:   tao->setupcalled = PETSC_FALSE;

2001:   (*create_xxx)(tao);
2002:   PetscObjectChangeTypeName((PetscObject)tao,type);
2003:   return(0);
2004: }

2006: /*MC
2007:    TaoRegister - Adds a method to the TAO package for unconstrained minimization.

2009:    Synopsis:
2010:    TaoRegister(char *name_solver,char *path,char *name_Create,int (*routine_Create)(Tao))

2012:    Not collective

2014:    Input Parameters:
2015: +  sname - name of a new user-defined solver
2016: -  func - routine to Create method context

2018:    Notes:
2019:    TaoRegister() may be called multiple times to add several user-defined solvers.

2021:    Sample usage:
2022: .vb
2023:    TaoRegister("my_solver",MySolverCreate);
2024: .ve

2026:    Then, your solver can be chosen with the procedural interface via
2027: $     TaoSetType(tao,"my_solver")
2028:    or at runtime via the option
2029: $     -tao_type my_solver

2031:    Level: advanced

2033: .seealso: TaoRegisterAll(), TaoRegisterDestroy()
2034: M*/
2035: PetscErrorCode TaoRegister(const char sname[], PetscErrorCode (*func)(Tao))
2036: {

2040:   PetscFunctionListAdd(&TaoList,sname, (void (*)(void))func);
2041:   return(0);
2042: }

2044: /*@C
2045:    TaoRegisterDestroy - Frees the list of minimization solvers that were
2046:    registered by TaoRegisterDynamic().

2048:    Not Collective

2050:    Level: advanced

2052: .seealso: TaoRegisterAll(), TaoRegister()
2053: @*/
2054: PetscErrorCode TaoRegisterDestroy(void)
2055: {
2058:   PetscFunctionListDestroy(&TaoList);
2059:   TaoRegisterAllCalled = PETSC_FALSE;
2060:   return(0);
2061: }

2063: /*@
2064:    TaoGetIterationNumber - Gets the number of Tao iterations completed
2065:    at this time.

2067:    Not Collective

2069:    Input Parameter:
2070: .  tao - Tao context

2072:    Output Parameter:
2073: .  iter - iteration number

2075:    Notes:
2076:    For example, during the computation of iteration 2 this would return 1.


2079:    Level: intermediate

2081: .keywords: Tao, nonlinear, get, iteration, number,

2083: .seealso:   TaoGetLinearSolveIterations()
2084: @*/
2085: PetscErrorCode  TaoGetIterationNumber(Tao tao,PetscInt *iter)
2086: {
2090:   *iter = tao->niter;
2091:   return(0);
2092: }

2094: /*@
2095:    TaoSetIterationNumber - Sets the current iteration number.

2097:    Not Collective

2099:    Input Parameter:
2100: .  tao - Tao context
2101: .  iter - iteration number

2103:    Level: developer

2105: .keywords: Tao, nonlinear, set, iteration, number,

2107: .seealso:   TaoGetLinearSolveIterations()
2108: @*/
2109: PetscErrorCode  TaoSetIterationNumber(Tao tao,PetscInt iter)
2110: {

2115:   PetscObjectSAWsTakeAccess((PetscObject)tao);
2116:   tao->niter = iter;
2117:   PetscObjectSAWsGrantAccess((PetscObject)tao);
2118:   return(0);
2119: }

2121: /*@
2122:    TaoGetTotalIterationNumber - Gets the total number of Tao iterations
2123:    completed. This number keeps accumulating if multiple solves
2124:    are called with the Tao object.

2126:    Not Collective

2128:    Input Parameter:
2129: .  tao - Tao context

2131:    Output Parameter:
2132: .  iter - iteration number

2134:    Notes:
2135:    The total iteration count is updated after each solve, if there is a current
2136:    TaoSolve() in progress then those iterations are not yet counted.

2138:    Level: intermediate

2140: .keywords: Tao, nonlinear, get, iteration, number,

2142: .seealso:   TaoGetLinearSolveIterations()
2143: @*/
2144: PetscErrorCode  TaoGetTotalIterationNumber(Tao tao,PetscInt *iter)
2145: {
2149:   *iter = tao->ntotalits;
2150:   return(0);
2151: }

2153: /*@
2154:    TaoSetTotalIterationNumber - Sets the current total iteration number.

2156:    Not Collective

2158:    Input Parameter:
2159: .  tao - Tao context
2160: .  iter - iteration number

2162:    Level: developer

2164: .keywords: Tao, nonlinear, set, iteration, number,

2166: .seealso:   TaoGetLinearSolveIterations()
2167: @*/
2168: PetscErrorCode  TaoSetTotalIterationNumber(Tao tao,PetscInt iter)
2169: {

2174:   PetscObjectSAWsTakeAccess((PetscObject)tao);
2175:   tao->ntotalits = iter;
2176:   PetscObjectSAWsGrantAccess((PetscObject)tao);
2177:   return(0);
2178: }

2180: /*@
2181:   TaoSetConvergedReason - Sets the termination flag on a Tao object

2183:   Logically Collective on Tao

2185:   Input Parameters:
2186: + tao - the Tao context
2187: - reason - one of
2188: $     TAO_CONVERGED_ATOL (2),
2189: $     TAO_CONVERGED_RTOL (3),
2190: $     TAO_CONVERGED_STEPTOL (4),
2191: $     TAO_CONVERGED_MINF (5),
2192: $     TAO_CONVERGED_USER (6),
2193: $     TAO_DIVERGED_MAXITS (-2),
2194: $     TAO_DIVERGED_NAN (-4),
2195: $     TAO_DIVERGED_MAXFCN (-5),
2196: $     TAO_DIVERGED_LS_FAILURE (-6),
2197: $     TAO_DIVERGED_TR_REDUCTION (-7),
2198: $     TAO_DIVERGED_USER (-8),
2199: $     TAO_CONTINUE_ITERATING (0)

2201:    Level: intermediate

2203: @*/
2204: PetscErrorCode TaoSetConvergedReason(Tao tao, TaoConvergedReason reason)
2205: {
2208:   tao->reason = reason;
2209:   return(0);
2210: }

2212: /*@
2213:    TaoGetConvergedReason - Gets the reason the Tao iteration was stopped.

2215:    Not Collective

2217:    Input Parameter:
2218: .  tao - the Tao solver context

2220:    Output Parameter:
2221: .  reason - one of
2222: $  TAO_CONVERGED_GATOL (3)           ||g(X)|| < gatol
2223: $  TAO_CONVERGED_GRTOL (4)           ||g(X)|| / f(X)  < grtol
2224: $  TAO_CONVERGED_GTTOL (5)           ||g(X)|| / ||g(X0)|| < gttol
2225: $  TAO_CONVERGED_STEPTOL (6)         step size small
2226: $  TAO_CONVERGED_MINF (7)            F < F_min
2227: $  TAO_CONVERGED_USER (8)            User defined
2228: $  TAO_DIVERGED_MAXITS (-2)          its > maxits
2229: $  TAO_DIVERGED_NAN (-4)             Numerical problems
2230: $  TAO_DIVERGED_MAXFCN (-5)          fevals > max_funcsals
2231: $  TAO_DIVERGED_LS_FAILURE (-6)      line search failure
2232: $  TAO_DIVERGED_TR_REDUCTION (-7)    trust region failure
2233: $  TAO_DIVERGED_USER(-8)             (user defined)
2234:  $  TAO_CONTINUE_ITERATING (0)

2236:    where
2237: +  X - current solution
2238: .  X0 - initial guess
2239: .  f(X) - current function value
2240: .  f(X*) - true solution (estimated)
2241: .  g(X) - current gradient
2242: .  its - current iterate number
2243: .  maxits - maximum number of iterates
2244: .  fevals - number of function evaluations
2245: -  max_funcsals - maximum number of function evaluations

2247:    Level: intermediate

2249: .seealso: TaoSetConvergenceTest(), TaoSetTolerances()

2251: @*/
2252: PetscErrorCode TaoGetConvergedReason(Tao tao, TaoConvergedReason *reason)
2253: {
2257:   *reason = tao->reason;
2258:   return(0);
2259: }

2261: /*@
2262:   TaoGetSolutionStatus - Get the current iterate, objective value,
2263:   residual, infeasibility, and termination

2265:   Not Collective

2267:    Input Parameters:
2268: .  tao - the Tao context

2270:    Output Parameters:
2271: +  iterate - the current iterate number (>=0)
2272: .  f - the current function value
2273: .  gnorm - the square of the gradient norm, duality gap, or other measure indicating distance from optimality.
2274: .  cnorm - the infeasibility of the current solution with regard to the constraints.
2275: .  xdiff - the step length or trust region radius of the most recent iterate.
2276: -  reason - The termination reason, which can equal TAO_CONTINUE_ITERATING

2278:    Level: intermediate

2280:    Note:
2281:    TAO returns the values set by the solvers in the routine TaoMonitor().

2283:    Note:
2284:    If any of the output arguments are set to NULL, no corresponding value will be returned.

2286: .seealso: TaoMonitor(), TaoGetConvergedReason()
2287: @*/
2288: PetscErrorCode TaoGetSolutionStatus(Tao tao, PetscInt *its, PetscReal *f, PetscReal *gnorm, PetscReal *cnorm, PetscReal *xdiff, TaoConvergedReason *reason)
2289: {
2291:   if (its) *its=tao->niter;
2292:   if (f) *f=tao->fc;
2293:   if (gnorm) *gnorm=tao->residual;
2294:   if (cnorm) *cnorm=tao->cnorm;
2295:   if (reason) *reason=tao->reason;
2296:   if (xdiff) *xdiff=tao->step;
2297:   return(0);
2298: }

2300: /*@C
2301:    TaoGetType - Gets the current Tao algorithm.

2303:    Not Collective

2305:    Input Parameter:
2306: .  tao - the Tao solver context

2308:    Output Parameter:
2309: .  type - Tao method

2311:    Level: intermediate

2313: @*/
2314: PetscErrorCode TaoGetType(Tao tao, const TaoType *type)
2315: {
2319:   *type=((PetscObject)tao)->type_name;
2320:   return(0);
2321: }

2323: /*@C
2324:   TaoMonitor - Monitor the solver and the current solution.  This
2325:   routine will record the iteration number and residual statistics,
2326:   call any monitors specified by the user, and calls the convergence-check routine.

2328:    Input Parameters:
2329: +  tao - the Tao context
2330: .  its - the current iterate number (>=0)
2331: .  f - the current objective function value
2332: .  res - the gradient norm, square root of the duality gap, or other measure indicating distince from optimality.  This measure will be recorded and
2333:           used for some termination tests.
2334: .  cnorm - the infeasibility of the current solution with regard to the constraints.
2335: -  steplength - multiple of the step direction added to the previous iterate.

2337:    Output Parameters:
2338: .  reason - The termination reason, which can equal TAO_CONTINUE_ITERATING

2340:    Options Database Key:
2341: .  -tao_monitor - Use the default monitor, which prints statistics to standard output

2343: .seealso TaoGetConvergedReason(), TaoDefaultMonitor(), TaoSetMonitor()

2345:    Level: developer

2347: @*/
2348: PetscErrorCode TaoMonitor(Tao tao, PetscInt its, PetscReal f, PetscReal res, PetscReal cnorm, PetscReal steplength, TaoConvergedReason *reason)
2349: {
2351:   PetscInt       i;

2355:   tao->fc = f;
2356:   tao->residual = res;
2357:   tao->cnorm = cnorm;
2358:   tao->step = steplength;
2359:   if (!its) {
2360:     tao->cnorm0 = cnorm; tao->gnorm0 = res;
2361:   }
2362:   TaoLogConvergenceHistory(tao,f,res,cnorm,tao->ksp_its);
2363:   if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(res)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
2364:   if (tao->ops->convergencetest) {
2365:     (*tao->ops->convergencetest)(tao,tao->cnvP);
2366:   }
2367:   for (i=0;i<tao->numbermonitors;i++) {
2368:     (*tao->monitor[i])(tao,tao->monitorcontext[i]);
2369:   }
2370:   *reason = tao->reason;
2371:   return(0);
2372: }

2374: /*@
2375:    TaoSetConvergenceHistory - Sets the array used to hold the convergence history.

2377:    Logically Collective on Tao

2379:    Input Parameters:
2380: +  tao - the Tao solver context
2381: .  obj   - array to hold objective value history
2382: .  resid - array to hold residual history
2383: .  cnorm - array to hold constraint violation history
2384: .  lits - integer array holds the number of linear iterations for each Tao iteration
2385: .  na  - size of obj, resid, and cnorm
2386: -  reset - PetscTrue indicates each new minimization resets the history counter to zero,
2387:            else it continues storing new values for new minimizations after the old ones

2389:    Notes:
2390:    If set, TAO will fill the given arrays with the indicated
2391:    information at each iteration.  If 'obj','resid','cnorm','lits' are
2392:    *all* NULL then space (using size na, or 1000 if na is PETSC_DECIDE or
2393:    PETSC_DEFAULT) is allocated for the history.
2394:    If not all are NULL, then only the non-NULL information categories
2395:    will be stored, the others will be ignored.

2397:    Any convergence information after iteration number 'na' will not be stored.

2399:    This routine is useful, e.g., when running a code for purposes
2400:    of accurate performance monitoring, when no I/O should be done
2401:    during the section of code that is being timed.

2403:    Level: intermediate

2405: .seealso: TaoGetConvergenceHistory()

2407: @*/
2408: PetscErrorCode TaoSetConvergenceHistory(Tao tao, PetscReal obj[], PetscReal resid[], PetscReal cnorm[], PetscInt lits[], PetscInt na,PetscBool reset)
2409: {


2419:   if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2420:   if (!obj && !resid && !cnorm && !lits) {
2421:     PetscCalloc1(na,&obj);
2422:     PetscCalloc1(na,&resid);
2423:     PetscCalloc1(na,&cnorm);
2424:     PetscCalloc1(na,&lits);
2425:     tao->hist_malloc=PETSC_TRUE;
2426:   }

2428:   tao->hist_obj = obj;
2429:   tao->hist_resid = resid;
2430:   tao->hist_cnorm = cnorm;
2431:   tao->hist_lits = lits;
2432:   tao->hist_max   = na;
2433:   tao->hist_reset = reset;
2434:   tao->hist_len = 0;
2435:   return(0);
2436: }

2438: /*@C
2439:    TaoGetConvergenceHistory - Gets the arrays used to hold the convergence history.

2441:    Collective on Tao

2443:    Input Parameter:
2444: .  tao - the Tao context

2446:    Output Parameters:
2447: +  obj   - array used to hold objective value history
2448: .  resid - array used to hold residual history
2449: .  cnorm - array used to hold constraint violation history
2450: .  lits  - integer array used to hold linear solver iteration count
2451: -  nhist  - size of obj, resid, cnorm, and lits (will be less than or equal to na given in TaoSetHistory)

2453:    Notes:
2454:     This routine must be preceded by calls to TaoSetConvergenceHistory()
2455:     and TaoSolve(), otherwise it returns useless information.

2457:     The calling sequence for this routine in Fortran is
2458: $   call TaoGetConvergenceHistory(Tao tao, PetscInt nhist, PetscErrorCode ierr)

2460:    This routine is useful, e.g., when running a code for purposes
2461:    of accurate performance monitoring, when no I/O should be done
2462:    during the section of code that is being timed.

2464:    Level: advanced

2466: .seealso: TaoSetConvergenceHistory()

2468: @*/
2469: PetscErrorCode TaoGetConvergenceHistory(Tao tao, PetscReal **obj, PetscReal **resid, PetscReal **cnorm, PetscInt **lits, PetscInt *nhist)
2470: {
2473:   if (obj)   *obj   = tao->hist_obj;
2474:   if (cnorm) *cnorm = tao->hist_cnorm;
2475:   if (resid) *resid = tao->hist_resid;
2476:   if (nhist) *nhist   = tao->hist_len;
2477:   return(0);
2478: }

2480: /*@
2481:    TaoSetApplicationContext - Sets the optional user-defined context for
2482:    a solver.

2484:    Logically Collective on Tao

2486:    Input Parameters:
2487: +  tao  - the Tao context
2488: -  usrP - optional user context

2490:    Level: intermediate

2492: .seealso: TaoGetApplicationContext(), TaoSetApplicationContext()
2493: @*/
2494: PetscErrorCode  TaoSetApplicationContext(Tao tao,void *usrP)
2495: {
2498:   tao->user = usrP;
2499:   return(0);
2500: }

2502: /*@
2503:    TaoGetApplicationContext - Gets the user-defined context for a
2504:    TAO solvers.

2506:    Not Collective

2508:    Input Parameter:
2509: .  tao  - Tao context

2511:    Output Parameter:
2512: .  usrP - user context

2514:    Level: intermediate

2516: .seealso: TaoSetApplicationContext()
2517: @*/
2518: PetscErrorCode  TaoGetApplicationContext(Tao tao,void *usrP)
2519: {
2522:   *(void**)usrP = tao->user;
2523:   return(0);
2524: }

2526: /*@
2527:    TaoSetGradientNorm - Sets the matrix used to define the inner product that measures the size of the gradient.

2529:    Collective on tao

2531:    Input Parameters:
2532: +  tao  - the Tao context
2533: -  M    - gradient norm

2535:    Level: beginner

2537: .seealso: TaoGetGradientNorm(), TaoGradientNorm()
2538: @*/
2539: PetscErrorCode  TaoSetGradientNorm(Tao tao, Mat M)
2540: {


2546:   if (tao->gradient_norm) {
2547:     PetscObjectDereference((PetscObject)tao->gradient_norm);
2548:     VecDestroy(&tao->gradient_norm_tmp);
2549:   }

2551:   PetscObjectReference((PetscObject)M);
2552:   tao->gradient_norm = M;
2553:   MatCreateVecs(M, NULL, &tao->gradient_norm_tmp);
2554:   return(0);
2555: }

2557: /*@
2558:    TaoGetGradientNorm - Returns the matrix used to define the inner product for measuring the size of the gradient.

2560:    Not Collective

2562:    Input Parameter:
2563: .  tao  - Tao context

2565:    Output Parameter:
2566: .  M - gradient norm

2568:    Level: beginner

2570: .seealso: TaoSetGradientNorm(), TaoGradientNorm()
2571: @*/
2572: PetscErrorCode  TaoGetGradientNorm(Tao tao, Mat *M)
2573: {
2576:   *M = tao->gradient_norm;
2577:   return(0);
2578: }

2580: /*c
2581:    TaoGradientNorm - Compute the norm with respect to the inner product the user has set.

2583:    Collective on tao

2585:    Input Parameter:
2586: .  tao      - the Tao context
2587: .  gradient - the gradient to be computed
2588: .  norm     - the norm type

2590:    Output Parameter:
2591: .  gnorm    - the gradient norm

2593:    Level: developer

2595: .seealso: TaoSetGradientNorm(), TaoGetGradientNorm()
2596: @*/
2597: PetscErrorCode  TaoGradientNorm(Tao tao, Vec gradient, NormType type, PetscReal *gnorm)
2598: {


2604:   if (tao->gradient_norm) {
2605:     PetscScalar gnorms;

2607:     if (type != NORM_2) SETERRQ(PetscObjectComm((PetscObject)gradient), PETSC_ERR_ARG_WRONGSTATE, "Norm type must be NORM_2 if an inner product for the gradient norm is set.");
2608:     MatMult(tao->gradient_norm, gradient, tao->gradient_norm_tmp);
2609:     VecDot(gradient, tao->gradient_norm_tmp, &gnorms);
2610:     *gnorm = PetscRealPart(PetscSqrtScalar(gnorms));
2611:   } else {
2612:     VecNorm(gradient, type, gnorm);
2613:   }
2614:   return(0);
2615: }

2617: /*@C
2618:    TaoMonitorDrawCtxCreate - Creates the monitor context for TaoMonitorDrawCtx

2620:    Collective on Tao

2622:    Output Patameter:
2623: .    ctx - the monitor context

2625:    Options Database:
2626: .   -tao_draw_solution_initial - show initial guess as well as current solution

2628:    Level: intermediate

2630: .keywords: Tao,  vector, monitor, view

2632: .seealso: TaoMonitorSet(), TaoMonitorDefault(), VecView(), TaoMonitorDrawCtx()
2633: @*/
2634: PetscErrorCode  TaoMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TaoMonitorDrawCtx *ctx)
2635: {
2636:   PetscErrorCode   ierr;

2639:   PetscNew(ctx);
2640:   PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);
2641:   PetscViewerSetFromOptions((*ctx)->viewer);
2642:   (*ctx)->howoften = howoften;
2643:   return(0);
2644: }

2646: /*@C
2647:    TaoMonitorDrawCtxDestroy - Destroys the monitor context for TaoMonitorDrawSolution()

2649:    Collective on Tao

2651:    Input Parameters:
2652: .    ctx - the monitor context

2654:    Level: intermediate

2656: .keywords: Tao,  vector, monitor, view

2658: .seealso: TaoMonitorSet(), TaoMonitorDefault(), VecView(), TaoMonitorDrawSolution()
2659: @*/
2660: PetscErrorCode  TaoMonitorDrawCtxDestroy(TaoMonitorDrawCtx *ictx)
2661: {

2665:   PetscViewerDestroy(&(*ictx)->viewer);
2666:   PetscFree(*ictx);
2667:   return(0);
2668: }