Actual source code: taoapp_ga.c
1: //File: taoapp_ga.c
3: /**************************************************************
5: Author: Limin Zhang, Ph.D.
6: Mathematics Department
7: Columbia Basin College
8: Pasco, WA 99301
9: Limin.Zhang@cbc2.org
11: Mentor: Jarek Naplocha, Ph.D.
12: Environmental Molecular Science Laboratory
13: Pacific Northwest National Laboratory
14: Richland, WA 99352
16: Date: 7/22/2002
18: Purpose:
19: to design and implement an application interface between TAO and global arrays.
20: **************************************************************/
22: #include "taoapp_ga.h" /*I "taoapp_ga.h" I*/
29: TaoGAApplication::TaoGAApplication(MPI_Comm mpicomm){
31: this->comm=mpicomm;
32: this->taox=0;
33: this->V = 0;
34: this->usrfctx=0;
35: this->usrgctx=0;
36: this->usrfgctx=0;
37: this->HesMat=0;
38: this->taoh=0;
39: this->usrhctx=0;
40: this->numbermonitors = 0;
42: this->computeumfunction=0;
43: this->computegradient=0;
44: this->computefunctiongradient=0;
45: this->computehessian=0;
46: this->computebounds=0;
47: for (int i=0;i<MAX_TAO_MONITORS;i++) {
48: this->monitor[i] = 0;
49: this->monitorcontext[i] = 0;
50: }
52: return;
53: }
57: TaoGAApplication::~TaoGAApplication(){
58: return;
59: }
63: int TaoGAApplication::GetVariableVector(TaoVec **xx){
64: int info;
65: TaoFunctionBegin;
66: if (this->V == 0) {
67: SETERRQ(1,"Variable vector is not set. Did you call TaoGAAppSetInitialSolutionVec?");
68: }
69: if (this->taox == 0) {
70: info = TaoWrapGaVec(this->V,&this->taox);
71: }
72: *xx= this->taox;
73: TaoFunctionReturn(0);
74: }
78: int TaoGAApplication::GetHessianMatrix(TaoMat **HH){
79: TaoFunctionBegin;
80: *HH = this->taoh;
81: TaoFunctionReturn(0);
82: }
86: int TaoGAApplication::EvaluateVariableBounds(TaoVec *xxll, TaoVec *xxuu) {
87: int info;
88: GAVec XL=0, XU=0;
89: TaoFunctionBegin;
90: if (this->computebounds) {
91: info = TaoVecGetGaVec(xxll, &XL); CHKERRQ(info);
92: info = TaoVecGetGaVec(xxuu, &XU); CHKERRQ(info);
93: info = (*this->computebounds)(this, XL, XU, this->usrvbctx); CHKERRQ(info);
94: }
95: TaoFunctionReturn(0);
96: }
101: int TaoGAApplication::EvaluateObjectiveFunction(TaoVec *xx, double *ff){
102: int info;
103: GAVec X = 0;
104: TaoVecGetGaVec(xx, &X);
105: GAVec G;
106: TaoVec *gg;
107:
108: TaoFunctionBegin;
110: if (this->computeumfunction){
111: info = (*this->computeumfunction)(this,X,ff,this->usrfctx); CHKERRQ(info);
112: } else if (this->computefunctiongradient) {
113: info = xx->Clone(&gg); CHKERRQ(info);
114: info = TaoVecGetGaVec(gg, &G); CHKERRQ(info);
115: info = (*this->computefunctiongradient)(this,X,ff,G,this->usrfgctx); CHKERRQ(info);
116: info=TaoVecDestroy(gg); CHKERRQ(info);
117: }
118: else {
119: SETERRQ(1,"function evaluation routine is not set");
120: }
122: TaoFunctionReturn(0);
123: }
129: int TaoGAApplication::EvaluateGradient(TaoVec *xx, TaoVec *gg){
130: int info;
131: GAVec X = 0, G = 0;
132: TaoVecGetGaVec(xx, &X);
133: TaoVecGetGaVec(gg, &G);
134: double ff;
136: TaoFunctionBegin;
138: if (this->computegradient){
139: info = (*this->computegradient)(this,X,G,this->usrgctx); CHKERRQ(info);
140: } else if ( this->computefunctiongradient ) {
141: info = (*this->computefunctiongradient)(this,X,&ff,G,this->usrfgctx);
142: CHKERRQ(info);
143: }
144: else {
145: SETERRQ(1,"Gradient evaluation routine is not set.");
146: }
147: TaoFunctionReturn(0);
148: }
153: int TaoGAApplication::EvaluateObjectiveAndGradient(TaoVec *xx, double *ff, TaoVec *gg){
154: int info;
155: GAVec X = 0, G = 0;
156: TaoVecGetGaVec(xx, &X);
157: TaoVecGetGaVec(gg, &G);
158: TaoFunctionBegin;
160: if (this->computefunctiongradient){
161: info = (*this->computefunctiongradient)(this,X,ff,G,this->usrfgctx);
162: CHKERRQ(info);
163: } else if ( this->computeumfunction && this->computegradient ) {
164: info = (*this->computeumfunction)(this,X,ff,this->usrfctx); CHKERRQ(info);
165: info = (*this->computegradient)(this,X,G,this->usrgctx); CHKERRQ(info);
166: } else {
167: SETERRQ(1,"Function and Gradient evaluation routines not set.");
168: }
169:
171: TaoFunctionReturn(0);
172: }
176: int TaoGAApplication::EvaluateHessian(TaoVec *xx, TaoMat *HH){
177: int info;
179: GAVec X = 0;
180: TaoVecGetGaVec(xx, &X);
181: TaoMatGa *MM=(TaoMatGa*)HH;
182: GAMat H=MM->GetMat(), Hpre=MM->pm_pre;;
184: TaoFunctionBegin;
185: if (this->computehessian){
186: info = (*this->computehessian)(this,X,H,this->usrhctx); CHKERRQ(info);
187: MM->pm=H;
188: MM->pm_pre=Hpre;
189: } else {
190: SETERRQ(1,"Hessian calculation routine was not set");
191: }
192: TaoFunctionReturn(0);
193: }
198: int TaoGAApplication::InitializeVariables(TaoVec *xx){
199: GAVec XX0=0;
201: TaoFunctionBegin;
202: if (xx){
203: TaoVecGetGaVec(xx, &XX0);
204: }
205: if (XX0 && this->V && XX0!=this->V){
206: GA_Copy(this->V,XX0);
207: }
208: TaoFunctionReturn(0);
209: }
214: // C stubs
218: /*@C
219: TaoGAApplicationCreate - Creates a TaoApplication that
220: uses GA data structures. The vectors used for gradient
221: and other information can be a GA Vec. The routines
222: for function evaluation, and derivative information can
223: also used GA arguments.
225: Input Parameters:
226: . comm - an MPI communiicator
228: Output Parameters:
229: . newapp - the TaoApplication structure
231: .seealso TaoGAAppSetObjectiveAndGradientRoutine(), TaoGAAppDestroy()
233: Level: beginner
235: .keywords: GAApplication
236: @*/
237: int TaoGAApplicationCreate(MPI_Comm comm, TAO_GA_APPLICATION* newapp){
238: *newapp=new TaoGAApplication(comm);
239: TaoFunctionReturn(0);
240: }
244: /*@C
245: TaoGAAppDestroy - Destroy the GA application
246: and all of the vectors and matrices associated wit it.
248: Input Parameters:
249: . gaapp - the GAApplication structure
251: .seealso TaoGAApplicationCreate()
253: Level: beginner
255: .keywords: Concepts: GAApplication, Destroy
256: @*/
257: int TaoGAAppDestroy(TAO_GA_APPLICATION gaapp) {
258: TaoFunctionBegin;
259: delete gaapp;
260: TaoFunctionReturn(0);
261: }
266: /*@C
267: TaoGAAppSetGradientRoutine - Sets the gradient evaluation routine and gradient
268: vector for use by the TAO_GA_APPLICATION routines.
270: Collective on TAO_GA_APPLICATION
272: Input Parameters:
273: + gaapp - the TAO_GA_APPLICATION context
274: . grad - gradient evaluation routine
275: - ctx - [optional] user-defined function context
277: Calling sequence of func:
278: $ grad (TAO_GA_APPLICATION gaapp,GAVec x,GAVec g,void *ctx);
280: + gaapp - the TAO_GA_APPLICATION application context
281: . x - input vector
282: . g - gradient vector
283: - ctx - user-defined function gradient context
285: Note:
286: This routine should be called before TaoSetApplication()
288: Level: beginner
290: Options Database Keys:
291: . -tao_view_gradient - view the gradient after each evaluation
293: .keywords: GAApplication, set, function
295: .seealso: TaoGAAppSetObjectiveAndGradientRoutine(), TaoGAAppSetHessianRoutine()
297: @*/
298: int TaoGAAppSetGradientRoutine(TAO_GA_APPLICATION gaapp, int (*grad)(TAO_GA_APPLICATION,GAVec,GAVec,void*),void *ctx){
300: TaoFunctionBegin;
301: gaapp->computegradient=grad;
302: gaapp->usrgctx=ctx;
303: TaoFunctionReturn(0);
304: }
310: /*@
311: TaoSetupGAApplicationSolver - This routine creates the vectors,
312: matrices, linear solvers, and other data structures used in
313: the during the optimization process. The application provides
314: the solver with an objective function, constraints, derivative
315: information, and application data structures. These structures
316: include a vector of variables, and Hessian matrix.
318: Collective on TAO_SOLVER
320: Input Parameters:
321: + myapp - user application context
322: - tao - the TAO_SOLVER solver context
324: Level: intermediate
326: Note: This routine should be called after TaoGAAppSetInitialSolutionVec()
328: Note:
329: This method is called during TaoSetOptions() and TaoApplicationSolve();
330:
331: .keywords: GAApplication
333: .seealso: TaoSolveGAApplication()
335: @*/
336: int TaoSetupGAApplicationSolver(TAO_GA_APPLICATION myapp, TAO_SOLVER tao ){
337: int info;
338: TaoFunctionBegin;
339: info = TaoSetApplication(tao,myapp);CHKERRQ(info);
340: TaoFunctionReturn(0);
341: }
346: /*@
347: TaoSolveGAApplication - Find a solution to the application using a TAO solver.
349: Collective on TAO_GA_APPLICATION
351: Input Parameters:
352: . tao - the TAO_GA_APPLICATION context
354: Level: beginner
356: .keywords: solve
358: .seealso: TaoSolve();
360: @*/
361: int TaoSolveGAApplication(TAO_GA_APPLICATION gaapp, TAO_SOLVER tao){
362: int info;
364: TaoFunctionBegin;
365: info = TaoSetupGAApplicationSolver(gaapp, tao); CHKERRQ(info);
366: info = TaoSolve(tao); CHKERRQ(info);
367: TaoFunctionReturn(0);
368: }
374: /*@C
375: TaoGAAppSetObjectiveAndGradientRoutine - Sets a routine for function and gradient evaluation.
377: Collective on TAO_GA_APPLICATION
379: Input Parameters:
380: + gaapp - the TAO_GA_APPLICATION context
381: . funcgrad - routine for evaluating the function and gradient
382: - ctx - optional user-defined context for private data for the
383: function and gradient evaluation routine (may be TAO_NULL)
385: Calling sequence of funcgrad:
386: $ funcgrad (TAO_GA_APPLICATION tao,GAVec x,double *f,GAVec g,void *ctx);
388: + tao - TAO_GA_APPLICATION application context
389: . x - input vector
390: . f - function value
391: . g - gradient vector
392: - ctx - optional user-defined context
394: Notes:
395: The user may call TaoGAAppSetObjectiveAndGradientRoutine() to set a routine
396: that evaluates both the function and gradient. Alternatively, the
397: user may call both TaoGAAppSetObjectiveRoutine() and TaoGAAppSetGradientRoutine() to set
398: separate routines for function and gradient evaluation.
400: Using a single routine to compute the function and gradient, as
401: specified via TaoGAAppSetObjectiveAndGradientRoutine(), may enable better performance
402: for applications in which many of the function and gradient computations
403: are identical.
405: Level: beginner
407: Options Database Keys:
408: . -tao_view_gradient - view the gradient after each iteration
410: .keywords: GAApplication, set, function
412: .seealso: TaoGAAppSetGradientRoutine(), TaoGAAppSetObjectiveRoutine(), TaoComputeFunctionGradient()
414: @*/
415: int TaoGAAppSetObjectiveAndGradientRoutine(TAO_GA_APPLICATION gaapp, int (*funcgrad)(TAO_GA_APPLICATION,GAVec,double*,GAVec, void*),void *ctx){
416: TaoFunctionBegin;
417: gaapp->computefunctiongradient=funcgrad;
418: gaapp->usrfgctx=ctx;
419: TaoFunctionReturn(0);
420: }
425: /*@C
426: TaoGAAppSetObjectiveRoutine - Sets a routine for function evaluations.
428: Collective on TAO_GA_APPLICATION
430: Input Parameters:
431: + gaapp - the TAO_GA_APPLICATION context
432: . func - routine for evaluating the function
433: - ctx - optional user-defined context for private data for the
434: function evaluation routine (may be TAO_NULL)
436: Calling sequence of funcgrad:
437: $ func (TAO_GA_APPLICATION tao,GAVec x,double *f,void *ctx);
439: + tao - TAO_GA_APPLICATION application context
440: . x - input vector
441: . f - function value
442: - ctx - optional user-defined context
444: Notes:
445: The user may call TaoGAAppSetObjectiveAndGradientRoutine() to set a routine
446: that evaluates both the function and gradient. Alternatively, the
447: user may call both TaoGAAppSetObjectiveRoutine() and TaoGAAppSetGradientRoutine() to set
448: separate routines for function and gradient evaluation.
450: Using a single routine to compute the function and gradient, as
451: specified via TaoGAAppSetObjectiveAndGradientRoutine(), may enable better performance
452: for applications in which many of the function and gradient computations
453: are identical.
455: Level: beginner
457: Options Database Keys:
458: . -tao_view_gradient - view the gradient after each iteration
460: .keywords: TAO_GA_APPLICATION, set, function
462: .seealso: TaoGAAppSetGradientRoutine(), TaoGAAppSetObjectiveAndGradientRoutine(), TaoComputeFunctionGradient()
464: @*/
465: int TaoGAAppSetObjectiveRoutine(TAO_GA_APPLICATION gaapp, int (*func)(TAO_GA_APPLICATION,GAVec,double*,void*), void *ctx) {
466: TaoFunctionBegin;
467: gaapp->computeumfunction = func;
468: gaapp->usrfctx=ctx;
469: TaoFunctionReturn(0);
470: }
474: /*@C
475: TaoGAAppSetHessianRoutine - Sets the function to compute the Hessian as well as the
476: location to store the matrix.
478: Collective on TAO_GA_APPLICATION and Mat
480: Input Parameters:
481: + gaapp - the TAO_GA_APPLICATION context
482: . hess - Hessian evaluation routine
483: - ctx - [optional] user-defined context for private data for the
484: Hessian evaluation routine (may be TAO_NULL)
486: Calling sequence of hess:
487: $ hess (TAO_GA_APPLICATION gaapp,GAVec x,GAMat H,void *ctx);
489: + gaapp - the TAO_GA_APPLICATION application context
490: . x - input vector
491: . H - Hessian matrix
492: - ctx - [optional] user-defined Hessian context
494: Options Database Keys:
495: . -tao_view_hessian - view the hessian after each evaluation
497: Level: beginner
499: .keywords: GAApplication, Hessian
501: .seealso: TaoGAAppSetObjectiveRoutine(), TaoGAAppSetGradientRoutine()
502: @*/
503: int TaoGAAppSetHessianRoutine(TAO_GA_APPLICATION gaapp, int (*hess)(TAO_GA_APPLICATION, GAVec, GAMat,void*),void *ctx){
504: TaoFunctionBegin;
505: gaapp->computehessian=hess;
506: gaapp->usrhctx=ctx;
507: TaoFunctionReturn(0);
508: }
513: /*@C
514: TaoGAAppSetVariableBoundsRoutine - Set bounds on the variables.
516: Collective on TAO_GA_APPLICATION
518: Input Parameters:
519: + gaapp - the TAO_GA_APPLICATION context
520: . func - the variable bounds evaluation routine
521: - ctx - user-defined context for private data for the variable bounds
522: evaluation routine (may be TAO_NULL)
524: calling sequence of func:
525: $ func (TAO_GA_APPLICATION gaapp, GAVec xl, GAVec xu, void *ctx);
527: + gaapp - the TAO_GA_APPLICATION application context
528: . xl - lower bounds vector
529: . xu - upper bounds vector
530: - ctx - user-defined variable bounds context
532: .keywords: GAApplication, bounds
534: Level: beginner
536: @*/
537: int TaoGAAppSetVariableBoundsRoutine(TAO_GA_APPLICATION gaapp,
538: int (*func)(TAO_GA_APPLICATION, GAVec, GAVec, void *), void *ctx) {
539: TaoFunctionBegin;
540: gaapp->computebounds = func;
541: gaapp->usrvbctx = ctx;
542: TaoFunctionReturn(0);
543: }
548: /*@
549: TaoGAAppSetInitialSolutionVec - Sets the vector representing the variables
550: and an initial guess.
552: Collective on TAO_GA_APPLICATION
554: Input Parameters:
555: + taoapp - the TAO_GA_APPLICATION context
556: . xx - variable vector that stores the solution
558: Level: beginner
560: Note: This vector will be used by the solver, so do not use it
561: for other purposes. The user should destroy this vector after
562: solving the application.
564: Note: If the user is unaware of a decent initial solution,
565: the vector should be set to zero.
567: Note: The TAO solvers will not use the contents of this
568: GAVec until the TaoSolveGAApplication() is called. Therefore the user
569: may compute an initial solution in this vector after this
570: routine -- but before TaoSolveGAApplication().
572: .seealso: TaoAppGetSolutionVec(), TaoAppSetObjectiveRoutine()
573: @*/
574: int TaoGAAppSetInitialSolutionVec(TAO_GA_APPLICATION gaapp, GAVec xx){
575: TaoFunctionBegin;
576: if (gaapp->V){
577: GA_Destroy(gaapp->V);
578: }
579: gaapp->V=xx;
580: TaoFunctionReturn(0);
581: }
584: /* -------------- Routines to set performance monitoring options --------------- */
588: /*@C
589: TaoGAAppSetMonitor - Sets an ADDITIONAL function that is to be used at every
590: iteration of the solver to display the interation's progress.
592: Collective on TAO_GA_APPLICATION
594: Input Parameters:
595: + gaapp - the TAO_GA_APPLICATION application context
596: . mymonitor - monitoring routine
597: - mctx - [optional] user-defined context for private data for the
598: monitor routine (may be TAO_NULL)
600: Calling sequence of mymonitor:
601: $ int mymonitor(TAO_DA_APPLICATION gaapp, void *mctx)
603: + gaapp - the TAO_GA_APPLICATION application context
604: - mctx - [optional] monitoring context
606: Notes:
607: Several different monitoring routines may be set by calling
608: TaoGAAppSetMonitor() mutiple times; all will be called in the
609: order in which they were set.
611: Level: intermediate
613: .keywords: GAApplication, monitor, View
615: .seealso: TaoGAAppMonitor()
616: @*/
617: int TaoGAAppSetMonitor(TAO_GA_APPLICATION gaapp, int (*mymonitor)(TAO_GA_APPLICATION, void*), void *mctx)
618: {
619: TaoFunctionBegin;
620: if (mymonitor) {
621: if (gaapp->numbermonitors >= MAX_TAO_MONITORS) {
622: SETERRQ(1,"Too many monitors set.");
623: }
624: gaapp->monitor[gaapp->numbermonitors] = mymonitor;
625: gaapp->monitorcontext[gaapp->numbermonitors++] = (void*)mctx;
626: }
627: TaoFunctionReturn(0);
628: }
632: /*@
633: TaoGAAppMonitor - Apply the monitor functions for a TAO_GA_APPLICATION object
635: Collective on TAO_GA_APPLICATION
637: Input Parameters:
638: . gaapp - the TAO_GA_APPLICATION application context
640: Level: developer
642: .keywords: GAApplication, monitor, View
644: .seealso: TaoGAAppSetMonitor()
645: @*/
646: int TaoGAAppMonitor(TAO_GA_APPLICATION gaapp)
647: {
648: int i, info;
649: TaoFunctionBegin;
650: for (i=0; i<gaapp->numbermonitors;i++) {
651: info = (*gaapp->monitor[i])(gaapp, gaapp->monitorcontext[i]); CHKERRQ(info);
653: }
654: TaoFunctionReturn(0);
655: }