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