Actual source code: taosolver.c
petsc-3.8.4 2018-03-24
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: }