Actual source code: taosolver_fg.c

petsc-3.6.1 2015-08-06
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: }