Date: 2015-10-02T22:30:02+00:00

Actual source code: taosolver_fg.c
petsc-3.6.2 2015-10-02
Report Typos and Errors

      1: #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/

      5: /*@
      6:   TaoSetInitialVector - Sets the initial guess for the solve

      8:   Logically collective on Tao

     10:   Input Parameters:
     11: + tao - the Tao context
     12: - x0  - the initial guess

     14:   Level: beginner
     15: .seealso: TaoCreate(), TaoSolve()
     16: @*/

     18: PetscErrorCode TaoSetInitialVector(Tao tao, Vec x0)
     19: {

     24:   if (x0) {
     26:     PetscObjectReference((PetscObject)x0);
     27:   }
     28:   VecDestroy(&tao->solution);
     29:   tao->solution = x0;
     30:   return(0);
     31: }

     35: /*@
     36:   TaoComputeGradient - Computes the gradient of the objective function

     38:   Collective on Tao

     40:   Input Parameters:
     41: + tao - the Tao context
     42: - X - input vector

     44:   Output Parameter:
     45: . G - gradient vector

     47:   Notes: TaoComputeGradient() is typically used within minimization implementations,
     48:   so most users would not generally call this routine themselves.

     50:   Level: advanced

     52: .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetGradientRoutine()
     53: @*/
     54: PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G)
     55: {
     57:   PetscReal      dummy;

     65:   if (tao->ops->computegradient) {
     66:     PetscLogEventBegin(Tao_GradientEval,tao,X,G,NULL);
     67:     PetscStackPush("Tao user gradient evaluation routine");
     68:     (*tao->ops->computegradient)(tao,X,G,tao->user_gradP);
     69:     PetscStackPop;
     70:     PetscLogEventEnd(Tao_GradientEval,tao,X,G,NULL);
     71:     tao->ngrads++;
     72:   } else if (tao->ops->computeobjectiveandgradient) {
     73:     PetscLogEventBegin(Tao_ObjGradientEval,tao,X,G,NULL);
     74:     PetscStackPush("Tao user objective/gradient evaluation routine");
     75:     (*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP);
     76:     PetscStackPop;
     77:     PetscLogEventEnd(Tao_ObjGradientEval,tao,X,G,NULL);
     78:     tao->nfuncgrads++;
     79:   }  else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradientRoutine() has not been called");
     80:   return(0);
     81: }

     85: /*@
     86:   TaoComputeObjective - Computes the objective function value at a given point

     88:   Collective on Tao

     90:   Input Parameters:
     91: + tao - the Tao context
     92: - X - input vector

     94:   Output Parameter:
     95: . f - Objective value at X

     97:   Notes: TaoComputeObjective() is typically used within minimization implementations,
     98:   so most users would not generally call this routine themselves.

    100:   Level: advanced

    102: .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjectiveRoutine()
    103: @*/
    104: PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f)
    105: {
    107:   Vec            temp;

    113:   if (tao->ops->computeobjective) {
    114:     PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);
    115:     PetscStackPush("Tao user objective evaluation routine");
    116:     (*tao->ops->computeobjective)(tao,X,f,tao->user_objP);
    117:     PetscStackPop;
    118:     PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);
    119:     tao->nfuncs++;
    120:   } else if (tao->ops->computeobjectiveandgradient) {
    121:     PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n");
    122:     VecDuplicate(X,&temp);
    123:     PetscLogEventBegin(Tao_ObjGradientEval,tao,X,NULL,NULL);
    124:     PetscStackPush("Tao user objective/gradient evaluation routine");
    125:     (*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP);
    126:     PetscStackPop;
    127:     PetscLogEventEnd(Tao_ObjGradientEval,tao,X,NULL,NULL);
    128:     VecDestroy(&temp);
    129:     tao->nfuncgrads++;
    130:   }  else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjectiveRoutine() has not been called");
    131:   PetscInfo1(tao,"TAO Function evaluation: %14.12e\n",(double)(*f));
    132:   return(0);
    133: }

    137: /*@
    138:   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point

    140:   Collective on Tao

    142:   Input Parameters:
    143: + tao - the Tao context
    144: - X - input vector

    146:   Output Parameter:
    147: + f - Objective value at X
    148: - g - Gradient vector at X

    150:   Notes: TaoComputeObjectiveAndGradient() is typically used within minimization implementations,
    151:   so most users would not generally call this routine themselves.

    153:   Level: advanced

    155: .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjectiveRoutine()
    156: @*/
    157: PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G)
    158: {

    167:   if (tao->ops->computeobjectiveandgradient) {
    168:     PetscLogEventBegin(Tao_ObjGradientEval,tao,X,G,NULL);
    169:     PetscStackPush("Tao user objective/gradient evaluation routine");
    170:     (*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP);
    171:     PetscStackPop;
    172:     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
    173:       /* Overwrite gradient with finite difference gradient */
    174:       TaoDefaultComputeGradient(tao,X,G,tao->user_objgradP);
    175:     }
    176:     PetscLogEventEnd(Tao_ObjGradientEval,tao,X,G,NULL);
    177:     tao->nfuncgrads++;
    178:   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
    179:     PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);
    180:     PetscStackPush("Tao user objective evaluation routine");
    181:     (*tao->ops->computeobjective)(tao,X,f,tao->user_objP);
    182:     PetscStackPop;
    183:     PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);
    184:     tao->nfuncs++;
    185:     PetscLogEventBegin(Tao_GradientEval,tao,X,G,NULL);
    186:     PetscStackPush("Tao user gradient evaluation routine");
    187:     (*tao->ops->computegradient)(tao,X,G,tao->user_gradP);
    188:     PetscStackPop;
    189:     PetscLogEventEnd(Tao_GradientEval,tao,X,G,NULL);
    190:     tao->ngrads++;
    191:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjectiveRoutine() or TaoSetGradientRoutine() not set");
    192:   PetscInfo1(tao,"TAO Function evaluation: %14.12e\n",(double)(*f));
    193:   return(0);
    194: }

    198: /*@C
    199:   TaoSetObjectiveRoutine - Sets the function evaluation routine for minimization

    201:   Logically collective on Tao

    203:   Input Parameter:
    204: + tao - the Tao context
    205: . func - the objective function
    206: - ctx - [optional] user-defined context for private data for the function evaluation
    207:         routine (may be NULL)

    209:   Calling sequence of func:
    210: $      func (Tao tao, Vec x, PetscReal *f, void *ctx);

    212: + x - input vector
    213: . f - function value
    214: - ctx - [optional] user-defined function context

    216:   Level: beginner

    218: .seealso: TaoSetGradientRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
    219: @*/
    220: PetscErrorCode TaoSetObjectiveRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx)
    221: {
    224:   tao->user_objP = ctx;
    225:   tao->ops->computeobjective = func;
    226:   return(0);
    227: }

    231: /*@C
    232:   TaoSetSeparableObjectiveRoutine - Sets the function evaluation routine for least-square applications

    234:   Logically collective on Tao

    236:   Input Parameter:
    237: + tao - the Tao context
    238: . func - the objective function evaluation routine
    239: - ctx - [optional] user-defined context for private data for the function evaluation
    240:         routine (may be NULL)

    242:   Calling sequence of func:
    243: $      func (Tao tao, Vec x, Vec f, void *ctx);

    245: + x - input vector
    246: . f - function value vector
    247: - ctx - [optional] user-defined function context

    249:   Level: beginner

    251: .seealso: TaoSetObjectiveRoutine(), TaoSetJacobianRoutine()
    252: @*/
    253: PetscErrorCode TaoSetSeparableObjectiveRoutine(Tao tao, Vec sepobj, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
    254: {
    258:   tao->user_sepobjP = ctx;
    259:   tao->sep_objective = sepobj;
    260:   tao->ops->computeseparableobjective = func;
    261:   return(0);
    262: }

    266: /*@
    267:   TaoComputeSeparableObjective - Computes a separable objective function vector at a given point (for least-square applications)

    269:   Collective on Tao

    271:   Input Parameters:
    272: + tao - the Tao context
    273: - X - input vector

    275:   Output Parameter:
    276: . f - Objective vector at X

    278:   Notes: TaoComputeSeparableObjective() is typically used within minimization implementations,
    279:   so most users would not generally call this routine themselves.

    281:   Level: advanced

    283: .seealso: TaoSetSeparableObjectiveRoutine()
    284: @*/
    285: PetscErrorCode TaoComputeSeparableObjective(Tao tao, Vec X, Vec F)
    286: {

    295:   if (tao->ops->computeseparableobjective) {
    296:     PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);
    297:     PetscStackPush("Tao user separable objective evaluation routine");
    298:     (*tao->ops->computeseparableobjective)(tao,X,F,tao->user_sepobjP);
    299:     PetscStackPop;
    300:     PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);
    301:     tao->nfuncs++;
    302:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetSeparableObjectiveRoutine() has not been called");
    303:   PetscInfo(tao,"TAO separable function evaluation.\n");
    304:   return(0);
    305: }

    309: /*@C
    310:   TaoSetGradientRoutine - Sets the gradient evaluation routine for minimization

    312:   Logically collective on Tao

    314:   Input Parameter:
    315: + tao - the Tao context
    316: . func - the gradient function
    317: - ctx - [optional] user-defined context for private data for the gradient evaluation
    318:         routine (may be NULL)

    320:   Calling sequence of func:
    321: $      func (Tao tao, Vec x, Vec g, void *ctx);

    323: + x - input vector
    324: . g - gradient value (output)
    325: - ctx - [optional] user-defined function context

    327:   Level: beginner

    329: .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
    330: @*/
    331: PetscErrorCode TaoSetGradientRoutine(Tao tao,  PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
    332: {
    335:   tao->user_gradP = ctx;
    336:   tao->ops->computegradient = func;
    337:   return(0);
    338: }

    343: /*@C
    344:   TaoSetObjectiveAndGradientRoutine - Sets a combined objective function and gradient evaluation routine for minimization

    346:   Logically collective on Tao

    348:   Input Parameter:
    349: + tao - the Tao context
    350: . func - the gradient function
    351: - ctx - [optional] user-defined context for private data for the gradient evaluation
    352:         routine (may be NULL)

    354:   Calling sequence of func:
    355: $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);

    357: + x - input vector
    358: . f - objective value (output)
    359: . g - gradient value (output)
    360: - ctx - [optional] user-defined function context

    362:   Level: beginner

    364: .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
    365: @*/
    366: PetscErrorCode TaoSetObjectiveAndGradientRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal *, Vec, void*), void *ctx)
    367: {
    370:   tao->user_objgradP = ctx;
    371:   tao->ops->computeobjectiveandgradient = func;
    372:   return(0);
    373: }

    377: /*@
    378:   TaoIsObjectiveDefined -- Checks to see if the user has
    379:   declared an objective-only routine.  Useful for determining when
    380:   it is appropriate to call TaoComputeObjective() or
    381:   TaoComputeObjectiveAndGradient()

    383:   Collective on Tao

    385:   Input Parameter:
    386: + tao - the Tao context
    387: - ctx - PETSC_TRUE if objective function routine is set by user,
    388:         PETSC_FALSE otherwise
    389:   Level: developer

    391: .seealso: TaoSetObjectiveRoutine(), TaoIsGradientDefined(), TaoIsObjectiveAndGradientDefined()
    392: @*/
    393: PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg)
    394: {
    397:   if (tao->ops->computeobjective == 0) *flg = PETSC_FALSE;
    398:   else *flg = PETSC_TRUE;
    399:   return(0);
    400: }

    404: /*@
    405:   TaoIsGradientDefined -- Checks to see if the user has
    406:   declared an objective-only routine.  Useful for determining when
    407:   it is appropriate to call TaoComputeGradient() or
    408:   TaoComputeGradientAndGradient()

    410:   Not Collective

    412:   Input Parameter:
    413: + tao - the Tao context
    414: - ctx - PETSC_TRUE if gradient routine is set by user, PETSC_FALSE otherwise
    415:   Level: developer

    417: .seealso: TaoSetGradientRoutine(), TaoIsObjectiveDefined(), TaoIsObjectiveAndGradientDefined()
    418: @*/
    419: PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg)
    420: {
    423:   if (tao->ops->computegradient == 0) *flg = PETSC_FALSE;
    424:   else *flg = PETSC_TRUE;
    425:   return(0);
    426: }

    431: /*@
    432:   TaoIsObjectiveAndGradientDefined -- Checks to see if the user has
    433:   declared a joint objective/gradient routine.  Useful for determining when
    434:   it is appropriate to call TaoComputeObjective() or
    435:   TaoComputeObjectiveAndGradient()

    437:   Not Collective

    439:   Input Parameter:
    440: + tao - the Tao context
    441: - ctx - PETSC_TRUE if objective/gradient routine is set by user, PETSC_FALSE otherwise
    442:   Level: developer

    444: .seealso: TaoSetObjectiveAndGradientRoutine(), TaoIsObjectiveDefined(), TaoIsGradientDefined()
    445: @*/
    446: PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg)
    447: {
    450:   if (tao->ops->computeobjectiveandgradient == 0) *flg = PETSC_FALSE;
    451:   else *flg = PETSC_TRUE;
    452:   return(0);
    453: }