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