Actual source code: taosolver.c
petsc-3.9.1 2018-04-29
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: VecViewFromOptions(tao->solution,(PetscObject)tao,"-tao_view_solution");
211: tao->ntotalits += tao->niter;
212: TaoViewFromOptions(tao,NULL,"-tao_view");
214: if (tao->printreason) {
215: if (tao->reason > 0) {
216: PetscPrintf(((PetscObject)tao)->comm,"TAO solve converged due to %s iterations %D\n",TaoConvergedReasons[tao->reason],tao->niter);
217: } else {
218: PetscPrintf(((PetscObject)tao)->comm,"TAO solve did not converge due to %s iteration %D\n",TaoConvergedReasons[tao->reason],tao->niter);
219: }
220: }
221: return(0);
222: }
224: /*@
225: TaoSetUp - Sets up the internal data structures for the later use
226: of a Tao solver
228: Collective on tao
230: Input Parameters:
231: . tao - the TAO context
233: Notes:
234: The user will not need to explicitly call TaoSetUp(), as it will
235: automatically be called in TaoSolve(). However, if the user
236: desires to call it explicitly, it should come after TaoCreate()
237: and any TaoSetSomething() routines, but before TaoSolve().
239: Level: advanced
241: .seealso: TaoCreate(), TaoSolve()
242: @*/
243: PetscErrorCode TaoSetUp(Tao tao)
244: {
249: if (tao->setupcalled) return(0);
251: if (!tao->solution) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetInitialVector");
252: if (tao->ops->setup) {
253: (*tao->ops->setup)(tao);
254: }
255: tao->setupcalled = PETSC_TRUE;
256: return(0);
257: }
259: /*@
260: TaoDestroy - Destroys the TAO context that was created with
261: TaoCreate()
263: Collective on Tao
265: Input Parameter:
266: . tao - the Tao context
268: Level: beginner
270: .seealso: TaoCreate(), TaoSolve()
271: @*/
272: PetscErrorCode TaoDestroy(Tao *tao)
273: {
277: if (!*tao) return(0);
279: if (--((PetscObject)*tao)->refct > 0) {*tao=0;return(0);}
281: if ((*tao)->ops->destroy) {
282: (*((*tao))->ops->destroy)(*tao);
283: }
284: KSPDestroy(&(*tao)->ksp);
285: TaoLineSearchDestroy(&(*tao)->linesearch);
287: if ((*tao)->ops->convergencedestroy) {
288: (*(*tao)->ops->convergencedestroy)((*tao)->cnvP);
289: if ((*tao)->jacobian_state_inv) {
290: MatDestroy(&(*tao)->jacobian_state_inv);
291: }
292: }
293: VecDestroy(&(*tao)->solution);
294: VecDestroy(&(*tao)->gradient);
296: if ((*tao)->gradient_norm) {
297: PetscObjectDereference((PetscObject)(*tao)->gradient_norm);
298: VecDestroy(&(*tao)->gradient_norm_tmp);
299: }
301: VecDestroy(&(*tao)->XL);
302: VecDestroy(&(*tao)->XU);
303: VecDestroy(&(*tao)->IL);
304: VecDestroy(&(*tao)->IU);
305: VecDestroy(&(*tao)->DE);
306: VecDestroy(&(*tao)->DI);
307: VecDestroy(&(*tao)->constraints_equality);
308: VecDestroy(&(*tao)->constraints_inequality);
309: VecDestroy(&(*tao)->stepdirection);
310: MatDestroy(&(*tao)->hessian_pre);
311: MatDestroy(&(*tao)->hessian);
312: MatDestroy(&(*tao)->jacobian_pre);
313: MatDestroy(&(*tao)->jacobian);
314: MatDestroy(&(*tao)->jacobian_state_pre);
315: MatDestroy(&(*tao)->jacobian_state);
316: MatDestroy(&(*tao)->jacobian_state_inv);
317: MatDestroy(&(*tao)->jacobian_design);
318: MatDestroy(&(*tao)->jacobian_equality);
319: MatDestroy(&(*tao)->jacobian_equality_pre);
320: MatDestroy(&(*tao)->jacobian_inequality);
321: MatDestroy(&(*tao)->jacobian_inequality_pre);
322: ISDestroy(&(*tao)->state_is);
323: ISDestroy(&(*tao)->design_is);
324: VecDestroy(&(*tao)->sep_weights_v);
325: TaoCancelMonitors(*tao);
326: if ((*tao)->hist_malloc) {
327: PetscFree((*tao)->hist_obj);
328: PetscFree((*tao)->hist_resid);
329: PetscFree((*tao)->hist_cnorm);
330: PetscFree((*tao)->hist_lits);
331: }
332: if ((*tao)->sep_weights_n) {
333: PetscFree((*tao)->sep_weights_rows);
334: PetscFree((*tao)->sep_weights_cols);
335: PetscFree((*tao)->sep_weights_w);
336: }
337: PetscHeaderDestroy(tao);
338: return(0);
339: }
341: /*@
342: TaoSetFromOptions - Sets various Tao parameters from user
343: options.
345: Collective on Tao
347: Input Paremeter:
348: . tao - the Tao solver context
350: options Database Keys:
351: + -tao_type <type> - The algorithm that TAO uses (lmvm, nls, etc.)
352: . -tao_gatol <gatol> - absolute error tolerance for ||gradient||
353: . -tao_grtol <grtol> - relative error tolerance for ||gradient||
354: . -tao_gttol <gttol> - reduction of ||gradient|| relative to initial gradient
355: . -tao_max_it <max> - sets maximum number of iterations
356: . -tao_max_funcs <max> - sets maximum number of function evaluations
357: . -tao_fmin <fmin> - stop if function value reaches fmin
358: . -tao_steptol <tol> - stop if trust region radius less than <tol>
359: . -tao_trust0 <t> - initial trust region radius
360: . -tao_monitor - prints function value and residual at each iteration
361: . -tao_smonitor - same as tao_monitor, but truncates very small values
362: . -tao_cmonitor - prints function value, residual, and constraint norm at each iteration
363: . -tao_view_solution - prints solution vector at each iteration
364: . -tao_view_separableobjective - prints separable objective vector at each iteration
365: . -tao_view_step - prints step direction vector at each iteration
366: . -tao_view_gradient - prints gradient vector at each iteration
367: . -tao_draw_solution - graphically view solution vector at each iteration
368: . -tao_draw_step - graphically view step vector at each iteration
369: . -tao_draw_gradient - graphically view gradient at each iteration
370: . -tao_fd_gradient - use gradient computed with finite differences
371: . -tao_fd_hessian - use hessian computed with finite differences
372: . -tao_mf_hessian - use matrix-free hessian computed with finite differences
373: . -tao_cancelmonitors - cancels all monitors (except those set with command line)
374: . -tao_view - prints information about the Tao after solving
375: - -tao_converged_reason - prints the reason TAO stopped iterating
377: Notes:
378: To see all options, run your program with the -help option or consult the
379: user's manual. Should be called after TaoCreate() but before TaoSolve()
381: Level: beginner
382: @*/
383: PetscErrorCode TaoSetFromOptions(Tao tao)
384: {
386: const TaoType default_type = TAOLMVM;
387: char type[256], monfilename[PETSC_MAX_PATH_LEN];
388: PetscViewer monviewer;
389: PetscBool flg;
390: MPI_Comm comm;
394: PetscObjectGetComm((PetscObject)tao,&comm);
396: /* So no warnings are given about unused options */
397: PetscOptionsHasName(((PetscObject)tao)->options,((PetscObject)tao)->prefix,"-tao_ls_type",&flg);
399: PetscObjectOptionsBegin((PetscObject)tao);
400: {
401: TaoRegisterAll();
402: if (((PetscObject)tao)->type_name) {
403: default_type = ((PetscObject)tao)->type_name;
404: }
405: /* Check for type from options */
406: PetscOptionsFList("-tao_type","Tao Solver type","TaoSetType",TaoList,default_type,type,256,&flg);
407: if (flg) {
408: TaoSetType(tao,type);
409: } else if (!((PetscObject)tao)->type_name) {
410: TaoSetType(tao,default_type);
411: }
413: PetscOptionsReal("-tao_catol","Stop if constraints violations within","TaoSetConstraintTolerances",tao->catol,&tao->catol,&flg);
414: if (flg) tao->catol_changed=PETSC_TRUE;
415: PetscOptionsReal("-tao_crtol","Stop if relative contraint violations within","TaoSetConstraintTolerances",tao->crtol,&tao->crtol,&flg);
416: if (flg) tao->crtol_changed=PETSC_TRUE;
417: PetscOptionsReal("-tao_gatol","Stop if norm of gradient less than","TaoSetTolerances",tao->gatol,&tao->gatol,&flg);
418: if (flg) tao->gatol_changed=PETSC_TRUE;
419: PetscOptionsReal("-tao_grtol","Stop if norm of gradient divided by the function value is less than","TaoSetTolerances",tao->grtol,&tao->grtol,&flg);
420: if (flg) tao->grtol_changed=PETSC_TRUE;
421: 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);
422: if (flg) tao->gttol_changed=PETSC_TRUE;
423: PetscOptionsInt("-tao_max_it","Stop if iteration number exceeds","TaoSetMaximumIterations",tao->max_it,&tao->max_it,&flg);
424: if (flg) tao->max_it_changed=PETSC_TRUE;
425: PetscOptionsInt("-tao_max_funcs","Stop if number of function evaluations exceeds","TaoSetMaximumFunctionEvaluations",tao->max_funcs,&tao->max_funcs,&flg);
426: if (flg) tao->max_funcs_changed=PETSC_TRUE;
427: PetscOptionsReal("-tao_fmin","Stop if function less than","TaoSetFunctionLowerBound",tao->fmin,&tao->fmin,&flg);
428: if (flg) tao->fmin_changed=PETSC_TRUE;
429: PetscOptionsReal("-tao_steptol","Stop if step size or trust region radius less than","",tao->steptol,&tao->steptol,&flg);
430: if (flg) tao->steptol_changed=PETSC_TRUE;
431: PetscOptionsReal("-tao_trust0","Initial trust region radius","TaoSetTrustRegionRadius",tao->trust0,&tao->trust0,&flg);
432: if (flg) tao->trust0_changed=PETSC_TRUE;
433: PetscOptionsString("-tao_view_solution","view solution vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
434: if (flg) {
435: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
436: TaoSetMonitor(tao,TaoSolutionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
437: }
439: PetscOptionsBool("-tao_converged_reason","Print reason for TAO converged","TaoSolve",tao->printreason,&tao->printreason,NULL);
440: PetscOptionsString("-tao_view_gradient","view gradient vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
441: if (flg) {
442: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
443: TaoSetMonitor(tao,TaoGradientMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
444: }
446: PetscOptionsString("-tao_view_stepdirection","view step direction vector after each iteration","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
447: if (flg) {
448: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
449: TaoSetMonitor(tao,TaoStepDirectionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
450: }
452: PetscOptionsString("-tao_view_separableobjective","view separable objective vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
453: if (flg) {
454: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
455: TaoSetMonitor(tao,TaoSeparableObjectiveMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
456: }
458: PetscOptionsString("-tao_monitor","Use the default convergence monitor","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
459: if (flg) {
460: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
461: TaoSetMonitor(tao,TaoMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
462: }
464: PetscOptionsString("-tao_smonitor","Use the short convergence monitor","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
465: if (flg) {
466: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
467: TaoSetMonitor(tao,TaoDefaultSMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
468: }
470: PetscOptionsString("-tao_cmonitor","Use the default convergence monitor with constraint norm","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
471: if (flg) {
472: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
473: TaoSetMonitor(tao,TaoDefaultCMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
474: }
477: flg = PETSC_FALSE;
478: PetscOptionsBool("-tao_cancelmonitors","cancel all monitors and call any registered destroy routines","TaoCancelMonitors",flg,&flg,NULL);
479: if (flg) {TaoCancelMonitors(tao);}
481: flg = PETSC_FALSE;
482: PetscOptionsBool("-tao_draw_solution","Plot solution vector at each iteration","TaoSetMonitor",flg,&flg,NULL);
483: if (flg) {
484: TaoMonitorDrawCtx drawctx;
485: PetscInt howoften = 1;
486: TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx);
487: TaoSetMonitor(tao,TaoDrawSolutionMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy);
488: }
490: flg = PETSC_FALSE;
491: PetscOptionsBool("-tao_draw_step","plots step direction at each iteration","TaoSetMonitor",flg,&flg,NULL);
492: if (flg) {
493: TaoSetMonitor(tao,TaoDrawStepMonitor,NULL,NULL);
494: }
496: flg = PETSC_FALSE;
497: PetscOptionsBool("-tao_draw_gradient","plots gradient at each iteration","TaoSetMonitor",flg,&flg,NULL);
498: if (flg) {
499: TaoMonitorDrawCtx drawctx;
500: PetscInt howoften = 1;
501: TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx);
502: TaoSetMonitor(tao,TaoDrawGradientMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy);
503: }
504: flg = PETSC_FALSE;
505: PetscOptionsBool("-tao_fd_gradient","compute gradient using finite differences","TaoDefaultComputeGradient",flg,&flg,NULL);
506: if (flg) {
507: TaoSetGradientRoutine(tao,TaoDefaultComputeGradient,NULL);
508: }
509: flg = PETSC_FALSE;
510: PetscOptionsBool("-tao_fd_hessian","compute hessian using finite differences","TaoDefaultComputeHessian",flg,&flg,NULL);
511: if (flg) {
512: Mat H;
514: MatCreate(PetscObjectComm((PetscObject)tao),&H);
515: MatSetType(H,MATAIJ);
516: TaoSetHessianRoutine(tao,H,H,TaoDefaultComputeHessian,NULL);
517: MatDestroy(&H);
518: }
519: flg = PETSC_FALSE;
520: PetscOptionsBool("-tao_mf_hessian","compute matrix-free hessian using finite differences","TaoDefaultComputeHessianMFFD",flg,&flg,NULL);
521: if (flg) {
522: Mat H;
524: MatCreate(PetscObjectComm((PetscObject)tao),&H);
525: TaoSetHessianRoutine(tao,H,H,TaoDefaultComputeHessianMFFD,NULL);
526: MatDestroy(&H);
527: }
528: PetscOptionsEnum("-tao_subset_type","subset type","",TaoSubSetTypes,(PetscEnum)tao->subset_type,(PetscEnum*)&tao->subset_type,NULL);
530: if (tao->ops->setfromoptions) {
531: (*tao->ops->setfromoptions)(PetscOptionsObject,tao);
532: }
533: }
534: PetscOptionsEnd();
535: return(0);
536: }
538: /*@C
539: TaoView - Prints information about the Tao
541: Collective on Tao
543: InputParameters:
544: + tao - the Tao context
545: - viewer - visualization context
547: Options Database Key:
548: . -tao_view - Calls TaoView() at the end of TaoSolve()
550: Notes:
551: The available visualization contexts include
552: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
553: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
554: output where only the first processor opens
555: the file. All other processors send their
556: data to the first processor to print.
558: Level: beginner
560: .seealso: PetscViewerASCIIOpen()
561: @*/
562: PetscErrorCode TaoView(Tao tao, PetscViewer viewer)
563: {
564: PetscErrorCode ierr;
565: PetscBool isascii,isstring;
566: const TaoType type;
570: if (!viewer) {
571: PetscViewerASCIIGetStdout(((PetscObject)tao)->comm,&viewer);
572: }
576: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
577: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
578: if (isascii) {
579: PetscInt tabs;
580: PetscViewerASCIIGetTab(viewer, &tabs);
581: PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
582: PetscObjectPrintClassNamePrefixType((PetscObject)tao,viewer);
584: if (tao->ops->view) {
585: PetscViewerASCIIPushTab(viewer);
586: (*tao->ops->view)(tao,viewer);
587: PetscViewerASCIIPopTab(viewer);
588: }
589: if (tao->linesearch) {
590: TaoLineSearchView(tao->linesearch,viewer);
591: }
592: if (tao->ksp) {
593: KSPView(tao->ksp,viewer);
594: PetscViewerASCIIPushTab(viewer);
595: PetscViewerASCIIPrintf(viewer,"total KSP iterations: %D\n",tao->ksp_tot_its);
596: PetscViewerASCIIPopTab(viewer);
597: }
599: PetscViewerASCIIPushTab(viewer);
601: if (tao->XL || tao->XU) {
602: PetscViewerASCIIPrintf(viewer,"Active Set subset type: %s\n",TaoSubSetTypes[tao->subset_type]);
603: }
605: PetscViewerASCIIPrintf(viewer,"convergence tolerances: gatol=%g,",(double)tao->gatol);
606: PetscViewerASCIIPrintf(viewer," steptol=%g,",(double)tao->steptol);
607: PetscViewerASCIIPrintf(viewer," gttol=%g\n",(double)tao->gttol);
608: PetscViewerASCIIPrintf(viewer,"Residual in Function/Gradient:=%g\n",(double)tao->residual);
610: if (tao->cnorm>0 || tao->catol>0 || tao->crtol>0){
611: ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances:");
612: ierr=PetscViewerASCIIPrintf(viewer," catol=%g,",(double)tao->catol);
613: ierr=PetscViewerASCIIPrintf(viewer," crtol=%g\n",(double)tao->crtol);
614: PetscViewerASCIIPrintf(viewer,"Residual in Constraints:=%g\n",(double)tao->cnorm);
615: }
617: if (tao->trust < tao->steptol){
618: ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: steptol=%g\n",(double)tao->steptol);
619: ierr=PetscViewerASCIIPrintf(viewer,"Final trust region radius:=%g\n",(double)tao->trust);
620: }
622: if (tao->fmin>-1.e25){
623: ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: function minimum=%g\n",(double)tao->fmin);
624: }
625: PetscViewerASCIIPrintf(viewer,"Objective value=%g\n",(double)tao->fc);
627: PetscViewerASCIIPrintf(viewer,"total number of iterations=%D, ",tao->niter);
628: PetscViewerASCIIPrintf(viewer," (max: %D)\n",tao->max_it);
630: if (tao->nfuncs>0){
631: PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%D,",tao->nfuncs);
632: PetscViewerASCIIPrintf(viewer," max: %D\n",tao->max_funcs);
633: }
634: if (tao->ngrads>0){
635: PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%D,",tao->ngrads);
636: PetscViewerASCIIPrintf(viewer," max: %D\n",tao->max_funcs);
637: }
638: if (tao->nfuncgrads>0){
639: PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%D,",tao->nfuncgrads);
640: PetscViewerASCIIPrintf(viewer," (max: %D)\n",tao->max_funcs);
641: }
642: if (tao->nhess>0){
643: PetscViewerASCIIPrintf(viewer,"total number of Hessian evaluations=%D\n",tao->nhess);
644: }
645: /* if (tao->linear_its>0){
646: PetscViewerASCIIPrintf(viewer," total Krylov method iterations=%D\n",tao->linear_its);
647: }*/
648: if (tao->nconstraints>0){
649: PetscViewerASCIIPrintf(viewer,"total number of constraint function evaluations=%D\n",tao->nconstraints);
650: }
651: if (tao->njac>0){
652: PetscViewerASCIIPrintf(viewer,"total number of Jacobian evaluations=%D\n",tao->njac);
653: }
655: if (tao->reason>0){
656: PetscViewerASCIIPrintf(viewer, "Solution converged: ");
657: switch (tao->reason) {
658: case TAO_CONVERGED_GATOL:
659: PetscViewerASCIIPrintf(viewer," ||g(X)|| <= gatol\n");
660: break;
661: case TAO_CONVERGED_GRTOL:
662: PetscViewerASCIIPrintf(viewer," ||g(X)||/|f(X)| <= grtol\n");
663: break;
664: case TAO_CONVERGED_GTTOL:
665: PetscViewerASCIIPrintf(viewer," ||g(X)||/||g(X0)|| <= gttol\n");
666: break;
667: case TAO_CONVERGED_STEPTOL:
668: PetscViewerASCIIPrintf(viewer," Steptol -- step size small\n");
669: break;
670: case TAO_CONVERGED_MINF:
671: PetscViewerASCIIPrintf(viewer," Minf -- f < fmin\n");
672: break;
673: case TAO_CONVERGED_USER:
674: PetscViewerASCIIPrintf(viewer," User Terminated\n");
675: break;
676: default:
677: PetscViewerASCIIPrintf(viewer,"\n");
678: break;
679: }
681: } else {
682: PetscViewerASCIIPrintf(viewer,"Solver terminated: %d",tao->reason);
683: switch (tao->reason) {
684: case TAO_DIVERGED_MAXITS:
685: PetscViewerASCIIPrintf(viewer," Maximum Iterations\n");
686: break;
687: case TAO_DIVERGED_NAN:
688: PetscViewerASCIIPrintf(viewer," NAN or Inf encountered\n");
689: break;
690: case TAO_DIVERGED_MAXFCN:
691: PetscViewerASCIIPrintf(viewer," Maximum Function Evaluations\n");
692: break;
693: case TAO_DIVERGED_LS_FAILURE:
694: PetscViewerASCIIPrintf(viewer," Line Search Failure\n");
695: break;
696: case TAO_DIVERGED_TR_REDUCTION:
697: PetscViewerASCIIPrintf(viewer," Trust Region too small\n");
698: break;
699: case TAO_DIVERGED_USER:
700: PetscViewerASCIIPrintf(viewer," User Terminated\n");
701: break;
702: default:
703: PetscViewerASCIIPrintf(viewer,"\n");
704: break;
705: }
706: }
707: PetscViewerASCIIPopTab(viewer);
708: PetscViewerASCIISetTab(viewer, tabs);
709: } else if (isstring) {
710: TaoGetType(tao,&type);
711: PetscViewerStringSPrintf(viewer," %-3.3s",type);
712: }
713: return(0);
714: }
716: /*@
717: TaoSetTolerances - Sets parameters used in TAO convergence tests
719: Logically collective on Tao
721: Input Parameters:
722: + tao - the Tao context
723: . gatol - stop if norm of gradient is less than this
724: . grtol - stop if relative norm of gradient is less than this
725: - gttol - stop if norm of gradient is reduced by this factor
727: Options Database Keys:
728: + -tao_gatol <gatol> - Sets gatol
729: . -tao_grtol <grtol> - Sets grtol
730: - -tao_gttol <gttol> - Sets gttol
732: Stopping Criteria:
733: $ ||g(X)|| <= gatol
734: $ ||g(X)|| / |f(X)| <= grtol
735: $ ||g(X)|| / ||g(X0)|| <= gttol
737: Notes:
738: Use PETSC_DEFAULT to leave one or more tolerances unchanged.
740: Level: beginner
742: .seealso: TaoGetTolerances()
744: @*/
745: PetscErrorCode TaoSetTolerances(Tao tao, PetscReal gatol, PetscReal grtol, PetscReal gttol)
746: {
752: if (gatol != PETSC_DEFAULT) {
753: if (gatol<0) {
754: PetscInfo(tao,"Tried to set negative gatol -- ignored.\n");
755: } else {
756: tao->gatol = PetscMax(0,gatol);
757: tao->gatol_changed=PETSC_TRUE;
758: }
759: }
761: if (grtol != PETSC_DEFAULT) {
762: if (grtol<0) {
763: PetscInfo(tao,"Tried to set negative grtol -- ignored.\n");
764: } else {
765: tao->grtol = PetscMax(0,grtol);
766: tao->grtol_changed=PETSC_TRUE;
767: }
768: }
770: if (gttol != PETSC_DEFAULT) {
771: if (gttol<0) {
772: PetscInfo(tao,"Tried to set negative gttol -- ignored.\n");
773: } else {
774: tao->gttol = PetscMax(0,gttol);
775: tao->gttol_changed=PETSC_TRUE;
776: }
777: }
778: return(0);
779: }
781: /*@
782: TaoSetConstraintTolerances - Sets constraint tolerance parameters used in TAO convergence tests
784: Logically collective on Tao
786: Input Parameters:
787: + tao - the Tao context
788: . catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
789: - crtol - relative contraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria
791: Options Database Keys:
792: + -tao_catol <catol> - Sets catol
793: - -tao_crtol <crtol> - Sets crtol
795: Notes:
796: Use PETSC_DEFAULT to leave any tolerance unchanged.
798: Level: intermediate
800: .seealso: TaoGetTolerances(), TaoGetConstraintTolerances(), TaoSetTolerances()
802: @*/
803: PetscErrorCode TaoSetConstraintTolerances(Tao tao, PetscReal catol, PetscReal crtol)
804: {
810: if (catol != PETSC_DEFAULT) {
811: if (catol<0) {
812: PetscInfo(tao,"Tried to set negative catol -- ignored.\n");
813: } else {
814: tao->catol = PetscMax(0,catol);
815: tao->catol_changed=PETSC_TRUE;
816: }
817: }
819: if (crtol != PETSC_DEFAULT) {
820: if (crtol<0) {
821: PetscInfo(tao,"Tried to set negative crtol -- ignored.\n");
822: } else {
823: tao->crtol = PetscMax(0,crtol);
824: tao->crtol_changed=PETSC_TRUE;
825: }
826: }
827: return(0);
828: }
830: /*@
831: TaoGetConstraintTolerances - Gets constraint tolerance parameters used in TAO convergence tests
833: Not ollective
835: Input Parameter:
836: . tao - the Tao context
838: Output Parameter:
839: + catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
840: - crtol - relative contraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria
842: Level: intermediate
844: .seealso: TaoGetTolerances(), TaoSetTolerances(), TaoSetConstraintTolerances()
846: @*/
847: PetscErrorCode TaoGetConstraintTolerances(Tao tao, PetscReal *catol, PetscReal *crtol)
848: {
851: if (catol) *catol = tao->catol;
852: if (crtol) *crtol = tao->crtol;
853: return(0);
854: }
856: /*@
857: TaoSetFunctionLowerBound - Sets a bound on the solution objective value.
858: When an approximate solution with an objective value below this number
859: has been found, the solver will terminate.
861: Logically Collective on Tao
863: Input Parameters:
864: + tao - the Tao solver context
865: - fmin - the tolerance
867: Options Database Keys:
868: . -tao_fmin <fmin> - sets the minimum function value
870: Level: intermediate
872: .seealso: TaoSetTolerances()
873: @*/
874: PetscErrorCode TaoSetFunctionLowerBound(Tao tao,PetscReal fmin)
875: {
878: tao->fmin = fmin;
879: tao->fmin_changed=PETSC_TRUE;
880: return(0);
881: }
883: /*@
884: TaoGetFunctionLowerBound - Gets the bound on the solution objective value.
885: When an approximate solution with an objective value below this number
886: has been found, the solver will terminate.
888: Not collective on Tao
890: Input Parameters:
891: . tao - the Tao solver context
893: OutputParameters:
894: . fmin - the minimum function value
896: Level: intermediate
898: .seealso: TaoSetFunctionLowerBound()
899: @*/
900: PetscErrorCode TaoGetFunctionLowerBound(Tao tao,PetscReal *fmin)
901: {
904: *fmin = tao->fmin;
905: return(0);
906: }
908: /*@
909: TaoSetMaximumFunctionEvaluations - Sets a maximum number of
910: function evaluations.
912: Logically Collective on Tao
914: Input Parameters:
915: + tao - the Tao solver context
916: - nfcn - the maximum number of function evaluations (>=0)
918: Options Database Keys:
919: . -tao_max_funcs <nfcn> - sets the maximum number of function evaluations
921: Level: intermediate
923: .seealso: TaoSetTolerances(), TaoSetMaximumIterations()
924: @*/
926: PetscErrorCode TaoSetMaximumFunctionEvaluations(Tao tao,PetscInt nfcn)
927: {
930: tao->max_funcs = PetscMax(0,nfcn);
931: tao->max_funcs_changed=PETSC_TRUE;
932: return(0);
933: }
935: /*@
936: TaoGetMaximumFunctionEvaluations - Sets a maximum number of
937: function evaluations.
939: Not Collective
941: Input Parameters:
942: . tao - the Tao solver context
944: Output Parameters:
945: . nfcn - the maximum number of function evaluations
947: Level: intermediate
949: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
950: @*/
952: PetscErrorCode TaoGetMaximumFunctionEvaluations(Tao tao,PetscInt *nfcn)
953: {
956: *nfcn = tao->max_funcs;
957: return(0);
958: }
960: /*@
961: TaoGetCurrentFunctionEvaluations - Get current number of
962: function evaluations.
964: Not Collective
966: Input Parameters:
967: . tao - the Tao solver context
969: Output Parameters:
970: . nfuncs - the current number of function evaluations
972: Level: intermediate
974: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
975: @*/
977: PetscErrorCode TaoGetCurrentFunctionEvaluations(Tao tao,PetscInt *nfuncs)
978: {
981: *nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
982: return(0);
983: }
985: /*@
986: TaoSetMaximumIterations - Sets a maximum number of iterates.
988: Logically Collective on Tao
990: Input Parameters:
991: + tao - the Tao solver context
992: - maxits - the maximum number of iterates (>=0)
994: Options Database Keys:
995: . -tao_max_it <its> - sets the maximum number of iterations
997: Level: intermediate
999: .seealso: TaoSetTolerances(), TaoSetMaximumFunctionEvaluations()
1000: @*/
1001: PetscErrorCode TaoSetMaximumIterations(Tao tao,PetscInt maxits)
1002: {
1005: tao->max_it = PetscMax(0,maxits);
1006: tao->max_it_changed=PETSC_TRUE;
1007: return(0);
1008: }
1010: /*@
1011: TaoGetMaximumIterations - Sets a maximum number of iterates.
1013: Not Collective
1015: Input Parameters:
1016: . tao - the Tao solver context
1018: Output Parameters:
1019: . maxits - the maximum number of iterates
1021: Level: intermediate
1023: .seealso: TaoSetMaximumIterations(), TaoGetMaximumFunctionEvaluations()
1024: @*/
1025: PetscErrorCode TaoGetMaximumIterations(Tao tao,PetscInt *maxits)
1026: {
1029: *maxits = tao->max_it;
1030: return(0);
1031: }
1033: /*@
1034: TaoSetInitialTrustRegionRadius - Sets the initial trust region radius.
1036: Logically collective on Tao
1038: Input Parameter:
1039: + tao - a TAO optimization solver
1040: - radius - the trust region radius
1042: Level: intermediate
1044: Options Database Key:
1045: . -tao_trust0 <t0> - sets initial trust region radius
1047: .seealso: TaoGetTrustRegionRadius(), TaoSetTrustRegionTolerance()
1048: @*/
1049: PetscErrorCode TaoSetInitialTrustRegionRadius(Tao tao, PetscReal radius)
1050: {
1053: tao->trust0 = PetscMax(0.0,radius);
1054: tao->trust0_changed=PETSC_TRUE;
1055: return(0);
1056: }
1058: /*@
1059: TaoGetInitialTrustRegionRadius - Sets the initial trust region radius.
1061: Not Collective
1063: Input Parameter:
1064: . tao - a TAO optimization solver
1066: Output Parameter:
1067: . radius - the trust region radius
1069: Level: intermediate
1071: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetCurrentTrustRegionRadius()
1072: @*/
1073: PetscErrorCode TaoGetInitialTrustRegionRadius(Tao tao, PetscReal *radius)
1074: {
1077: *radius = tao->trust0;
1078: return(0);
1079: }
1081: /*@
1082: TaoGetCurrentTrustRegionRadius - Gets the current trust region radius.
1084: Not Collective
1086: Input Parameter:
1087: . tao - a TAO optimization solver
1089: Output Parameter:
1090: . radius - the trust region radius
1092: Level: intermediate
1094: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetInitialTrustRegionRadius()
1095: @*/
1096: PetscErrorCode TaoGetCurrentTrustRegionRadius(Tao tao, PetscReal *radius)
1097: {
1100: *radius = tao->trust;
1101: return(0);
1102: }
1104: /*@
1105: TaoGetTolerances - gets the current values of tolerances
1107: Not Collective
1109: Input Parameters:
1110: . tao - the Tao context
1112: Output Parameters:
1113: + gatol - stop if norm of gradient is less than this
1114: . grtol - stop if relative norm of gradient is less than this
1115: - gttol - stop if norm of gradient is reduced by a this factor
1117: Note: NULL can be used as an argument if not all tolerances values are needed
1119: .seealso TaoSetTolerances()
1121: Level: intermediate
1122: @*/
1123: PetscErrorCode TaoGetTolerances(Tao tao, PetscReal *gatol, PetscReal *grtol, PetscReal *gttol)
1124: {
1127: if (gatol) *gatol=tao->gatol;
1128: if (grtol) *grtol=tao->grtol;
1129: if (gttol) *gttol=tao->gttol;
1130: return(0);
1131: }
1133: /*@
1134: TaoGetKSP - Gets the linear solver used by the optimization solver.
1135: Application writers should use TaoGetKSP if they need direct access
1136: to the PETSc KSP object.
1138: Not Collective
1140: Input Parameters:
1141: . tao - the TAO solver
1143: Output Parameters:
1144: . ksp - the KSP linear solver used in the optimization solver
1146: Level: intermediate
1148: @*/
1149: PetscErrorCode TaoGetKSP(Tao tao, KSP *ksp)
1150: {
1152: *ksp = tao->ksp;
1153: return(0);
1154: }
1156: /*@
1157: TaoGetLinearSolveIterations - Gets the total number of linear iterations
1158: used by the TAO solver
1160: Not Collective
1162: Input Parameter:
1163: . tao - TAO context
1165: Output Parameter:
1166: . lits - number of linear iterations
1168: Notes:
1169: This counter is reset to zero for each successive call to TaoSolve()
1171: Level: intermediate
1173: .keywords: TAO
1175: .seealso: TaoGetKSP()
1176: @*/
1177: PetscErrorCode TaoGetLinearSolveIterations(Tao tao,PetscInt *lits)
1178: {
1182: *lits = tao->ksp_tot_its;
1183: return(0);
1184: }
1186: /*@
1187: TaoGetLineSearch - Gets the line search used by the optimization solver.
1188: Application writers should use TaoGetLineSearch if they need direct access
1189: to the TaoLineSearch object.
1191: Not Collective
1193: Input Parameters:
1194: . tao - the TAO solver
1196: Output Parameters:
1197: . ls - the line search used in the optimization solver
1199: Level: intermediate
1201: @*/
1202: PetscErrorCode TaoGetLineSearch(Tao tao, TaoLineSearch *ls)
1203: {
1205: *ls = tao->linesearch;
1206: return(0);
1207: }
1209: /*@
1210: TaoAddLineSearchCounts - Adds the number of function evaluations spent
1211: in the line search to the running total.
1213: Input Parameters:
1214: + tao - the TAO solver
1215: - ls - the line search used in the optimization solver
1217: Level: developer
1219: .seealso: TaoLineSearchApply()
1220: @*/
1221: PetscErrorCode TaoAddLineSearchCounts(Tao tao)
1222: {
1224: PetscBool flg;
1225: PetscInt nfeval,ngeval,nfgeval;
1229: if (tao->linesearch) {
1230: TaoLineSearchIsUsingTaoRoutines(tao->linesearch,&flg);
1231: if (!flg) {
1232: TaoLineSearchGetNumberFunctionEvaluations(tao->linesearch,&nfeval,&ngeval,&nfgeval);
1233: tao->nfuncs+=nfeval;
1234: tao->ngrads+=ngeval;
1235: tao->nfuncgrads+=nfgeval;
1236: }
1237: }
1238: return(0);
1239: }
1241: /*@
1242: TaoGetSolutionVector - Returns the vector with the current TAO solution
1244: Not Collective
1246: Input Parameter:
1247: . tao - the Tao context
1249: Output Parameter:
1250: . X - the current solution
1252: Level: intermediate
1254: Note: The returned vector will be the same object that was passed into TaoSetInitialVector()
1255: @*/
1256: PetscErrorCode TaoGetSolutionVector(Tao tao, Vec *X)
1257: {
1260: *X = tao->solution;
1261: return(0);
1262: }
1264: /*@
1265: TaoGetGradientVector - Returns the vector with the current TAO gradient
1267: Not Collective
1269: Input Parameter:
1270: . tao - the Tao context
1272: Output Parameter:
1273: . G - the current solution
1275: Level: intermediate
1276: @*/
1277: PetscErrorCode TaoGetGradientVector(Tao tao, Vec *G)
1278: {
1281: *G = tao->gradient;
1282: return(0);
1283: }
1285: /*@
1286: TaoResetStatistics - Initialize the statistics used by TAO for all of the solvers.
1287: These statistics include the iteration number, residual norms, and convergence status.
1288: This routine gets called before solving each optimization problem.
1290: Collective on Tao
1292: Input Parameters:
1293: . solver - the Tao context
1295: Level: developer
1297: .seealso: TaoCreate(), TaoSolve()
1298: @*/
1299: PetscErrorCode TaoResetStatistics(Tao tao)
1300: {
1303: tao->niter = 0;
1304: tao->nfuncs = 0;
1305: tao->nfuncgrads = 0;
1306: tao->ngrads = 0;
1307: tao->nhess = 0;
1308: tao->njac = 0;
1309: tao->nconstraints = 0;
1310: tao->ksp_its = 0;
1311: tao->ksp_tot_its = 0;
1312: tao->reason = TAO_CONTINUE_ITERATING;
1313: tao->residual = 0.0;
1314: tao->cnorm = 0.0;
1315: tao->step = 0.0;
1316: tao->lsflag = PETSC_FALSE;
1317: if (tao->hist_reset) tao->hist_len=0;
1318: return(0);
1319: }
1321: /*@C
1322: TaoSetConvergenceTest - Sets the function that is to be used to test
1323: for convergence o fthe iterative minimization solution. The new convergence
1324: testing routine will replace TAO's default convergence test.
1326: Logically Collective on Tao
1328: Input Parameters:
1329: + tao - the Tao object
1330: . conv - the routine to test for convergence
1331: - ctx - [optional] context for private data for the convergence routine
1332: (may be NULL)
1334: Calling sequence of conv:
1335: $ PetscErrorCode conv(Tao tao, void *ctx)
1337: + tao - the Tao object
1338: - ctx - [optional] convergence context
1340: Note: The new convergence testing routine should call TaoSetConvergedReason().
1342: Level: advanced
1344: .seealso: TaoSetConvergedReason(), TaoGetSolutionStatus(), TaoGetTolerances(), TaoSetMonitor
1346: @*/
1347: PetscErrorCode TaoSetConvergenceTest(Tao tao, PetscErrorCode (*conv)(Tao,void*), void *ctx)
1348: {
1351: (tao)->ops->convergencetest = conv;
1352: (tao)->cnvP = ctx;
1353: return(0);
1354: }
1356: /*@C
1357: TaoSetMonitor - Sets an ADDITIONAL function that is to be used at every
1358: iteration of the solver to display the iteration's
1359: progress.
1361: Logically Collective on Tao
1363: Input Parameters:
1364: + tao - the Tao solver context
1365: . mymonitor - monitoring routine
1366: - mctx - [optional] user-defined context for private data for the
1367: monitor routine (may be NULL)
1369: Calling sequence of mymonitor:
1370: $ int mymonitor(Tao tao,void *mctx)
1372: + tao - the Tao solver context
1373: - mctx - [optional] monitoring context
1376: Options Database Keys:
1377: + -tao_monitor - sets TaoMonitorDefault()
1378: . -tao_smonitor - sets short monitor
1379: . -tao_cmonitor - same as smonitor plus constraint norm
1380: . -tao_view_solution - view solution at each iteration
1381: . -tao_view_gradient - view gradient at each iteration
1382: . -tao_view_separableobjective - view separable objective function at each iteration
1383: - -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.
1386: Notes:
1387: Several different monitoring routines may be set by calling
1388: TaoSetMonitor() multiple times; all will be called in the
1389: order in which they were set.
1391: Fortran Notes: Only one monitor function may be set
1393: Level: intermediate
1395: .seealso: TaoMonitorDefault(), TaoCancelMonitors(), TaoSetDestroyRoutine()
1396: @*/
1397: PetscErrorCode TaoSetMonitor(Tao tao, PetscErrorCode (*func)(Tao, void*), void *ctx,PetscErrorCode (*dest)(void**))
1398: {
1400: PetscInt i;
1404: if (tao->numbermonitors >= MAXTAOMONITORS) SETERRQ1(PETSC_COMM_SELF,1,"Cannot attach another monitor -- max=",MAXTAOMONITORS);
1406: for (i=0; i<tao->numbermonitors;i++) {
1407: if (func == tao->monitor[i] && dest == tao->monitordestroy[i] && ctx == tao->monitorcontext[i]) {
1408: if (dest) {
1409: (*dest)(&ctx);
1410: }
1411: return(0);
1412: }
1413: }
1414: tao->monitor[tao->numbermonitors] = func;
1415: tao->monitorcontext[tao->numbermonitors] = ctx;
1416: tao->monitordestroy[tao->numbermonitors] = dest;
1417: ++tao->numbermonitors;
1418: return(0);
1419: }
1421: /*@
1422: TaoCancelMonitors - Clears all the monitor functions for a Tao object.
1424: Logically Collective on Tao
1426: Input Parameters:
1427: . tao - the Tao solver context
1429: Options Database:
1430: . -tao_cancelmonitors - cancels all monitors that have been hardwired
1431: into a code by calls to TaoSetMonitor(), but does not cancel those
1432: set via the options database
1434: Notes:
1435: There is no way to clear one specific monitor from a Tao object.
1437: Level: advanced
1439: .seealso: TaoMonitorDefault(), TaoSetMonitor()
1440: @*/
1441: PetscErrorCode TaoCancelMonitors(Tao tao)
1442: {
1443: PetscInt i;
1448: for (i=0;i<tao->numbermonitors;i++) {
1449: if (tao->monitordestroy[i]) {
1450: (*tao->monitordestroy[i])(&tao->monitorcontext[i]);
1451: }
1452: }
1453: tao->numbermonitors=0;
1454: return(0);
1455: }
1457: /*@
1458: TaoMonitorDefault - Default routine for monitoring progress of the
1459: Tao solvers (default). This monitor prints the function value and gradient
1460: norm at each iteration. It can be turned on from the command line using the
1461: -tao_monitor option
1463: Collective on Tao
1465: Input Parameters:
1466: + tao - the Tao context
1467: - ctx - PetscViewer context or NULL
1469: Options Database Keys:
1470: . -tao_monitor
1472: Level: advanced
1474: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1475: @*/
1476: PetscErrorCode TaoMonitorDefault(Tao tao, void *ctx)
1477: {
1479: PetscInt its, tabs;
1480: PetscReal fct,gnorm;
1481: PetscViewer viewer = (PetscViewer)ctx;
1485: its=tao->niter;
1486: fct=tao->fc;
1487: gnorm=tao->residual;
1488: PetscViewerASCIIGetTab(viewer, &tabs);
1489: PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
1490: if (its == 0 && ((PetscObject)tao)->prefix) {
1491: PetscViewerASCIIPrintf(viewer," Iteration information for %s solve.\n",((PetscObject)tao)->prefix);
1492: }
1493: ierr=PetscViewerASCIIPrintf(viewer,"%3D TAO,",its);
1494: ierr=PetscViewerASCIIPrintf(viewer," Function value: %g,",(double)fct);
1495: if (gnorm >= PETSC_INFINITY) {
1496: ierr=PetscViewerASCIIPrintf(viewer," Residual: Inf \n");
1497: } else {
1498: ierr=PetscViewerASCIIPrintf(viewer," Residual: %g \n",(double)gnorm);
1499: }
1500: PetscViewerASCIISetTab(viewer, tabs);
1501: return(0);
1502: }
1504: /*@
1505: TaoDefaultSMonitor - Default routine for monitoring progress of the
1506: solver. Same as TaoMonitorDefault() except
1507: it prints fewer digits of the residual as the residual gets smaller.
1508: This is because the later digits are meaningless and are often
1509: different on different machines; by using this routine different
1510: machines will usually generate the same output. It can be turned on
1511: by using the -tao_smonitor option
1513: Collective on Tao
1515: Input Parameters:
1516: + tao - the Tao context
1517: - ctx - PetscViewer context of type ASCII
1519: Options Database Keys:
1520: . -tao_smonitor
1522: Level: advanced
1524: .seealso: TaoMonitorDefault(), TaoSetMonitor()
1525: @*/
1526: PetscErrorCode TaoDefaultSMonitor(Tao tao, void *ctx)
1527: {
1529: PetscInt its;
1530: PetscReal fct,gnorm;
1531: PetscViewer viewer = (PetscViewer)ctx;
1535: its=tao->niter;
1536: fct=tao->fc;
1537: gnorm=tao->residual;
1538: ierr=PetscViewerASCIIPrintf(viewer,"iter = %3D,",its);
1539: ierr=PetscViewerASCIIPrintf(viewer," Function value %g,",(double)fct);
1540: if (gnorm >= PETSC_INFINITY) {
1541: ierr=PetscViewerASCIIPrintf(viewer," Residual: Inf \n");
1542: } else if (gnorm > 1.e-6) {
1543: ierr=PetscViewerASCIIPrintf(viewer," Residual: %g \n",(double)gnorm);
1544: } else if (gnorm > 1.e-11) {
1545: ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-6 \n");
1546: } else {
1547: ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-11 \n");
1548: }
1549: return(0);
1550: }
1552: /*@
1553: TaoDefaultCMonitor - same as TaoMonitorDefault() except
1554: it prints the norm of the constraints function. It can be turned on
1555: from the command line using the -tao_cmonitor option
1557: Collective on Tao
1559: Input Parameters:
1560: + tao - the Tao context
1561: - ctx - PetscViewer context or NULL
1563: Options Database Keys:
1564: . -tao_cmonitor
1566: Level: advanced
1568: .seealso: TaoMonitorDefault(), TaoSetMonitor()
1569: @*/
1570: PetscErrorCode TaoDefaultCMonitor(Tao tao, void *ctx)
1571: {
1573: PetscInt its;
1574: PetscReal fct,gnorm;
1575: PetscViewer viewer = (PetscViewer)ctx;
1579: its=tao->niter;
1580: fct=tao->fc;
1581: gnorm=tao->residual;
1582: ierr=PetscViewerASCIIPrintf(viewer,"iter = %D,",its);
1583: ierr=PetscViewerASCIIPrintf(viewer," Function value: %g,",(double)fct);
1584: ierr=PetscViewerASCIIPrintf(viewer," Residual: %g ",(double)gnorm);
1585: PetscViewerASCIIPrintf(viewer," Constraint: %g \n",(double)tao->cnorm);
1586: return(0);
1587: }
1589: /*@C
1590: TaoSolutionMonitor - Views the solution at each iteration
1591: It can be turned on from the command line using the
1592: -tao_view_solution option
1594: Collective on Tao
1596: Input Parameters:
1597: + tao - the Tao context
1598: - ctx - PetscViewer context or NULL
1600: Options Database Keys:
1601: . -tao_view_solution
1603: Level: advanced
1605: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1606: @*/
1607: PetscErrorCode TaoSolutionMonitor(Tao tao, void *ctx)
1608: {
1610: PetscViewer viewer = (PetscViewer)ctx;;
1614: VecView(tao->solution, viewer);
1615: return(0);
1616: }
1618: /*@C
1619: TaoGradientMonitor - Views the gradient at each iteration
1620: It can be turned on from the command line using the
1621: -tao_view_gradient option
1623: Collective on Tao
1625: Input Parameters:
1626: + tao - the Tao context
1627: - ctx - PetscViewer context or NULL
1629: Options Database Keys:
1630: . -tao_view_gradient
1632: Level: advanced
1634: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1635: @*/
1636: PetscErrorCode TaoGradientMonitor(Tao tao, void *ctx)
1637: {
1639: PetscViewer viewer = (PetscViewer)ctx;
1643: VecView(tao->gradient, viewer);
1644: return(0);
1645: }
1647: /*@C
1648: TaoStepDirectionMonitor - Views the gradient at each iteration
1649: It can be turned on from the command line using the
1650: -tao_view_gradient option
1652: Collective on Tao
1654: Input Parameters:
1655: + tao - the Tao context
1656: - ctx - PetscViewer context or NULL
1658: Options Database Keys:
1659: . -tao_view_gradient
1661: Level: advanced
1663: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1664: @*/
1665: PetscErrorCode TaoStepDirectionMonitor(Tao tao, void *ctx)
1666: {
1668: PetscViewer viewer = (PetscViewer)ctx;
1672: VecView(tao->stepdirection, viewer);
1673: return(0);
1674: }
1676: /*@C
1677: TaoDrawSolutionMonitor - Plots the solution at each iteration
1678: It can be turned on from the command line using the
1679: -tao_draw_solution option
1681: Collective on Tao
1683: Input Parameters:
1684: + tao - the Tao context
1685: - ctx - TaoMonitorDraw context
1687: Options Database Keys:
1688: . -tao_draw_solution
1690: Level: advanced
1692: .seealso: TaoSolutionMonitor(), TaoSetMonitor(), TaoDrawGradientMonitor
1693: @*/
1694: PetscErrorCode TaoDrawSolutionMonitor(Tao tao, void *ctx)
1695: {
1696: PetscErrorCode ierr;
1697: TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;
1700: if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return(0);
1701: VecView(tao->solution,ictx->viewer);
1702: return(0);
1703: }
1705: /*@C
1706: TaoDrawGradientMonitor - Plots the gradient at each iteration
1707: It can be turned on from the command line using the
1708: -tao_draw_gradient option
1710: Collective on Tao
1712: Input Parameters:
1713: + tao - the Tao context
1714: - ctx - PetscViewer context
1716: Options Database Keys:
1717: . -tao_draw_gradient
1719: Level: advanced
1721: .seealso: TaoGradientMonitor(), TaoSetMonitor(), TaoDrawSolutionMonitor
1722: @*/
1723: PetscErrorCode TaoDrawGradientMonitor(Tao tao, void *ctx)
1724: {
1725: PetscErrorCode ierr;
1726: TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;
1729: if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return(0);
1730: VecView(tao->gradient,ictx->viewer);
1731: return(0);
1732: }
1734: /*@C
1735: TaoDrawStepMonitor - Plots the step direction at each iteration
1736: It can be turned on from the command line using the
1737: -tao_draw_step option
1739: Collective on Tao
1741: Input Parameters:
1742: + tao - the Tao context
1743: - ctx - PetscViewer context
1745: Options Database Keys:
1746: . -tao_draw_step
1748: Level: advanced
1750: .seealso: TaoSetMonitor(), TaoDrawSolutionMonitor
1751: @*/
1752: PetscErrorCode TaoDrawStepMonitor(Tao tao, void *ctx)
1753: {
1755: PetscViewer viewer = (PetscViewer)(ctx);
1758: VecView(tao->stepdirection, viewer);
1759: return(0);
1760: }
1762: /*@C
1763: TaoSeparableObjectiveMonitor - Views the separable objective function at each iteration
1764: It can be turned on from the command line using the
1765: -tao_view_separableobjective option
1767: Collective on Tao
1769: Input Parameters:
1770: + tao - the Tao context
1771: - ctx - PetscViewer context or NULL
1773: Options Database Keys:
1774: . -tao_view_separableobjective
1776: Level: advanced
1778: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1779: @*/
1780: PetscErrorCode TaoSeparableObjectiveMonitor(Tao tao, void *ctx)
1781: {
1783: PetscViewer viewer = (PetscViewer)ctx;
1787: VecView(tao->sep_objective,viewer);
1788: return(0);
1789: }
1791: /*@
1792: TaoDefaultConvergenceTest - Determines whether the solver should continue iterating
1793: or terminate.
1795: Collective on Tao
1797: Input Parameters:
1798: + tao - the Tao context
1799: - dummy - unused dummy context
1801: Output Parameter:
1802: . reason - for terminating
1804: Notes:
1805: This routine checks the residual in the optimality conditions, the
1806: relative residual in the optimity conditions, the number of function
1807: evaluations, and the function value to test convergence. Some
1808: solvers may use different convergence routines.
1810: Level: developer
1812: .seealso: TaoSetTolerances(),TaoGetConvergedReason(),TaoSetConvergedReason()
1813: @*/
1815: PetscErrorCode TaoDefaultConvergenceTest(Tao tao,void *dummy)
1816: {
1817: PetscInt niter=tao->niter, nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
1818: PetscInt max_funcs=tao->max_funcs;
1819: PetscReal gnorm=tao->residual, gnorm0=tao->gnorm0;
1820: PetscReal f=tao->fc, steptol=tao->steptol,trradius=tao->step;
1821: PetscReal gatol=tao->gatol,grtol=tao->grtol,gttol=tao->gttol;
1822: PetscReal catol=tao->catol,crtol=tao->crtol;
1823: PetscReal fmin=tao->fmin, cnorm=tao->cnorm;
1824: TaoConvergedReason reason=tao->reason;
1825: PetscErrorCode ierr;
1829: if (reason != TAO_CONTINUE_ITERATING) {
1830: return(0);
1831: }
1833: if (PetscIsInfOrNanReal(f)) {
1834: PetscInfo(tao,"Failed to converged, function value is Inf or NaN\n");
1835: reason = TAO_DIVERGED_NAN;
1836: } else if (f <= fmin && cnorm <=catol) {
1837: PetscInfo2(tao,"Converged due to function value %g < minimum function value %g\n", (double)f,(double)fmin);
1838: reason = TAO_CONVERGED_MINF;
1839: } else if (gnorm<= gatol && cnorm <=catol) {
1840: PetscInfo2(tao,"Converged due to residual norm ||g(X)||=%g < %g\n",(double)gnorm,(double)gatol);
1841: reason = TAO_CONVERGED_GATOL;
1842: } else if ( f!=0 && PetscAbsReal(gnorm/f) <= grtol && cnorm <= crtol) {
1843: PetscInfo2(tao,"Converged due to residual ||g(X)||/|f(X)| =%g < %g\n",(double)(gnorm/f),(double)grtol);
1844: reason = TAO_CONVERGED_GRTOL;
1845: } else if (gnorm0 != 0 && ((gttol == 0 && gnorm == 0) || gnorm/gnorm0 < gttol) && cnorm <= crtol) {
1846: PetscInfo2(tao,"Converged due to relative residual norm ||g(X)||/||g(X0)|| = %g < %g\n",(double)(gnorm/gnorm0),(double)gttol);
1847: reason = TAO_CONVERGED_GTTOL;
1848: } else if (nfuncs > max_funcs){
1849: PetscInfo2(tao,"Exceeded maximum number of function evaluations: %D > %D\n", nfuncs,max_funcs);
1850: reason = TAO_DIVERGED_MAXFCN;
1851: } else if ( tao->lsflag != 0 ){
1852: PetscInfo(tao,"Tao Line Search failure.\n");
1853: reason = TAO_DIVERGED_LS_FAILURE;
1854: } else if (trradius < steptol && niter > 0){
1855: PetscInfo2(tao,"Trust region/step size too small: %g < %g\n", (double)trradius,(double)steptol);
1856: reason = TAO_CONVERGED_STEPTOL;
1857: } else if (niter > tao->max_it) {
1858: PetscInfo2(tao,"Exceeded maximum number of iterations: %D > %D\n",niter,tao->max_it);
1859: reason = TAO_DIVERGED_MAXITS;
1860: } else {
1861: reason = TAO_CONTINUE_ITERATING;
1862: }
1863: tao->reason = reason;
1864: return(0);
1865: }
1867: /*@C
1868: TaoSetOptionsPrefix - Sets the prefix used for searching for all
1869: TAO options in the database.
1872: Logically Collective on Tao
1874: Input Parameters:
1875: + tao - the Tao context
1876: - prefix - the prefix string to prepend to all TAO option requests
1878: Notes:
1879: A hyphen (-) must NOT be given at the beginning of the prefix name.
1880: The first character of all runtime options is AUTOMATICALLY the hyphen.
1882: For example, to distinguish between the runtime options for two
1883: different TAO solvers, one could call
1884: .vb
1885: TaoSetOptionsPrefix(tao1,"sys1_")
1886: TaoSetOptionsPrefix(tao2,"sys2_")
1887: .ve
1889: This would enable use of different options for each system, such as
1890: .vb
1891: -sys1_tao_method blmvm -sys1_tao_gtol 1.e-3
1892: -sys2_tao_method lmvm -sys2_tao_gtol 1.e-4
1893: .ve
1896: Level: advanced
1898: .seealso: TaoAppendOptionsPrefix(), TaoGetOptionsPrefix()
1899: @*/
1901: PetscErrorCode TaoSetOptionsPrefix(Tao tao, const char p[])
1902: {
1906: PetscObjectSetOptionsPrefix((PetscObject)tao,p);
1907: if (tao->linesearch) {
1908: TaoLineSearchSetOptionsPrefix(tao->linesearch,p);
1909: }
1910: if (tao->ksp) {
1911: KSPSetOptionsPrefix(tao->ksp,p);
1912: }
1913: return(0);
1914: }
1916: /*@C
1917: TaoAppendOptionsPrefix - Appends to the prefix used for searching for all
1918: TAO options in the database.
1921: Logically Collective on Tao
1923: Input Parameters:
1924: + tao - the Tao solver context
1925: - prefix - the prefix string to prepend to all TAO option requests
1927: Notes:
1928: A hyphen (-) must NOT be given at the beginning of the prefix name.
1929: The first character of all runtime options is AUTOMATICALLY the hyphen.
1932: Level: advanced
1934: .seealso: TaoSetOptionsPrefix(), TaoGetOptionsPrefix()
1935: @*/
1936: PetscErrorCode TaoAppendOptionsPrefix(Tao tao, const char p[])
1937: {
1941: PetscObjectAppendOptionsPrefix((PetscObject)tao,p);
1942: if (tao->linesearch) {
1943: TaoLineSearchSetOptionsPrefix(tao->linesearch,p);
1944: }
1945: if (tao->ksp) {
1946: KSPSetOptionsPrefix(tao->ksp,p);
1947: }
1948: return(0);
1949: }
1951: /*@C
1952: TaoGetOptionsPrefix - Gets the prefix used for searching for all
1953: TAO options in the database
1955: Not Collective
1957: Input Parameters:
1958: . tao - the Tao context
1960: Output Parameters:
1961: . prefix - pointer to the prefix string used is returned
1963: Notes: On the fortran side, the user should pass in a string 'prefix' of
1964: sufficient length to hold the prefix.
1966: Level: advanced
1968: .seealso: TaoSetOptionsPrefix(), TaoAppendOptionsPrefix()
1969: @*/
1970: PetscErrorCode TaoGetOptionsPrefix(Tao tao, const char *p[])
1971: {
1972: return PetscObjectGetOptionsPrefix((PetscObject)tao,p);
1973: }
1975: /*@C
1976: TaoSetType - Sets the method for the unconstrained minimization solver.
1978: Collective on Tao
1980: Input Parameters:
1981: + solver - the Tao solver context
1982: - type - a known method
1984: Options Database Key:
1985: . -tao_type <type> - Sets the method; use -help for a list
1986: of available methods (for instance, "-tao_type lmvm" or "-tao_type tron")
1988: Available methods include:
1989: + nls - Newton's method with line search for unconstrained minimization
1990: . ntr - Newton's method with trust region for unconstrained minimization
1991: . ntl - Newton's method with trust region, line search for unconstrained minimization
1992: . lmvm - Limited memory variable metric method for unconstrained minimization
1993: . cg - Nonlinear conjugate gradient method for unconstrained minimization
1994: . nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
1995: . tron - Newton Trust Region method for bound constrained minimization
1996: . gpcg - Newton Trust Region method for quadratic bound constrained minimization
1997: . blmvm - Limited memory variable metric method for bound constrained minimization
1998: - pounders - Model-based algorithm pounder extended for nonlinear least squares
2000: Level: intermediate
2002: .seealso: TaoCreate(), TaoGetType(), TaoType
2004: @*/
2005: PetscErrorCode TaoSetType(Tao tao, const TaoType type)
2006: {
2008: PetscErrorCode (*create_xxx)(Tao);
2009: PetscBool issame;
2014: PetscObjectTypeCompare((PetscObject)tao,type,&issame);
2015: if (issame) return(0);
2017: PetscFunctionListFind(TaoList, type, (void(**)(void))&create_xxx);
2018: if (!create_xxx) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Tao type %s",type);
2020: /* Destroy the existing solver information */
2021: if (tao->ops->destroy) {
2022: (*tao->ops->destroy)(tao);
2023: }
2024: KSPDestroy(&tao->ksp);
2025: TaoLineSearchDestroy(&tao->linesearch);
2026: VecDestroy(&tao->gradient);
2027: VecDestroy(&tao->stepdirection);
2029: tao->ops->setup = 0;
2030: tao->ops->solve = 0;
2031: tao->ops->view = 0;
2032: tao->ops->setfromoptions = 0;
2033: tao->ops->destroy = 0;
2035: tao->setupcalled = PETSC_FALSE;
2037: (*create_xxx)(tao);
2038: PetscObjectChangeTypeName((PetscObject)tao,type);
2039: return(0);
2040: }
2042: /*MC
2043: TaoRegister - Adds a method to the TAO package for unconstrained minimization.
2045: Synopsis:
2046: TaoRegister(char *name_solver,char *path,char *name_Create,int (*routine_Create)(Tao))
2048: Not collective
2050: Input Parameters:
2051: + sname - name of a new user-defined solver
2052: - func - routine to Create method context
2054: Notes:
2055: TaoRegister() may be called multiple times to add several user-defined solvers.
2057: Sample usage:
2058: .vb
2059: TaoRegister("my_solver",MySolverCreate);
2060: .ve
2062: Then, your solver can be chosen with the procedural interface via
2063: $ TaoSetType(tao,"my_solver")
2064: or at runtime via the option
2065: $ -tao_type my_solver
2067: Level: advanced
2069: .seealso: TaoRegisterAll(), TaoRegisterDestroy()
2070: M*/
2071: PetscErrorCode TaoRegister(const char sname[], PetscErrorCode (*func)(Tao))
2072: {
2076: PetscFunctionListAdd(&TaoList,sname, (void (*)(void))func);
2077: return(0);
2078: }
2080: /*@C
2081: TaoRegisterDestroy - Frees the list of minimization solvers that were
2082: registered by TaoRegisterDynamic().
2084: Not Collective
2086: Level: advanced
2088: .seealso: TaoRegisterAll(), TaoRegister()
2089: @*/
2090: PetscErrorCode TaoRegisterDestroy(void)
2091: {
2094: PetscFunctionListDestroy(&TaoList);
2095: TaoRegisterAllCalled = PETSC_FALSE;
2096: return(0);
2097: }
2099: /*@
2100: TaoGetIterationNumber - Gets the number of Tao iterations completed
2101: at this time.
2103: Not Collective
2105: Input Parameter:
2106: . tao - Tao context
2108: Output Parameter:
2109: . iter - iteration number
2111: Notes:
2112: For example, during the computation of iteration 2 this would return 1.
2115: Level: intermediate
2117: .keywords: Tao, nonlinear, get, iteration, number,
2119: .seealso: TaoGetLinearSolveIterations(), TaoGetResidualNorm(), TaoGetObjective()
2120: @*/
2121: PetscErrorCode TaoGetIterationNumber(Tao tao,PetscInt *iter)
2122: {
2126: *iter = tao->niter;
2127: return(0);
2128: }
2130: /*@
2131: TaoGetObjective - Gets the current value of the objective function
2132: at this time.
2134: Not Collective
2136: Input Parameter:
2137: . tao - Tao context
2139: Output Parameter:
2140: . value - the current value
2142: Level: intermediate
2144: .keywords: Tao, nonlinear, get, iteration, number,
2146: .seealso: TaoGetLinearSolveIterations(), TaoGetIterationNumber(), TaoGetResidualNorm()
2147: @*/
2148: PetscErrorCode TaoGetObjective(Tao tao,PetscReal *value)
2149: {
2153: *value = tao->fc;
2154: return(0);
2155: }
2157: /*@
2158: TaoGetResidualNorm - Gets the current value of the norm of the residual
2159: at this time.
2161: Not Collective
2163: Input Parameter:
2164: . tao - Tao context
2166: Output Parameter:
2167: . value - the current value
2169: Level: intermediate
2171: Developer Note: This is the 2-norm of the residual, we cannot use TaoGetGradientNorm() because that has
2172: a different meaning. For some reason Tao sometimes calls the gradient the residual.
2174: .keywords: Tao, nonlinear, get, iteration, number,
2176: .seealso: TaoGetLinearSolveIterations(), TaoGetIterationNumber(), TaoGetObjective()
2177: @*/
2178: PetscErrorCode TaoGetResidualNorm(Tao tao,PetscReal *value)
2179: {
2183: *value = tao->residual;
2184: return(0);
2185: }
2187: /*@
2188: TaoSetIterationNumber - Sets the current iteration number.
2190: Not Collective
2192: Input Parameter:
2193: . tao - Tao context
2194: . iter - iteration number
2196: Level: developer
2198: .keywords: Tao, nonlinear, set, iteration, number,
2200: .seealso: TaoGetLinearSolveIterations()
2201: @*/
2202: PetscErrorCode TaoSetIterationNumber(Tao tao,PetscInt iter)
2203: {
2208: PetscObjectSAWsTakeAccess((PetscObject)tao);
2209: tao->niter = iter;
2210: PetscObjectSAWsGrantAccess((PetscObject)tao);
2211: return(0);
2212: }
2214: /*@
2215: TaoGetTotalIterationNumber - Gets the total number of Tao iterations
2216: completed. This number keeps accumulating if multiple solves
2217: are called with the Tao object.
2219: Not Collective
2221: Input Parameter:
2222: . tao - Tao context
2224: Output Parameter:
2225: . iter - iteration number
2227: Notes:
2228: The total iteration count is updated after each solve, if there is a current
2229: TaoSolve() in progress then those iterations are not yet counted.
2231: Level: intermediate
2233: .keywords: Tao, nonlinear, get, iteration, number,
2235: .seealso: TaoGetLinearSolveIterations()
2236: @*/
2237: PetscErrorCode TaoGetTotalIterationNumber(Tao tao,PetscInt *iter)
2238: {
2242: *iter = tao->ntotalits;
2243: return(0);
2244: }
2246: /*@
2247: TaoSetTotalIterationNumber - Sets the current total iteration number.
2249: Not Collective
2251: Input Parameter:
2252: . tao - Tao context
2253: . iter - iteration number
2255: Level: developer
2257: .keywords: Tao, nonlinear, set, iteration, number,
2259: .seealso: TaoGetLinearSolveIterations()
2260: @*/
2261: PetscErrorCode TaoSetTotalIterationNumber(Tao tao,PetscInt iter)
2262: {
2267: PetscObjectSAWsTakeAccess((PetscObject)tao);
2268: tao->ntotalits = iter;
2269: PetscObjectSAWsGrantAccess((PetscObject)tao);
2270: return(0);
2271: }
2273: /*@
2274: TaoSetConvergedReason - Sets the termination flag on a Tao object
2276: Logically Collective on Tao
2278: Input Parameters:
2279: + tao - the Tao context
2280: - reason - one of
2281: $ TAO_CONVERGED_ATOL (2),
2282: $ TAO_CONVERGED_RTOL (3),
2283: $ TAO_CONVERGED_STEPTOL (4),
2284: $ TAO_CONVERGED_MINF (5),
2285: $ TAO_CONVERGED_USER (6),
2286: $ TAO_DIVERGED_MAXITS (-2),
2287: $ TAO_DIVERGED_NAN (-4),
2288: $ TAO_DIVERGED_MAXFCN (-5),
2289: $ TAO_DIVERGED_LS_FAILURE (-6),
2290: $ TAO_DIVERGED_TR_REDUCTION (-7),
2291: $ TAO_DIVERGED_USER (-8),
2292: $ TAO_CONTINUE_ITERATING (0)
2294: Level: intermediate
2296: @*/
2297: PetscErrorCode TaoSetConvergedReason(Tao tao, TaoConvergedReason reason)
2298: {
2301: tao->reason = reason;
2302: return(0);
2303: }
2305: /*@
2306: TaoGetConvergedReason - Gets the reason the Tao iteration was stopped.
2308: Not Collective
2310: Input Parameter:
2311: . tao - the Tao solver context
2313: Output Parameter:
2314: . reason - one of
2315: $ TAO_CONVERGED_GATOL (3) ||g(X)|| < gatol
2316: $ TAO_CONVERGED_GRTOL (4) ||g(X)|| / f(X) < grtol
2317: $ TAO_CONVERGED_GTTOL (5) ||g(X)|| / ||g(X0)|| < gttol
2318: $ TAO_CONVERGED_STEPTOL (6) step size small
2319: $ TAO_CONVERGED_MINF (7) F < F_min
2320: $ TAO_CONVERGED_USER (8) User defined
2321: $ TAO_DIVERGED_MAXITS (-2) its > maxits
2322: $ TAO_DIVERGED_NAN (-4) Numerical problems
2323: $ TAO_DIVERGED_MAXFCN (-5) fevals > max_funcsals
2324: $ TAO_DIVERGED_LS_FAILURE (-6) line search failure
2325: $ TAO_DIVERGED_TR_REDUCTION (-7) trust region failure
2326: $ TAO_DIVERGED_USER(-8) (user defined)
2327: $ TAO_CONTINUE_ITERATING (0)
2329: where
2330: + X - current solution
2331: . X0 - initial guess
2332: . f(X) - current function value
2333: . f(X*) - true solution (estimated)
2334: . g(X) - current gradient
2335: . its - current iterate number
2336: . maxits - maximum number of iterates
2337: . fevals - number of function evaluations
2338: - max_funcsals - maximum number of function evaluations
2340: Level: intermediate
2342: .seealso: TaoSetConvergenceTest(), TaoSetTolerances()
2344: @*/
2345: PetscErrorCode TaoGetConvergedReason(Tao tao, TaoConvergedReason *reason)
2346: {
2350: *reason = tao->reason;
2351: return(0);
2352: }
2354: /*@
2355: TaoGetSolutionStatus - Get the current iterate, objective value,
2356: residual, infeasibility, and termination
2358: Not Collective
2360: Input Parameters:
2361: . tao - the Tao context
2363: Output Parameters:
2364: + iterate - the current iterate number (>=0)
2365: . f - the current function value
2366: . gnorm - the square of the gradient norm, duality gap, or other measure indicating distance from optimality.
2367: . cnorm - the infeasibility of the current solution with regard to the constraints.
2368: . xdiff - the step length or trust region radius of the most recent iterate.
2369: - reason - The termination reason, which can equal TAO_CONTINUE_ITERATING
2371: Level: intermediate
2373: Note:
2374: TAO returns the values set by the solvers in the routine TaoMonitor().
2376: Note:
2377: If any of the output arguments are set to NULL, no corresponding value will be returned.
2379: .seealso: TaoMonitor(), TaoGetConvergedReason()
2380: @*/
2381: PetscErrorCode TaoGetSolutionStatus(Tao tao, PetscInt *its, PetscReal *f, PetscReal *gnorm, PetscReal *cnorm, PetscReal *xdiff, TaoConvergedReason *reason)
2382: {
2384: if (its) *its=tao->niter;
2385: if (f) *f=tao->fc;
2386: if (gnorm) *gnorm=tao->residual;
2387: if (cnorm) *cnorm=tao->cnorm;
2388: if (reason) *reason=tao->reason;
2389: if (xdiff) *xdiff=tao->step;
2390: return(0);
2391: }
2393: /*@C
2394: TaoGetType - Gets the current Tao algorithm.
2396: Not Collective
2398: Input Parameter:
2399: . tao - the Tao solver context
2401: Output Parameter:
2402: . type - Tao method
2404: Level: intermediate
2406: @*/
2407: PetscErrorCode TaoGetType(Tao tao, const TaoType *type)
2408: {
2412: *type=((PetscObject)tao)->type_name;
2413: return(0);
2414: }
2416: /*@C
2417: TaoMonitor - Monitor the solver and the current solution. This
2418: routine will record the iteration number and residual statistics,
2419: call any monitors specified by the user, and calls the convergence-check routine.
2421: Input Parameters:
2422: + tao - the Tao context
2423: . its - the current iterate number (>=0)
2424: . f - the current objective function value
2425: . res - the gradient norm, square root of the duality gap, or other measure indicating distince from optimality. This measure will be recorded and
2426: used for some termination tests.
2427: . cnorm - the infeasibility of the current solution with regard to the constraints.
2428: - steplength - multiple of the step direction added to the previous iterate.
2430: Output Parameters:
2431: . reason - The termination reason, which can equal TAO_CONTINUE_ITERATING
2433: Options Database Key:
2434: . -tao_monitor - Use the default monitor, which prints statistics to standard output
2436: .seealso TaoGetConvergedReason(), TaoMonitorDefault(), TaoSetMonitor()
2438: Level: developer
2440: @*/
2441: PetscErrorCode TaoMonitor(Tao tao, PetscInt its, PetscReal f, PetscReal res, PetscReal cnorm, PetscReal steplength)
2442: {
2444: PetscInt i;
2448: tao->fc = f;
2449: tao->residual = res;
2450: tao->cnorm = cnorm;
2451: tao->step = steplength;
2452: if (!its) {
2453: tao->cnorm0 = cnorm; tao->gnorm0 = res;
2454: }
2455: if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(res)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
2456: for (i=0;i<tao->numbermonitors;i++) {
2457: (*tao->monitor[i])(tao,tao->monitorcontext[i]);
2458: }
2459: return(0);
2460: }
2462: /*@
2463: TaoSetConvergenceHistory - Sets the array used to hold the convergence history.
2465: Logically Collective on Tao
2467: Input Parameters:
2468: + tao - the Tao solver context
2469: . obj - array to hold objective value history
2470: . resid - array to hold residual history
2471: . cnorm - array to hold constraint violation history
2472: . lits - integer array holds the number of linear iterations for each Tao iteration
2473: . na - size of obj, resid, and cnorm
2474: - reset - PetscTrue indicates each new minimization resets the history counter to zero,
2475: else it continues storing new values for new minimizations after the old ones
2477: Notes:
2478: If set, TAO will fill the given arrays with the indicated
2479: information at each iteration. If 'obj','resid','cnorm','lits' are
2480: *all* NULL then space (using size na, or 1000 if na is PETSC_DECIDE or
2481: PETSC_DEFAULT) is allocated for the history.
2482: If not all are NULL, then only the non-NULL information categories
2483: will be stored, the others will be ignored.
2485: Any convergence information after iteration number 'na' will not be stored.
2487: This routine is useful, e.g., when running a code for purposes
2488: of accurate performance monitoring, when no I/O should be done
2489: during the section of code that is being timed.
2491: Level: intermediate
2493: .seealso: TaoGetConvergenceHistory()
2495: @*/
2496: PetscErrorCode TaoSetConvergenceHistory(Tao tao, PetscReal obj[], PetscReal resid[], PetscReal cnorm[], PetscInt lits[], PetscInt na,PetscBool reset)
2497: {
2507: if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2508: if (!obj && !resid && !cnorm && !lits) {
2509: PetscCalloc1(na,&obj);
2510: PetscCalloc1(na,&resid);
2511: PetscCalloc1(na,&cnorm);
2512: PetscCalloc1(na,&lits);
2513: tao->hist_malloc=PETSC_TRUE;
2514: }
2516: tao->hist_obj = obj;
2517: tao->hist_resid = resid;
2518: tao->hist_cnorm = cnorm;
2519: tao->hist_lits = lits;
2520: tao->hist_max = na;
2521: tao->hist_reset = reset;
2522: tao->hist_len = 0;
2523: return(0);
2524: }
2526: /*@C
2527: TaoGetConvergenceHistory - Gets the arrays used to hold the convergence history.
2529: Collective on Tao
2531: Input Parameter:
2532: . tao - the Tao context
2534: Output Parameters:
2535: + obj - array used to hold objective value history
2536: . resid - array used to hold residual history
2537: . cnorm - array used to hold constraint violation history
2538: . lits - integer array used to hold linear solver iteration count
2539: - nhist - size of obj, resid, cnorm, and lits (will be less than or equal to na given in TaoSetHistory)
2541: Notes:
2542: This routine must be preceded by calls to TaoSetConvergenceHistory()
2543: and TaoSolve(), otherwise it returns useless information.
2545: The calling sequence for this routine in Fortran is
2546: $ call TaoGetConvergenceHistory(Tao tao, PetscInt nhist, PetscErrorCode ierr)
2548: This routine is useful, e.g., when running a code for purposes
2549: of accurate performance monitoring, when no I/O should be done
2550: during the section of code that is being timed.
2552: Level: advanced
2554: .seealso: TaoSetConvergenceHistory()
2556: @*/
2557: PetscErrorCode TaoGetConvergenceHistory(Tao tao, PetscReal **obj, PetscReal **resid, PetscReal **cnorm, PetscInt **lits, PetscInt *nhist)
2558: {
2561: if (obj) *obj = tao->hist_obj;
2562: if (cnorm) *cnorm = tao->hist_cnorm;
2563: if (resid) *resid = tao->hist_resid;
2564: if (nhist) *nhist = tao->hist_len;
2565: return(0);
2566: }
2568: /*@
2569: TaoSetApplicationContext - Sets the optional user-defined context for
2570: a solver.
2572: Logically Collective on Tao
2574: Input Parameters:
2575: + tao - the Tao context
2576: - usrP - optional user context
2578: Level: intermediate
2580: .seealso: TaoGetApplicationContext(), TaoSetApplicationContext()
2581: @*/
2582: PetscErrorCode TaoSetApplicationContext(Tao tao,void *usrP)
2583: {
2586: tao->user = usrP;
2587: return(0);
2588: }
2590: /*@
2591: TaoGetApplicationContext - Gets the user-defined context for a
2592: TAO solvers.
2594: Not Collective
2596: Input Parameter:
2597: . tao - Tao context
2599: Output Parameter:
2600: . usrP - user context
2602: Level: intermediate
2604: .seealso: TaoSetApplicationContext()
2605: @*/
2606: PetscErrorCode TaoGetApplicationContext(Tao tao,void *usrP)
2607: {
2610: *(void**)usrP = tao->user;
2611: return(0);
2612: }
2614: /*@
2615: TaoSetGradientNorm - Sets the matrix used to define the inner product that measures the size of the gradient.
2617: Collective on tao
2619: Input Parameters:
2620: + tao - the Tao context
2621: - M - gradient norm
2623: Level: beginner
2625: .seealso: TaoGetGradientNorm(), TaoGradientNorm()
2626: @*/
2627: PetscErrorCode TaoSetGradientNorm(Tao tao, Mat M)
2628: {
2634: if (tao->gradient_norm) {
2635: PetscObjectDereference((PetscObject)tao->gradient_norm);
2636: VecDestroy(&tao->gradient_norm_tmp);
2637: }
2639: PetscObjectReference((PetscObject)M);
2640: tao->gradient_norm = M;
2641: MatCreateVecs(M, NULL, &tao->gradient_norm_tmp);
2642: return(0);
2643: }
2645: /*@
2646: TaoGetGradientNorm - Returns the matrix used to define the inner product for measuring the size of the gradient.
2648: Not Collective
2650: Input Parameter:
2651: . tao - Tao context
2653: Output Parameter:
2654: . M - gradient norm
2656: Level: beginner
2658: .seealso: TaoSetGradientNorm(), TaoGradientNorm()
2659: @*/
2660: PetscErrorCode TaoGetGradientNorm(Tao tao, Mat *M)
2661: {
2664: *M = tao->gradient_norm;
2665: return(0);
2666: }
2668: /*c
2669: TaoGradientNorm - Compute the norm with respect to the inner product the user has set.
2671: Collective on tao
2673: Input Parameter:
2674: . tao - the Tao context
2675: . gradient - the gradient to be computed
2676: . norm - the norm type
2678: Output Parameter:
2679: . gnorm - the gradient norm
2681: Level: developer
2683: .seealso: TaoSetGradientNorm(), TaoGetGradientNorm()
2684: @*/
2685: PetscErrorCode TaoGradientNorm(Tao tao, Vec gradient, NormType type, PetscReal *gnorm)
2686: {
2692: if (tao->gradient_norm) {
2693: PetscScalar gnorms;
2695: 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.");
2696: MatMult(tao->gradient_norm, gradient, tao->gradient_norm_tmp);
2697: VecDot(gradient, tao->gradient_norm_tmp, &gnorms);
2698: *gnorm = PetscRealPart(PetscSqrtScalar(gnorms));
2699: } else {
2700: VecNorm(gradient, type, gnorm);
2701: }
2702: return(0);
2703: }
2705: /*@C
2706: TaoMonitorDrawCtxCreate - Creates the monitor context for TaoMonitorDrawCtx
2708: Collective on Tao
2710: Output Patameter:
2711: . ctx - the monitor context
2713: Options Database:
2714: . -tao_draw_solution_initial - show initial guess as well as current solution
2716: Level: intermediate
2718: .keywords: Tao, vector, monitor, view
2720: .seealso: TaoMonitorSet(), TaoMonitorDefault(), VecView(), TaoMonitorDrawCtx()
2721: @*/
2722: PetscErrorCode TaoMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TaoMonitorDrawCtx *ctx)
2723: {
2724: PetscErrorCode ierr;
2727: PetscNew(ctx);
2728: PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);
2729: PetscViewerSetFromOptions((*ctx)->viewer);
2730: (*ctx)->howoften = howoften;
2731: return(0);
2732: }
2734: /*@C
2735: TaoMonitorDrawCtxDestroy - Destroys the monitor context for TaoMonitorDrawSolution()
2737: Collective on Tao
2739: Input Parameters:
2740: . ctx - the monitor context
2742: Level: intermediate
2744: .keywords: Tao, vector, monitor, view
2746: .seealso: TaoMonitorSet(), TaoMonitorDefault(), VecView(), TaoMonitorDrawSolution()
2747: @*/
2748: PetscErrorCode TaoMonitorDrawCtxDestroy(TaoMonitorDrawCtx *ictx)
2749: {
2753: PetscViewerDestroy(&(*ictx)->viewer);
2754: PetscFree(*ictx);
2755: return(0);
2756: }