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: }