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: for (int i=0;i<MAX_TAO_MONITORS;i++) {
47: this->monitor[i] = 0;
48: this->monitorcontext[i] = 0;
49: }
51: return;
52: }
56: TaoGAApplication::~TaoGAApplication(){
57: return;
58: }
62: int TaoGAApplication::GetVariableVector(TaoVec **xx){
63: int info;
64: TaoFunctionBegin;
65: if (this->V == 0) {
66: SETERRQ(1,"Variable vector is not set. Did you call TaoGAAppSetInitialSolutionVec?");
67: }
68: if (this->taox == 0) {
69: info = TaoWrapGaVec(this->V,&this->taox);
70: }
71: *xx= this->taox;
72: TaoFunctionReturn(0);
73: }
77: int TaoGAApplication::GetHessianMatrix(TaoMat **HH){
78: TaoFunctionBegin;
79: *HH = this->taoh;
80: TaoFunctionReturn(0);
81: }
85: int TaoGAApplication::EvaluateVariableBounds(TaoVec *xxll, TaoVec *xxuu) {
86: int info;
87: GAVec XL=0, XU=0;
88: TaoFunctionBegin;
89: if (this->computebounds) {
90: info = TaoVecGetGaVec(xxll, &XL); CHKERRQ(info);
91: info = TaoVecGetGaVec(xxuu, &XU); CHKERRQ(info);
92: info = (*this->computebounds)(this, XL, XU, this->usrvbctx); CHKERRQ(info);
93: } else {
94: SETERRQ(1,"Variable bounds evaluation routine not set.");
95: }
96: TaoFunctionReturn(0);
97: }
102: int TaoGAApplication::EvaluateObjectiveFunction(TaoVec *xx, double *ff){
103: int info;
104: GAVec X = 0;
105: TaoVecGetGaVec(xx, &X);
106: GAVec G;
107: TaoVec *gg;
108:
109: TaoFunctionBegin;
111: if (this->computeumfunction){
112: info = (*this->computeumfunction)(this,X,ff,this->usrfctx); CHKERRQ(info);
113: } else if (this->computefunctiongradient) {
114: info = xx->Clone(&gg); CHKERRQ(info);
115: info = TaoVecGetGaVec(gg, &G); CHKERRQ(info);
116: info = (*this->computefunctiongradient)(this,X,ff,G,this->usrfgctx); CHKERRQ(info);
117: info=TaoVecDestroy(gg); CHKERRQ(info);
118: }
119: else {
120: SETERRQ(1,"function evaluation routine is not set");
121: }
123: TaoFunctionReturn(0);
124: }
130: int TaoGAApplication::EvaluateGradient(TaoVec *xx, TaoVec *gg){
131: int info;
132: GAVec X = 0, G = 0;
133: TaoVecGetGaVec(xx, &X);
134: TaoVecGetGaVec(gg, &G);
135: double ff;
137: TaoFunctionBegin;
139: if (this->computegradient){
140: info = (*this->computegradient)(this,X,G,this->usrgctx); CHKERRQ(info);
141: } else if ( this->computefunctiongradient ) {
142: info = (*this->computefunctiongradient)(this,X,&ff,G,this->usrfgctx);
143: CHKERRQ(info);
144: }
145: else {
146: SETERRQ(1,"Gradient evaluation routine is not set.");
147: }
148: TaoFunctionReturn(0);
149: }
154: int TaoGAApplication::EvaluateObjectiveAndGradient(TaoVec *xx, double *ff, TaoVec *gg){
155: int info;
156: GAVec X = 0, G = 0;
157: TaoVecGetGaVec(xx, &X);
158: TaoVecGetGaVec(gg, &G);
159: TaoFunctionBegin;
161: if (this->computefunctiongradient){
162: info = (*this->computefunctiongradient)(this,X,ff,G,this->usrfgctx);
163: CHKERRQ(info);
164: } else if ( this->computeumfunction && this->computegradient ) {
165: info = (*this->computeumfunction)(this,X,ff,this->usrfctx); CHKERRQ(info);
166: info = (*this->computegradient)(this,X,G,this->usrgctx); CHKERRQ(info);
167: } else {
168: SETERRQ(1,"Function and Gradient evaluation routines not set.");
169: }
170:
172: TaoFunctionReturn(0);
173: }
177: int TaoGAApplication::EvaluateHessian(TaoVec *xx, TaoMat *HH){
178: int info;
180: GAVec X = 0;
181: TaoVecGetGaVec(xx, &X);
182: TaoMatGa *MM=(TaoMatGa*)HH;
183: GAMat H=MM->GetMat(), Hpre=MM->pm_pre;;
185: TaoFunctionBegin;
186: if (this->computehessian){
187: info = (*this->computehessian)(this,X,H,this->usrhctx); CHKERRQ(info);
188: MM->pm=H;
189: MM->pm_pre=Hpre;
190: } else {
191: SETERRQ(1,"Hessian calculation routine was not set");
192: }
193: TaoFunctionReturn(0);
194: }
199: int TaoGAApplication::InitializeVariables(TaoVec *xx){
200: GAVec XX0=0;
202: TaoFunctionBegin;
203: if (xx){
204: TaoVecGetGaVec(xx, &XX0);
205: }
206: if (XX0 && this->V && XX0!=this->V){
207: GA_Copy(this->V,XX0);
208: }
209: TaoFunctionReturn(0);
210: }
215: // C stubs
219: /*@C
220: TaoGAApplicationCreate - Creates a TaoApplication that
221: uses GA data structures. The vectors used for gradient
222: and other information can be a GA Vec. The routines
223: for function evaluation, and derivative information can
224: also used GA arguments.
226: Input Parameters:
227: . comm - an MPI communiicator
229: Output Parameters:
230: . newapp - the TaoApplication structure
232: .seealso TaoGAAppSetObjectiveAndGradientRoutine(), TaoGAAppDestroy()
234: Level: beginner
236: .keywords: GAApplication
237: @*/
238: int TaoGAApplicationCreate(MPI_Comm comm, TAO_GA_APPLICATION* newapp){
239: *newapp=new TaoGAApplication(comm);
240: TaoFunctionReturn(0);
241: }
245: /*@C
246: TaoGAAppDestroy - Destroy the GA application
247: and all of the vectors and matrices associated wit it.
249: Input Parameters:
250: . gaapp - the GAApplication structure
252: .seealso TaoGAApplicationCreate()
254: Level: beginner
256: .keywords: Concepts: GAApplication, Destroy
257: @*/
258: int TaoGAAppDestroy(TAO_GA_APPLICATION gaapp) {
259: TaoFunctionBegin;
260: delete gaapp;
261: TaoFunctionReturn(0);
262: }
267: /*@C
268: TaoGAAppSetGradientRoutine - Sets the gradient evaluation routine and gradient
269: vector for use by the TAO_GA_APPLICATION routines.
271: Collective on TAO_GA_APPLICATION
273: Input Parameters:
274: + gaapp - the TAO_GA_APPLICATION context
275: . grad - gradient evaluation routine
276: - ctx - [optional] user-defined function context
278: Calling sequence of func:
279: $ grad (TAO_GA_APPLICATION gaapp,GAVec x,GAVec g,void *ctx);
281: + gaapp - the TAO_GA_APPLICATION application context
282: . x - input vector
283: . g - gradient vector
284: - ctx - user-defined function gradient context
286: Note:
287: This routine should be called before TaoSetApplication()
289: Level: beginner
291: Options Database Keys:
292: . -tao_view_gradient - view the gradient after each evaluation
294: .keywords: GAApplication, set, function
296: .seealso: TaoGAAppSetObjectiveAndGradientRoutine(), TaoGAAppSetHessianRoutine()
298: @*/
299: int TaoGAAppSetGradientRoutine(TAO_GA_APPLICATION gaapp, int (*grad)(TAO_GA_APPLICATION,GAVec,GAVec,void*),void *ctx){
301: TaoFunctionBegin;
302: gaapp->computegradient=grad;
303: gaapp->usrgctx=ctx;
304: TaoFunctionReturn(0);
305: }
311: /*@
312: TaoSetupGAApplicationSolver - This routine creates the vectors,
313: matrices, linear solvers, and other data structures used in
314: the during the optimization process. The application provides
315: the solver with an objective function, constraints, derivative
316: information, and application data structures. These structures
317: include a vector of variables, and Hessian matrix.
319: Collective on TAO_SOLVER
321: Input Parameters:
322: + myapp - user application context
323: - tao - the TAO_SOLVER solver context
325: Level: intermediate
327: Note: This routine should be called after TaoGAAppSetInitialSolutionVec()
329: Note:
330: This method is called during TaoSetOptions() and TaoApplicationSolve();
331:
332: .keywords: GAApplication
334: .seealso: TaoSolveGAApplication()
336: @*/
337: int TaoSetupGAApplicationSolver(TAO_GA_APPLICATION myapp, TAO_SOLVER tao ){
338: int info;
339: TaoFunctionBegin;
340: info = TaoSetApplication(tao,myapp);CHKERRQ(info);
341: TaoFunctionReturn(0);
342: }
347: /*@
348: TaoSolveGAApplication - Find a solution to the application using a TAO solver.
350: Collective on TAO_GA_APPLICATION
352: Input Parameters:
353: . tao - the TAO_GA_APPLICATION context
355: Level: beginner
357: .keywords: solve
359: .seealso: TaoSolve();
361: @*/
362: int TaoSolveGAApplication(TAO_GA_APPLICATION gaapp, TAO_SOLVER tao){
363: int info;
365: TaoFunctionBegin;
366: info = TaoSetupGAApplicationSolver(gaapp, tao); CHKERRQ(info);
367: info = TaoSolve(tao); CHKERRQ(info);
368: TaoFunctionReturn(0);
369: }
375: /*@C
376: TaoGAAppSetObjectiveAndGradientRoutine - Sets a routine for function and gradient evaluation.
378: Collective on TAO_GA_APPLICATION
380: Input Parameters:
381: + gaapp - the TAO_GA_APPLICATION context
382: . funcgrad - routine for evaluating the function and gradient
383: - ctx - optional user-defined context for private data for the
384: function and gradient evaluation routine (may be TAO_NULL)
386: Calling sequence of funcgrad:
387: $ funcgrad (TAO_GA_APPLICATION tao,GAVec x,double *f,GAVec g,void *ctx);
389: + tao - TAO_GA_APPLICATION application context
390: . x - input vector
391: . f - function value
392: . g - gradient vector
393: - ctx - optional user-defined context
395: Notes:
396: The user may call TaoGAAppSetObjectiveAndGradientRoutine() to set a routine
397: that evaluates both the function and gradient. Alternatively, the
398: user may call both TaoGAAppSetObjectiveRoutine() and TaoGAAppSetGradientRoutine() to set
399: separate routines for function and gradient evaluation.
401: Using a single routine to compute the function and gradient, as
402: specified via TaoGAAppSetObjectiveAndGradientRoutine(), may enable better performance
403: for applications in which many of the function and gradient computations
404: are identical.
406: Level: beginner
408: Options Database Keys:
409: . -tao_view_gradient - view the gradient after each iteration
411: .keywords: GAApplication, set, function
413: .seealso: TaoGAAppSetGradientRoutine(), TaoGAAppSetObjectiveRoutine(), TaoComputeFunctionGradient()
415: @*/
416: int TaoGAAppSetObjectiveAndGradientRoutine(TAO_GA_APPLICATION gaapp, int (*funcgrad)(TAO_GA_APPLICATION,GAVec,double*,GAVec, void*),void *ctx){
417: TaoFunctionBegin;
418: gaapp->computefunctiongradient=funcgrad;
419: gaapp->usrfgctx=ctx;
420: TaoFunctionReturn(0);
421: }
426: /*@C
427: TaoGAAppSetObjectiveRoutine - Sets a routine for function evaluations.
429: Collective on TAO_GA_APPLICATION
431: Input Parameters:
432: + gaapp - the TAO_GA_APPLICATION context
433: . func - routine for evaluating the function
434: - ctx - optional user-defined context for private data for the
435: function evaluation routine (may be TAO_NULL)
437: Calling sequence of funcgrad:
438: $ func (TAO_GA_APPLICATION tao,GAVec x,double *f,void *ctx);
440: + tao - TAO_GA_APPLICATION application context
441: . x - input vector
442: . f - function value
443: - ctx - optional user-defined context
445: Notes:
446: The user may call TaoGAAppSetObjectiveAndGradientRoutine() to set a routine
447: that evaluates both the function and gradient. Alternatively, the
448: user may call both TaoGAAppSetObjectiveRoutine() and TaoGAAppSetGradientRoutine() to set
449: separate routines for function and gradient evaluation.
451: Using a single routine to compute the function and gradient, as
452: specified via TaoGAAppSetObjectiveAndGradientRoutine(), may enable better performance
453: for applications in which many of the function and gradient computations
454: are identical.
456: Level: beginner
458: Options Database Keys:
459: . -tao_view_gradient - view the gradient after each iteration
461: .keywords: TAO_GA_APPLICATION, set, function
463: .seealso: TaoGAAppSetGradientRoutine(), TaoGAAppSetObjectiveAndGradientRoutine(), TaoComputeFunctionGradient()
465: @*/
466: int TaoGAAppSetObjectiveRoutine(TAO_GA_APPLICATION gaapp, int (*func)(TAO_GA_APPLICATION,GAVec,double*,void*), void *ctx) {
467: TaoFunctionBegin;
468: gaapp->computeumfunction = func;
469: gaapp->usrfctx=ctx;
470: TaoFunctionReturn(0);
471: }
475: /*@C
476: TaoGAAppSetHessianRoutine - Sets the function to compute the Hessian as well as the
477: location to store the matrix.
479: Collective on TAO_GA_APPLICATION and Mat
481: Input Parameters:
482: + gaapp - the TAO_GA_APPLICATION context
483: . hess - Hessian evaluation routine
484: - ctx - [optional] user-defined context for private data for the
485: Hessian evaluation routine (may be TAO_NULL)
487: Calling sequence of hess:
488: $ hess (TAO_GA_APPLICATION gaapp,GAVec x,GAMat H,void *ctx);
490: + gaapp - the TAO_GA_APPLICATION application context
491: . x - input vector
492: . H - Hessian matrix
493: - ctx - [optional] user-defined Hessian context
495: Options Database Keys:
496: . -tao_view_hessian - view the hessian after each evaluation
498: Level: beginner
500: .keywords: GAApplication, Hessian
502: .seealso: TaoGAAppSetObjectiveRoutine(), TaoGAAppSetGradientRoutine()
503: @*/
504: int TaoGAAppSetHessianRoutine(TAO_GA_APPLICATION gaapp, int (*hess)(TAO_GA_APPLICATION, GAVec, GAMat,void*),void *ctx){
505: TaoFunctionBegin;
506: gaapp->computehessian=hess;
507: gaapp->usrhctx=ctx;
508: TaoFunctionReturn(0);
509: }
514: /*@C
515: TaoGAAppSetVariableBoundsRoutine - Set bounds on the variables.
517: Collective on TAO_GA_APPLICATION
519: Input Parameters:
520: + gaapp - the TAO_GA_APPLICATION context
521: . func - the variable bounds evaluation routine
522: - ctx - user-defined context for private data for the variable bounds
523: evaluation routine (may be TAO_NULL)
525: calling sequence of func:
526: $ func (TAO_GA_APPLICATION gaapp, GAVec xl, GAVec xu, void *ctx);
528: + gaapp - the TAO_GA_APPLICATION application context
529: . xl - lower bounds vector
530: . xu - upper bounds vector
531: - ctx - user-defined variable bounds context
533: .keywords: GAApplication, bounds
535: Level: beginner
537: @*/
538: int TaoGAAppSetVariableBoundsRoutine(TAO_GA_APPLICATION gaapp,
539: int (*func)(TAO_GA_APPLICATION, GAVec, GAVec, void *), void *ctx) {
540: TaoFunctionBegin;
541: gaapp->computebounds = func;
542: gaapp->usrvbctx = ctx;
543: TaoFunctionReturn(0);
544: }
549: /*@
550: TaoGAAppSetInitialSolutionVec - Sets the vector representing the variables
551: and an initial guess.
553: Collective on TAO_GA_APPLICATION
555: Input Parameters:
556: + taoapp - the TAO_GA_APPLICATION context
557: . xx - variable vector that stores the solution
559: Level: beginner
561: Note: This vector will be used by the solver, so do not use it
562: for other purposes. The user should destroy this vector after
563: solving the application.
565: Note: If the user is unaware of a decent initial solution,
566: the vector should be set to zero.
568: Note: The TAO solvers will not use the contents of this
569: GAVec until the TaoSolveGAApplication() is called. Therefore the user
570: may compute an initial solution in this vector after this
571: routine -- but before TaoSolveGAApplication().
573: .seealso: TaoAppGetSolutionVec(), TaoAppSetObjectiveRoutine()
574: @*/
575: int TaoGAAppSetInitialSolutionVec(TAO_GA_APPLICATION gaapp, GAVec xx){
576: TaoFunctionBegin;
577: if (gaapp->V){
578: GA_Destroy(gaapp->V);
579: }
580: gaapp->V=xx;
581: TaoFunctionReturn(0);
582: }
585: /* -------------- Routines to set performance monitoring options --------------- */
589: /*@C
590: TaoGAAppSetMonitor - Sets an ADDITIONAL function that is to be used at every
591: iteration of the solver to display the interation's progress.
593: Collective on TAO_GA_APPLICATION
595: Input Parameters:
596: + gaapp - the TAO_GA_APPLICATION application context
597: . mymonitor - monitoring routine
598: - mctx - [optional] user-defined context for private data for the
599: monitor routine (may be TAO_NULL)
601: Calling sequence of mymonitor:
602: $ int mymonitor(TAO_DA_APPLICATION gaapp, void *mctx)
604: + gaapp - the TAO_GA_APPLICATION application context
605: - mctx - [optional] monitoring context
607: Notes:
608: Several different monitoring routines may be set by calling
609: TaoGAAppSetMonitor() mutiple times; all will be called in the
610: order in which they were set.
612: Level: intermediate
614: .keywords: GAApplication, monitor, View
616: .seealso: TaoGAAppMonitor()
617: @*/
618: int TaoGAAppSetMonitor(TAO_GA_APPLICATION gaapp, int (*mymonitor)(TAO_GA_APPLICATION, void*), void *mctx)
619: {
620: TaoFunctionBegin;
621: if (mymonitor) {
622: if (gaapp->numbermonitors >= MAX_TAO_MONITORS) {
623: SETERRQ(1,"Too many monitors set.");
624: }
625: gaapp->monitor[gaapp->numbermonitors] = mymonitor;
626: gaapp->monitorcontext[gaapp->numbermonitors++] = (void*)mctx;
627: }
628: TaoFunctionReturn(0);
629: }
633: /*@
634: TaoGAAppMonitor - Apply the monitor functions for a TAO_GA_APPLICATION object
636: Collective on TAO_GA_APPLICATION
638: Input Parameters:
639: . gaapp - the TAO_GA_APPLICATION application context
641: Level: developer
643: .keywords: GAApplication, monitor, View
645: .seealso: TaoGAAppSetMonitor()
646: @*/
647: int TaoGAAppMonitor(TAO_GA_APPLICATION gaapp)
648: {
649: int i, info;
650: TaoFunctionBegin;
651: for (i=0; i<gaapp->numbermonitors;i++) {
652: info = (*gaapp->monitor[i])(gaapp, gaapp->monitorcontext[i]); CHKERRQ(info);
654: }
655: TaoFunctionReturn(0);
656: }