Actual source code: taosolver_fg.c
petsc-3.5.4 2015-05-23
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: }