Actual source code: tao.c
1: /*$Id$*/
3: #include "src/tao_impl.h" /*I "tao_solver.h" I*/
8: /*@C
9: TaoMonitor - Monitor the solver and the current solution. This
10: routine will calls the records the iteration number and residual statistics,
11: monitors specified by the user, and calls the termaination routine.
13: Input Parameters:
14: + tao - the TAO_SOLVER context
15: . f - the current objective function value
16: . iterate - the current iterate number (>=0)
17: . fnorm - the gradient norm, square root of the duality gap, or other measure
18: indicating distince from optimality. This measure will be recorded and
19: used for some termination tests.
20: . cnorm - the infeasibility of the current solution with regard to the constraints.
21: - step - multiple of the step direction added to the previous iterate.
23: Output Parameters:
24: . reason - The termination reason, which can equal TAO_CONTINUE_ITERATING
26: Options Database Key:
27: . -tao_monitor - The default monitor, which prints statistics to standard output is used.
29: .seealso TaoGetTerminationReason(),TaoGetSolutionStatus()
31: Level: developer
33: .keywords: Monitor, convergence
34: @*/
35: int TaoMonitor(TAO_SOLVER tao, int iterate, double f, double fnorm, double cnorm, double step, TaoTerminateReason *reason)
36: {
37: int i,info;
38: TaoTruth cstop;
39: TaoFunctionBegin;
40: if (iterate>=tao->iter){
41: TaoLogConvHistory(tao,fnorm,tao->iter);
42: tao->norm=fnorm; tao->cnorm=cnorm; tao->fc=f;
43: tao->iter=TaoMax(tao->iter,iterate);
44: tao->step=step;
45: }
46: if (iterate==0){
47: tao->norm0=fnorm; tao->cnorm0=cnorm;
48: }
49: info=TaoCheckConvergence(tao,&tao->reason);CHKERRQ(info);
50: if (iterate>0){
51: info=tao->taoappl->Monitor2(tao->vec_sol,tao->vec_grad,tao->vec_sol_update,&cstop);CHKERRQ(info);
52: if (cstop==TAO_TRUE) tao->reason=TAO_CONVERGED_USER;
53: }
54: for ( i=0; i<tao->numbermonitors; i++ ) {
55: info = (*tao->monitor[i])(tao,tao->monitorcontext[i]);CHKERRQ(info);
56: }
57: info=tao->taoappl->Monitor();CHKERRQ(info);
58: *reason = tao->reason;
60: TaoFunctionReturn(0);
61: }
66: /*@C
67: TaoGetSolutionStatus - Get the current iterate, objective value, residual,
68: infeasibility, and termination
70: Input Parameters:
71: . tao - the TAO_SOLVER context
73: Output Parameters:
74: + iterate - the current iterate number (>=0)
75: . f - the current function value
76: . gnorm - the square of the gradient norm, duality gap, or other measure
77: indicating distance from optimality.
78: . cnorm - the infeasibility of the current solution with regard to the constraints.
79: . xdiff - the step length or trust region radius of the most recent iterate.
80: - reason - The termination reason, which can equal TAO_CONTINUE_ITERATING
82: Level: intermediate
84: Note:
85: TAO returns the values set by the solvers in the routine TaoMonitor().
87: Note:
88: If any of the output arguments are set to TAO_NULL, no value will be
89: returned.
92: .seealso: TaoMonitor(), TaoGetTerminationReason()
94: .keywords: convergence, monitor
95: @*/
96: int TaoGetSolutionStatus(TAO_SOLVER tao, int* iterate, double* f, double* gnorm, double *cnorm, double *xdiff, TaoTerminateReason *reason)
97: {
99: TaoFunctionBegin;
100: if (iterate) *iterate=tao->iter;
101: if (f) *f=tao->fc;
102: if (gnorm) *gnorm=tao->norm;
103: if (cnorm) *cnorm=tao->cnorm;
104: if (reason) *reason=tao->reason;
105: if (xdiff) *xdiff=tao->step;
107: TaoFunctionReturn(0);
108: }
113: /*@C
115: TaoCheckConvergence - Checks the convergence of the solver
117: Collective on TAO_SOLVER
119: Input Parameters:
120: . tao - the TAO_SOLVER context
122: Output Parameters:
123: . reason - one of
125: $ TAO_CONVERGED_ATOL (2), (res <= atol)
126: $ TAO_CONVERGED_RTOL (3), (res/res0 <= rtol)
127: $ TAO_CONVERGED_TRTOL (4), (xdiff <= trtol)
128: $ TAO_CONVERGED_MINF (5), (f <= fmin)
129: $ TAO_CONVERGED_USER (6), (user defined)
131: $ TAO_DIVERGED_MAXITS (-2), (its>maxits)
132: $ TAO_DIVERGED_NAN (-4), (Numerical problems)
133: $ TAO_DIVERGED_MAXFCN (-5), (nfunc > maxnfuncts)
134: $ TAO_DIVERGED_LS_FAILURE (-6), (line search failure)
135: $ TAO_DIVERGED_TR_REDUCTION (-7),
136: $ TAO_DIVERGED_USER (-8), (user defined)
138: $ TAO_CONTINUE_ITERATING (0)
140: where
141: + res - residual of optimality conditions
142: . res0 - initial residual of optimality conditions
143: . xdiff - current trust region size
144: . f - function value
145: . atol - absolute tolerance
146: . rtol - relative tolerance
147: . its - current iterate number
148: . maxits - maximum number of iterates
149: . nfunc - number of function evaluations
150: - maxnfuncts - maximum number of function evaluations
153: Level: advanced
155: .seealso: TaoGetTerminationReason()
157: .keywords: Convergence
159: @*/
160: int TaoCheckConvergence(TAO_SOLVER tao, TaoTerminateReason *reason)
161: {
162: int info;
164: TaoFunctionBegin;
165: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
166: if (tao->converged){
167: info = (*tao->converged)(tao,tao->cnvP);CHKERRQ(info);
168: }
169: if (reason) *reason=tao->reason;
171: TaoFunctionReturn(0);
172: }
176: /*@
177: TaoView - Prints the TAO_SOLVER data structure.
179: Collective on TAO_SOLVER
181: Input Parameters:
182: . tao - the TAO_SOLVER context
184: Options Database Key:
185: . -tao_view - Calls TaoView() at end of TaoSolve()
187: Level: beginner
189: .seealso: TaoGetTerminationReason(), TaoGetSolutionStatus(), TaoViewLinearSolver()
191: .keywords: View
193: @*/
194: int TaoView(TAO_SOLVER tao)
195: {
196: int info;
197: TaoMethod type;
199: TaoFunctionBegin;
200: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
202: info = TaoPrintStatement(tao,"TAO_SOLVER:\n");CHKERRQ(info);
203: info = TaoGetMethod(tao,&type);CHKERRQ(info);
204: if (type) {
205: info = TaoPrintString(tao," method: %s\n",type);CHKERRQ(info);
206: } else {
207: info = TaoPrintStatement(tao," method: not set yet\n");CHKERRQ(info);
208: }
209: if (tao->view) {
210: info = (*tao->view)(tao,tao->data);CHKERRQ(info);
211: }
212:
213: info=TaoPrintDouble(tao," convergence tolerances: fatol=%g,",tao->fatol);CHKERRQ(info);
214: info=TaoPrintDouble(tao," frtol=%g\n",tao->frtol);CHKERRQ(info);
216: info=TaoPrintDouble(tao," convergence tolerances: gatol=%g,",tao->gatol);CHKERRQ(info);
217: info=TaoPrintDouble(tao," trtol=%g,",tao->trtol);CHKERRQ(info);
218: info=TaoPrintDouble(tao," gttol=%g\n",tao->gttol);CHKERRQ(info);
220: info = TaoPrintDouble(tao," Residual in Function/Gradient:=%e\n",tao->norm);CHKERRQ(info);
222: if (tao->cnorm>0 || tao->catol>0 || tao->crtol>0){
223: info=TaoPrintStatement(tao," convergence tolerances:");CHKERRQ(info);
224: info=TaoPrintDouble(tao," catol=%g,",tao->catol);CHKERRQ(info);
225: info=TaoPrintDouble(tao," crtol=%g\n",tao->crtol);CHKERRQ(info);
226: info = TaoPrintDouble(tao," Residual in Constraints:=%e\n",tao->cnorm);CHKERRQ(info);
227: }
229: if (tao->trtol>0){
230: info=TaoPrintDouble(tao," convergence tolerances: trtol=%g\n",tao->trtol);CHKERRQ(info);
231: info=TaoPrintDouble(tao," Final step size/trust region radius:=%g\n",tao->step);CHKERRQ(info);
232: }
234: if (tao->fmin>-1.e25){
235: info=TaoPrintDouble(tao," convergence tolerances: function minimum=%g\n",tao->fmin);CHKERRQ(info);
236: }
237: info = TaoPrintDouble(tao," Objective value=%e\n",tao->fc);CHKERRQ(info);
239: info = TaoPrintInt(tao," total number of iterations=%d, ",tao->iter);CHKERRQ(info);
240: info = TaoPrintInt(tao," (max: %d)\n",tao->max_its);CHKERRQ(info);
242: if (tao->nfuncs>0){
243: info = TaoPrintInt(tao," total number of function evaluations=%d,",tao->nfuncs);CHKERRQ(info);
244: info = TaoPrintInt(tao," max: %d\n",tao->max_funcs);CHKERRQ(info);
245: }
246: if (tao->ngrads>0){
247: info = TaoPrintInt(tao," total number of gradient evaluations=%d,",tao->ngrads);CHKERRQ(info);
248: info = TaoPrintInt(tao," max: %d\n",tao->max_funcs);CHKERRQ(info);
249: }
250: if (tao->nfgrads>0){
251: info = TaoPrintInt(tao," total number of function/gradient evaluations=%d,",tao->nfgrads);CHKERRQ(info);
252: info = TaoPrintInt(tao," (max: %d)\n",tao->max_funcs);CHKERRQ(info);
253: }
254: if (tao->nhesss>0){
255: info = TaoPrintInt(tao," total number of Hessian evaluations=%d\n",tao->nhesss);CHKERRQ(info);
256: }
257: if (tao->linear_its>0){
258: info = TaoPrintInt(tao," total Krylov method iterations=%d\n",tao->linear_its);CHKERRQ(info);
259: }
260: if (tao->nvfunc>0){
261: info = TaoPrintInt(tao," total number of constraint function evaluations=%d\n",tao->nvfunc);CHKERRQ(info);
262: }
263: if (tao->njac>0){
264: info = TaoPrintInt(tao," total number of Jacobian evaluations=%d\n",tao->njac);CHKERRQ(info);
265: }
267: if (tao->reason>0){
268: info = TaoPrintStatement(tao," Solution found\n");CHKERRQ(info);
269: } else {
270: info = TaoPrintInt(tao," Solver terminated: %d\n",tao->reason);CHKERRQ(info);
271: }
273: TaoFunctionReturn(0);
274: }
278: /* ----------- Routines to set solver parameters ---------- */
282: /*@
283: TaoSetGradientTolerances - Sets the stopping criteria in terms of the norm
284: of the Lagrangian function. The algorithm will terminate when the norm
285: of the gradient is less that the absolute tolerance, or when the norm
286: of the gradient has been reduced by a factor of the reduction tolerance,
287: or when the norm of the gradient divided by the absolute value of the
288: objective function is less than the relative tolerance.
290: Collective on TAO_SOLVER
292: Input Parameters:
293: + tao - the TAO_SOLVER solver context
294: . gatol - stop if norm of gradient is less than
295: . grtol - stop if relative norm of gradient is less than
296: - gttol - stop if norm of gradient is reduced by a factor of
298: Options Database Keys:
299: + -tao_gatol <gatol> - sets gatol
300: . -tao_grtol <grtol> - sets grtol
301: - -tao_gttol <gttol> - sets gttol
303: Level: intermediate
305: .keywords: Gradient, options, convergence
307: .seealso: TaoSetTolerances(), TaoGetGradientTolerances()
308: @*/
309: int TaoSetGradientTolerances(TAO_SOLVER tao,double gatol, double grtol, double gttol)
310: {
311: int info;
312: double zero=0.0;
313: TaoFunctionBegin;
314: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
316: if (gatol==TAO_DEFAULT){}
317: else if (gatol<0){
318: info=PetscInfo(tao,"Absolute Gradient tolerance < 0 and ignored"); CHKERRQ(info);
319: CHKERRQ(info); }
320: else{
321: tao->gatol = TaoMax(zero,gatol);
322: }
324: if (grtol==TAO_DEFAULT){}
325: else if (grtol<0){
326: info=PetscInfo(tao,"Relative Gradient tolerance < 0 and ignored");
327: CHKERRQ(info); }
328: else{
329: tao->grtol = TaoMax(zero,grtol);
330: }
332: if (gttol==TAO_DEFAULT){}
333: else if (gttol<0){
334: info=PetscInfo(tao,"Gradient reduction tolerance < 0 and ignored");
335: CHKERRQ(info); }
336: else{
337: tao->gttol = TaoMax(zero,gttol);
338: }
341: TaoFunctionReturn(0);
342: }
344: /* ----------- Routines to set solver parameters ---------- */
348: /*@
349: TaoGetGradientTolerances - Returns the gradient termination tolerances.
351: Collective on TAO_SOLVER
353: Input Parameters:
354: . tao - the TAO_SOLVER tao context
356: Output Parameters:
357: + gatol - the absolute gradient tolerance
358: . grtol - the relative gradient tolerance
359: - gttol - the gradient reduction tolerance
361: Level: intermediate
363: .keywords: options, convergence, View
365: .seealso: TaoSetGradientTolerances()
366: @*/
367: int TaoGetGradientTolerances(TAO_SOLVER tao,double *gatol, double *grtol, double *gttol)
368: {
369: TaoFunctionBegin;
370: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
371: if (gatol) *gatol = tao->gatol;
372: if (grtol) *grtol = tao->grtol;
373: if (gttol) *gttol = tao->gttol;
374: TaoFunctionReturn(0);
375: }
379: /*@
380: TaoSetFunctionLowerBound - Sets a bound on the solution objective value.
381: When an approximate solution with an objective value below this number
382: has been found, the solver will terminate.
384: Collective on TAO_SOLVER
386: Input Parameters:
387: + tao - the TAO_SOLVER solver context
388: - fmin - the tolerance
390: Options Database Keys:
391: . -tao_fmin <fmin> - sets the minimum function value
393: Level: intermediate
395: .keywords: options, View, Bounds,
397: .seealso: TaoSetTolerances()
398: @*/
399: int TaoSetFunctionLowerBound(TAO_SOLVER tao,double fmin)
400: {
401: double dflt=-1.0e+30;
402: TaoFunctionBegin;
403: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
404: if (fmin != TAO_DEFAULT) tao->fmin = fmin;
405: else tao->fmin=dflt;
406: TaoFunctionReturn(0);
407: }
412: /*@
413: TaoSetMaximumIterates - Sets a maximum number of iterates.
415: Collective on TAO_SOLVER
417: Input Parameters:
418: + tao - the TAO_SOLVER solver context
419: - maxits - the maximum number of iterates (>=0)
421: Options Database Keys:
422: . -tao_max_its <its> - sets the maximum number of iterations
424: Level: intermediate
426: .keywords: options, Iterate, convergence
428: .seealso: TaoSetTolerances(), TaoSetMaximumFunctionEvaluations()
429: @*/
430: int TaoSetMaximumIterates(TAO_SOLVER tao,int maxits)
431: {
432: int zero=0;
433: TaoFunctionBegin;
434: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
435: if (maxits != TAO_DEFAULT) tao->max_its = TaoMax(zero,maxits);
436: TaoFunctionReturn(0);
437: }
442: /*@
443: TaoSetMaximumFunctionEvaluations - Sets a maximum number of
444: function evaluations.
446: Collective on TAO_SOLVER
448: Input Parameters:
449: + tao - the TAO_SOLVER solver context
450: - nfcn - the maximum number of function evaluations (>=0)
452: Options Database Keys:
453: . -tao_max_funcs <nfcn> - sets the maximum number of function evaluations
455: Level: intermediate
457: .keywords: options, Iterate, convergence
459: .seealso: TaoSetTolerances(), TaoSetMaximumIterates()
460: @*/
461: int TaoSetMaximumFunctionEvaluations(TAO_SOLVER tao,int nfcn)
462: {
463: int zero=0;
464: TaoFunctionBegin;
465: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
466: if (nfcn != TAO_DEFAULT) tao->max_funcs = TaoMax(zero,nfcn);
467: TaoFunctionReturn(0);
468: }
473: /*@
474: TaoSetTolerances - Sets convergence parameters. TAO tries to satisfy an
475: absolute stopping criteria or a relative stopping criteria.
476:
477: Collective on TAO_SOLVER
479: Input Parameters:
480: + tao - the TAO_SOLVER solver context
481: . fatol - absolute convergence tolerance
482: . frtol - relative convergence tolerance
483: . catol - allowable error in constraints
484: - crtol - allowable relative error in constraints
486: Options Database Keys:
487: + -tao_fatol <fatol> - Sets fatol
488: . -tao_frtol <frtol> - Sets frtol
489: . -tao_catol <catol> - Sets catol
490: - -tao_crtol <crtol> - Sets crtol
492: Absolute Stopping Criteria:
493: $ f <= f + fatol
494: $ B1 - catol <= B(X) <= B2 + catol
496: Relative stopping criteria:
497: $ f <= f + frtol*|f|
498: $ B1 - catol <= B(X) <= B2 + catol
500: Level: beginner
502: .keywords: options, convergence
504: .seealso: TaoSetMaximumIterates(),TaoSetTrustRegionTolerance(), TaoSetGradientTolerances
505: TaoSetMaximumFunctionEvaluations()
506: @*/
507: int TaoSetTolerances(TAO_SOLVER tao,double fatol,double frtol,double catol,double crtol)
508: {
509: int info;
510: double zero=0.0;
511: TaoFunctionBegin;
512: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
514: if (fatol==TAO_DEFAULT){}
515: else if (fatol<0){
516: info=PetscInfo(tao,"Absolute convergence tolerance < 0 and ignored");
517: CHKERRQ(info); }
518: else{
519: tao->fatol = TaoMax(zero,fatol);
520: }
522: if (frtol==TAO_DEFAULT){}
523: else if (frtol<0){
524: info=PetscInfo(tao,"Relative convergence tolerance < 0 and ignored");
525: CHKERRQ(info); }
526: else{
527: tao->frtol = TaoMax(zero,frtol);
528: }
530: if (catol==TAO_DEFAULT){}
531: else if (catol<0){
532: info=PetscInfo(tao,"Absolute constraint tolerance < 0 and ignored");
533: CHKERRQ(info); }
534: else{
535: tao->catol = TaoMax(zero,catol);
536: }
538: if (crtol==TAO_DEFAULT){}
539: else if (crtol<0){
540: info=PetscInfo(tao,"Relative constraint tolerance < 0 and ignored");
541: CHKERRQ(info); }
542: else{
543: tao->crtol = TaoMax(zero,crtol);
544: }
546: TaoFunctionReturn(0);
547: }
553: /*@
554: TaoGetTolerances - Gets convergence parameters.
555:
557: Collective on TAO_SOLVER
559: Input Parameters:
560: . tao - the TAO_SOLVER solver context
562: Input Parameters:
563: + fatol - absolute convergence tolerance
564: . frtol - relative convergence tolerance
565: . catol - trust region convergence tolerance
566: - crtol - convergence of the function evaluates less than this tolerance
568: Level: advanced
570: .keywords: options, convergence
572: .seealso: TaoSetTolerances
573: @*/
574: int TaoGetTolerances(TAO_SOLVER tao,double *fatol,double *frtol,double *catol,double *crtol)
575: {
576: TaoFunctionBegin;
577: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
578: if (fatol) *fatol = tao->fatol;
579: if (frtol) *frtol = tao->frtol;
580: if (catol) *catol = tao->catol;
581: if (crtol) *crtol = tao->crtol;
582: TaoFunctionReturn(0);
583: }
586: /* ------------ Routines to set performance monitoring options ----------- */
590: /*@C
591: TaoSetMonitor - Sets an ADDITIONAL function that is to be used at every
592: iteration of the unconstrained minimization solver to display the iteration's
593: progress.
595: Collective on TAO_SOLVER
597: Input Parameters:
598: + tao - the TAO_SOLVER solver context
599: . mymonitor - monitoring routine
600: - mctx - [optional] user-defined context for private data for the
601: monitor routine (may be TAO_NULL)
603: Calling sequence of mymonitor:
604: $ int mymonitor(TAO_SOLVER tao,void *mctx)
606: + tao - the TAO_SOLVER solver context
607: - mctx - [optional] monitoring context
610: Options Database Keys:
611: + -tao_monitor - sets TaoDefaultMonitor()
612: . -tao_smonitor - sets short monitor
613: - -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.
615: Notes:
616: Several different monitoring routines may be set by calling
617: TaoSetMonitor() multiple times; all will be called in the
618: order in which they were set.
620: Level: intermediate
622: .keywords: options, monitor, View
624: .seealso: TaoDefaultMonitor(), TaoClearMonitor(), TaoSetDestroyRoutine()
625: @*/
626: int TaoSetMonitor(TAO_SOLVER tao,int (*mymonitor)(TAO_SOLVER,void*),void *mctx)
627: {
628: TaoFunctionBegin;
629: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
630: if (tao->numbermonitors >= MAX_TAO_MONITORS) {
631: SETERRQ(1,"Too many monitors set");
632: }
634: tao->monitor[tao->numbermonitors] = mymonitor;
635: tao->monitorcontext[tao->numbermonitors++] = (void*)mctx;
636: TaoFunctionReturn(0);
637: }
641: /*@
642: TaoClearMonitor - Clears all the monitor functions for a TAO_SOLVER object.
644: Collective on TAO_SOLVER
646: Input Parameters:
647: . tao - the TAO_SOLVER solver context
649: Options Database:
650: . -tao_cancelmonitors - cancels all monitors that have been hardwired
651: into a code by calls to TaoSetMonitor(), but does not cancel those
652: set via the options database
654: Notes:
655: There is no way to clear one specific monitor from a TAO_SOLVER object.
657: Level: advanced
659: .keywords: options, monitor, View
661: .seealso: TaoDefaultMonitor(), TaoSetMonitor()
662: @*/
663: int TaoClearMonitor(TAO_SOLVER tao)
664: {
665: TaoFunctionBegin;
666: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
667: tao->numbermonitors = 0;
668: TaoFunctionReturn(0);
669: }
673: /*@C
674: TaoSetConvergenceTest - Sets the function that is to be used
675: to test for convergence of the iterative minimization solution. The
676: new convergence testing routine will replace TAO's default
677: convergence test.
679: Collective on TAO_SOLVER
681: Input Parameters:
682: + tao - the TAO_SOLVER solver context
683: . conv - routine to test for convergence
684: - cctx - [optional] context for private data for the convergence routine
685: (may be TAO_NULL)
687: Calling sequence of conv:
688: $ int conv (TAO_SOLVER tao, void *cctx)
690: + tao - the TAO_SOLVER solver context
691: - cctx - [optional] convergence context
693: Note: The new convergence testing routine should call TaoSetTerminationReason().
695: Level: intermediate
697: .keywords: options, convergence
699: .seealso: TaoSetTerminationReason(), TaoGetSolutionStatus(), TaoGetTolerances(), TaoGetGradientTolerances()
701: @*/
702: int TaoSetConvergenceTest(TAO_SOLVER tao,int (*conv)(TAO_SOLVER,void*),void *cctx)
703: {
704: TaoFunctionBegin;
705: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
706: (tao)->converged = conv;
707: (tao)->cnvP = cctx;
708: TaoFunctionReturn(0);
709: }
714: /*@C
715: TaoGetTerminationReason - Gets the reason the TAO_SOLVER iteration was stopped.
717: Not Collective
719: Input Parameter:
720: . tao - the TAO_SOLVER solver context
722: Output Parameter:
723: . reason - one of
725: $ TAO_CONVERGED_ATOL (2), (res <= atol)
726: $ TAO_CONVERGED_RTOL (3), (res/res0 <= rtol)
727: $ TAO_CONVERGED_TRTOL (4), (xdiff <= trtol)
728: $ TAO_CONVERGED_MINF (5), (f <= fmin)
729: $ TAO_CONVERGED_USER (6), (user defined)
731: $ TAO_DIVERGED_MAXITS (-2), (its>maxits)
732: $ TAO_DIVERGED_NAN (-4), (Numerical problems)
733: $ TAO_DIVERGED_MAXFCN (-5), (nfunc > maxnfuncts)
734: $ TAO_DIVERGED_LS_FAILURE (-6), (line search failure)
735: $ TAO_DIVERGED_TR_REDUCTION (-7),
736: $ TAO_DIVERGED_USER (-8), (user defined)
738: $ TAO_CONTINUE_ITERATING (0)
740: where
741: + res - residual of optimality conditions
742: . res0 - initial residual of optimality conditions
743: . xdiff - current trust region size
744: . f - function value
745: . atol - absolute tolerance
746: . rtol - relative tolerance
747: . its - current iterate number
748: . maxits - maximum number of iterates
749: . nfunc - number of function evaluations
750: - maxnfuncts - maximum number of function evaluations
752: Level: intermediate
754: .keywords: convergence, View
756: .seealso: TaoSetConvergenceTest(), TaoSetTolerances()
757: @*/
758: int TaoGetTerminationReason(TAO_SOLVER tao,TaoTerminateReason *reason)
759: {
760: TaoFunctionBegin;
761: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
762: *reason = tao->reason;
763: TaoFunctionReturn(0);
764: }
768: /*@
769: TaoSetConvergenceHistory - Sets the array used to hold the convergence history.
771: Collective on TAO_SOLVER
773: Input Parameters:
774: + tao - the TAO_SOLVER solver context
775: . a - array to hold history
776: . its - integer array holds the number of linear iterations (or
777: negative if not converged) for each solve.
778: . na - size of a and its
779: - reset - TAO_TRUE indicates each new minimization resets the history counter to zero,
780: else it continues storing new values for new minimizations after the old ones
782: Notes:
783: If set, this array will contain the gradient norms computed at each step.
785: This routine is useful, e.g., when running a code for purposes
786: of accurate performance monitoring, when no I/O should be done
787: during the section of code that is being timed.
789: Level: intermediate
791: .keywords: options, view, monitor, convergence, history
793: .seealso: TaoGetConvergenceHistory()
795: @*/
796: int TaoSetConvergenceHistory(TAO_SOLVER tao, double *a, int *its,int na,TaoTruth reset)
797: {
798: TaoFunctionBegin;
799: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
800: if (na) TaoValidScalarPointer(a,2);
801: tao->conv_hist = a;
802: tao->conv_hist_its = its;
803: tao->conv_hist_max = na;
804: tao->conv_hist_reset = reset;
805: TaoFunctionReturn(0);
806: }
810: /*@C
811: TaoGetConvergenceHistory - Gets the array used to hold the convergence history.
813: Collective on TAO_SOLVER
815: Input Parameter:
816: . tao - the TAO_SOLVER solver context
818: Output Parameters:
819: + a - array to hold history
820: . its - integer array holds the number of linear iterations (or
821: negative if not converged) for each solve.
822: - na - size of a and its
824: Notes:
825: The calling sequence for this routine in Fortran is
826: $ call TaoGetConvergenceHistory(TAO_SOLVER tao, integer na, integer info)
828: This routine is useful, e.g., when running a code for purposes
829: of accurate performance monitoring, when no I/O should be done
830: during the section of code that is being timed.
832: Level: advanced
834: .keywords: convergence, history, monitor, View
836: .seealso: TaoSetConvergencHistory()
838: @*/
839: int TaoGetConvergenceHistory(TAO_SOLVER tao, double **a, int **its,int *na)
840: {
841: TaoFunctionBegin;
842: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
843: if (a) *a = tao->conv_hist;
844: if (its) *its = tao->conv_hist_its;
845: if (na) *na = tao->conv_hist_len;
846: TaoFunctionReturn(0);
847: }
852: /*@
853: TaoSolve - Solves an unconstrained minimization problem. Call TaoSolve()
854: after calling TaoCreate() and optional routines of the form TaoSetXXX().
856: Collective on TAO_SOLVER
858: Input Parameters:
859: . tao - the TAO_SOLVER solver context
861: Notes:
862: By default the TAO solvers use an initial starting guess of zero. To
863: provide an alternative initial guess, the user must call TaoAppSetInitialSolutionVec()
864: before calling TaoSolve().
866: Level: advanced
868: .keywords: Solve
870: .seealso: TaoCreate(), TaoDestroy()
871: @*/
872: int TaoSolve(TAO_SOLVER tao)
873: {
874: int info;
875: TaoVec *xx;
877: TaoFunctionBegin;
878: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
879: info = TaoGetSolution(tao,&xx);CHKERRQ(info);
880: info = tao->taoappl->InitializeVariables(xx);CHKERRQ(info);
881: info = TaoSetUp(tao);CHKERRQ(info);
882: info = TaoSetDefaultStatistics(tao); CHKERRQ(info);
883: if (tao->solve){ info = (*(tao)->solve)(tao,tao->data);CHKERRQ(info); }
884: if (tao->viewtao) { info = TaoView(tao);CHKERRQ(info); }
885: if (tao->viewksptao) { info = TaoViewLinearSolver(tao);CHKERRQ(info); }
886: TaoFunctionReturn(0);
887: }
892: /*@C
893: TaoGetMethod - Gets the TAO_SOLVER method type and name (as a string).
895: Not Collective
897: Input Parameter:
898: . tao - the TAO_SOLVER solver context
900: Output Parameter:
901: . type - TAO_SOLVER method (a charactor string)
903: Level: intermediate
905: .keywords: method
906: @*/
907: int TaoGetMethod(TAO_SOLVER tao, TaoMethod *type)
908: {
909: TaoFunctionBegin;
910: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
911: *type = tao->type_name;
912: TaoFunctionReturn(0);
913: }
918: /*@C
919: TaoSetStepDirectionVector - Sets the vector where the solution update is
920: stored.
922: Not Collective, but Vec is parallel if TAO_SOLVER is parallel
924: Input Parameter:
925: + tao - the TAO_SOLVER solver context
926: - dx - the step direction vector
928: Level: developer
930: .keywords: solution, step direction
932: .seealso: TaoGetSolution(), TaoGetStepDirectionVector()
933: @*/
934: int TaoSetStepDirectionVector(TAO_SOLVER tao,TaoVec* dx)
935: {
936: TaoFunctionBegin;
937: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
938: tao->vec_sol_update=dx;
939: TaoFunctionReturn(0);
940: }
945: /*@C
946: TaoGetStepDirectionVector - Returns the vector where the solution update is
947: stored.
949: Not Collective, but Vec is parallel if TAO_SOLVER is parallel
951: Input Parameter:
952: . tao - the TAO_SOLVER solver context
954: Output Parameter:
955: . xx - the solution update
957: Level: developer
959: .keywords: solution
961: .seealso: TaoGetSolution()
962: @*/
963: int TaoGetStepDirectionVector(TAO_SOLVER tao,TaoVec** xx)
964: {
965: TaoFunctionBegin;
966: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
967: *xx = tao->vec_sol_update;
968: TaoFunctionReturn(0);
969: }
975: /*@
976: TaoSetTrustRegionTolerance - Sets a minimum step size or trust region radius. The
977: solver will terminate when the step size or radius of the trust region is smaller
978: than this tolerance.
979:
980: Collective on TAO_SOLVER
981:
982: Input Parameters:
983: + tao - the TAO_SOLVER solver context
984: - steptol - tolerance
985:
986: Options Database Key:
987: . -tao_steptol <trtol> - Sets steptol
988:
989: Level: intermediate
990:
991: .keywords: options, convergence, trust region
992:
993: .seealso: TaoSetTolerances()
994: @*/
995: int TaoSetTrustRegionTolerance(TAO_SOLVER tao,double steptol)
996: {
997: double zero=0.0, dflt=0.0;
999: TaoFunctionBegin;
1000: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1001: if (steptol != TAO_DEFAULT) tao->xtol = TaoMax(zero,steptol);
1002: else tao->xtol=dflt;
1003: tao->trtol=steptol;
1004: TaoFunctionReturn(0);
1005: }
1009: /*@
1010: TaoGetTrustRegionRadius - Gets the current trust region radius
1012: Collective on TAO_SOLVER
1014: Input Parameter:
1015: . tao - a TAO optimization solver
1017: Output Parameter:
1018: . radius - the trust region radius
1020: Level: advanced
1022: .keywords: options, view, trust region
1024: .seealso: TaoSetTrustRegionRadius(), TaoSetTrustRegionTolerance()
1025: @*/
1026: int TaoGetTrustRegionRadius(TAO_SOLVER tao,double *radius)
1027: {
1028: TaoFunctionBegin;
1029: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1030: *radius=tao->step;
1031: TaoFunctionReturn(0);
1032: }
1035: /*@C
1036: TaoGetInitialTrustRegionRadius - Gets the initial trust region radius
1038: Collective on TAO_SOLVER
1040: Input Parameter:
1041: . tao - a TAO optimization solver
1043: Output Parameter:
1044: . radius - the initial trust region radius
1046: Level: intermediate
1048: .keywords: options, trust region
1050: .seealso: TaoGetTrustRegionRadius(), TaoSetTrustRegionRadius()
1051: @*/
1052: int TaoGetInitialTrustRegionRadius(TAO_SOLVER tao,double *radius)
1053: {
1054: TaoFunctionBegin;
1055: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1056: *radius=tao->trust0;
1057: TaoFunctionReturn(0);
1058: }
1062: /*@
1063: TaoSetTrustRegionRadius - Sets the initial trust region radius.
1065: Collective on TAO_SOLVER
1067: Input Parameter:
1068: + tao - a TAO optimization solver
1069: - radius - the trust region radius
1071: Level: intermediate
1073: Options Database Key:
1074: . -tao_trust0
1076: .keywords: trust region
1078: .seealso: TaoGetTrustRegionRadius(), TaoSetTrustRegionTolerance()
1079: @*/
1080: int TaoSetTrustRegionRadius(TAO_SOLVER tao,double radius)
1081: {
1082: TaoFunctionBegin;
1083: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1084: tao->trust0=radius;
1085: tao->step=radius;
1086: TaoFunctionReturn(0);
1087: }
1092: /*@
1093: TaoSetVariableBounds - Sets lower and upper bounds on the variables.
1095: Collective on TAO_SOLVER
1097: Input Parameters:
1098: + tao - the TAO_SOLVER solver context
1099: . xxll - vector of lower bounds upon the solution vector
1100: - xxuu - vector of upper bounds upon the solution vector
1102: Level: developer
1104: .keywords: bounds
1106: .seealso: TaoGetVariableBounds(), TaoAppSetVariableBounds()
1107: @*/
1108: int TaoSetVariableBounds(TAO_SOLVER tao,TaoVec *xxll,TaoVec *xxuu)
1109: {
1110: int info;
1111: double dd;
1112: TaoVec *xx;
1113: TaoTruth flag;
1115: TaoFunctionBegin;
1116: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1117: info=TaoGetSolution(tao,&xx);CHKERRQ(info);
1118: if (xxll){
1119: info=xx->Compatible(xxll,&flag); CHKERRQ(info);
1120: if (flag == TAO_FALSE){
1121: SETERRQ(1,"Vector of lower bounds not Compatible with Variable Vector");
1122: }
1123: if (tao->XL==0){
1124: dd=-TAO_INFINITY;
1125: info = xxll->SetToConstant(dd); CHKERRQ(info);
1126: }
1127: }
1128: if (xxuu){
1129: info=xx->Compatible(xxuu,&flag); CHKERRQ(info);
1130: if (flag == TAO_FALSE){
1131: SETERRQ(1,"Vector of upper bounds not Compatible with Variable vector");
1132: }
1133: if (tao->XU==0){
1134: dd= TAO_INFINITY;
1135: info = xxuu->SetToConstant(dd); CHKERRQ(info);
1136: }
1137: }
1138: tao->XL=xxll;
1139: tao->XU=xxuu;
1140: TaoFunctionReturn(0);
1141: }
1145: /*@
1146: TaoGetDualVariables - Gets the dual variables corresponding to
1147: the bounds of the variables.
1149: Collective on TAO_SOLVER
1151: Input Parameter:
1152: + tao - the TAO_SOLVER solver context
1153: . DXL - vector to place the dual variables of the lower bounds
1154: - DXU - vector to place the dual variables of the upper bounds
1156: Output Parameter:
1157: + DXL - dual variables of the lower bounds
1158: - DXU - dual variables of the upper bounds
1160: Level: advanced
1162: .keywords: dual, bounds
1164: .seealso: TaoGetVariableBounds()
1165: @*/
1166: int TaoGetDualVariables(TAO_SOLVER tao, TaoVec *DXL, TaoVec *DXU)
1167: {
1168: int info;
1169: TaoTruth flag;
1170: TaoVec *XL, *XU;
1172: TaoFunctionBegin;
1173: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1174: info=TaoGetVariableBounds(tao,&XL,&XU);CHKERRQ(info);
1176: info=DXU->Compatible(XU,&flag); CHKERRQ(info);
1177: if (flag == TAO_FALSE){
1178: SETERRQ(1,"Dual bound vectors not Compatible");
1179: }
1181: info=DXL->Compatible(XL,&flag); CHKERRQ(info);
1182: if (flag == TAO_FALSE){
1183: SETERRQ(1,"Dual bound vectors not Compatible");
1184: }
1186: if (tao->CopyDuals){
1187: info = (*tao->CopyDuals)(tao,DXL,DXU,tao->data);CHKERRQ(info);
1188: } else {
1189: info=DXL->SetToZero();CHKERRQ(info);
1190: info=DXU->SetToZero();CHKERRQ(info);
1191: }
1193: TaoFunctionReturn(0);
1194: }
1199: /* ---------------------------------------------------------- */
1200: /* @C
1201: TaoSetInitialVector - Sets the initial vector used by the TAO
1202: solver.
1204: Collective on TAO_SOLVER
1206: Input Parameters:
1207: + tao - the TAO solver
1208: - xx0 - vector used for initial point (set xx0==TAO_NULL for default)
1210: Notes:
1211: By default the TAO solvers use an initial starting guess of zero.
1212: To provide an alternative initial guess, the user must call
1213: TaoSetInitialVector() before calling TaoSolve().
1215: This vector will replace the variable vector set in the TaoCreate() routine.
1217: The user is responsible for destroying this vector.
1219: If this vector is TAO_NULL, TAO will use the set the previous variable
1220: vector to a default starting point.
1222: Level: developer
1224: .seealso: TaoSolve(), TaoGetSolution()
1225: @ */
1226: int TaoSetInitialVector(TAO_SOLVER tao,TaoVec *xx0)
1227: {
1228: int info;
1229: TaoTruth flag;
1230: TaoVec* X;
1232: TaoFunctionBegin;
1233: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1234: if (xx0==TAO_NULL){
1235: // tao->userstart=TAO_FALSE;
1236: } else {
1237: info=TaoGetSolution(tao,&X);CHKERRQ(info);
1238: info=X->Compatible(xx0,&flag);CHKERRQ(info);
1239: if (flag == TAO_FALSE){
1240: SETERRQ(1,"New TAO variable vector must have identical structure as the previous variable vector.");
1241: }
1242: tao->vec_sol=xx0;
1243: /* info=X->CopyFrom(xx0);CHKERRQ(info); */
1244: // tao->userstart=TAO_TRUE;
1245: }
1246: TaoFunctionReturn(0);
1247: }
1252: /*@C
1253: TaoGetVariableBounds - Sets the vector pointers to the vectors
1254: containing the upper and lower bounds on the variables.
1256: Collective on TAO_SOLVER
1258: Input Parameter:
1259: . tao - the TAO_SOLVER solver context
1261: Output Parameters:
1262: + xxll - Pointer to lower bounds on all the variables
1263: - xxuu - Pointer to upper bounds on all the variables
1265: Level: advanced
1267: .keywords: bounds, View
1269: @*/
1270: int TaoGetVariableBounds(TAO_SOLVER tao,TaoVec **xxll,TaoVec **xxuu)
1271: {
1272: TaoFunctionBegin;
1273: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1274: if (xxll){
1275: *xxll=tao->XL;
1276: }
1277: if (xxuu){
1278: *xxuu=tao->XU;
1279: }
1280: TaoFunctionReturn(0);
1281: }
1283: /* ---------------------------------------------------------- */
1286: /*@C
1287: TaoSetTerminationReason - Sets the termination reason
1289: Collective on TAO_SOLVER
1291: Input Parameters:
1292: + tao - the TAO_SOLVER context
1293: - reason - one of
1295: $ TAO_CONVERGED_ATOL (2), (res <= atol)
1296: $ TAO_CONVERGED_RTOL (3), (res/res0 <= rtol)
1297: $ TAO_CONVERGED_TRTOL (4), (xdiff <= trtol)
1298: $ TAO_CONVERGED_MINF (5), (f <= fmin)
1299: $ TAO_CONVERGED_USER (6), (user defined)
1301: $ TAO_DIVERGED_MAXITS (-2), (its>maxits)
1302: $ TAO_DIVERGED_NAN (-4), (Numerical problems)
1303: $ TAO_DIVERGED_MAXFCN (-5), (nfunc > maxnfuncts)
1304: $ TAO_DIVERGED_LS_FAILURE (-6), (line search failure)
1305: $ TAO_DIVERGED_TR_REDUCTION (-7),
1306: $ TAO_DIVERGED_USER (-8), (user defined)
1308: $ TAO_CONTINUE_ITERATING (0)
1310: where
1311: + res - residual of optimality conditions
1312: . res0 - initial residual of optimality conditions
1313: . xdiff - current trust region size
1314: . f - function value
1315: . atol - absolute tolerance
1316: . rtol - relative tolerance
1317: . its - current iterate number
1318: . maxits - maximum number of iterates
1319: . nfunc - number of function evaluations
1320: - maxnfuncts - maximum number of function evaluations
1323: Output Parameter:
1325: Level: intermediate
1327: .seealso TaoGetTerminationReason(), TaoAppSetMonitor(), TaoSetMonitor()
1329: .keywords: convergence
1331: @*/
1332: int TaoSetTerminationReason(TAO_SOLVER tao,TaoTerminateReason reason)
1333: {
1334: TaoFunctionBegin;
1335: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
1337: tao->reason=reason;
1339: TaoFunctionReturn(0);
1340: }
1343: /* ------------ Routines to called when destroying this application ----------- */
1346: /*@C
1347: TaoSetDestroyRoutine - Sets an ADDITIONAL function that will be called when
1348: this object is destroyed.
1350: Collective on TAO_SOLVER
1352: Input Parameters:
1353: + taoapp - the TAO_SOLVER solver context
1354: . destroy - function pointer
1355: - mctx - [optional] user-defined context for private data for the
1356: destroy routine (may be TAO_NULL)
1358: Calling sequence of destroy:
1359: $ int mydestroy(void *mctx)
1361: . mctx - [optional] destroy context
1364: Level: intermediate
1366: .keywords: destroy
1368: .seealso: TaoSetMonitor(), TaoDestroy()
1369: @*/
1370: int TaoSetDestroyRoutine(TAO_SOLVER tao,int (*destroy)(void*),void *mctx)
1371: {
1372: TaoFunctionBegin;
1373: if (destroy){
1374: if (tao->numberdestroyers >= MAX_TAO_DESTROY) {
1375: SETERRQ(1,"TAO ERRROR: Too many TAO destroy routines set");
1376: }
1377:
1378: tao->userdestroy[tao->numberdestroyers] = destroy;
1379: tao->userctxdestroy[tao->numberdestroyers++] = mctx;
1380: }
1381: TaoFunctionReturn(0);
1382: }