Actual source code: tao_util.c
1: /*$Id$*/
3: #include "src/tao_impl.h" /*I "tao_solver.h" I*/
8: /*@C
9: TaoVecViewMonitor - Monitors progress of the TAO_SOLVER solvers by calling
10: VecView() for the approximate solution at each iteration.
12: Collective on TAO_SOLVER
14: Input Parameters:
15: + tao - the TAO_SOLVER context
16: - dummy - either a viewer or TAO_NULL
18: Level: advanced
20: .keywords: TAO_SOLVER, vector, monitor, view
22: .seealso: TaoSetMonitor(), TaoDefaultMonitor(), VecView()
23: @*/
24: int TaoVecViewMonitor(TAO_SOLVER tao,void *dummy)
25: {
26: int info;
27: TaoVec *xx;
29: TaoFunctionBegin;
30: info = TaoGetSolution(tao,&xx);CHKERRQ(info);
31: info = xx->View();CHKERRQ(info);
32: TaoFunctionReturn(0);
33: }
37: /*@C
38: TaoVecViewMonitorUpdate - Monitors progress of the TAO_SOLVER solvers by calling
39: VecView() for the UPDATE to the solution at each iteration.
41: Collective on TAO_SOLVER
43: Input Parameters:
44: + tao - the TAO_SOLVER context
45: - dummy - either a viewer or TAO_NULL
47: Level: advanced
49: .keywords: TAO_SOLVER, vector, monitor, view
51: .seealso: TaoSetMonitor(), TaoDefaultMonitor(), VecView()
52: @*/
53: int TaoVecViewMonitorUpdate(TAO_SOLVER tao,void *dummy)
54: {
55: int info;
56: TaoVec *xx;
58: TaoFunctionBegin;
59: info = TaoGetStepDirectionVector(tao,&xx);CHKERRQ(info);
60: if (xx){ info = xx->View();CHKERRQ(info); }
61: TaoFunctionReturn(0);
62: }
66: /*@C
67: TaoDefaultMonitor - Default routine for monitoring progress of the
68: TAO_SOLVER solvers (default).
70: Collective on TAO_SOLVER
72: Input Parameters:
73: + tao - the TAO_SOLVER context
74: - dummy - unused context
76: Notes:
77: The routine prints the function value and gradient norm at each iteration.
79: Level: advanced
81: .keywords: TAO_SOLVER, default, monitor, norm
83: .seealso: TaoSetMonitor(), TaoVecViewMonitor()
84: @*/
85: int TaoDefaultMonitor(TAO_SOLVER tao,void *dummy)
86: {
87: int info;
88: TaoInt its;
89: double fct,gnorm;
91: TaoFunctionBegin;
92: its=tao->iter;
93: fct=tao->fc;
94: gnorm=tao->norm;
95: info=TaoPrintInt(tao,"iter = %d,",its); CHKERRQ(info);
96: info=TaoPrintDouble(tao," Function value: %12.10e,",fct); CHKERRQ(info);
97: info=TaoPrintDouble(tao," Residual: %12.10e \n",gnorm);CHKERRQ(info);
98: TaoFunctionReturn(0);
99: }
103: /*
104: Default (short) TAO_SOLVER Monitor, same as TaoDefaultMonitor() except
105: it prints fewer digits of the residual as the residual gets smaller.
106: This is because the later digits are meaningless and are often
107: different on different machines; by using this routine different
108: machines will usually generate the same output.
109: */
110: int TaoDefaultSMonitor(TAO_SOLVER tao,void *dummy)
111: {
112: int info;
113: TaoInt its;
114: double fct,gnorm;
116: TaoFunctionBegin;
117: its=tao->iter;
118: fct=tao->fc;
119: gnorm=tao->norm;
121: if (gnorm > 1.e-6) {
122: info=TaoPrintInt(tao,"iter = %d,",its); CHKERRQ(info);
123: info=TaoPrintDouble(tao," Function value %g,",fct); CHKERRQ(info);
124: info=TaoPrintDouble(tao," Residual: %7.6f \n",gnorm);CHKERRQ(info);
125: } else if (gnorm > 1.e-11) {
126: info=TaoPrintInt(tao,"iter = %d,",its); CHKERRQ(info);
127: info=TaoPrintDouble(tao," Function value %g,",fct); CHKERRQ(info);
128: info=TaoPrintStatement(tao," Residual: < 1.0e-6 \n");
129: } else {
130: info=TaoPrintInt(tao,"iter = %d,",its); CHKERRQ(info);
131: info=TaoPrintDouble(tao," Function value %g,",fct); CHKERRQ(info);
132: info=TaoPrintStatement(tao," Residual: < 1.0e-11 \n");
133: }
134: TaoFunctionReturn(0);
135: }
138: /* ---------------------------------------------------------- */
141: /*@
142: TaoConverged_MaxIts - Determines whether the solver has reached maximum number
143: of iterations.
145: Collective on TAO_SOLVER
147: Input Parameters:
148: + tao - the TAO_SOLVER context
149: - dummy - unused dummy context
151: Level: developer
153: .seealso: TaoSetTolerances(),TaoGetTerminationReason(),TaoSetTerminationReason()
154: @*/
155: int TaoConverged_MaxIts(TAO_SOLVER tao,void *dummy)
156: {
157: int info;
158: TaoInt its, maxits=tao->max_its;
159: TaoTerminateReason reason=TAO_CONTINUE_ITERATING;
161: TaoFunctionBegin;
162: info = TaoGetSolutionStatus(tao,&its,0,0,0,0,0);CHKERRQ(info);
163: if (its >= maxits) {
164: info = PetscInfo2(tao,"TaoConverged_Default: Exceeded maximum number of iterations: %d > %d\n",its,maxits); CHKERRQ(info);
165: reason = TAO_DIVERGED_MAXITS;
166: info = TaoSetTerminationReason(tao,reason); CHKERRQ(info);
167: }
168: TaoFunctionReturn(0);
169: }
171: /* ---------------------------------------------------------- */
174: /*@
175: TaoConverged_Default - Determines whether the solver should continue iterating
176: or terminate.
178: Collective on TAO_SOLVER
180: Input Parameters:
181: + tao - the TAO_SOLVER context
182: - dummy - unused dummy context
184: Output Parameter:
185: . reason - for terminating
187: Notes:
188: This routine checks the residual in the optimality conditions, the
189: relative residual in the optimity conditions, the number of function
190: evaluations, and the function value to test convergence. Some
191: solvers may use different convergence routines.
193: Level: developer
195: .seealso: TaoSetTolerances(),TaoGetTerminationReason(),TaoSetTerminationReason()
196: @*/
197: int TaoConverged_Default(TAO_SOLVER tao,void *dummy)
198: {
199: int info;
200: TaoInt its;
201: TaoInt nfuncs=tao->nfuncs+tao->ngrads+tao->nfgrads, max_funcs=tao->max_funcs;
202: double gnorm, gnorm0=tao->norm0;
203: double f, trtol=tao->trtol,trradius=tao->step;
204: double gatol,grtol,gttol,fatol,frtol,catol,crtol;
205: double fmin=tao->fmin, cnorm, cnorm0=tao->cnorm0;
206: double gnorm2;
207: TaoTerminateReason reason=TAO_CONTINUE_ITERATING;
209: TaoFunctionBegin;
210: info = TaoGetSolutionStatus(tao,&its,&f,&gnorm,&cnorm,&trradius,&reason);
211: info = TaoGetTolerances(tao,&fatol,&frtol,&catol,&crtol);CHKERRQ(info);
212: info = TaoGetGradientTolerances(tao,&gatol,&grtol,>tol);CHKERRQ(info);
213: gnorm2=gnorm*gnorm;
215: if (f != f ) {
216: info = PetscInfo(tao,"TaoConverged_Default: Failed to converged, function is NaN\n"); CHKERRQ(info);
217: reason = TAO_DIVERGED_NAN;
218: } else if (f <= fmin && cnorm <=catol) {
219: info = PetscInfo2(tao,"TaoConverged_Default: Converged due to function value %g < minimum function value %g\n", f,fmin); CHKERRQ(info);
220: reason = TAO_CONVERGED_MINF;
221: } else if (gnorm2 <= fatol && cnorm <=catol) {
222: info = PetscInfo2(tao,"TaoConverged_Default: Converged due to residual norm %g < %g\n",gnorm2,fatol); CHKERRQ(info);
223: reason = TAO_CONVERGED_ATOL;
224: } else if (gnorm2 / TaoAbsScalar(f+1.0e-10)<= frtol && cnorm/TaoMax(cnorm0,1.0) <= crtol) {
225: info = PetscInfo2(tao,"TaoConverged_Default: Converged due to relative residual norm %g < %g\n",gnorm2/TaoAbsScalar(f+1.0e-10),frtol); CHKERRQ(info);
226: reason = TAO_CONVERGED_RTOL;
227: } else if (gnorm<= gatol && cnorm <=catol) {
228: info = PetscInfo2(tao,"TaoConverged_Default: Converged due to residual norm %g < %g\n",gnorm,gatol); CHKERRQ(info);
229: reason = TAO_CONVERGED_ATOL;
230: } else if ( f!=0 && TaoAbsScalar(gnorm/f) <= grtol && cnorm <= crtol) {
231: info = PetscInfo3(tao,"TaoConverged_Default: Converged due to residual norm %g < |%g| %g\n",gnorm,f,grtol); CHKERRQ(info);
232: reason = TAO_CONVERGED_ATOL;
233: } else if (gnorm/gnorm0 <= gttol && cnorm <= crtol) {
234: info = PetscInfo2(tao,"TaoConverged_Default: Converged due to relative residual norm %g < %g\n",gnorm/gnorm0,gttol); CHKERRQ(info);
235: reason = TAO_CONVERGED_RTOL;
236: } else if (nfuncs > max_funcs){
237: info = PetscInfo2(tao,"TaoConverged_Default: Exceeded maximum number of function evaluations: %d > %d\n", nfuncs,max_funcs); CHKERRQ(info);
238: reason = TAO_DIVERGED_MAXFCN;
239: } else if ( tao->lsflag != 0 ){
240: info = PetscInfo(tao,"TaoConverged_Default: Tao Line Search failure.\n"); CHKERRQ(info);
241: reason = TAO_DIVERGED_LS_FAILURE;
242: } else if (trradius < trtol && its > 0){
243: info = PetscInfo2(tao,"TaoConverged_Default: Trust region/step size too small: %g < %g\n", trradius,trtol); CHKERRQ(info);
244: reason = TAO_CONVERGED_TRTOL;
245: } else {
246: reason = TAO_CONTINUE_ITERATING;
247: }
248: info = TaoSetTerminationReason(tao,reason); CHKERRQ(info);
249: info=TaoConverged_MaxIts(tao,0); CHKERRQ(info);
250: TaoFunctionReturn(0);
251: }
253: /* ---------------------------------------------------------- */
256: /*@C
257: TaoCheckFG - Check if the function and gradient vectors have
258: been set properly and are compatible.
260: Collective on TAO_SOLVER
262: Input Parameters:
263: . tao - the TAO_SOLVER context
265: Level: developer
267: .seealso: TaoCheckFGH()
268: @*/
269: int TaoCheckFG(TAO_SOLVER tao)
270: {
271: TaoVec *xx,*gg;
272: TaoTruth flag;
273: int info;
275: TaoFunctionBegin;
276: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
278: info=TaoGetSolution(tao,&xx);CHKERRQ(info);
279: info=TaoGetGradient(tao,&gg);CHKERRQ(info);
281: info=xx->Compatible(gg,&flag);CHKERRQ(info);
282: if (flag==TAO_FALSE){
283: SETERRQ(1,"Gradient and Variable vectors must have identical structure.");
284: }
286: TaoFunctionReturn(0);
287: }
291: /*@C
292: TaoCheckFGH - Check if the function, gradient vector, and
293: Hessian matrix have been set properly and are compatible.
295: Collective on TAO_SOLVER
297: Input Parameters:
298: . tao - the TAO_SOLVER context
300: Level: developer
302: .seealso: TaoCheckFG()
303: @*/
304: int TaoCheckFGH(TAO_SOLVER tao)
305: {
306: int info;
307: TaoMat *HH;
308: TaoFunctionBegin;
309:
310: info=TaoCheckFG(tao);CHKERRQ(info);
311: info = TaoGetHessian(tao,&HH);CHKERRQ(info);
312: if (!HH) {
313: SETERRQ(1,"Must Provide Hessian Matrix");
314: }
316: TaoFunctionReturn(0);
317: }
321: /*@C
322: TaoCheckConstraints - Check if the nonlinear constraints have
323: been set and if the data structures are compatible.
325: Collective on TAO_SOLVER
327: Input Parameters:
328: . tao - the TAO_SOLVER context
330: Level: developer
332: .seealso: TaoCheckFG()
333: @*/
334: int TaoCheckConstraints(TAO_SOLVER tao)
335: {
336: TaoVec *solu, *cons;
337: TaoMat *jac;
338: TaoTruth flag;
339: int info;
341: TaoFunctionBegin;
342: TaoValidHeaderSpecific(tao,TAO_COOKIE,1);
344: info = TaoGetSolution(tao, &solu); CHKERRQ(info);
345: info = TaoGetConstraints(tao, &cons); CHKERRQ(info);
346: info = TaoGetJacobian(tao, &jac); CHKERRQ(info);
347:
348: info = jac->Compatible(solu,cons,&flag);CHKERRQ(info);
349: if (flag == TAO_FALSE){
350: SETERRQ(1,"Jacobian matrix not consistent with Variable Vector or Constraint Vector");
351: }
353: TaoFunctionReturn(0);
354: }
355:
358: /*@C
359: TaoCheckBounds - Check if the variable bounds have been
360: set and the data structures are compatible.
362: Collective on TAO_SOLVER
364: Input Parameters:
365: . tao - the TAO_SOLVER context
367: Level: developer
369: .seealso: TaoCheckFG()
370: @*/
371: int TaoCheckBounds(TAO_SOLVER tao)
372: {
373: int info;
374: TaoTruth flag;
375: TaoVec *xx,*xxll,*xxuu;
377: info=TaoGetSolution(tao,&xx);CHKERRQ(info);
378: info=TaoGetVariableBounds(tao,&xxll,&xxuu);CHKERRQ(info);
380: info=xx->Compatible(xxll,&flag);CHKERRQ(info);
381: if (flag==TAO_FALSE){
382: SETERRQ(1,"Vector of lower bounds not Compatible with Variable Vector");
383: }
385: info=xx->Compatible(xxuu,&flag);CHKERRQ(info);
386: if (flag==TAO_FALSE){
387: SETERRQ(1,"Vector of upper bounds not Compatible with Variable vector");
388: }
390: TaoFunctionReturn(0);
391: }
393: static int TaoDefaultMeritFunction(TAO_SOLVER,TaoVec*,double*,void*);
394: static int TaoDefaultMeritFunctionGradient(TAO_SOLVER,TaoVec*,double*,TaoVec*,void*);
395: static int TaoDefaultMeritGradient(TAO_SOLVER,TaoVec*,TaoVec*,void*);
399: static int TaoDefaultMeritFunction(TAO_SOLVER tao, TaoVec *xx, double *f, void *ctx)
400: {
401: int info;
403: TaoFunctionBegin;
404: info=TaoComputeFunction(tao,xx,f);CHKERRQ(info);
405: TaoFunctionReturn(0);
406: }
410: static int TaoDefaultMeritFunctionGradient(TAO_SOLVER tao, TaoVec *xx, double *f, TaoVec *gg, void *ctx)
411: {
412: int info;
414: TaoFunctionBegin;
415: info=TaoComputeFunctionGradient(tao,xx,f,gg);CHKERRQ(info);
416: TaoFunctionReturn(0);
417: }
421: static int TaoDefaultMeritGradient(TAO_SOLVER tao, TaoVec *xx, TaoVec *gg, void *ctx)
422: {
423: int info;
425: TaoFunctionBegin;
426: info=TaoComputeGradient(tao,xx,gg);CHKERRQ(info);
427: TaoFunctionReturn(0);
428: }
434: /*@
435: TaoSetDefaultMeritFunction - Set the merit function equal to the
436: objective function
438: Collective on TAO_SOLVER
440: Input Parameters:
441: . tao - the TAO_SOLVER context
443: Level: developer
445: @*/
446: int TaoSetDefaultMeritFunction(TAO_SOLVER tao)
447: {
448: int info;
449: TaoFunctionBegin;
450: info=TaoSetMeritFunction(tao,TaoDefaultMeritFunction,TaoDefaultMeritFunctionGradient,TaoDefaultMeritGradient,0,0);
451: CHKERRQ(info);
452: TaoFunctionReturn(0);
453: }
456: /* @C
457: TaoSetQuadraticMeritFunction - Set the merit function to a quadratic
458: objective function 1/2 x^T A x + b^T x + c
460: Collective on TAO_SOLVER
462: Input Parameters:
463: + tao - the TAO_SOLVER context
464: . A - The matrix term of the quadratic function
465: . b - The linear term of the quadratic function
466: - c - The constant term of the quadratic funtion
468: Level: developer
470: @ */
471: int TaoSetQuadraticMeritFunction(TAO_SOLVER tao, TaoMat *A, TaoVec*b, double c)
472: {
473: TaoFunctionBegin;
474: SETERRQ(1,"TAO ERROR: Not implemented");
475: // TaoFunctionReturn(0);
476: }