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