xref: /petsc/src/tao/interface/taosolver_fg.c (revision 87f595a510d358797c1cc8101e6f6c6930cb072f)
1a7e14dcfSSatish Balay #include "tao-private/taosolver_impl.h" /*I "taosolver.h" I*/
2a7e14dcfSSatish Balay 
3a7e14dcfSSatish Balay #undef __FUNCT__
4a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetInitialVector"
5a7e14dcfSSatish Balay /*@
6a7e14dcfSSatish Balay   TaoSetInitialVector - Sets the initial guess for the solve
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay   Logically collective on TaoSolver
9a7e14dcfSSatish Balay 
10a7e14dcfSSatish Balay   Input Parameters:
11a7e14dcfSSatish Balay + tao - the TaoSolver context
12a7e14dcfSSatish Balay - x0  - the initial guess
13a7e14dcfSSatish Balay 
14a7e14dcfSSatish Balay   Level: beginner
15a7e14dcfSSatish Balay .seealso: TaoCreate(), TaoSolve()
16a7e14dcfSSatish Balay @*/
17a7e14dcfSSatish Balay 
18a7e14dcfSSatish Balay PetscErrorCode TaoSetInitialVector(TaoSolver tao, Vec x0) {
19a7e14dcfSSatish Balay     PetscErrorCode ierr;
20a7e14dcfSSatish Balay 
21a7e14dcfSSatish Balay     PetscFunctionBegin;
22a7e14dcfSSatish Balay     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
23a7e14dcfSSatish Balay     if (x0) {
24a7e14dcfSSatish Balay 	PetscValidHeaderSpecific(x0,VEC_CLASSID,2);
25a7e14dcfSSatish Balay 	PetscObjectReference((PetscObject)x0);
26a7e14dcfSSatish Balay     }
27a7e14dcfSSatish Balay     if (tao->solution) {
28a7e14dcfSSatish Balay 	ierr = VecDestroy(&tao->solution); CHKERRQ(ierr);
29a7e14dcfSSatish Balay     }
30a7e14dcfSSatish Balay     tao->solution = x0;
31a7e14dcfSSatish Balay     PetscFunctionReturn(0);
32a7e14dcfSSatish Balay }
33a7e14dcfSSatish Balay 
34a7e14dcfSSatish Balay #undef __FUNCT__
35a7e14dcfSSatish Balay #define __FUNCT__ "TaoComputeGradient"
36a7e14dcfSSatish Balay /*@
37a7e14dcfSSatish Balay   TaoComputeGradient - Computes the gradient of the objective function
38a7e14dcfSSatish Balay 
39a7e14dcfSSatish Balay   Collective on TaoSolver
40a7e14dcfSSatish Balay 
41a7e14dcfSSatish Balay   Input Parameters:
42a7e14dcfSSatish Balay + tao - the TaoSolver context
43a7e14dcfSSatish Balay - X - input vector
44a7e14dcfSSatish Balay 
45a7e14dcfSSatish Balay   Output Parameter:
46a7e14dcfSSatish Balay . G - gradient vector
47a7e14dcfSSatish Balay 
48a7e14dcfSSatish Balay   Notes: TaoComputeGradient() is typically used within minimization implementations,
49a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
50a7e14dcfSSatish Balay 
51a7e14dcfSSatish Balay   Level: advanced
52a7e14dcfSSatish Balay 
53a7e14dcfSSatish Balay .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetGradientRoutine()
54a7e14dcfSSatish Balay @*/
55a7e14dcfSSatish Balay PetscErrorCode TaoComputeGradient(TaoSolver tao, Vec X, Vec G)
56a7e14dcfSSatish Balay {
57a7e14dcfSSatish Balay   PetscErrorCode ierr;
58a7e14dcfSSatish Balay   PetscReal      dummy;
59*87f595a5SBarry Smith 
60a7e14dcfSSatish Balay   PetscFunctionBegin;
61a7e14dcfSSatish Balay   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
62a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
63a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G,VEC_CLASSID,2);
64a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
65a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,3);
66a7e14dcfSSatish Balay   if (tao->ops->computegradient) {
676c23d075SBarry Smith     ierr = PetscLogEventBegin(TaoSolver_GradientEval,tao,X,G,NULL); CHKERRQ(ierr);
68a7e14dcfSSatish Balay     PetscStackPush("TaoSolver user gradient evaluation routine");
69a7e14dcfSSatish Balay     CHKMEMQ;
70a7e14dcfSSatish Balay     ierr = (*tao->ops->computegradient)(tao,X,G,tao->user_gradP); CHKERRQ(ierr);
71a7e14dcfSSatish Balay     CHKMEMQ;
72a7e14dcfSSatish Balay     PetscStackPop;
736c23d075SBarry Smith     ierr = PetscLogEventEnd(TaoSolver_GradientEval,tao,X,G,NULL); CHKERRQ(ierr);
74a7e14dcfSSatish Balay     tao->ngrads++;
75a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
766c23d075SBarry Smith     ierr = PetscLogEventBegin(TaoSolver_ObjGradientEval,tao,X,G,NULL); CHKERRQ(ierr);
77a7e14dcfSSatish Balay     PetscStackPush("Tao user objective/gradient evaluation routine");
78a7e14dcfSSatish Balay     CHKMEMQ;
79a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP); CHKERRQ(ierr);
80a7e14dcfSSatish Balay     CHKMEMQ;
81a7e14dcfSSatish Balay     PetscStackPop;
826c23d075SBarry Smith     ierr = PetscLogEventEnd(TaoSolver_ObjGradientEval,tao,X,G,NULL); CHKERRQ(ierr);
83a7e14dcfSSatish Balay     tao->nfuncgrads++;
84*87f595a5SBarry Smith   }  else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradientRoutine() has not been called");
85a7e14dcfSSatish Balay   PetscFunctionReturn(0);
86a7e14dcfSSatish Balay }
87a7e14dcfSSatish Balay 
88a7e14dcfSSatish Balay 
89a7e14dcfSSatish Balay #undef __FUNCT__
90a7e14dcfSSatish Balay #define __FUNCT__ "TaoComputeObjective"
91a7e14dcfSSatish Balay /*@
92a7e14dcfSSatish Balay   TaoComputeObjective - Computes the objective function value at a given point
93a7e14dcfSSatish Balay 
94a7e14dcfSSatish Balay   Collective on TaoSolver
95a7e14dcfSSatish Balay 
96a7e14dcfSSatish Balay   Input Parameters:
97a7e14dcfSSatish Balay + tao - the TaoSolver context
98a7e14dcfSSatish Balay - X - input vector
99a7e14dcfSSatish Balay 
100a7e14dcfSSatish Balay   Output Parameter:
101a7e14dcfSSatish Balay . f - Objective value at X
102a7e14dcfSSatish Balay 
103a7e14dcfSSatish Balay   Notes: TaoComputeObjective() is typically used within minimization implementations,
104a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
105a7e14dcfSSatish Balay 
106a7e14dcfSSatish Balay   Level: advanced
107a7e14dcfSSatish Balay 
108a7e14dcfSSatish Balay .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjectiveRoutine()
109a7e14dcfSSatish Balay @*/
110a7e14dcfSSatish Balay PetscErrorCode TaoComputeObjective(TaoSolver tao, Vec X, PetscReal *f)
111a7e14dcfSSatish Balay {
112a7e14dcfSSatish Balay   PetscErrorCode ierr;
113a7e14dcfSSatish Balay   Vec            temp;
114*87f595a5SBarry Smith 
115a7e14dcfSSatish Balay   PetscFunctionBegin;
116a7e14dcfSSatish Balay   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
117a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
118a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
119a7e14dcfSSatish Balay   if (tao->ops->computeobjective) {
1206c23d075SBarry Smith     ierr = PetscLogEventBegin(TaoSolver_ObjectiveEval,tao,X,NULL,NULL); CHKERRQ(ierr);
121a7e14dcfSSatish Balay     PetscStackPush("TaoSolver user objective evaluation routine");
122a7e14dcfSSatish Balay     CHKMEMQ;
123a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjective)(tao,X,f,tao->user_objP); CHKERRQ(ierr);
124a7e14dcfSSatish Balay     CHKMEMQ;
125a7e14dcfSSatish Balay     PetscStackPop;
1266c23d075SBarry Smith     ierr = PetscLogEventEnd(TaoSolver_ObjectiveEval,tao,X,NULL,NULL); CHKERRQ(ierr);
127a7e14dcfSSatish Balay     tao->nfuncs++;
128a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
129a7e14dcfSSatish Balay     ierr = PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine"); CHKERRQ(ierr);
130a7e14dcfSSatish Balay     ierr = VecDuplicate(X,&temp); CHKERRQ(ierr);
1316c23d075SBarry Smith     ierr = PetscLogEventBegin(TaoSolver_ObjGradientEval,tao,X,NULL,NULL); CHKERRQ(ierr);
132a7e14dcfSSatish Balay     PetscStackPush("TaoSolver user objective/gradient evaluation routine");
133a7e14dcfSSatish Balay     CHKMEMQ;
134a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP); CHKERRQ(ierr);
135a7e14dcfSSatish Balay     CHKMEMQ;
136a7e14dcfSSatish Balay     PetscStackPop;
1376c23d075SBarry Smith     ierr = PetscLogEventEnd(TaoSolver_ObjGradientEval,tao,X,NULL,NULL); CHKERRQ(ierr);
138a7e14dcfSSatish Balay     ierr = VecDestroy(&temp); CHKERRQ(ierr);
139a7e14dcfSSatish Balay     tao->nfuncgrads++;
140*87f595a5SBarry Smith   }  else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjectiveRoutine() has not been called");
141a7e14dcfSSatish Balay   ierr = PetscInfo1(tao,"TAO Function evaluation: %14.12e\n",*f);CHKERRQ(ierr);
142a7e14dcfSSatish Balay   PetscFunctionReturn(0);
143a7e14dcfSSatish Balay }
144a7e14dcfSSatish Balay 
145a7e14dcfSSatish Balay #undef __FUNCT__
146a7e14dcfSSatish Balay #define __FUNCT__ "TaoComputeObjectiveAndGradient"
147a7e14dcfSSatish Balay /*@
148a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point
149a7e14dcfSSatish Balay 
150a7e14dcfSSatish Balay   Collective on TaoSolver
151a7e14dcfSSatish Balay 
152a7e14dcfSSatish Balay   Input Parameters:
153a7e14dcfSSatish Balay + tao - the TaoSolver context
154a7e14dcfSSatish Balay - X - input vector
155a7e14dcfSSatish Balay 
156a7e14dcfSSatish Balay   Output Parameter:
157a7e14dcfSSatish Balay + f - Objective value at X
158a7e14dcfSSatish Balay - g - Gradient vector at X
159a7e14dcfSSatish Balay 
160a7e14dcfSSatish Balay   Notes: TaoComputeObjectiveAndGradient() is typically used within minimization implementations,
161a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
162a7e14dcfSSatish Balay 
163a7e14dcfSSatish Balay   Level: advanced
164a7e14dcfSSatish Balay 
165a7e14dcfSSatish Balay .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjectiveRoutine()
166a7e14dcfSSatish Balay @*/
167a7e14dcfSSatish Balay PetscErrorCode TaoComputeObjectiveAndGradient(TaoSolver tao, Vec X, PetscReal *f, Vec G)
168a7e14dcfSSatish Balay {
169a7e14dcfSSatish Balay   PetscErrorCode ierr;
170*87f595a5SBarry Smith 
171a7e14dcfSSatish Balay   PetscFunctionBegin;
172a7e14dcfSSatish Balay   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
173a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
174a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G,VEC_CLASSID,4);
175a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
176a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,4);
177a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient) {
1786c23d075SBarry Smith     ierr = PetscLogEventBegin(TaoSolver_ObjGradientEval,tao,X,G,NULL); CHKERRQ(ierr);
179a7e14dcfSSatish Balay     PetscStackPush("TaoSolver user objective/gradient evaluation routine");
180a7e14dcfSSatish Balay     CHKMEMQ;
181a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP); CHKERRQ(ierr);
182a7e14dcfSSatish Balay     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
183a7e14dcfSSatish Balay       /* Overwrite gradient with finite difference gradient */
184a7e14dcfSSatish Balay       ierr = TaoDefaultComputeGradient(tao,X,G,tao->user_objgradP); CHKERRQ(ierr);
185a7e14dcfSSatish Balay     }
186a7e14dcfSSatish Balay     CHKMEMQ;
187a7e14dcfSSatish Balay     PetscStackPop;
1886c23d075SBarry Smith     ierr = PetscLogEventEnd(TaoSolver_ObjGradientEval,tao,X,G,NULL); CHKERRQ(ierr);
189a7e14dcfSSatish Balay     tao->nfuncgrads++;
190a7e14dcfSSatish Balay   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
1916c23d075SBarry Smith     ierr = PetscLogEventBegin(TaoSolver_ObjectiveEval,tao,X,NULL,NULL); CHKERRQ(ierr);
192a7e14dcfSSatish Balay     PetscStackPush("TaoSolver user objective evaluation routine");
193a7e14dcfSSatish Balay     CHKMEMQ;
194a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjective)(tao,X,f,tao->user_objP); CHKERRQ(ierr);
195a7e14dcfSSatish Balay     CHKMEMQ;
196a7e14dcfSSatish Balay     PetscStackPop;
1976c23d075SBarry Smith     ierr = PetscLogEventEnd(TaoSolver_ObjectiveEval,tao,X,NULL,NULL); CHKERRQ(ierr);
198a7e14dcfSSatish Balay     tao->nfuncs++;
1996c23d075SBarry Smith     ierr = PetscLogEventBegin(TaoSolver_GradientEval,tao,X,G,NULL); CHKERRQ(ierr);
200a7e14dcfSSatish Balay     PetscStackPush("TaoSolver user gradient evaluation routine");
201a7e14dcfSSatish Balay     CHKMEMQ;
202a7e14dcfSSatish Balay     ierr = (*tao->ops->computegradient)(tao,X,G,tao->user_gradP); CHKERRQ(ierr);
203a7e14dcfSSatish Balay     CHKMEMQ;
204a7e14dcfSSatish Balay     PetscStackPop;
2056c23d075SBarry Smith     ierr = PetscLogEventEnd(TaoSolver_GradientEval,tao,X,G,NULL); CHKERRQ(ierr);
206a7e14dcfSSatish Balay     tao->ngrads++;
207*87f595a5SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjectiveRoutine() or TaoSetGradientRoutine() not set");
208a7e14dcfSSatish Balay   ierr = PetscInfo1(tao,"TAO Function evaluation: %14.12e\n",*f);CHKERRQ(ierr);
209a7e14dcfSSatish Balay   PetscFunctionReturn(0);
210a7e14dcfSSatish Balay }
211a7e14dcfSSatish Balay 
212a7e14dcfSSatish Balay #undef __FUNCT__
213a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetObjectiveRoutine"
214a7e14dcfSSatish Balay /*@C
215a7e14dcfSSatish Balay   TaoSetObjectiveRoutine - Sets the function evaluation routine for minimization
216a7e14dcfSSatish Balay 
217a7e14dcfSSatish Balay   Logically collective on TaoSolver
218a7e14dcfSSatish Balay 
219a7e14dcfSSatish Balay   Input Parameter:
220a7e14dcfSSatish Balay + tao - the TaoSolver context
221a7e14dcfSSatish Balay . func - the objective function
222a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2236c23d075SBarry Smith         routine (may be NULL)
224a7e14dcfSSatish Balay 
225a7e14dcfSSatish Balay   Calling sequence of func:
226a7e14dcfSSatish Balay $      func (TaoSolver tao, Vec x, PetscReal *f, void *ctx);
227a7e14dcfSSatish Balay 
228a7e14dcfSSatish Balay + x - input vector
229a7e14dcfSSatish Balay . f - function value
230a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
231a7e14dcfSSatish Balay 
232a7e14dcfSSatish Balay   Level: beginner
233a7e14dcfSSatish Balay 
234a7e14dcfSSatish Balay .seealso: TaoSetGradientRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
235a7e14dcfSSatish Balay @*/
236a7e14dcfSSatish Balay PetscErrorCode TaoSetObjectiveRoutine(TaoSolver tao, PetscErrorCode (*func)(TaoSolver, Vec, PetscReal*,void*),void *ctx)
237a7e14dcfSSatish Balay {
238a7e14dcfSSatish Balay     PetscFunctionBegin;
239a7e14dcfSSatish Balay     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
240a7e14dcfSSatish Balay     tao->user_objP = ctx;
241a7e14dcfSSatish Balay     tao->ops->computeobjective = func;
242a7e14dcfSSatish Balay     PetscFunctionReturn(0);
243a7e14dcfSSatish Balay }
244a7e14dcfSSatish Balay 
245a7e14dcfSSatish Balay #undef __FUNCT__
246a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetSeparableObjectiveRoutine"
247a7e14dcfSSatish Balay /*@C
248a7e14dcfSSatish Balay   TaoSetSeparableObjectiveRoutine - Sets the function evaluation routine for least-square applications
249a7e14dcfSSatish Balay 
250a7e14dcfSSatish Balay   Logically collective on TaoSolver
251a7e14dcfSSatish Balay 
252a7e14dcfSSatish Balay   Input Parameter:
253a7e14dcfSSatish Balay + tao - the TaoSolver context
254a7e14dcfSSatish Balay . func - the objective function evaluation routine
255a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2566c23d075SBarry Smith         routine (may be NULL)
257a7e14dcfSSatish Balay 
258a7e14dcfSSatish Balay   Calling sequence of func:
259a7e14dcfSSatish Balay $      func (TaoSolver tao, Vec x, Vec f, void *ctx);
260a7e14dcfSSatish Balay 
261a7e14dcfSSatish Balay + x - input vector
262a7e14dcfSSatish Balay . f - function value vector
263a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
264a7e14dcfSSatish Balay 
265a7e14dcfSSatish Balay   Level: beginner
266a7e14dcfSSatish Balay 
267a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetJacobianRoutine()
268a7e14dcfSSatish Balay @*/
269a7e14dcfSSatish Balay PetscErrorCode TaoSetSeparableObjectiveRoutine(TaoSolver tao, Vec sepobj, PetscErrorCode (*func)(TaoSolver, Vec, Vec, void*),void *ctx)
270a7e14dcfSSatish Balay {
271a7e14dcfSSatish Balay     PetscFunctionBegin;
272a7e14dcfSSatish Balay     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
273a7e14dcfSSatish Balay     PetscValidHeaderSpecific(sepobj, VEC_CLASSID,2);
274a7e14dcfSSatish Balay     tao->user_sepobjP = ctx;
275a7e14dcfSSatish Balay     tao->sep_objective = sepobj;
276a7e14dcfSSatish Balay     tao->ops->computeseparableobjective = func;
277a7e14dcfSSatish Balay     PetscFunctionReturn(0);
278a7e14dcfSSatish Balay }
279a7e14dcfSSatish Balay 
280a7e14dcfSSatish Balay #undef __FUNCT__
281a7e14dcfSSatish Balay #define __FUNCT__ "TaoComputeSeparableObjective"
282a7e14dcfSSatish Balay /*@
283a7e14dcfSSatish Balay   TaoComputeSeparableObjective - Computes a separable objective function vector at a given point (for least-square applications)
284a7e14dcfSSatish Balay 
285a7e14dcfSSatish Balay   Collective on TaoSolver
286a7e14dcfSSatish Balay 
287a7e14dcfSSatish Balay   Input Parameters:
288a7e14dcfSSatish Balay + tao - the TaoSolver context
289a7e14dcfSSatish Balay - X - input vector
290a7e14dcfSSatish Balay 
291a7e14dcfSSatish Balay   Output Parameter:
292a7e14dcfSSatish Balay . f - Objective vector at X
293a7e14dcfSSatish Balay 
294a7e14dcfSSatish Balay   Notes: TaoComputeSeparableObjective() is typically used within minimization implementations,
295a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
296a7e14dcfSSatish Balay 
297a7e14dcfSSatish Balay   Level: advanced
298a7e14dcfSSatish Balay 
299a7e14dcfSSatish Balay .seealso: TaoSetSeparableObjectiveRoutine()
300a7e14dcfSSatish Balay @*/
301a7e14dcfSSatish Balay PetscErrorCode TaoComputeSeparableObjective(TaoSolver tao, Vec X, Vec F)
302a7e14dcfSSatish Balay {
303a7e14dcfSSatish Balay   PetscErrorCode ierr;
304*87f595a5SBarry Smith 
305a7e14dcfSSatish Balay   PetscFunctionBegin;
306a7e14dcfSSatish Balay   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
307a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
308a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
309a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
310a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,F,3);
311a7e14dcfSSatish Balay   if (tao->ops->computeseparableobjective) {
3126c23d075SBarry Smith     ierr = PetscLogEventBegin(TaoSolver_ObjectiveEval,tao,X,NULL,NULL); CHKERRQ(ierr);
313a7e14dcfSSatish Balay     PetscStackPush("TaoSolver user separable objective evaluation routine");
314a7e14dcfSSatish Balay     CHKMEMQ;
315a7e14dcfSSatish Balay     ierr = (*tao->ops->computeseparableobjective)(tao,X,F,tao->user_sepobjP); CHKERRQ(ierr);
316a7e14dcfSSatish Balay     CHKMEMQ;
317a7e14dcfSSatish Balay     PetscStackPop;
3186c23d075SBarry Smith     ierr = PetscLogEventEnd(TaoSolver_ObjectiveEval,tao,X,NULL,NULL); CHKERRQ(ierr);
319a7e14dcfSSatish Balay     tao->nfuncs++;
320*87f595a5SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetSeparableObjectiveRoutine() has not been called");
321a7e14dcfSSatish Balay   ierr = PetscInfo(tao,"TAO separable function evaluation.\n"); CHKERRQ(ierr);
322a7e14dcfSSatish Balay   PetscFunctionReturn(0);
323a7e14dcfSSatish Balay }
324a7e14dcfSSatish Balay 
325a7e14dcfSSatish Balay #undef __FUNCT__
326a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetGradientRoutine"
327a7e14dcfSSatish Balay /*@C
328a7e14dcfSSatish Balay   TaoSetGradientRoutine - Sets the gradient evaluation routine for minimization
329a7e14dcfSSatish Balay 
330a7e14dcfSSatish Balay   Logically collective on TaoSolver
331a7e14dcfSSatish Balay 
332a7e14dcfSSatish Balay   Input Parameter:
333a7e14dcfSSatish Balay + tao - the TaoSolver context
334a7e14dcfSSatish Balay . func - the gradient function
335a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
3366c23d075SBarry Smith         routine (may be NULL)
337a7e14dcfSSatish Balay 
338a7e14dcfSSatish Balay   Calling sequence of func:
339a7e14dcfSSatish Balay $      func (TaoSolver tao, Vec x, Vec g, void *ctx);
340a7e14dcfSSatish Balay 
341a7e14dcfSSatish Balay + x - input vector
342a7e14dcfSSatish Balay . g - gradient value (output)
343a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
344a7e14dcfSSatish Balay 
345a7e14dcfSSatish Balay   Level: beginner
346a7e14dcfSSatish Balay 
347a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
348a7e14dcfSSatish Balay @*/
349a7e14dcfSSatish Balay PetscErrorCode TaoSetGradientRoutine(TaoSolver tao,  PetscErrorCode (*func)(TaoSolver, Vec, Vec, void*),void *ctx)
350a7e14dcfSSatish Balay {
351a7e14dcfSSatish Balay     PetscFunctionBegin;
352a7e14dcfSSatish Balay     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
353a7e14dcfSSatish Balay     tao->user_gradP = ctx;
354a7e14dcfSSatish Balay     tao->ops->computegradient = func;
355a7e14dcfSSatish Balay     PetscFunctionReturn(0);
356a7e14dcfSSatish Balay }
357a7e14dcfSSatish Balay 
358a7e14dcfSSatish Balay 
359a7e14dcfSSatish Balay #undef __FUNCT__
360a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetObjectiveAndGradientRoutine"
361a7e14dcfSSatish Balay /*@C
362a7e14dcfSSatish Balay   TaoSetObjectiveAndGradientRoutine - Sets a combined objective function and gradient evaluation routine for minimization
363a7e14dcfSSatish Balay 
364a7e14dcfSSatish Balay   Logically collective on TaoSolver
365a7e14dcfSSatish Balay 
366a7e14dcfSSatish Balay   Input Parameter:
367a7e14dcfSSatish Balay + tao - the TaoSolver context
368a7e14dcfSSatish Balay . func - the gradient function
369a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
3706c23d075SBarry Smith         routine (may be NULL)
371a7e14dcfSSatish Balay 
372a7e14dcfSSatish Balay   Calling sequence of func:
373a7e14dcfSSatish Balay $      func (TaoSolver tao, Vec x, Vec g, void *ctx);
374a7e14dcfSSatish Balay 
375a7e14dcfSSatish Balay + x - input vector
376a7e14dcfSSatish Balay . g - gradient value (output)
377a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
378a7e14dcfSSatish Balay 
379a7e14dcfSSatish Balay   Level: beginner
380a7e14dcfSSatish Balay 
381a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
382a7e14dcfSSatish Balay @*/
383a7e14dcfSSatish Balay PetscErrorCode TaoSetObjectiveAndGradientRoutine(TaoSolver tao, PetscErrorCode (*func)(TaoSolver, Vec, PetscReal *, Vec, void*), void *ctx)
384a7e14dcfSSatish Balay {
385a7e14dcfSSatish Balay     PetscFunctionBegin;
386a7e14dcfSSatish Balay     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
387a7e14dcfSSatish Balay     tao->user_objgradP = ctx;
388a7e14dcfSSatish Balay     tao->ops->computeobjectiveandgradient = func;
389a7e14dcfSSatish Balay     PetscFunctionReturn(0);
390a7e14dcfSSatish Balay }
391a7e14dcfSSatish Balay 
392a7e14dcfSSatish Balay #undef __FUNCT__
393a7e14dcfSSatish Balay #define __FUNCT__ "TaoIsObjectiveDefined"
394a7e14dcfSSatish Balay /*@
395a7e14dcfSSatish Balay   TaoIsObjectiveDefined -- Checks to see if the user has
396a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
397a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
398a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
399a7e14dcfSSatish Balay 
400a7e14dcfSSatish Balay   Collective on TaoSolver
401a7e14dcfSSatish Balay 
402a7e14dcfSSatish Balay   Input Parameter:
403a7e14dcfSSatish Balay + tao - the TaoSolver context
404a7e14dcfSSatish Balay - ctx - PETSC_TRUE if objective function routine is set by user,
405a7e14dcfSSatish Balay         PETSC_FALSE otherwise
406a7e14dcfSSatish Balay   Level: developer
407a7e14dcfSSatish Balay 
408a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoIsGradientDefined(), TaoIsObjectiveAndGradientDefined()
409a7e14dcfSSatish Balay @*/
410a7e14dcfSSatish Balay PetscErrorCode TaoIsObjectiveDefined(TaoSolver tao, PetscBool *flg)
411a7e14dcfSSatish Balay {
412a7e14dcfSSatish Balay   PetscFunctionBegin;
413a7e14dcfSSatish Balay   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
414a7e14dcfSSatish Balay   if (tao->ops->computeobjective == 0)
415a7e14dcfSSatish Balay     *flg = PETSC_FALSE;
416a7e14dcfSSatish Balay   else
417a7e14dcfSSatish Balay     *flg = PETSC_TRUE;
418a7e14dcfSSatish Balay   PetscFunctionReturn(0);
419a7e14dcfSSatish Balay }
420a7e14dcfSSatish Balay 
421a7e14dcfSSatish Balay #undef __FUNCT__
422a7e14dcfSSatish Balay #define __FUNCT__ "TaoIsGradientDefined"
423a7e14dcfSSatish Balay /*@
424a7e14dcfSSatish Balay   TaoIsGradientDefined -- Checks to see if the user has
425a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
426a7e14dcfSSatish Balay   it is appropriate to call TaoComputeGradient() or
427a7e14dcfSSatish Balay   TaoComputeGradientAndGradient()
428a7e14dcfSSatish Balay 
429a7e14dcfSSatish Balay   Not Collective
430a7e14dcfSSatish Balay 
431a7e14dcfSSatish Balay   Input Parameter:
432a7e14dcfSSatish Balay + tao - the TaoSolver context
433a7e14dcfSSatish Balay - ctx - PETSC_TRUE if gradient routine is set by user, PETSC_FALSE otherwise
434a7e14dcfSSatish Balay   Level: developer
435a7e14dcfSSatish Balay 
436a7e14dcfSSatish Balay .seealso: TaoSetGradientRoutine(), TaoIsObjectiveDefined(), TaoIsObjectiveAndGradientDefined()
437a7e14dcfSSatish Balay @*/
438a7e14dcfSSatish Balay PetscErrorCode TaoIsGradientDefined(TaoSolver tao, PetscBool *flg)
439a7e14dcfSSatish Balay {
440a7e14dcfSSatish Balay   PetscFunctionBegin;
441a7e14dcfSSatish Balay   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
442a7e14dcfSSatish Balay   if (tao->ops->computegradient == 0)
443a7e14dcfSSatish Balay     *flg = PETSC_FALSE;
444a7e14dcfSSatish Balay   else
445a7e14dcfSSatish Balay     *flg = PETSC_TRUE;
446a7e14dcfSSatish Balay   PetscFunctionReturn(0);
447a7e14dcfSSatish Balay }
448a7e14dcfSSatish Balay 
449a7e14dcfSSatish Balay 
450a7e14dcfSSatish Balay #undef __FUNCT__
451a7e14dcfSSatish Balay #define __FUNCT__ "TaoIsObjectiveAndGradientDefined"
452a7e14dcfSSatish Balay /*@
453a7e14dcfSSatish Balay   TaoIsObjectiveAndGradientDefined -- Checks to see if the user has
454a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
455a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
456a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
457a7e14dcfSSatish Balay 
458a7e14dcfSSatish Balay   Not Collective
459a7e14dcfSSatish Balay 
460a7e14dcfSSatish Balay   Input Parameter:
461a7e14dcfSSatish Balay + tao - the TaoSolver context
462a7e14dcfSSatish Balay - ctx - PETSC_TRUE if objective/gradient routine is set by user, PETSC_FALSE otherwise
463a7e14dcfSSatish Balay   Level: developer
464a7e14dcfSSatish Balay 
465a7e14dcfSSatish Balay .seealso: TaoSetObjectiveAndGradientRoutine(), TaoIsObjectiveDefined(), TaoIsGradientDefined()
466a7e14dcfSSatish Balay @*/
467a7e14dcfSSatish Balay PetscErrorCode TaoIsObjectiveAndGradientDefined(TaoSolver tao, PetscBool *flg)
468a7e14dcfSSatish Balay {
469a7e14dcfSSatish Balay   PetscFunctionBegin;
470a7e14dcfSSatish Balay   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
471a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient == 0)
472a7e14dcfSSatish Balay     *flg = PETSC_FALSE;
473a7e14dcfSSatish Balay   else
474a7e14dcfSSatish Balay     *flg = PETSC_TRUE;
475a7e14dcfSSatish Balay   PetscFunctionReturn(0);
476a7e14dcfSSatish Balay }
477a7e14dcfSSatish Balay 
478a7e14dcfSSatish Balay 
479a7e14dcfSSatish Balay 
480