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