Actual source code: taosolver_fg.c

petsc-3.5.4 2015-05-23
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");
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, Vec g, void *ctx);

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

361:   Level: beginner

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

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

382:   Collective on Tao

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

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

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

409:   Not Collective

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

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


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

436:   Not Collective

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

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