Actual source code: taosolver_fg.c
petsc-3.6.1 2015-08-06
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: }