Actual source code: taosolver.c
1: #define TAOSOLVER_DLL
3: #include "include/private/taosolver_impl.h" /*I "taosolver.h" I*/
5: PetscBool TaoSolverRegisterAllCalled = PETSC_FALSE;
6: PetscFList TaoSolverList = PETSC_NULL;
8: PetscClassId TAOSOLVER_CLASSID;
9: PetscLogEvent TaoSolver_Solve, TaoSolver_ObjectiveEval, TaoSolver_GradientEval, TaoSolver_ObjGradientEval, TaoSolver_HessianEval, TaoSolver_ConstraintsEval, TaoSolver_JacobianEval;
13: static const char *TAO_SUBSET[64] = {
14: "subvec","mask","matrixfree"
15: };
19: /*@
20: TaoCreate - Creates a TAO solver
22: Collective on MPI_Comm
24: Input Parameter:
25: . comm - MPI communicator
27: Output Parameter:
28: . newtao - the new TaoSolver context
30: Available methods include:
31: + tao_nls - Newton's method with line search for unconstrained minimization
32: . tao_ntr - Newton's method with trust region for unconstrained minimization
33: . tao_ntl - Newton's method with trust region, line search for unconstrained minimization
34: . tao_lmvm - Limited memory variable metric method for unconstrained minimization
35: . tao_cg - Nonlinear conjugate gradient method for unconstrained minimization
36: . tao_nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
37: ation
38: . tao_tron - Newton Trust Region method for bound constrained minimization
39: . tao_gpcg - Newton Trust Region method for quadratic bound constrained minimization
40: . tao_blmvm - Limited memory variable metric method for bound constrained minimization
41: . tao_lcl - Linearly constrained Lagrangian method for pde-constrained minimization
42: - tao_pounders - Model-based algorithm for nonlinear least squares
44: Options Database Keys:
45: + -tao_method - select which method TAO should use
46: - -tao_type - identical to -tao_method
48: Level: beginner
50: .seealso: TaoSolve(), TaoDestroy()
51: @*/
52: PetscErrorCode TaoCreate(MPI_Comm comm, TaoSolver *newtao)
53: {
55: TaoSolver tao;
56:
59: *newtao = PETSC_NULL;
61: TaoInitializePackage(PETSC_NULL);
62: TaoLineSearchInitializePackage(PETSC_NULL);
64: PetscHeaderCreate(tao,_p_TaoSolver, struct _TaoSolverOps, TAOSOLVER_CLASSID,0,"TaoSolver",0,0,comm,TaoDestroy,TaoView);
65:
66: tao->ops->computeobjective=0;
67: tao->ops->computeobjectiveandgradient=0;
68: tao->ops->computegradient=0;
69: tao->ops->computehessian=0;
70: tao->ops->computeseparableobjective=0;
71: tao->ops->computeconstraints=0;
72: tao->ops->computejacobian=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=PETSC_NULL;
83: tao->gradient=PETSC_NULL;
84: tao->sep_objective = PETSC_NULL;
85: tao->constraints=PETSC_NULL;
86: tao->stepdirection=PETSC_NULL;
87: tao->XL = PETSC_NULL;
88: tao->XU = PETSC_NULL;
89: tao->hessian = PETSC_NULL;
90: tao->hessian_pre = PETSC_NULL;
91: tao->jacobian = PETSC_NULL;
92: tao->jacobian_pre = PETSC_NULL;
93: tao->jacobian_state = PETSC_NULL;
94: tao->jacobian_state_pre = PETSC_NULL;
95: tao->jacobian_state_inv = PETSC_NULL;
96: tao->jacobian_design = PETSC_NULL;
97: tao->jacobian_design_pre = PETSC_NULL;
98: tao->state_is = PETSC_NULL;
99: tao->design_is = PETSC_NULL;
101: tao->max_it = 10000;
102: tao->max_funcs = 10000;
103: tao->fatol = 1e-8;
104: tao->frtol = 1e-8;
105: tao->gatol = 1e-8;
106: tao->grtol = 1e-8;
107: tao->gttol = 0.0;
108: tao->catol = 0.0;
109: tao->crtol = 0.0;
110: tao->xtol = 0.0;
111: tao->steptol = 0.0;
112: tao->trust0 = TAO_INFINITY;
113: tao->fmin = -1e100;
114: tao->hist_reset = PETSC_TRUE;
115: tao->hist_max = 0;
116: tao->hist_len = 0;
117: tao->hist_obj = PETSC_NULL;
118: tao->hist_resid = PETSC_NULL;
119: tao->hist_cnorm = PETSC_NULL;
121: tao->numbermonitors=0;
122: tao->viewsolution=PETSC_FALSE;
123: tao->viewhessian=PETSC_FALSE;
124: tao->viewgradient=PETSC_FALSE;
125: tao->viewjacobian=PETSC_FALSE;
126: tao->viewconstraints = PETSC_FALSE;
127: tao->viewtao = PETSC_FALSE;
128:
129: TaoResetStatistics(tao);
132: *newtao = tao;
133: return(0);
134: }
139: /*@
140: TaoSolve - Solves an optimization problem min F(x) s.t. l <= x <= u
142: Collective on TaoSolver
143:
144: Input Parameters:
145: . tao - the TaoSolver context
147: Notes:
148: The user must set up the TaoSolver with calls to TaoSetInitialVector(),
149: TaoSetObjectiveRoutine(),
150: TaoSetGradientRoutine(), and (if using 2nd order method) TaoSetHessianRoutine().
152: Level: beginner
154: .seealso: TaoCreate(), TaoSetObjectiveRoutine(), TaoSetGradientRoutine(), TaoSetHessianRoutine()
155: @*/
156: PetscErrorCode TaoSolve(TaoSolver tao)
157: {
159: char filename[PETSC_MAX_PATH_LEN];
160: PetscBool flg;
161: PetscViewer viewer;
165: TaoSetUp(tao);
166: TaoResetStatistics(tao);
167: if (tao->linesearch) {
168: TaoLineSearchReset(tao->linesearch);
169: }
171: PetscLogEventBegin(TaoSolver_Solve,tao,0,0,0);
172: if (tao->ops->solve){ (*tao->ops->solve)(tao); }
173: PetscLogEventEnd(TaoSolver_Solve,tao,0,0,0);
176:
177: PetscOptionsGetString(((PetscObject)tao)->prefix,"-tao_view",filename,PETSC_MAX_PATH_LEN,&flg);
178: if (flg && !PetscPreLoadingOn) {
179: PetscViewerASCIIOpen(((PetscObject)tao)->comm,filename,&viewer);
180: TaoView(tao,viewer);
181: PetscViewerDestroy(&viewer);
182: }
183:
185: if (tao->printreason) {
186: if (tao->reason > 0) {
187: PetscPrintf(((PetscObject)tao)->comm,"TAO solve converged due to %s\n",TaoSolverTerminationReasons[tao->reason]);
188: } else {
189: PetscPrintf(((PetscObject)tao)->comm,"TAO solve did not converge due to %s\n",TaoSolverTerminationReasons[tao->reason]);
190: }
191: }
192:
194: return(0);
196:
197: }
202: /*@
203: TaoSetUp - Sets up the internal data structures for the later use
204: of a Tao solver
206: Collective on tao
207:
208: Input Parameters:
209: . tao - the TAO context
211: Notes:
212: The user will not need to explicitly call TaoSetUp(), as it will
213: automatically be called in TaoSolve(). However, if the user
214: desires to call it explicitly, it should come after TaoCreate()
215: and any TaoSetSomething() routines, but before TaoSolve().
217: Level: advanced
219: .seealso: TaoCreate(), TaoSolve()
220: @*/
221: PetscErrorCode TaoSetUp(TaoSolver tao)
222: {
226: if (tao->setupcalled) return(0);
228: if (!tao->solution) {
229: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetInitialVector");
230: }
231: if (tao->ops->setup) {
232: (*tao->ops->setup)(tao);
233: }
234:
235: tao->setupcalled = PETSC_TRUE;
236: return(0);
237: }
241: /*@
242: TaoDestroy - Destroys the TAO context that was created with
243: TaoCreate()
245: Collective on TaoSolver
247: Input Parameter:
248: . tao - the TaoSolver context
250: Level: beginner
252: .seealso: TaoCreate(), TaoSolve()
253: @*/
254: PetscErrorCode TaoDestroy(TaoSolver *tao)
255: {
258: if (!*tao) return(0);
261: if (--((PetscObject)*tao)->refct > 0) {*tao=0;return(0);}
263: PetscObjectDepublish(*tao);
264:
265: if ((*tao)->ops->destroy) {
266: (*((*tao))->ops->destroy)(*tao);
267: }
268: KSPDestroy(&(*tao)->ksp);
269: TaoLineSearchDestroy(&(*tao)->linesearch);
271: if ((*tao)->ops->convergencedestroy) {
272: (*(*tao)->ops->convergencedestroy)((*tao)->cnvP);
273: if ((*tao)->jacobian_state_inv) {
274: MatDestroy(&(*tao)->jacobian_state_inv);
275: (*tao)->jacobian_state_inv = PETSC_NULL;
276: }
277: }
278: VecDestroy(&(*tao)->solution);
279: VecDestroy(&(*tao)->gradient);
281: VecDestroy(&(*tao)->XL);
282: VecDestroy(&(*tao)->XU);
283: VecDestroy(&(*tao)->stepdirection);
284: MatDestroy(&(*tao)->hessian_pre);
285: MatDestroy(&(*tao)->hessian);
286: MatDestroy(&(*tao)->jacobian_pre);
287: MatDestroy(&(*tao)->jacobian);
288: MatDestroy(&(*tao)->jacobian_state_pre);
289: MatDestroy(&(*tao)->jacobian_state);
290: MatDestroy(&(*tao)->jacobian_state_inv);
291: MatDestroy(&(*tao)->jacobian_design_pre);
292: MatDestroy(&(*tao)->jacobian_design);
293: ISDestroy(&(*tao)->state_is);
294: ISDestroy(&(*tao)->design_is);
295: TaoCancelMonitors(*tao);
296: PetscHeaderDestroy(tao);
297: return(0);
298: }
302: /*@
303: TaoSetFromOptions - Sets various TaoSolver parameters from user
304: options.
306: Collective on TaoSolver
308: Input Paremeter:
309: . tao - the TaoSolver solver context
311: options Database Keys:
312: + -tao_method <type> - The algorithm that TAO uses (tao_lmvm, tao_nls, etc.)
313: . -tao_fatol <fatol> - absolute error tolerance in function value
314: . -tao_frtol <frtol> - relative error tolerance in function value
315: . -tao_gatol <gatol> - absolute error tolerance for ||gradient||
316: . -tao_grtol <grtol> - relative error tolerance for ||gradient||
317: . -tao_gttol <gttol> - reduction of ||gradient|| relative to initial gradient
318: . -tao_max_it <max> - sets maximum number of iterations
319: . -tao_max_funcs <max> - sets maximum number of function evaluations
320: . -tao_fmin <fmin> - stop if function value reaches fmin
321: . -tao_steptol <tol> - stop if trust region radius less than <tol>
322: . -tao_trust0 <t> - initial trust region radius
323: . -tao_monitor - prints function value and residual at each iteration
324: . -tao_smonitor - same as tao_monitor, but truncates very small values
325: . -tao_cmonitor - prints function value, residual, and constraint norm at each iteration
326: . -tao_view_solution - prints solution vector at each iteration
327: . -tao_view_separableobjective - prints separable objective vector at each iteration
328: . -tao_view_step - prints step direction vector at each iteration
329: . -tao_view_gradient - prints gradient vector at each iteration
330: . -tao_draw_solution - graphically view solution vector at each iteration
331: . -tao_draw_step - graphically view step vector at each iteration
332: . -tao_draw_gradient - graphically view gradient at each iteration
333: . -tao_fd_gradient - use gradient computed with finite differences
334: . -tao_cancelmonitors - cancels all monitors (except those set with command line)
335: . -tao_view - prints information about the TaoSolver after solving
336: - -tao_converged_reason - prints the reason TAO stopped iterating
338: Notes:
339: To see all options, run your program with the -help option or consult the
340: user's manual. Should be called after TaoCreate() but before TaoSolve()
342: Level: beginner
343: @*/
344: PetscErrorCode TaoSetFromOptions(TaoSolver tao)
345: {
347: const TaoSolverType default_type = "tao_lmvm";
348: const char *prefix;
349: char type[256], monfilename[PETSC_MAX_PATH_LEN];
350: PetscViewer monviewer;
351: PetscBool flg;
352: MPI_Comm comm;
353:
356: PetscObjectGetComm((PetscObject)tao,&comm);
357: TaoGetOptionsPrefix(tao,&prefix);
358: /* So no warnings are given about unused options */
359: PetscOptionsHasName(prefix,"-tao_ksp_type",&flg);
360: PetscOptionsHasName(prefix,"-tao_pc_type",&flg);
361: PetscOptionsHasName(prefix,"-tao_ls_type",&flg);
362:
364: PetscOptionsBegin(comm, ((PetscObject)tao)->prefix,"TaoSolver options","TaoSolver");
365: {
366:
368: if (!TaoSolverRegisterAllCalled) {
369: TaoSolverRegisterAll(PETSC_NULL);
370: }
371: if (((PetscObject)tao)->type_name) {
372: default_type = ((PetscObject)tao)->type_name;
373: }
374: /* Check for type from options */
375: PetscOptionsList("-tao_type","Tao Solver type","TaoSetType",TaoSolverList,default_type,type,256,&flg);
376: if (flg) {
377: TaoSetType(tao,type);
378: } else {
379: PetscOptionsList("-tao_method","Tao Solver type","TaoSetType",TaoSolverList,default_type,type,256,&flg);
380: if (flg) {
381: TaoSetType(tao,type);
382: } else if (!((PetscObject)tao)->type_name) {
383: TaoSetType(tao,default_type);
384: }
385: }
387: PetscOptionsBool("-tao_view","view TaoSolver info after each minimization has completed","TaoView",PETSC_FALSE,&tao->viewtao,&flg);
388: PetscOptionsReal("-tao_fatol","Stop if solution within","TaoSetTolerances",tao->fatol,&tao->fatol,&flg);
389: PetscOptionsReal("-tao_frtol","Stop if relative solution within","TaoSetTolerances",tao->frtol,&tao->frtol,&flg);
390: PetscOptionsReal("-tao_catol","Stop if constraints violations within","TaoSetConstraintTolerances",tao->catol,&tao->catol,&flg);
391: PetscOptionsReal("-tao_crtol","Stop if relative contraint violations within","TaoSetConstraintTolerances",tao->crtol,&tao->crtol,&flg);
392: PetscOptionsReal("-tao_gatol","Stop if norm of gradient less than","TaoSetTolerances",tao->gatol,&tao->gatol,&flg);
393: PetscOptionsReal("-tao_grtol","Stop if norm of gradient divided by the function value is less than","TaoSetTolerances",tao->grtol,&tao->grtol,&flg);
394: 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);
395: PetscOptionsInt("-tao_max_it","Stop if iteration number exceeds",
396: "TaoSetMaximumIterations",tao->max_it,&tao->max_it,
397: &flg);
398: PetscOptionsInt("-tao_max_funcs","Stop if number of function evaluations exceeds","TaoSetMaximumFunctionEvaluations",tao->max_funcs,&tao->max_funcs,&flg);
399: PetscOptionsReal("-tao_fmin","Stop if function less than","TaoSetFunctionLowerBound",tao->fmin,&tao->fmin,&flg);
400: PetscOptionsReal("-tao_steptol","Stop if step size or trust region radius less than","",tao->steptol,&tao->steptol,&flg);
401: PetscOptionsReal("-tao_trust0","Initial trust region radius","TaoSetTrustRegionRadius",tao->trust0,&tao->trust0,&flg);
403: PetscOptionsString("-tao_view_solution","view solution vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
404: if (flg) {
405: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
406: TaoSetMonitor(tao,TaoSolutionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
407: }
409: PetscOptionsBool("-tao_converged_reason","Print reason for TAO termination","TaoSolve",flg,&flg,PETSC_NULL);
410: if (flg) {
411: tao->printreason = PETSC_TRUE;
412: }
413: PetscOptionsString("-tao_view_gradient","view gradient vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
414: if (flg) {
415: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
416: TaoSetMonitor(tao,TaoGradientMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
417: }
419:
420: PetscOptionsString("-tao_view_stepdirection","view step direction vector after each iteration","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
421: if (flg) {
422: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
423: TaoSetMonitor(tao,TaoStepDirectionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
424: }
426: PetscOptionsString("-tao_view_separableobjective","view separable objective vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
427: if (flg) {
428: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
429: TaoSetMonitor(tao,TaoSeparableObjectiveMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
430: }
431:
432: PetscOptionsString("-tao_monitor","Use the default convergence monitor","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
433: if (flg) {
434: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
435: TaoSetMonitor(tao,TaoDefaultMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
436: }
438: PetscOptionsString("-tao_smonitor","Use the short convergence monitor","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
439: if (flg) {
440: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
441: TaoSetMonitor(tao,TaoDefaultSMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
442: }
444: PetscOptionsString("-tao_cmonitor","Use the default convergence monitor with constraint norm","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
445: if (flg) {
446: PetscViewerASCIIOpen(comm,monfilename,&monviewer);
447: TaoSetMonitor(tao,TaoDefaultCMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
448: }
451: PetscOptionsBool("-tao_cancelmonitors","cancel all monitors and call any registered destroy routines","TaoCancelMonitors",PETSC_FALSE,&flg,PETSC_NULL);
452: if (flg) {TaoCancelMonitors(tao);}
454: PetscOptionsBool("-tao_draw_solution","Plot solution vector at each iteration","TaoSetMonitor",PETSC_FALSE,&flg,PETSC_NULL);
455: if (flg) {
456: TaoSetMonitor(tao,TaoDrawSolutionMonitor,PETSC_NULL,PETSC_NULL);
457: }
459: PetscOptionsBool("-tao_draw_step","plots step direction at each iteration","TaoSetMonitor",PETSC_FALSE,&flg,PETSC_NULL);
460: if (flg) {
461: TaoSetMonitor(tao,TaoDrawStepMonitor,PETSC_NULL,PETSC_NULL);
462: }
464: PetscOptionsBool("-tao_draw_gradient","plots gradient at each iteration","TaoSetMonitor",PETSC_FALSE,&flg,PETSC_NULL);
465: if (flg) {
466: TaoSetMonitor(tao,TaoDrawGradientMonitor,PETSC_NULL,PETSC_NULL);
467: }
468: PetscOptionsBool("-tao_fd_gradient","compute gradient using finite differences","TaoDefaultComputeGradient",PETSC_FALSE,&flg,PETSC_NULL);
469: if (flg) {
470: TaoSetGradientRoutine(tao,TaoDefaultComputeGradient,PETSC_NULL);
471: }
472: PetscOptionsEList("-tao_subset_type","subset type", "", TAO_SUBSET, TAO_SUBSET_TYPES,TAO_SUBSET[tao->subset_type], &tao->subset_type, 0);
474: if (tao->ops->setfromoptions) {
475: (*tao->ops->setfromoptions)(tao);
476: }
477:
478: }
479: PetscOptionsEnd();
480: return(0);
482: }
487: /*@C
488: TaoView - Prints information about the TaoSolver
489:
490: Collective on TaoSolver
492: InputParameters:
493: + tao - the TaoSolver context
494: - viewer - visualization context
496: Options Database Key:
497: . -tao_view - Calls TaoView() at the end of TaoSolve()
499: Notes:
500: The available visualization contexts include
501: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
502: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
503: output where only the first processor opens
504: the file. All other processors send their
505: data to the first processor to print.
507: Level: beginner
509: .seealso: PetscViewerASCIIOpen()
510: @*/
511: PetscErrorCode TaoView(TaoSolver tao, PetscViewer viewer)
512: {
514: PetscBool isascii,isstring;
515: const TaoSolverType type;
518: if (!viewer) {
519: PetscViewerASCIIGetStdout(((PetscObject)tao)->comm,&viewer);
520: }
524: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
525: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
526: if (isascii) {
527: PetscObjectPrintClassNamePrefixType((PetscObject)tao,viewer,"TaoSolver");
528: PetscViewerASCIIPushTab(viewer);
530: if (tao->ops->view) {
531: PetscViewerASCIIPushTab(viewer);
532: (*tao->ops->view)(tao,viewer);
533: PetscViewerASCIIPopTab(viewer);
534: }
535: if (tao->linesearch) {
536: PetscObjectPrintClassNamePrefixType((PetscObject)(tao->linesearch),viewer,"TaoLineSearch");
537: }
538: if (tao->ksp) {
539: PetscObjectPrintClassNamePrefixType((PetscObject)(tao->ksp),viewer,"KSP Solver");
540: PetscViewerASCIIPrintf(viewer,"total KSP iterations: %D\n",tao->ksp_its);
541: }
542: if (tao->XL || tao->XU) {
543: PetscViewerASCIIPrintf(viewer,"Active Set subset type: %s\n",TAO_SUBSET[tao->subset_type]);
544: }
545:
546: ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: fatol=%G,",tao->fatol);
547: ierr=PetscViewerASCIIPrintf(viewer," frtol=%G\n",tao->frtol);
549: ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: gatol=%G,",tao->gatol);
550: ierr=PetscViewerASCIIPrintf(viewer," steptol=%G,",tao->steptol);
551: ierr=PetscViewerASCIIPrintf(viewer," gttol=%G\n",tao->gttol);
553: PetscViewerASCIIPrintf(viewer,"Residual in Function/Gradient:=%G\n",tao->residual);
555: if (tao->cnorm>0 || tao->catol>0 || tao->crtol>0){
556: ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances:");
557: ierr=PetscViewerASCIIPrintf(viewer," catol=%G,",tao->catol);
558: ierr=PetscViewerASCIIPrintf(viewer," crtol=%G\n",tao->crtol);
559: PetscViewerASCIIPrintf(viewer,"Residual in Constraints:=%G\n",tao->cnorm);
560: }
562: if (tao->trust < tao->steptol){
563: ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: steptol=%G\n",tao->steptol);
564: ierr=PetscViewerASCIIPrintf(viewer,"Final trust region radius:=%G\n",tao->trust);
565: }
567: if (tao->fmin>-1.e25){
568: ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: function minimum=%G\n"
569: ,tao->fmin);
570: }
571: PetscViewerASCIIPrintf(viewer,"Objective value=%G\n",
572: tao->fc);
574: PetscViewerASCIIPrintf(viewer,"total number of iterations=%D, ",
575: tao->niter);
576: PetscViewerASCIIPrintf(viewer," (max: %D)\n",tao->max_it);
578: if (tao->nfuncs>0){
579: PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%D,",
580: tao->nfuncs);
581: PetscViewerASCIIPrintf(viewer," max: %D\n",
582: tao->max_funcs);
583: }
584: if (tao->ngrads>0){
585: PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%D,",
586: tao->ngrads);
587: PetscViewerASCIIPrintf(viewer," max: %D\n",
588: tao->max_funcs);
589: }
590: if (tao->nfuncgrads>0){
591: PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%D,",
592: tao->nfuncgrads);
593: PetscViewerASCIIPrintf(viewer," (max: %D)\n",
594: tao->max_funcs);
595: }
596: if (tao->nhess>0){
597: PetscViewerASCIIPrintf(viewer,"total number of Hessian evaluations=%D\n",
598: tao->nhess);
599: }
600: /* if (tao->linear_its>0){
601: PetscViewerASCIIPrintf(viewer," total Krylov method iterations=%D\n",
602: tao->linear_its);
603: }*/
604: if (tao->nconstraints>0){
605: PetscViewerASCIIPrintf(viewer,"total number of constraint function evaluations=%D\n",
606: tao->nconstraints);
607: }
608: if (tao->njac>0){
609: PetscViewerASCIIPrintf(viewer,"total number of Jacobian evaluations=%D\n",
610: tao->njac);
611: }
613: if (tao->reason>0){
614: PetscViewerASCIIPrintf(viewer, "Solution converged: ");
615: switch (tao->reason) {
616: case TAO_CONVERGED_FATOL:
617: PetscViewerASCIIPrintf(viewer,"estimated f(x)-f(X*) <= fatol\n");
618: break;
619: case TAO_CONVERGED_FRTOL:
620: PetscViewerASCIIPrintf(viewer,"estimated |f(x)-f(X*)|/|f(X*)| <= frtol\n");
621: break;
622: case TAO_CONVERGED_GATOL:
623: PetscViewerASCIIPrintf(viewer," ||g(X)|| <= gatol\n");
624: break;
625: case TAO_CONVERGED_GRTOL:
626: PetscViewerASCIIPrintf(viewer," ||g(X)||/|f(X)| <= grtol\n");
627: break;
628: case TAO_CONVERGED_GTTOL:
629: PetscViewerASCIIPrintf(viewer," ||g(X)||/||g(X0)|| <= gttol\n");
630: break;
631: case TAO_CONVERGED_STEPTOL:
632: PetscViewerASCIIPrintf(viewer," Steptol -- step size small\n");
633: break;
634: case TAO_CONVERGED_MINF:
635: PetscViewerASCIIPrintf(viewer," Minf -- f < fmin\n");
636: break;
637: case TAO_CONVERGED_USER:
638: PetscViewerASCIIPrintf(viewer," User Terminated\n");
639: break;
640: default:
641: PetscViewerASCIIPrintf(viewer,"\n");
642: break;
643: }
644:
645: } else {
646: PetscViewerASCIIPrintf(viewer,"Solver terminated: %D",tao->reason);
647: switch (tao->reason) {
648: case TAO_DIVERGED_MAXITS:
649: PetscViewerASCIIPrintf(viewer," Maximum Iterations\n");
650:
651: break;
652: case TAO_DIVERGED_NAN:
653: PetscViewerASCIIPrintf(viewer," NAN or Inf encountered\n");
654:
655: break;
656: case TAO_DIVERGED_MAXFCN:
657: PetscViewerASCIIPrintf(viewer," Maximum Function Evaluations\n");
658:
659: break;
660: case TAO_DIVERGED_LS_FAILURE:
661: PetscViewerASCIIPrintf(viewer," Line Search Failure\n");
662:
663: break;
664: case TAO_DIVERGED_TR_REDUCTION:
665: PetscViewerASCIIPrintf(viewer," Trust Region too small\n");
666:
667: break;
668: case TAO_DIVERGED_USER:
669: PetscViewerASCIIPrintf(viewer," User Terminated\n");
670:
671: break;
672: default:
673: PetscViewerASCIIPrintf(viewer,"\n");
674: break;
675: }
676: }
677: PetscViewerASCIIPopTab(viewer);
678: } else if (isstring) {
679: TaoGetType(tao,&type);
680: PetscViewerStringSPrintf(viewer," %-3.3s",type);
681: }
682: return(0);
683:
684: }
688: /*@
689: TaoSetTolerances - Sets parameters used in TAO convergence tests
691: Logically collective on TaoSolver
693: Input Parameters:
694: + tao - the TaoSolver context
695: . fatol - absolute convergence tolerance
696: . frtol - relative convergence tolerance
697: . gatol - stop if norm of gradient is less than this
698: . grtol - stop if relative norm of gradient is less than this
699: - gttol - stop if norm of gradient is reduced by this factor
701: Options Database Keys:
702: + -tao_fatol <fatol> - Sets fatol
703: . -tao_frtol <frtol> - Sets frtol
704: . -tao_gatol <gatol> - Sets gatol
705: . -tao_grtol <grtol> - Sets grtol
706: - -tao_gttol <gttol> - Sets gttol
708: Stopping Criteria:
709: $ f(X) - f(X*) (estimated) <= fatol
710: $ |f(X) - f(X*)| (estimated) / |f(X)| <= frtol
711: $ ||g(X)|| <= gatol
712: $ ||g(X)|| / |f(X)| <= grtol
713: $ ||g(X)|| / ||g(X0)|| <= gttol
715: Notes:
716: Use PETSC_DEFAULT to leave one or more tolerances unchanged.
718: Level: beginner
720: .seealso: TaoGetTolerances()
722: @*/
723: PetscErrorCode TaoSetTolerances(TaoSolver tao, PetscReal fatol, PetscReal frtol, PetscReal gatol, PetscReal grtol, PetscReal gttol)
724: {
728:
729: if (fatol != PETSC_DEFAULT) {
730: if (fatol<0) {
731: PetscInfo(tao,"Tried to set negative fatol -- ignored.");
732:
733: } else {
734: tao->fatol = PetscMax(0,fatol);
735: }
736: }
737:
738: if (frtol != PETSC_DEFAULT) {
739: if (frtol<0) {
740: PetscInfo(tao,"Tried to set negative frtol -- ignored.");
741:
742: } else {
743: tao->frtol = PetscMax(0,frtol);
744: }
745: }
747: if (gatol != PETSC_DEFAULT) {
748: if (gatol<0) {
749: PetscInfo(tao,"Tried to set negative gatol -- ignored.");
750:
751: } else {
752: tao->gatol = PetscMax(0,gatol);
753: }
754: }
756: if (grtol != PETSC_DEFAULT) {
757: if (grtol<0) {
758: PetscInfo(tao,"Tried to set negative grtol -- ignored.");
759:
760: } else {
761: tao->grtol = PetscMax(0,grtol);
762: }
763: }
765: if (gttol != PETSC_DEFAULT) {
766: if (gttol<0) {
767: PetscInfo(tao,"Tried to set negative gttol -- ignored.");
768:
769: } else {
770: tao->gttol = PetscMax(0,gttol);
771: }
772: }
774: return(0);
775: }
779: /*@
780: TaoSetConstraintTolerances - Sets contraint tolerance parameters used in TAO
781: convergence tests
783: Logically collective on TaoSolver
785: Input Parameters:
786: + tao - the TaoSolver context
787: . catol - absolute constraint tolerance, constraint norm must be less than catol for used for fatol, gatol convergence criteria
788: - crtol - relative contraint tolerance, constraint norm must be less than crtol for used for fatol, gatol, gttol convergence criteria
790: Options Database Keys:
791: + -tao_catol <catol> - Sets catol
792: - -tao_crtol <crtol> - Sets crtol
794: Level: intermediate
796: .seealso: TaoGetTolerances()
798: @*/
799: PetscErrorCode TaoSetConstraintTolerances(TaoSolver tao, PetscReal catol, PetscReal crtol)
800: {
804:
805: if (catol != PETSC_DEFAULT) {
806: if (catol<0) {
807: PetscInfo(tao,"Tried to set negative catol -- ignored.");
808:
809: } else {
810: tao->catol = PetscMax(0,catol);
811: }
812: }
813:
814: if (crtol != PETSC_DEFAULT) {
815: if (crtol<0) {
816: PetscInfo(tao,"Tried to set negative crtol -- ignored.");
817:
818: } else {
819: tao->crtol = PetscMax(0,crtol);
820: }
821: }
823: return(0);
824: }
828: /*@
829: TaoSetFunctionLowerBound - Sets a bound on the solution objective value.
830: When an approximate solution with an objective value below this number
831: has been found, the solver will terminate.
833: Logically Collective on TaoSolver
835: Input Parameters:
836: + tao - the TaoSolver solver context
837: - fmin - the tolerance
839: Options Database Keys:
840: . -tao_fmin <fmin> - sets the minimum function value
842: Level: intermediate
844: .seealso: TaoSetTolerances()
845: @*/
846: PetscErrorCode TaoSetFunctionLowerBound(TaoSolver tao,PetscReal fmin)
847: {
850: tao->fmin = fmin;
851: return(0);
852: }
856: /*@
857: TaoGetFunctionLowerBound - 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: Not collective on TaoSolver
863: Input Parameters:
864: . tao - the TaoSolver solver context
866: OutputParameters:
867: . fmin - the minimum function value
869: Level: intermediate
871: .seealso: TaoSetFunctionLowerBound()
872: @*/
873: PetscErrorCode TaoGetFunctionLowerBound(TaoSolver tao,PetscReal *fmin)
874: {
877: *fmin = tao->fmin;
878: return(0);
879: }
885: /*@
886: TaoSetMaximumFunctionEvaluations - Sets a maximum number of
887: function evaluations.
889: Logically Collective on TaoSolver
891: Input Parameters:
892: + tao - the TaoSolver solver context
893: - nfcn - the maximum number of function evaluations (>=0)
895: Options Database Keys:
896: . -tao_max_funcs <nfcn> - sets the maximum number of function evaluations
898: Level: intermediate
900: .seealso: TaoSetTolerances(), TaoSetMaximumIterations()
901: @*/
903: PetscErrorCode TaoSetMaximumFunctionEvaluations(TaoSolver tao,PetscInt nfcn)
904: {
905: PetscInt zero=0;
908: tao->max_funcs = PetscMax(zero,nfcn);
909: return(0);
910: }
914: /*@
915: TaoGetMaximumFunctionEvaluations - Sets a maximum number of
916: function evaluations.
918: Not Collective
920: Input Parameters:
921: . tao - the TaoSolver solver context
923: Output Parameters:
924: . nfcn - the maximum number of function evaluations
926: Level: intermediate
928: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
929: @*/
931: PetscErrorCode TaoGetMaximumFunctionEvaluations(TaoSolver tao,PetscInt *nfcn)
932: {
935: *nfcn = tao->max_funcs;
936: return(0);
937: }
942: /*@
943: TaoSetMaximumIterations - Sets a maximum number of iterates.
945: Logically Collective on TaoSolver
947: Input Parameters:
948: + tao - the TaoSolver solver context
949: - maxits - the maximum number of iterates (>=0)
951: Options Database Keys:
952: . -tao_max_it <its> - sets the maximum number of iterations
954: Level: intermediate
956: .seealso: TaoSetTolerances(), TaoSetMaximumFunctionEvaluations()
957: @*/
958: PetscErrorCode TaoSetMaximumIterations(TaoSolver tao,PetscInt maxits)
959: {
960: PetscInt zero=0;
963: tao->max_it = PetscMax(zero,maxits);
964: return(0);
965: }
970: /*@
971: TaoGetMaximumIterations - Sets a maximum number of iterates.
973: Not Collective
975: Input Parameters:
976: . tao - the TaoSolver solver context
978: Output Parameters:
979: . maxits - the maximum number of iterates
981: Level: intermediate
983: .seealso: TaoSetMaximumIterations(), TaoGetMaximumFunctionEvaluations()
984: @*/
985: PetscErrorCode TaoGetMaximumIterations(TaoSolver tao,PetscInt *maxits)
986: {
989: *maxits = tao->max_it;
990: return(0);
991: }
995: /*@
996: TaoSetInitialTrustRegionRadius - Sets the initial trust region radius.
998: Logically collective on TaoSolver
1000: Input Parameter:
1001: + tao - a TAO optimization solver
1002: - radius - the trust region radius
1004: Level: intermediate
1006: Options Database Key:
1007: . -tao_trust0 <t0> - sets initial trust region radius
1010: .seealso: TaoGetTrustRegionRadius(), TaoSetTrustRegionTolerance()
1011: @*/
1012: PetscErrorCode TaoSetInitialTrustRegionRadius(TaoSolver tao, PetscReal radius)
1013: {
1016: tao->trust0 = PetscMax(0.0,radius);
1017: return(0);
1018: }
1023: /*@
1024: TaoGetInitialTrustRegionRadius - Sets the initial trust region radius.
1026: Not Collective
1028: Input Parameter:
1029: . tao - a TAO optimization solver
1031: Output Parameter:
1032: . radius - the trust region radius
1034: Level: intermediate
1036: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetCurrentTrustRegionRadius()
1037: @*/
1038: PetscErrorCode TaoGetInitialTrustRegionRadius(TaoSolver tao, PetscReal *radius)
1039: {
1042: *radius = tao->trust0;
1043: return(0);
1044: }
1048: /*@
1049: TaoGetCurrentTrustRegionRadius - Gets the current trust region radius.
1051: Not Collective
1053: Input Parameter:
1054: . tao - a TAO optimization solver
1056: Output Parameter:
1057: . radius - the trust region radius
1059: Level: intermediate
1061: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetInitialTrustRegionRadius()
1062: @*/
1063: PetscErrorCode TaoGetCurrentTrustRegionRadius(TaoSolver tao, PetscReal *radius)
1064: {
1067: *radius = tao->trust;
1068: return(0);
1069: }
1074: /*@
1075: TaoGetTolerances - gets the current values of tolerances
1077: Not Collective
1079: Input Parameters:
1080: . tao - the TaoSolver context
1081:
1082: Output Parameters:
1083: + fatol - absolute convergence tolerance
1084: . frtol - relative convergence tolerance
1085: . gatol - stop if norm of gradient is less than this
1086: . grtol - stop if relative norm of gradient is less than this
1087: - gttol - stop if norm of gradient is reduced by a this factor
1089: Note:
1090: PETSC_NULL can be used as an argument if not all tolerances values are needed
1092: .seealso TaoSetTolerances()
1093:
1094: Level: intermediate
1095: @*/
1096: PetscErrorCode TaoGetTolerances(TaoSolver tao, PetscReal *fatol, PetscReal *frtol, PetscReal *gatol, PetscReal *grtol, PetscReal *gttol)
1097: {
1100: if (fatol) *fatol=tao->fatol;
1101: if (frtol) *frtol=tao->frtol;
1102: if (gatol) *gatol=tao->gatol;
1103: if (grtol) *grtol=tao->grtol;
1104: if (gttol) *gttol=tao->gttol;
1105: return(0);
1106: }
1111: /*@
1112: TaoGetKSP - Gets the linear solver used by the optimization solver.
1113: Application writers should use TaoGetKSP if they need direct access
1114: to the PETSc KSP object.
1116: Not Collective
1117:
1118: Input Parameters:
1119: . tao - the TAO solver
1121: Output Parameters:
1122: . ksp - the KSP linear solver used in the optimization solver
1124: Level: intermediate
1126: @*/
1127: PetscErrorCode TaoGetKSP(TaoSolver tao, KSP *ksp) {
1129: *ksp = tao->ksp;
1130: return(0);
1131: }
1135: /*@
1136: TaoGetLineSearch - Gets the line search used by the optimization solver.
1137: Application writers should use TaoGetLineSearch if they need direct access
1138: to the TaoLineSearch object.
1139:
1140: Not Collective
1141:
1142: Input Parameters:
1143: . tao - the TAO solver
1145: Output Parameters:
1146: . ls - the line search used in the optimization solver
1148: Level: intermediate
1150: @*/
1151: PetscErrorCode TaoGetLineSearch(TaoSolver tao, TaoLineSearch *ls) {
1153: *ls = tao->linesearch;
1154: return(0);
1155: }
1159: /*@
1160: TaoAddLineSearchCounts - Adds the number of function evaluations spent
1161: in the line search to the running total.
1162:
1163: Input Parameters:
1164: + tao - the TAO solver
1165: - ls - the line search used in the optimization solver
1167: Level: developer
1169: .seealso: TaoLineSearchApply()
1170: @*/
1171: PetscErrorCode TaoAddLineSearchCounts(TaoSolver tao) {
1173: PetscBool flg;
1174: PetscInt nfeval,ngeval,nfgeval;
1177: if (tao->linesearch) {
1178: TaoLineSearchIsUsingTaoSolverRoutines(tao->linesearch,&flg);
1179: if (flg == PETSC_FALSE) {
1180: TaoLineSearchGetNumberFunctionEvaluations(tao->linesearch,&nfeval,
1181: &ngeval,&nfgeval);
1182: tao->nfuncs+=nfeval;
1183: tao->ngrads+=ngeval;
1184: tao->nfuncgrads+=nfgeval;
1185: }
1186: }
1187:
1188: return(0);
1189: }
1194: /*@
1195: TaoGetSolutionVector - Returns the vector with the current TAO solution
1197: Not Collective
1199: Input Parameter:
1200: . tao - the TaoSolver context
1202: Output Parameter:
1203: . X - the current solution
1205: Level: intermediate
1206:
1207: Note: The returned vector will be the same object that was passed into TaoSetInitialVector()
1208: @*/
1209: PetscErrorCode TaoGetSolutionVector(TaoSolver tao, Vec *X)
1210: {
1213: *X = tao->solution;
1214: return(0);
1215: }
1220: /*@
1221: TaoGetGradientVector - Returns the vector with the current TAO gradient
1223: Not Collective
1225: Input Parameter:
1226: . tao - the TaoSolver context
1228: Output Parameter:
1229: . G - the current solution
1231: Level: intermediate
1232: @*/
1233: PetscErrorCode TaoGetGradientVector(TaoSolver tao, Vec *G)
1234: {
1237: *G = tao->gradient;
1238: return(0);
1239: }
1244: /*@
1245: TaoResetStatistics - Initialize the statistics used by TAO for all of the solvers.
1246: These statistics include the iteration number, residual norms, and convergence status.
1247: This routine gets called before solving each optimization problem.
1249: Collective on TaoSolver
1251: Input Parameters:
1252: . solver - the TaoSolver context
1254: Level: developer
1256: .seealso: TaoCreate(), TaoSolve()
1257: @*/
1258: PetscErrorCode TaoResetStatistics(TaoSolver tao)
1259: {
1262: tao->niter = 0;
1263: tao->nfuncs = 0;
1264: tao->nfuncgrads = 0;
1265: tao->ngrads = 0;
1266: tao->nhess = 0;
1267: tao->njac = 0;
1268: tao->nconstraints = 0;
1269: tao->ksp_its = 0;
1270: tao->reason = TAO_CONTINUE_ITERATING;
1271: tao->residual = 0.0;
1272: tao->cnorm = 0.0;
1273: tao->step = 0.0;
1274: tao->lsflag = PETSC_FALSE;
1275: if (tao->hist_reset) tao->hist_len=0;
1276: return(0);
1277: }
1282: /*@C
1283: TaoSetConvergenceTest - Sets the function that is to be used to test
1284: for convergence o fthe iterative minimization solution. The new convergence
1285: testing routine will replace TAO's default convergence test.
1287: Logically Collective on TaoSolver
1289: Input Parameters:
1290: + tao - the TaoSolver object
1291: . conv - the routine to test for convergence
1292: - ctx - [optional] context for private data for the convergence routine
1293: (may be PETSC_NULL)
1295: Calling sequence of conv:
1296: $ PetscErrorCode conv(TaoSolver tao, void *ctx)
1298: + tao - the TaoSolver object
1299: - ctx - [optional] convergence context
1301: Note: The new convergence testing routine should call TaoSetTerminationReason().
1303: Level: advanced
1305: .seealso: TaoSetTerminationReason(), TaoGetSolutionStatus(), TaoGetTolerances(), TaoSetMonitor
1307: @*/
1308: PetscErrorCode TaoSetConvergenceTest(TaoSolver tao, PetscErrorCode (*conv)(TaoSolver,void*), void *ctx)
1309: {
1312: (tao)->ops->convergencetest = conv;
1313: (tao)->cnvP = ctx;
1314: return(0);
1315: }
1319: /*@C
1320: TaoSetMonitor - Sets an ADDITIONAL function that is to be used at every
1321: iteration of the solver to display the iteration's
1322: progress.
1324: Logically Collective on TaoSolver
1326: Input Parameters:
1327: + tao - the TaoSolver solver context
1328: . mymonitor - monitoring routine
1329: - mctx - [optional] user-defined context for private data for the
1330: monitor routine (may be PETSC_NULL)
1332: Calling sequence of mymonitor:
1333: $ int mymonitor(TaoSolver tao,void *mctx)
1335: + tao - the TaoSolver solver context
1336: - mctx - [optional] monitoring context
1339: Options Database Keys:
1340: + -tao_monitor - sets TaoDefaultMonitor()
1341: . -tao_smonitor - sets short monitor
1342: . -tao_cmonitor - same as smonitor plus constraint norm
1343: . -tao_view_solution - view solution at each iteration
1344: . -tao_view_gradient - view gradient at each iteration
1345: . -tao_view_separableobjective - view separable objective function at each iteration
1346: - -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.
1349: Notes:
1350: Several different monitoring routines may be set by calling
1351: TaoSetMonitor() multiple times; all will be called in the
1352: order in which they were set.
1354: Fortran Notes: Only one monitor function may be set
1356: Level: intermediate
1358: .seealso: TaoDefaultMonitor(), TaoCancelMonitors(), TaoSetDestroyRoutine()
1359: @*/
1360: PetscErrorCode TaoSetMonitor(TaoSolver tao, PetscErrorCode (*func)(TaoSolver, void*), void *ctx,PetscErrorCode (*dest)(void**))
1361: {
1364: if (tao->numbermonitors >= MAXTAOMONITORS) {
1365: SETERRQ1(PETSC_COMM_SELF,1,"Cannot attach another monitor -- max=",MAXTAOMONITORS);
1366: }
1367: tao->monitor[tao->numbermonitors] = func;
1368: tao->monitorcontext[tao->numbermonitors] = ctx;
1369: tao->monitordestroy[tao->numbermonitors] = dest;
1370: ++tao->numbermonitors;
1371: return(0);
1372: }
1376: /*@
1377: TaoCancelMonitors - Clears all the monitor functions for a TaoSolver object.
1379: Logically Collective on TaoSolver
1381: Input Parameters:
1382: . tao - the TaoSolver solver context
1384: Options Database:
1385: . -tao_cancelmonitors - cancels all monitors that have been hardwired
1386: into a code by calls to TaoSetMonitor(), but does not cancel those
1387: set via the options database
1389: Notes:
1390: There is no way to clear one specific monitor from a TaoSolver object.
1392: Level: advanced
1394: .seealso: TaoDefaultMonitor(), TaoSetMonitor()
1395: @*/
1396: PetscErrorCode TaoCancelMonitors(TaoSolver tao)
1397: {
1398: PetscInt i;
1402: for (i=0;i<tao->numbermonitors;i++) {
1403: if (tao->monitordestroy[i]) {
1404: (*tao->monitordestroy[i])(&tao->monitorcontext[i]);
1405: }
1406: }
1407: tao->numbermonitors=0;
1408: return(0);
1409: }
1415: /*@C
1416: TaoDefaultMonitor - Default routine for monitoring progress of the
1417: TaoSolver solvers (default). This monitor prints the function value and gradient
1418: norm at each iteration. It can be turned on from the command line using the
1419: -tao_monitor option
1421: Collective on TaoSolver
1423: Input Parameters:
1424: + tao - the TaoSolver context
1425: - ctx - PetscViewer context or PETSC_NULL
1427: Options Database Keys:
1428: . -tao_monitor
1430: Level: advanced
1432: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1433: @*/
1434: PetscErrorCode TaoDefaultMonitor(TaoSolver tao, void *ctx)
1435: {
1437: PetscInt its;
1438: PetscReal fct,gnorm;
1439: PetscViewer viewer;
1441: if (ctx) {
1442: viewer = (PetscViewer)ctx;
1443: } else {
1444: viewer = PETSC_VIEWER_STDOUT_(((PetscObject)tao)->comm);
1445: }
1446: its=tao->niter;
1447: fct=tao->fc;
1448: gnorm=tao->residual;
1449: ierr=PetscViewerASCIIPrintf(viewer,"iter = %3D,",its);
1450: ierr=PetscViewerASCIIPrintf(viewer," Function value: %G,",fct);
1451: ierr=PetscViewerASCIIPrintf(viewer," Residual: %G \n",gnorm);
1452: return(0);
1453: }
1459: /*@C
1460: TaoDefaultSMonitor - Default routine for monitoring progress of the
1461: solver. Same as TaoDefaultMonitor() except
1462: it prints fewer digits of the residual as the residual gets smaller.
1463: This is because the later digits are meaningless and are often
1464: different on different machines; by using this routine different
1465: machines will usually generate the same output. It can be turned on
1466: by using the -tao_smonitor option
1467:
1468: Collective on TaoSolver
1470: Input Parameters:
1471: + tao - the TaoSolver context
1472: - ctx - PetscViewer context or PETSC_NULL
1474: Options Database Keys:
1475: . -tao_smonitor
1477: Level: advanced
1479: .seealso: TaoDefaultMonitor(), TaoSetMonitor()
1480: @*/
1481: PetscErrorCode TaoDefaultSMonitor(TaoSolver tao, void *ctx)
1482: {
1484: PetscInt its;
1485: PetscReal fct,gnorm;
1486: PetscViewer viewer;
1488: if (ctx) {
1489: viewer = (PetscViewer)ctx;
1490: } else {
1491: viewer = PETSC_VIEWER_STDOUT_(((PetscObject)tao)->comm);
1492: }
1493: its=tao->niter;
1494: fct=tao->fc;
1495: gnorm=tao->residual;
1496: ierr=PetscViewerASCIIPrintf(viewer,"iter = %3D,",its);
1497: ierr=PetscViewerASCIIPrintf(viewer," Function value %G,",fct);
1498: if (gnorm > 1.e-6) {
1499: ierr=PetscViewerASCIIPrintf(viewer," Residual: %G \n",gnorm);
1500: } else if (gnorm > 1.e-11) {
1501: ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-6 \n");
1502: } else {
1503: ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-11 \n");
1504: }
1505: return(0);
1506: }
1511: /*@C
1512: TaoDefaultCMonitor - same as TaoDefaultMonitor() except
1513: it prints the norm of the constraints function. It can be turned on
1514: from the command line using the -tao_cmonitor option
1515:
1516: Collective on TaoSolver
1518: Input Parameters:
1519: + tao - the TaoSolver context
1520: - ctx - PetscViewer context or PETSC_NULL
1522: Options Database Keys:
1523: . -tao_cmonitor
1525: Level: advanced
1527: .seealso: TaoDefaultMonitor(), TaoSetMonitor()
1528: @*/
1529: PetscErrorCode TaoDefaultCMonitor(TaoSolver tao, void *ctx)
1530: {
1532: PetscInt its;
1533: PetscReal fct,gnorm;
1534: PetscViewer viewer;
1537: if (ctx) {
1538: viewer = (PetscViewer)ctx;
1539: } else {
1540: viewer = PETSC_VIEWER_STDOUT_(((PetscObject)tao)->comm);
1541: }
1542: its=tao->niter;
1543: fct=tao->fc;
1544: gnorm=tao->residual;
1545: ierr=PetscViewerASCIIPrintf(viewer,"iter = %D,",its);
1546: ierr=PetscViewerASCIIPrintf(viewer," Function value: %G,",fct);
1547: ierr=PetscViewerASCIIPrintf(viewer," Residual: %G ",gnorm);
1548: PetscViewerASCIIPrintf(viewer," Constraint: %G \n",tao->cnorm);
1549: return(0);
1550: }
1558: /*@C
1559: TaoSolutionMonitor - Views the solution at each iteration
1560: It can be turned on from the command line using the
1561: -tao_view_solution option
1563: Collective on TaoSolver
1565: Input Parameters:
1566: + tao - the TaoSolver context
1567: - ctx - PetscViewer context or PETSC_NULL
1569: Options Database Keys:
1570: . -tao_view_solution
1572: Level: advanced
1574: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1575: @*/
1576: PetscErrorCode TaoSolutionMonitor(TaoSolver tao, void *ctx)
1577: {
1579: PetscViewer viewer;
1581: if (ctx) {
1582: viewer = (PetscViewer)ctx;
1583: } else {
1584: viewer = PETSC_VIEWER_STDOUT_(((PetscObject)tao)->comm);
1585: }
1586: VecView(tao->solution, viewer);
1587: return(0);
1588: }
1592: /*@C
1593: TaoGradientMonitor - Views the gradient at each iteration
1594: It can be turned on from the command line using the
1595: -tao_view_gradient option
1597: Collective on TaoSolver
1599: Input Parameters:
1600: + tao - the TaoSolver context
1601: - ctx - PetscViewer context or PETSC_NULL
1603: Options Database Keys:
1604: . -tao_view_gradient
1606: Level: advanced
1608: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1609: @*/
1610: PetscErrorCode TaoGradientMonitor(TaoSolver tao, void *ctx)
1611: {
1613: PetscViewer viewer;
1615: if (ctx) {
1616: viewer = (PetscViewer)ctx;
1617: } else {
1618: viewer = PETSC_VIEWER_STDOUT_(((PetscObject)tao)->comm);
1619: }
1620: VecView(tao->gradient, viewer);
1621: return(0);
1622: }
1626: /*@C
1627: TaoStepDirectionMonitor - Views the gradient at each iteration
1628: It can be turned on from the command line using the
1629: -tao_view_gradient option
1631: Collective on TaoSolver
1633: Input Parameters:
1634: + tao - the TaoSolver context
1635: - ctx - PetscViewer context or PETSC_NULL
1637: Options Database Keys:
1638: . -tao_view_gradient
1640: Level: advanced
1642: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1643: @*/
1644: PetscErrorCode TaoStepDirectionMonitor(TaoSolver tao, void *ctx)
1645: {
1647: PetscViewer viewer;
1649: if (ctx) {
1650: viewer = (PetscViewer)ctx;
1651: } else {
1652: viewer = PETSC_VIEWER_STDOUT_(((PetscObject)tao)->comm);
1653: }
1654: VecView(tao->stepdirection, viewer);
1655: return(0);
1656: }
1661: /*@C
1662: TaoDrawSolutionMonitor - Plots the solution at each iteration
1663: It can be turned on from the command line using the
1664: -tao_draw_solution option
1666: Collective on TaoSolver
1668: Input Parameters:
1669: + tao - the TaoSolver context
1670: - ctx - PetscViewer context or PETSC_NULL
1672: Options Database Keys:
1673: . -tao_draw_solution
1675: Level: advanced
1677: .seealso: TaoSolutionMonitor(), TaoSetMonitor(), TaoDrawGradientMonitor
1678: @*/
1679: PetscErrorCode TaoDrawSolutionMonitor(TaoSolver tao, void *ctx)
1680: {
1682: PetscViewer viewer = (PetscViewer) ctx;
1683: MPI_Comm comm;
1685: if (!viewer) {
1686: PetscObjectGetComm((PetscObject)tao,&comm);
1687: viewer = PETSC_VIEWER_DRAW_(comm);
1688: }
1689: VecView(tao->solution, viewer);
1690: return(0);
1691: }
1695: /*@C
1696: TaoDrawGradientMonitor - Plots the gradient at each iteration
1697: It can be turned on from the command line using the
1698: -tao_draw_gradient option
1700: Collective on TaoSolver
1702: Input Parameters:
1703: + tao - the TaoSolver context
1704: - ctx - PetscViewer context or PETSC_NULL
1706: Options Database Keys:
1707: . -tao_draw_gradient
1709: Level: advanced
1711: .seealso: TaoGradientMonitor(), TaoSetMonitor(), TaoDrawSolutionMonitor
1712: @*/
1713: PetscErrorCode TaoDrawGradientMonitor(TaoSolver tao, void *ctx)
1714: {
1716: PetscViewer viewer = (PetscViewer)ctx;
1717: MPI_Comm comm;
1719: if (!viewer) {
1720: PetscObjectGetComm((PetscObject)tao,&comm);
1721: viewer = PETSC_VIEWER_DRAW_(comm);
1722: }
1723: VecView(tao->gradient, viewer);
1724: return(0);
1725: }
1729: /*@C
1730: TaoDrawStepMonitor - Plots the step direction at each iteration
1731: It can be turned on from the command line using the
1732: -tao_draw_step option
1734: Collective on TaoSolver
1736: Input Parameters:
1737: + tao - the TaoSolver context
1738: - ctx - PetscViewer context or PETSC_NULL
1740: Options Database Keys:
1741: . -tao_draw_step
1743: Level: advanced
1745: .seealso: TaoSetMonitor(), TaoDrawSolutionMonitor
1746: @*/
1747: PetscErrorCode TaoDrawStepMonitor(TaoSolver tao, void *ctx)
1748: {
1750: PetscViewer viewer = (PetscViewer)(ctx);
1751: MPI_Comm comm;
1753: if (!viewer) {
1754: PetscObjectGetComm((PetscObject)tao,&comm);
1755: viewer = PETSC_VIEWER_DRAW_(comm);
1756: }
1757: VecView(tao->stepdirection, viewer);
1758: return(0);
1759: }
1764: /*@C
1765: TaoSeparableObjectiveMonitor - Views the separable objective function at each iteration
1766: It can be turned on from the command line using the
1767: -tao_view_separableobjective option
1769: Collective on TaoSolver
1771: Input Parameters:
1772: + tao - the TaoSolver context
1773: - ctx - PetscViewer context or PETSC_NULL
1775: Options Database Keys:
1776: . -tao_view_separableobjective
1778: Level: advanced
1780: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
1781: @*/
1782: PetscErrorCode TaoSeparableObjectiveMonitor(TaoSolver tao, void *ctx)
1783: {
1785: PetscViewer viewer;
1787: if (ctx) {
1788: viewer = (PetscViewer)ctx;
1789: } else {
1790: viewer = PETSC_VIEWER_STDOUT_(((PetscObject)tao)->comm);
1791: }
1792: VecView(tao->sep_objective,viewer);
1793: return(0);
1794: }
1798: /*@C
1799: TaoDefaultConvergenceTest - Determines whether the solver should continue iterating
1800: or terminate.
1802: Collective on TaoSolver
1804: Input Parameters:
1805: + tao - the TaoSolver context
1806: - dummy - unused dummy context
1808: Output Parameter:
1809: . reason - for terminating
1811: Notes:
1812: This routine checks the residual in the optimality conditions, the
1813: relative residual in the optimity conditions, the number of function
1814: evaluations, and the function value to test convergence. Some
1815: solvers may use different convergence routines.
1817: Level: developer
1819: .seealso: TaoSetTolerances(),TaoGetTerminationReason(),TaoSetTerminationReason()
1820: @*/
1822: PetscErrorCode TaoDefaultConvergenceTest(TaoSolver tao,void *dummy)
1823: {
1824: PetscInt niter=tao->niter, nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
1825: PetscInt max_funcs=tao->max_funcs;
1826: PetscReal gnorm=tao->residual, gnorm0=tao->gnorm0;
1827: PetscReal f=tao->fc, steptol=tao->steptol,trradius=tao->step;
1828: PetscReal gatol=tao->gatol,grtol=tao->grtol,gttol=tao->gttol;
1829: PetscReal fatol=tao->fatol,frtol=tao->frtol,catol=tao->catol,crtol=tao->crtol;
1830: PetscReal fmin=tao->fmin, cnorm=tao->cnorm, cnorm0=tao->cnorm0;
1831: PetscReal gnorm2;
1832: TaoSolverTerminationReason reason=tao->reason;
1837:
1838: if (reason != TAO_CONTINUE_ITERATING) {
1839: return(0);
1840: }
1841: gnorm2=gnorm*gnorm;
1843: if (PetscIsInfOrNanReal(f)) {
1844: PetscInfo(tao,"Failed to converged, function value is Inf or NaN\n");
1845: reason = TAO_DIVERGED_NAN;
1846: } else if (f <= fmin && cnorm <=catol) {
1847: PetscInfo2(tao,"Converged due to function value %G < minimum function value %G\n", f,fmin);
1848: reason = TAO_CONVERGED_MINF;
1849: } else if (gnorm2 <= fatol && cnorm <=catol) {
1850: PetscInfo2(tao,"Converged due to estimated f(X) - f(X*) = %G < %G\n",gnorm2,fatol);
1851: reason = TAO_CONVERGED_FATOL;
1852: } else if (f != 0 && gnorm2 / PetscAbsReal(f)<= frtol && cnorm/PetscMax(cnorm0,1.0) <= crtol) {
1853: PetscInfo2(tao,"Converged due to estimated |f(X)-f(X*)|/f(X) = %G < %G\n",gnorm2/PetscAbsReal(f),frtol);
1854: reason = TAO_CONVERGED_FRTOL;
1855: } else if (gnorm<= gatol && cnorm <=catol) {
1856: PetscInfo2(tao,"Converged due to residual norm ||g(X)||=%G < %G\n",gnorm,gatol);
1857: reason = TAO_CONVERGED_GATOL;
1858: } else if ( f!=0 && PetscAbsReal(gnorm/f) <= grtol && cnorm <= crtol) {
1859: PetscInfo2(tao,"Converged due to residual ||g(X)||/|f(X)| =%G < %G\n",gnorm/f,grtol);
1860: reason = TAO_CONVERGED_GRTOL;
1861: } else if (gnorm0 != 0 && gnorm/gnorm0 <= gttol && cnorm <= crtol) {
1862: PetscInfo2(tao,"Converged due to relative residual norm ||g(X)||/||g(X0)|| = %G < %G\n",gnorm/gnorm0,gttol);
1863: reason = TAO_CONVERGED_GTTOL;
1864: } else if (nfuncs > max_funcs){
1865: PetscInfo2(tao,"Exceeded maximum number of function evaluations: %D > %D\n", nfuncs,max_funcs);
1866: reason = TAO_DIVERGED_MAXFCN;
1867: } else if ( tao->lsflag != 0 ){
1868: PetscInfo(tao,"Tao Line Search failure.\n");
1869: reason = TAO_DIVERGED_LS_FAILURE;
1870: } else if (trradius < steptol && niter > 0){
1871: PetscInfo2(tao,"Trust region/step size too small: %G < %G\n", trradius,steptol);
1872: reason = TAO_CONVERGED_STEPTOL;
1873: } else if (niter > tao->max_it) {
1874: PetscInfo2(tao,"Exceeded maximum number of iterations: %D > %D\n",niter,tao->max_it);
1875: reason = TAO_DIVERGED_MAXITS;
1876: } else {
1877: reason = TAO_CONTINUE_ITERATING;
1878: }
1879: tao->reason = reason;
1881: return(0);
1882: }
1886: /*@C
1887: TaoSetOptionsPrefix - Sets the prefix used for searching for all
1888: TAO options in the database.
1891: Logically Collective on TaoSolver
1893: Input Parameters:
1894: + tao - the TaoSolver context
1895: - prefix - the prefix string to prepend to all TAO option requests
1897: Notes:
1898: A hyphen (-) must NOT be given at the beginning of the prefix name.
1899: The first character of all runtime options is AUTOMATICALLY the hyphen.
1901: For example, to distinguish between the runtime options for two
1902: different TAO solvers, one could call
1903: .vb
1904: TaoSetOptionsPrefix(tao1,"sys1_")
1905: TaoSetOptionsPrefix(tao2,"sys2_")
1906: .ve
1908: This would enable use of different options for each system, such as
1909: .vb
1910: -sys1_tao_method blmvm -sys1_tao_gtol 1.e-3
1911: -sys2_tao_method lmvm -sys2_tao_gtol 1.e-4
1912: .ve
1915: Level: advanced
1917: .seealso: TaoAppendOptionsPrefix(), TaoGetOptionsPrefix()
1918: @*/
1920: PetscErrorCode TaoSetOptionsPrefix(TaoSolver tao, const char p[])
1921: {
1922: PetscObjectSetOptionsPrefix((PetscObject)tao,p);
1923: return(0);
1924: }
1928: /*@C
1929: TaoAppendOptionsPrefix - Appends to the prefix used for searching for all
1930: TAO options in the database.
1933: Logically Collective on TaoSolver
1935: Input Parameters:
1936: + tao - the TaoSolver solver context
1937: - prefix - the prefix string to prepend to all TAO option requests
1939: Notes:
1940: A hyphen (-) must NOT be given at the beginning of the prefix name.
1941: The first character of all runtime options is AUTOMATICALLY the hyphen.
1944: Level: advanced
1946: .seealso: TaoSetOptionsPrefix(), TaoGetOptionsPrefix()
1947: @*/
1948: PetscErrorCode TaoAppendOptionsPrefix(TaoSolver tao, const char p[])
1949: {
1950: PetscObjectAppendOptionsPrefix((PetscObject)tao,p);
1951: return(0);
1952: }
1956: /*@C
1957: TaoGetOptionsPrefix - Gets the prefix used for searching for all
1958: TAO options in the database
1960: Not Collective
1962: Input Parameters:
1963: . tao - the TaoSolver context
1964:
1965: Output Parameters:
1966: . prefix - pointer to the prefix string used is returned
1968: Notes: On the fortran side, the user should pass in a string 'prefix' of
1969: sufficient length to hold the prefix.
1971: Level: advanced
1973: .seealso: TaoSetOptionsPrefix(), TaoAppendOptionsPrefix()
1974: @*/
1975: PetscErrorCode TaoGetOptionsPrefix(TaoSolver tao, const char *p[])
1976: {
1977: PetscObjectGetOptionsPrefix((PetscObject)tao,p);
1978: return 0;
1979: }
1983: /*@
1984: TaoSetDefaultKSPType - Sets the default KSP type if a KSP object
1985: is created.
1987: Logically Collective on TaoSolver
1989: InputParameters:
1990: + tao - the TaoSolver context
1991: - ktype - the KSP type TAO will use by default
1993: Note: Some solvers may require a particular KSP type and will not work
1994: correctly if the default value is changed
1996: Options Database Key:
1997: - tao_ksp_type
1999: Level: advanced
2000: @*/
2001: PetscErrorCode TaoSetDefaultKSPType(TaoSolver tao, KSPType ktype)
2002: {
2003: const char *prefix=0;
2004: char *option=0;
2005: size_t n1,n2;
2008:
2010: TaoGetOptionsPrefix(tao,&prefix);
2011: PetscStrlen(prefix,&n1);
2012: PetscStrlen("_ksp_type",&n2);
2013: PetscMalloc(n1+n2+1,&option);
2014: PetscStrncpy(option,prefix,n1+1);
2015: PetscStrncat(option,"_ksp_type",n2+1);
2016: PetscOptionsSetValue(option,ktype);
2017: return(0);
2018: }
2022: /*@
2023: TaoSetDefaultLineSearchType - Sets the default LineSearch type if a LineSearch object
2024: is created.
2026: Logically Collective on TaoSolver
2028: InputParameters:
2029: + tao - the TaoSolver context
2030: - lstype - the line search type TAO will use by default
2032: Note: Some solvers may require a particular line search type and will not work
2033: correctly if the default value is changed
2035: Options Database Key:
2036: - tao_ls_type
2038: Level: advanced
2039: @*/
2040: PetscErrorCode TaoSetDefaultLineSearchType(TaoSolver tao, TaoLineSearchType lstype)
2041: {
2042: const char *prefix=0;
2043: char *option=0;
2044: size_t n1,n2;
2047:
2049: TaoGetOptionsPrefix(tao,&prefix);
2050: PetscStrlen(prefix,&n1);
2051: PetscStrlen("_ls_type",&n2);
2052: PetscMalloc(n1+n2+1,&option);
2053: PetscStrncpy(option,prefix,n1+1);
2054: PetscStrncat(option,"_ls_type",n2+1);
2055: PetscOptionsSetValue(option,lstype);
2056: return(0);
2057: }
2061: /*@
2062: TaoSetDefaultPCType - Sets the default PC type if a PC object
2063: is created.
2065: Logically Collective on TaoSolver
2067: InputParameters:
2068: + tao - the TaoSolver context
2069: - pctype - the preconditioner type TAO will use by default
2071: Note: Some solvers may require a particular PC type and will not work
2072: correctly if the default value is changed
2074: Options Database Key:
2075: - tao_pc_type
2077: Level: advanced
2078: @*/
2079: PetscErrorCode TaoSetDefaultPCType(TaoSolver tao, PCType pctype)
2080: {
2081:
2082: const char *prefix=0;
2083: char *option=0;
2084: size_t n1,n2;
2087:
2089: TaoGetOptionsPrefix(tao,&prefix);
2090: PetscStrlen(prefix,&n1);
2091: PetscStrlen("_pc_type",&n2);
2092: PetscMalloc(n1+n2+1,&option);
2093: PetscStrncpy(option,prefix,n1+1);
2094: PetscStrncat(option,"_pc_type",n2+1);
2095: PetscOptionsSetValue(option,pctype);
2096: return(0);
2097: }
2101: /*@C
2102: TaoSetType - Sets the method for the unconstrained minimization solver.
2104: Collective on TaoSolver
2106: Input Parameters:
2107: + solver - the TaoSolver solver context
2108: - type - a known method
2110: Options Database Key:
2111: + -tao_method <type> - Sets the method; use -help for a list
2112: of available methods (for instance, "-tao_method tao_lmvm" or
2113: "-tao_method tao_tron")
2114: - -tao_type <type> - identical to -tao_method
2116: Available methods include:
2117: + tao_nls - Newton's method with line search for unconstrained minimization
2118: . tao_ntr - Newton's method with trust region for unconstrained minimization
2119: . tao_ntl - Newton's method with trust region, line search for unconstrained minimization
2120: . tao_lmvm - Limited memory variable metric method for unconstrained minimization
2121: . tao_cg - Nonlinear conjugate gradient method for unconstrained minimization
2122: . tao_nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
2123: . tao_tron - Newton Trust Region method for bound constrained minimization
2124: . tao_gpcg - Newton Trust Region method for quadratic bound constrained minimization
2125: . tao_blmvm - Limited memory variable metric method for bound constrained minimization
2126: + tao_pounders - Model-based algorithm pounder extended for nonlinear least squares
2128: Level: intermediate
2130: .seealso: TaoCreate(), TaoGetType()
2132: @*/
2133: PetscErrorCode TaoSetType(TaoSolver tao, const TaoSolverType type)
2134: {
2136: PetscErrorCode (*create_xxx)(TaoSolver);
2137: PetscBool issame;
2141:
2142: PetscTypeCompare((PetscObject)tao,type,&issame);
2143: if (issame) return(0);
2145: PetscFListFind(TaoSolverList,((PetscObject)tao)->comm, type, PETSC_TRUE, (void(**)(void))&create_xxx);
2146: if (!create_xxx) {
2147: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested TaoSolver type %s",type);
2148: }
2149:
2151: /* Destroy the existing solver information */
2152: if (tao->ops->destroy) {
2153: (*tao->ops->destroy)(tao);
2154: }
2155: KSPDestroy(&tao->ksp);
2156: TaoLineSearchDestroy(&tao->linesearch);
2157: VecDestroy(&tao->gradient);
2158: VecDestroy(&tao->stepdirection);
2160: tao->ops->setup = 0;
2161: tao->ops->solve = 0;
2162: tao->ops->view = 0;
2163: tao->ops->setfromoptions = 0;
2164: tao->ops->destroy = 0;
2166: tao->setupcalled = PETSC_FALSE;
2168: (*create_xxx)(tao);
2169: PetscObjectChangeTypeName((PetscObject)tao,type);
2170:
2171: return(0);
2172:
2173: }
2176: /*MC
2177: TaoSolverRegister - Adds a method to the TAO package for unconstrained minimization.
2179: Synopsis:
2180: TaoSolverRegister(char *name_solver,char *path,char *name_Create,int (*routine_Create)(TaoSolver))
2182: Not collective
2184: Input Parameters:
2185: + sname - name of a new user-defined solver
2186: . path - path (either absolute or relative) the library containing this solver
2187: . cname - name of routine to Create method context
2188: - func - routine to Create method context
2190: Notes:
2191: TaoSolverRegister() may be called multiple times to add several user-defined solvers.
2193: If dynamic libraries are used, then the fourth input argument (func)
2194: is ignored.
2196: Environmental variables such as ${TAO_DIR}, ${PETSC_ARCH}, ${PETSC_DIR},
2197: and others of the form ${any_environmental_variable} occuring in pathname will be
2198: replaced with the appropriate values used when PETSc and TAO were compiled.
2200: Sample usage:
2201: .vb
2202: TaoSolverRegister("my_solver","/home/username/mylibraries/${PETSC_ARCH}/mylib.a",
2203: "MySolverCreate",MySolverCreate);
2204: .ve
2206: Then, your solver can be chosen with the procedural interface via
2207: $ TaoSetType(tao,"my_solver")
2208: or at runtime via the option
2209: $ -tao_method my_solver
2211: Level: advanced
2213: .seealso: TaoSolverRegisterAll(), TaoSolverRegisterDestroy()
2214: M*/
2215: PetscErrorCode TaoSolverRegister(const char sname[], const char path[], const char cname[], PetscErrorCode (*func)(TaoSolver))
2216: {
2217: char fullname[PETSC_MAX_PATH_LEN];
2221: PetscFListConcat(path,cname,fullname);
2222: PetscFListAdd(&TaoSolverList,sname, fullname,(void (*)(void))func);
2223: return(0);
2224: }
2228: /*@C
2229: TaoSolverRegisterDestroy - Frees the list of minimization solvers that were
2230: registered by TaoSolverRegisterDynamic().
2232: Not Collective
2234: Level: advanced
2236: .seealso: TaoSolverRegisterAll(), TaoSolverRegister()
2237: @*/
2238: PetscErrorCode TaoSolverRegisterDestroy(void)
2239: {
2242: PetscFListDestroy(&TaoSolverList);
2243: TaoSolverRegisterAllCalled = PETSC_FALSE;
2244: return(0);
2245: }
2248: /*@
2249: TaoSetTerminationReason - Sets the termination flag on a TaoSolver object
2251: Logically Collective on TaoSolver
2253: Input Parameters:
2254: + tao - the TaoSolver context
2255: - reason - one of
2256: $ TAO_CONVERGED_ATOL (2),
2257: $ TAO_CONVERGED_RTOL (3),
2258: $ TAO_CONVERGED_STEPTOL (4),
2259: $ TAO_CONVERGED_MINF (5),
2260: $ TAO_CONVERGED_USER (6),
2261: $ TAO_DIVERGED_MAXITS (-2),
2262: $ TAO_DIVERGED_NAN (-4),
2263: $ TAO_DIVERGED_MAXFCN (-5),
2264: $ TAO_DIVERGED_LS_FAILURE (-6),
2265: $ TAO_DIVERGED_TR_REDUCTION (-7),
2266: $ TAO_DIVERGED_USER (-8),
2267: $ TAO_CONTINUE_ITERATING (0)
2269: Level: intermediate
2271: @*/
2272: PetscErrorCode TaoSetTerminationReason(TaoSolver tao, TaoSolverTerminationReason reason)
2273: {
2276: tao->reason = reason;
2277: return(0);
2278: }
2282: /*@
2283: TaoGetTerminationReason - Gets the reason the TaoSolver iteration was stopped.
2285: Not Collective
2287: Input Parameter:
2288: . tao - the TaoSolver solver context
2290: Output Parameter:
2291: . reason - one of
2294: $ TAO_CONVERGED_FATOL (1) f(X)-f(X*) <= fatol
2295: $ TAO_CONVERGED_FRTOL (2) |f(X) - f(X*)|/|f(X)| < frtol
2296: $ TAO_CONVERGED_GATOL (3) ||g(X)|| < gatol
2297: $ TAO_CONVERGED_GRTOL (4) ||g(X)|| / f(X) < grtol
2298: $ TAO_CONVERGED_GTTOL (5) ||g(X)|| / ||g(X0)|| < gttol
2299: $ TAO_CONVERGED_STEPTOL (6) step size small
2300: $ TAO_CONVERGED_MINF (7) F < F_min
2301: $ TAO_CONVERGED_USER (8) User defined
2303: $ TAO_DIVERGED_MAXITS (-2) its > maxits
2304: $ TAO_DIVERGED_NAN (-4) Numerical problems
2305: $ TAO_DIVERGED_MAXFCN (-5) fevals > max_funcsals
2306: $ TAO_DIVERGED_LS_FAILURE (-6) line search failure
2307: $ TAO_DIVERGED_TR_REDUCTION (-7) trust region failure
2308: $ TAO_DIVERGED_USER(-8) (user defined)
2310: $ TAO_CONTINUE_ITERATING (0)
2312: where
2313: + X - current solution
2314: . X0 - initial guess
2315: . f(X) - current function value
2316: . f(X*) - true solution (estimated)
2317: . g(X) - current gradient
2318: . its - current iterate number
2319: . maxits - maximum number of iterates
2320: . fevals - number of function evaluations
2321: - max_funcsals - maximum number of function evaluations
2323: Level: intermediate
2325: .seealso: TaoSetConvergenceTest(), TaoSetTolerances()
2327: @*/
2328: PetscErrorCode TaoGetTerminationReason(TaoSolver tao, TaoSolverTerminationReason *reason)
2329: {
2333: *reason = tao->reason;
2334: return(0);
2335: }
2339: /*@
2340: TaoGetSolutionStatus - Get the current iterate, objective value,
2341: residual, infeasibility, and termination
2343: Not Collective
2345: Input Parameters:
2346: . tao - the TaoSolver context
2348: Output Parameters:
2349: + iterate - the current iterate number (>=0)
2350: . f - the current function value
2351: . gnorm - the square of the gradient norm, duality gap, or other measure
2352: indicating distance from optimality.
2353: . cnorm - the infeasibility of the current solution with regard to the constraints.
2354: . xdiff - the step length or trust region radius of the most recent iterate.
2355: - reason - The termination reason, which can equal TAO_CONTINUE_ITERATING
2357: Level: intermediate
2359: Note:
2360: TAO returns the values set by the solvers in the routine TaoMonitor().
2362: Note:
2363: If any of the output arguments are set to PETSC_NULL, no corresponding value will be returned.
2366: .seealso: TaoMonitor(), TaoGetTerminationReason()
2367: @*/
2368: PetscErrorCode TaoGetSolutionStatus(TaoSolver tao, PetscInt *its, PetscReal *f, PetscReal *gnorm, PetscReal *cnorm, PetscReal *xdiff, TaoSolverTerminationReason *reason)
2369: {
2371: if (its) *its=tao->niter;
2372: if (f) *f=tao->fc;
2373: if (gnorm) *gnorm=tao->residual;
2374: if (cnorm) *cnorm=tao->cnorm;
2375: if (reason) *reason=tao->reason;
2376: if (xdiff) *xdiff=tao->step;
2378: return(0);
2379:
2380: }
2385: /*@C
2386: TaoGetType - Gets the current TaoSolver algorithm.
2388: Not Collective
2390: Input Parameter:
2391: . tao - the TaoSolver solver context
2393: Output Parameter:
2394: . type - TaoSolver method
2396: Level: intermediate
2398: @*/
2399: PetscErrorCode TaoGetType(TaoSolver tao, const TaoSolverType *type)
2400: {
2404: *type=((PetscObject)tao)->type_name;
2405: return(0);
2406: }
2410: /*@C
2411: TaoMonitor - Monitor the solver and the current solution. This
2412: routine will record the iteration number and residual statistics,
2413: call any monitors specified by the user, and calls the convergence-check routine.
2415: Input Parameters:
2416: + tao - the TaoSolver context
2417: . its - the current iterate number (>=0)
2418: . f - the current objective function value
2419: . res - the gradient norm, square root of the duality gap, or other measure
2420: indicating distince from optimality. This measure will be recorded and
2421: used for some termination tests.
2422: . cnorm - the infeasibility of the current solution with regard to the constraints.
2423: - steplength - multiple of the step direction added to the previous iterate.
2425: Output Parameters:
2426: . reason - The termination reason, which can equal TAO_CONTINUE_ITERATING
2428: Options Database Key:
2429: . -tao_monitor - Use the default monitor, which prints statistics to standard output
2431: .seealso TaoGetTerminationReason(), TaoDefaultMonitor(), TaoSetMonitor()
2433: Level: developer
2435: @*/
2436: PetscErrorCode TaoMonitor(TaoSolver tao, PetscInt its, PetscReal f, PetscReal res, PetscReal cnorm, PetscReal steplength, TaoSolverTerminationReason *reason)
2437: {
2439: int i;
2442: tao->fc = f;
2443: tao->residual = res;
2444: tao->cnorm = cnorm;
2445: tao->step = steplength;
2446: tao->niter=its;
2447: TaoLogHistory(tao,f,res,cnorm);
2448: if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(res)) {
2449: SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
2450: }
2451: if (tao->ops->convergencetest) {
2452: (*tao->ops->convergencetest)(tao,tao->cnvP);
2453: }
2454: for (i=0;i<tao->numbermonitors;i++) {
2455: (*tao->monitor[i])(tao,tao->monitorcontext[i]);
2456: }
2457: *reason = tao->reason;
2458:
2459: return(0);
2461: }
2465: /*@
2466: TaoSetHistory - Sets the array used to hold the convergence history.
2468: Logically Collective on TaoSolver
2470: Input Parameters:
2471: + tao - the TaoSolver solver context
2472: . obj - array to hold objective value history
2473: . resid - array to hold residual history
2474: . cnorm - array to hold constraint violation history
2475: . na - size of obj, resid, and cnorm
2476: - reset - PetscTrue indicates each new minimization resets the history counter to zero,
2477: else it continues storing new values for new minimizations after the old ones
2479: Notes:
2480: If set, TAO will fill the given arrays with the indicated
2481: information at each iteration. If no information is desired
2482: for a given array, then PETSC_NULL may be used.
2484: This routine is useful, e.g., when running a code for purposes
2485: of accurate performance monitoring, when no I/O should be done
2486: during the section of code that is being timed.
2488: Level: intermediate
2490: .seealso: TaoGetHistory()
2492: @*/
2493: PetscErrorCode TaoSetHistory(TaoSolver tao, PetscReal *obj, PetscReal *resid, PetscReal *cnorm, PetscInt na,PetscBool reset)
2494: {
2497: tao->hist_obj = obj;
2498: tao->hist_resid = resid;
2499: tao->hist_cnorm = cnorm;
2500: tao->hist_max = na;
2501: tao->hist_reset = reset;
2502: return(0);
2503: }
2507: /*@C
2508: TaoGetHistory - Gets the array used to hold the convergence history.
2510: Collective on TaoSolver
2512: Input Parameter:
2513: . tao - the TaoSolver context
2515: Output Parameters:
2516: + obj - array used to hold objective value history
2517: . resid - array used to hold residual history
2518: . cnorm - array used to hold constraint violation history
2519: - nhist - size of obj, resid, and cnorm (will be less than or equal to na given in TaoSetHistory)
2522: Notes:
2523: The calling sequence for this routine in Fortran is
2524: $ call TaoGetHistory(TaoSolver tao, integer nhist, integer info)
2526: This routine is useful, e.g., when running a code for purposes
2527: of accurate performance monitoring, when no I/O should be done
2528: during the section of code that is being timed.
2530: Level: advanced
2532: .seealso: TaoSetHistory()
2534: @*/
2535: PetscErrorCode TaoGetHistory(TaoSolver tao, PetscReal **obj, PetscReal **resid, PetscReal **cnorm, PetscInt *nhist)
2536: {
2539: if (obj) *obj = tao->hist_obj;
2540: if (cnorm) *cnorm = tao->hist_cnorm;
2541: if (resid) *resid = tao->hist_resid;
2542: if (nhist) *nhist = tao->hist_len;
2543: return(0);
2544: }
2549: /*@
2550: TaoSetApplicationContext - Sets the optional user-defined context for
2551: a solver.
2553: Logically Collective on TaoSolver
2555: Input Parameters:
2556: + tao - the TaoSolver context
2557: - usrP - optional user context
2559: Level: intermediate
2561: .seealso: TaoGetApplicationContext(), TaoSetApplicationContext()
2562: @*/
2563: PetscErrorCode TaoSetApplicationContext(TaoSolver tao,void *usrP)
2564: {
2568: tao->user = usrP;
2569: return(0);
2570: }
2574: /*@
2575: TaoGetApplicationContext - Gets the user-defined context for a
2576: TAO solvers.
2578: Not Collective
2580: Input Parameter:
2581: . tao - TaoSolver context
2583: Output Parameter:
2584: . usrP - user context
2586: Level: intermediate
2588: .seealso: TaoSetApplicationContext()
2589: @*/
2590: PetscErrorCode TaoGetApplicationContext(TaoSolver tao,void *usrP)
2591: {
2594: *(void**)usrP = tao->user;
2595: return(0);
2596: }