xref: /petsc/src/tao/interface/taosolver_fg.c (revision 9566063d113dddea24716c546802770db7481bc0)
1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2a7e14dcfSSatish Balay 
3a7e14dcfSSatish Balay /*@
4a82e8c82SStefano Zampini   TaoSetSolution - Sets the vector holding the initial guess for the solve
5a7e14dcfSSatish Balay 
6441846f8SBarry Smith   Logically collective on Tao
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay   Input Parameters:
9441846f8SBarry Smith + tao - the Tao context
10a7e14dcfSSatish Balay - x0  - the initial guess
11a7e14dcfSSatish Balay 
12a7e14dcfSSatish Balay   Level: beginner
13a82e8c82SStefano Zampini .seealso: TaoCreate(), TaoSolve(), TaoGetSolution()
14a7e14dcfSSatish Balay @*/
15a82e8c82SStefano Zampini PetscErrorCode TaoSetSolution(Tao tao, Vec x0)
1645cf516eSBarry Smith {
17a7e14dcfSSatish Balay   PetscFunctionBegin;
18441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
19a82e8c82SStefano Zampini   if (x0) PetscValidHeaderSpecific(x0,VEC_CLASSID,2);
20*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)x0));
21*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tao->solution));
22a7e14dcfSSatish Balay   tao->solution = x0;
23a7e14dcfSSatish Balay   PetscFunctionReturn(0);
24a7e14dcfSSatish Balay }
25a7e14dcfSSatish Balay 
26412cdd55SHong Zhang PetscErrorCode TaoTestGradient(Tao tao,Vec x,Vec g1)
2709baa881SHong Zhang {
28412cdd55SHong Zhang   Vec               g2,g3;
2909baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE;
3009baa881SHong Zhang   PetscReal         hcnorm,fdnorm,hcmax,fdmax,diffmax,diffnorm;
3109baa881SHong Zhang   PetscScalar       dot;
3209baa881SHong Zhang   MPI_Comm          comm;
33913eda9aSHong Zhang   PetscViewer       viewer,mviewer;
34913eda9aSHong Zhang   PetscViewerFormat format;
3509baa881SHong Zhang   PetscInt          tabs;
3609baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
3709baa881SHong Zhang   PetscErrorCode    ierr;
3809baa881SHong Zhang 
3909baa881SHong Zhang   PetscFunctionBegin;
40*9566063dSJacob Faibussowitsch   ierr = PetscObjectOptionsBegin((PetscObject)tao);PetscCall(ierr);
41*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-tao_test_gradient","Compare hand-coded and finite difference Gradients","None",&test));
42*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-tao_test_gradient_view","View difference between hand-coded and finite difference Gradients element entries","None",&mviewer,&format,&complete_print));
43*9566063dSJacob Faibussowitsch   ierr = PetscOptionsEnd();PetscCall(ierr);
442f4b6201SAlp Dener   if (!test) {
452f4b6201SAlp Dener     if (complete_print) {
46*9566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&mviewer));
472f4b6201SAlp Dener     }
482f4b6201SAlp Dener     PetscFunctionReturn(0);
492f4b6201SAlp Dener   }
5009baa881SHong Zhang 
51*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao,&comm));
52*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm,&viewer));
53*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
54*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
55*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Gradient -------------\n"));
5609baa881SHong Zhang   if (!complete_print && !directionsprinted) {
57*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_gradient_view and optionally -tao_test_gradient <threshold> to show difference\n"));
58*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference gradient entries greater than <threshold>.\n"));
5909baa881SHong Zhang   }
6009baa881SHong Zhang   if (!directionsprinted) {
61*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Gradient, if (for double precision runs) ||G - Gfd||/||G|| is\n"));
62*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Gradient is probably correct.\n"));
6309baa881SHong Zhang     directionsprinted = PETSC_TRUE;
6409baa881SHong Zhang   }
65913eda9aSHong Zhang   if (complete_print) {
66*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(mviewer,format));
67913eda9aSHong Zhang   }
6809baa881SHong Zhang 
69*9566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x,&g2));
70*9566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x,&g3));
7109baa881SHong Zhang 
7209baa881SHong Zhang   /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */
73*9566063dSJacob Faibussowitsch   PetscCall(TaoDefaultComputeGradient(tao,x,g2,NULL));
7409baa881SHong Zhang 
75*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2,NORM_2,&fdnorm));
76*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1,NORM_2,&hcnorm));
77*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2,NORM_INFINITY,&fdmax));
78*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1,NORM_INFINITY,&hcmax));
79*9566063dSJacob Faibussowitsch   PetscCall(VecDot(g1,g2,&dot));
80*9566063dSJacob Faibussowitsch   PetscCall(VecCopy(g1,g3));
81*9566063dSJacob Faibussowitsch   PetscCall(VecAXPY(g3,-1.0,g2));
82*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3,NORM_2,&diffnorm));
83*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3,NORM_INFINITY,&diffmax));
84*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  ||Gfd|| %g, ||G|| = %g, angle cosine = (Gfd'G)/||Gfd||||G|| = %g\n", (double)fdnorm, (double)hcnorm, (double)(PetscRealPart(dot)/(fdnorm*hcnorm))));
85*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffnorm/PetscMax(hcnorm,fdnorm)),(double)diffnorm));
86*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffmax/PetscMax(hcmax,fdmax)),(double)diffmax));
8709baa881SHong Zhang 
8809baa881SHong Zhang   if (complete_print) {
89*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded gradient ----------\n"));
90*9566063dSJacob Faibussowitsch     PetscCall(VecView(g1,mviewer));
91*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite difference gradient ----------\n"));
92*9566063dSJacob Faibussowitsch     PetscCall(VecView(g2,mviewer));
93*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference gradient ----------\n"));
94*9566063dSJacob Faibussowitsch     PetscCall(VecView(g3,mviewer));
9509baa881SHong Zhang   }
96*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g2));
97*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g3));
98913eda9aSHong Zhang 
99913eda9aSHong Zhang   if (complete_print) {
100*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
101*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
102913eda9aSHong Zhang   }
103*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer,tabs));
10409baa881SHong Zhang   PetscFunctionReturn(0);
10509baa881SHong Zhang }
10609baa881SHong Zhang 
107a7e14dcfSSatish Balay /*@
108a7e14dcfSSatish Balay   TaoComputeGradient - Computes the gradient of the objective function
109a7e14dcfSSatish Balay 
110441846f8SBarry Smith   Collective on Tao
111a7e14dcfSSatish Balay 
112a7e14dcfSSatish Balay   Input Parameters:
113441846f8SBarry Smith + tao - the Tao context
114a7e14dcfSSatish Balay - X - input vector
115a7e14dcfSSatish Balay 
116a7e14dcfSSatish Balay   Output Parameter:
117a7e14dcfSSatish Balay . G - gradient vector
118a7e14dcfSSatish Balay 
11909baa881SHong Zhang   Options Database Keys:
12009baa881SHong Zhang +    -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors
121dfe02fe6SHong Zhang -    -tao_test_gradient_view - display the user provided gradient, the finite difference gradient and the difference between them to help users detect the location of errors in the user provided gradient
12209baa881SHong Zhang 
12395452b02SPatrick Sanan   Notes:
12495452b02SPatrick Sanan     TaoComputeGradient() is typically used within minimization implementations,
125a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
126a7e14dcfSSatish Balay 
127a7e14dcfSSatish Balay   Level: advanced
128a7e14dcfSSatish Balay 
129a82e8c82SStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetGradient()
130a7e14dcfSSatish Balay @*/
131441846f8SBarry Smith PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G)
132a7e14dcfSSatish Balay {
133a7e14dcfSSatish Balay   PetscReal      dummy;
13487f595a5SBarry Smith 
135a7e14dcfSSatish Balay   PetscFunctionBegin;
136441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
137a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
138064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(G,VEC_CLASSID,3);
139a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
140a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,3);
141*9566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
142a7e14dcfSSatish Balay   if (tao->ops->computegradient) {
143*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL));
144441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
145*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP));
146a7e14dcfSSatish Balay     PetscStackPop;
147*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL));
148a7e14dcfSSatish Balay     tao->ngrads++;
149a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
150*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL));
151a7e14dcfSSatish Balay     PetscStackPush("Tao user objective/gradient evaluation routine");
152*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP));
153a7e14dcfSSatish Balay     PetscStackPop;
154*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL));
155a7e14dcfSSatish Balay     tao->nfuncgrads++;
156a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradient() has not been called");
157*9566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
15809baa881SHong Zhang 
159*9566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao,X,G));
160a7e14dcfSSatish Balay   PetscFunctionReturn(0);
161a7e14dcfSSatish Balay }
162a7e14dcfSSatish Balay 
163a7e14dcfSSatish Balay /*@
164a7e14dcfSSatish Balay   TaoComputeObjective - Computes the objective function value at a given point
165a7e14dcfSSatish Balay 
166441846f8SBarry Smith   Collective on Tao
167a7e14dcfSSatish Balay 
168a7e14dcfSSatish Balay   Input Parameters:
169441846f8SBarry Smith + tao - the Tao context
170a7e14dcfSSatish Balay - X - input vector
171a7e14dcfSSatish Balay 
172a7e14dcfSSatish Balay   Output Parameter:
173a7e14dcfSSatish Balay . f - Objective value at X
174a7e14dcfSSatish Balay 
17595452b02SPatrick Sanan   Notes:
17695452b02SPatrick Sanan     TaoComputeObjective() is typically used within minimization implementations,
177a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
178a7e14dcfSSatish Balay 
179a7e14dcfSSatish Balay   Level: advanced
180a7e14dcfSSatish Balay 
181a82e8c82SStefano Zampini .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjective()
182a7e14dcfSSatish Balay @*/
183441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f)
184a7e14dcfSSatish Balay {
185a7e14dcfSSatish Balay   Vec            temp;
18687f595a5SBarry Smith 
187a7e14dcfSSatish Balay   PetscFunctionBegin;
188441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
189a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
190a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
191*9566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
192a7e14dcfSSatish Balay   if (tao->ops->computeobjective) {
193*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
194441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
195*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP));
196a7e14dcfSSatish Balay     PetscStackPop;
197*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
198a7e14dcfSSatish Balay     tao->nfuncs++;
199a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
200*9566063dSJacob Faibussowitsch     PetscCall(PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n"));
201*9566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(X,&temp));
202*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,NULL,NULL));
203441846f8SBarry Smith     PetscStackPush("Tao user objective/gradient evaluation routine");
204*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP));
205a7e14dcfSSatish Balay     PetscStackPop;
206*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,NULL,NULL));
207*9566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&temp));
208a7e14dcfSSatish Balay     tao->nfuncgrads++;
209a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() has not been called");
210*9566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f)));
211*9566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
212a7e14dcfSSatish Balay   PetscFunctionReturn(0);
213a7e14dcfSSatish Balay }
214a7e14dcfSSatish Balay 
215a7e14dcfSSatish Balay /*@
216a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point
217a7e14dcfSSatish Balay 
218441846f8SBarry Smith   Collective on Tao
219a7e14dcfSSatish Balay 
220a7e14dcfSSatish Balay   Input Parameters:
221441846f8SBarry Smith + tao - the Tao context
222a7e14dcfSSatish Balay - X - input vector
223a7e14dcfSSatish Balay 
224d8d19677SJose E. Roman   Output Parameters:
225a7e14dcfSSatish Balay + f - Objective value at X
226a7e14dcfSSatish Balay - g - Gradient vector at X
227a7e14dcfSSatish Balay 
22895452b02SPatrick Sanan   Notes:
22995452b02SPatrick Sanan     TaoComputeObjectiveAndGradient() is typically used within minimization implementations,
230a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
231a7e14dcfSSatish Balay 
232a7e14dcfSSatish Balay   Level: advanced
233a7e14dcfSSatish Balay 
234a82e8c82SStefano Zampini .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjective()
235a7e14dcfSSatish Balay @*/
236441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G)
237a7e14dcfSSatish Balay {
238a7e14dcfSSatish Balay   PetscFunctionBegin;
239441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
240a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
241a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G,VEC_CLASSID,4);
242a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
243a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,4);
244*9566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
245a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient) {
246*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL));
247f4c1ad5cSStefano Zampini     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
248*9566063dSJacob Faibussowitsch       PetscCall(TaoComputeObjective(tao,X,f));
249*9566063dSJacob Faibussowitsch       PetscCall(TaoDefaultComputeGradient(tao,X,G,NULL));
250f4c1ad5cSStefano Zampini     } else {
251441846f8SBarry Smith       PetscStackPush("Tao user objective/gradient evaluation routine");
252*9566063dSJacob Faibussowitsch       PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP));
2530cbffdbaSBarry Smith       PetscStackPop;
254a7e14dcfSSatish Balay     }
255*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL));
256a7e14dcfSSatish Balay     tao->nfuncgrads++;
257a7e14dcfSSatish Balay   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
258*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
259441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
260*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP));
261a7e14dcfSSatish Balay     PetscStackPop;
262*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
263a7e14dcfSSatish Balay     tao->nfuncs++;
264*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL));
265441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
266*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP));
267a7e14dcfSSatish Balay     PetscStackPop;
268*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL));
269a7e14dcfSSatish Balay     tao->ngrads++;
270a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() or TaoSetGradient() not set");
271*9566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f)));
272*9566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
2731657496cSHong Zhang 
274*9566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao,X,G));
275a7e14dcfSSatish Balay   PetscFunctionReturn(0);
276a7e14dcfSSatish Balay }
277a7e14dcfSSatish Balay 
278a7e14dcfSSatish Balay /*@C
279a82e8c82SStefano Zampini   TaoSetObjective - Sets the function evaluation routine for minimization
280a7e14dcfSSatish Balay 
281441846f8SBarry Smith   Logically collective on Tao
282a7e14dcfSSatish Balay 
283d8d19677SJose E. Roman   Input Parameters:
284441846f8SBarry Smith + tao - the Tao context
285a7e14dcfSSatish Balay . func - the objective function
286a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2876c23d075SBarry Smith         routine (may be NULL)
288a7e14dcfSSatish Balay 
289a7e14dcfSSatish Balay   Calling sequence of func:
290441846f8SBarry Smith $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
291a7e14dcfSSatish Balay 
292a7e14dcfSSatish Balay + x - input vector
293a7e14dcfSSatish Balay . f - function value
294a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
295a7e14dcfSSatish Balay 
296a7e14dcfSSatish Balay   Level: beginner
297a7e14dcfSSatish Balay 
298a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoGetObjective()
299a7e14dcfSSatish Balay @*/
300a82e8c82SStefano Zampini PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx)
301a7e14dcfSSatish Balay {
302a7e14dcfSSatish Balay   PetscFunctionBegin;
303441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
304a82e8c82SStefano Zampini   if (ctx) tao->user_objP = ctx;
305a82e8c82SStefano Zampini   if (func) tao->ops->computeobjective = func;
306a82e8c82SStefano Zampini   PetscFunctionReturn(0);
307a82e8c82SStefano Zampini }
308a82e8c82SStefano Zampini 
309a82e8c82SStefano Zampini /*@C
310a82e8c82SStefano Zampini   TaoGetObjective - Gets the function evaluation routine for minimization
311a82e8c82SStefano Zampini 
312a82e8c82SStefano Zampini   Not collective
313a82e8c82SStefano Zampini 
314a82e8c82SStefano Zampini   Input Parameter:
315a82e8c82SStefano Zampini . tao - the Tao context
316a82e8c82SStefano Zampini 
317a82e8c82SStefano Zampini   Output Parameters
318a82e8c82SStefano Zampini + func - the objective function
319a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation
320a82e8c82SStefano Zampini 
321a82e8c82SStefano Zampini   Calling sequence of func:
322a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
323a82e8c82SStefano Zampini 
324a82e8c82SStefano Zampini + x - input vector
325a82e8c82SStefano Zampini . f - function value
326a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
327a82e8c82SStefano Zampini 
328a82e8c82SStefano Zampini   Level: beginner
329a82e8c82SStefano Zampini 
330a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoSetHessian(), TaoSetObjective()
331a82e8c82SStefano Zampini @*/
332a82e8c82SStefano Zampini PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal*,void*),void **ctx)
333a82e8c82SStefano Zampini {
334a82e8c82SStefano Zampini   PetscFunctionBegin;
335a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
336a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjective;
337a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objP;
338a7e14dcfSSatish Balay   PetscFunctionReturn(0);
339a7e14dcfSSatish Balay }
340a7e14dcfSSatish Balay 
341a7e14dcfSSatish Balay /*@C
3424a48860cSAlp Dener   TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications
343a7e14dcfSSatish Balay 
344441846f8SBarry Smith   Logically collective on Tao
345a7e14dcfSSatish Balay 
346d8d19677SJose E. Roman   Input Parameters:
347441846f8SBarry Smith + tao - the Tao context
3484a48860cSAlp Dener . func - the residual evaluation routine
349a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
3506c23d075SBarry Smith         routine (may be NULL)
351a7e14dcfSSatish Balay 
352a7e14dcfSSatish Balay   Calling sequence of func:
353441846f8SBarry Smith $      func (Tao tao, Vec x, Vec f, void *ctx);
354a7e14dcfSSatish Balay 
355a7e14dcfSSatish Balay + x - input vector
356a7e14dcfSSatish Balay . f - function value vector
357a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
358a7e14dcfSSatish Balay 
359a7e14dcfSSatish Balay   Level: beginner
360a7e14dcfSSatish Balay 
361a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetJacobianRoutine()
362a7e14dcfSSatish Balay @*/
3634a48860cSAlp Dener PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
364a7e14dcfSSatish Balay {
365a7e14dcfSSatish Balay   PetscFunctionBegin;
366441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3674a48860cSAlp Dener   PetscValidHeaderSpecific(res,VEC_CLASSID,2);
368*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)res));
369737f463aSAlp Dener   if (tao->ls_res) {
370*9566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->ls_res));
371737f463aSAlp Dener   }
3724a48860cSAlp Dener   tao->ls_res = res;
3734ffbe8acSAlp Dener   tao->user_lsresP = ctx;
3744a48860cSAlp Dener   tao->ops->computeresidual = func;
375737f463aSAlp Dener 
376737f463aSAlp Dener   PetscFunctionReturn(0);
377737f463aSAlp Dener }
378737f463aSAlp Dener 
379737f463aSAlp Dener /*@
380737f463aSAlp Dener   TaoSetResidualWeights - Give weights for the residual values. A vector can be used if only diagonal terms are used, otherwise a matrix can be give. If this function is not used, or if sigma_v and sigma_w are both NULL, then the default identity matrix will be used for weights.
381737f463aSAlp Dener 
382737f463aSAlp Dener   Collective on Tao
383737f463aSAlp Dener 
384737f463aSAlp Dener   Input Parameters:
385737f463aSAlp Dener + tao - the Tao context
386737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only)
387737f463aSAlp Dener . n       - the number of weights (if using off-diagonal)
388737f463aSAlp Dener . rows    - index list of rows for sigma_w
389737f463aSAlp Dener . cols    - index list of columns for sigma_w
390737f463aSAlp Dener - vals - array of weights
391737f463aSAlp Dener 
392737f463aSAlp Dener   Note: Either sigma_v or sigma_w (or both) should be NULL
393737f463aSAlp Dener 
394737f463aSAlp Dener   Level: intermediate
395737f463aSAlp Dener 
396737f463aSAlp Dener .seealso: TaoSetResidualRoutine()
397737f463aSAlp Dener @*/
398737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals)
399737f463aSAlp Dener {
400737f463aSAlp Dener   PetscInt       i;
401a82e8c82SStefano Zampini 
402737f463aSAlp Dener   PetscFunctionBegin;
403737f463aSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
404a82e8c82SStefano Zampini   if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2);
405*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)sigma_v));
406*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tao->res_weights_v));
4074ffbe8acSAlp Dener   tao->res_weights_v = sigma_v;
408737f463aSAlp Dener   if (vals) {
409*9566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_rows));
410*9566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_cols));
411*9566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_w));
412*9566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_rows));
413*9566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_cols));
414*9566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_w));
415737f463aSAlp Dener     tao->res_weights_n = n;
416737f463aSAlp Dener     for (i=0;i<n;i++) {
417737f463aSAlp Dener       tao->res_weights_rows[i] = rows[i];
418737f463aSAlp Dener       tao->res_weights_cols[i] = cols[i];
419737f463aSAlp Dener       tao->res_weights_w[i] = vals[i];
420737f463aSAlp Dener     }
421737f463aSAlp Dener   } else {
422737f463aSAlp Dener     tao->res_weights_n = 0;
42383c8fe1dSLisandro Dalcin     tao->res_weights_rows = NULL;
42483c8fe1dSLisandro Dalcin     tao->res_weights_cols = NULL;
425737f463aSAlp Dener   }
426a7e14dcfSSatish Balay   PetscFunctionReturn(0);
427a7e14dcfSSatish Balay }
428a7e14dcfSSatish Balay 
4298b7a9b22SJason Sarich /*@
4304a48860cSAlp Dener   TaoComputeResidual - Computes a least-squares residual vector at a given point
431a7e14dcfSSatish Balay 
432441846f8SBarry Smith   Collective on Tao
433a7e14dcfSSatish Balay 
434a7e14dcfSSatish Balay   Input Parameters:
435441846f8SBarry Smith + tao - the Tao context
436a7e14dcfSSatish Balay - X - input vector
437a7e14dcfSSatish Balay 
438a7e14dcfSSatish Balay   Output Parameter:
439a7e14dcfSSatish Balay . f - Objective vector at X
440a7e14dcfSSatish Balay 
44195452b02SPatrick Sanan   Notes:
4424a48860cSAlp Dener     TaoComputeResidual() is typically used within minimization implementations,
443a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
444a7e14dcfSSatish Balay 
445a7e14dcfSSatish Balay   Level: advanced
446a7e14dcfSSatish Balay 
4474a48860cSAlp Dener .seealso: TaoSetResidualRoutine()
448a7e14dcfSSatish Balay @*/
4494a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F)
450a7e14dcfSSatish Balay {
451a7e14dcfSSatish Balay   PetscFunctionBegin;
452441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
453a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
454a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
455a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
456a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,F,3);
4574a48860cSAlp Dener   if (tao->ops->computeresidual) {
458*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
4594a48860cSAlp Dener     PetscStackPush("Tao user least-squares residual evaluation routine");
460*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP));
461a7e14dcfSSatish Balay     PetscStackPop;
462*9566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
463a7e14dcfSSatish Balay     tao->nfuncs++;
464691b26d3SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called");
465*9566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO least-squares residual evaluation.\n"));
466a7e14dcfSSatish Balay   PetscFunctionReturn(0);
467a7e14dcfSSatish Balay }
468a7e14dcfSSatish Balay 
469a7e14dcfSSatish Balay /*@C
470a82e8c82SStefano Zampini   TaoSetGradient - Sets the gradient evaluation routine for minimization
471a7e14dcfSSatish Balay 
472441846f8SBarry Smith   Logically collective on Tao
473a7e14dcfSSatish Balay 
474d8d19677SJose E. Roman   Input Parameters:
475441846f8SBarry Smith + tao - the Tao context
476a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
477a7e14dcfSSatish Balay . func - the gradient function
478a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
4796c23d075SBarry Smith         routine (may be NULL)
480a7e14dcfSSatish Balay 
481a7e14dcfSSatish Balay   Calling sequence of func:
482441846f8SBarry Smith $      func (Tao tao, Vec x, Vec g, void *ctx);
483a7e14dcfSSatish Balay 
484a7e14dcfSSatish Balay + x - input vector
485a7e14dcfSSatish Balay . g - gradient value (output)
486a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
487a7e14dcfSSatish Balay 
488a7e14dcfSSatish Balay   Level: beginner
489a7e14dcfSSatish Balay 
490a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoGetGradient()
491a7e14dcfSSatish Balay @*/
492a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
493a7e14dcfSSatish Balay {
494a7e14dcfSSatish Balay   PetscFunctionBegin;
495441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
496a82e8c82SStefano Zampini   if (g) {
497a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
498a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
499*9566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
500*9566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
501a82e8c82SStefano Zampini     tao->gradient = g;
502a82e8c82SStefano Zampini   }
503a82e8c82SStefano Zampini   if (func) tao->ops->computegradient = func;
504a82e8c82SStefano Zampini   if (ctx) tao->user_gradP = ctx;
505a7e14dcfSSatish Balay   PetscFunctionReturn(0);
506a7e14dcfSSatish Balay }
507a7e14dcfSSatish Balay 
508a7e14dcfSSatish Balay /*@C
509a82e8c82SStefano Zampini   TaoGetGradient - Gets the gradient evaluation routine for minimization
510a82e8c82SStefano Zampini 
511a82e8c82SStefano Zampini   Not collective
512a82e8c82SStefano Zampini 
513a82e8c82SStefano Zampini   Input Parameter:
514a82e8c82SStefano Zampini . tao - the Tao context
515a82e8c82SStefano Zampini 
516a82e8c82SStefano Zampini   Output Parameters:
517a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation
518a82e8c82SStefano Zampini . func - the gradient function
519a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
520a82e8c82SStefano Zampini 
521a82e8c82SStefano Zampini   Calling sequence of func:
522a82e8c82SStefano Zampini $      func (Tao tao, Vec x, Vec g, void *ctx);
523a82e8c82SStefano Zampini 
524a82e8c82SStefano Zampini + x - input vector
525a82e8c82SStefano Zampini . g - gradient value (output)
526a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
527a82e8c82SStefano Zampini 
528a82e8c82SStefano Zampini   Level: beginner
529a82e8c82SStefano Zampini 
530a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoSetGradient()
531a82e8c82SStefano Zampini @*/
532a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx)
533a82e8c82SStefano Zampini {
534a82e8c82SStefano Zampini   PetscFunctionBegin;
535a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
536a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
537a82e8c82SStefano Zampini   if (func) *func = tao->ops->computegradient;
538a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_gradP;
539a82e8c82SStefano Zampini   PetscFunctionReturn(0);
540a82e8c82SStefano Zampini }
541a82e8c82SStefano Zampini 
542a82e8c82SStefano Zampini /*@C
543a82e8c82SStefano Zampini   TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for minimization
544a7e14dcfSSatish Balay 
545441846f8SBarry Smith   Logically collective on Tao
546a7e14dcfSSatish Balay 
547d8d19677SJose E. Roman   Input Parameters:
548441846f8SBarry Smith + tao - the Tao context
549a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
550a7e14dcfSSatish Balay . func - the gradient function
551a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
5526c23d075SBarry Smith         routine (may be NULL)
553a7e14dcfSSatish Balay 
554a7e14dcfSSatish Balay   Calling sequence of func:
55517477c02SJason Sarich $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
556a7e14dcfSSatish Balay 
557a7e14dcfSSatish Balay + x - input vector
55817477c02SJason Sarich . f - objective value (output)
559a7e14dcfSSatish Balay . g - gradient value (output)
560a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
561a7e14dcfSSatish Balay 
562a7e14dcfSSatish Balay   Level: beginner
563a7e14dcfSSatish Balay 
564a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetGradient(), TaoGetObjectiveAndGradient()
565a7e14dcfSSatish Balay @*/
566a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx)
567a82e8c82SStefano Zampini {
568a82e8c82SStefano Zampini   PetscFunctionBegin;
569a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
570a82e8c82SStefano Zampini   if (g) {
571a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
572a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
573*9566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
574*9566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
575a82e8c82SStefano Zampini     tao->gradient = g;
576a82e8c82SStefano Zampini   }
577a82e8c82SStefano Zampini   if (ctx) tao->user_objgradP = ctx;
578a82e8c82SStefano Zampini   if (func) tao->ops->computeobjectiveandgradient = func;
579a82e8c82SStefano Zampini   PetscFunctionReturn(0);
580a82e8c82SStefano Zampini }
581a82e8c82SStefano Zampini 
582a82e8c82SStefano Zampini /*@C
583a82e8c82SStefano Zampini   TaoGetObjectiveAndGradient - Gets a combined objective function and gradient evaluation routine for minimization
584a82e8c82SStefano Zampini 
585a82e8c82SStefano Zampini   Not collective
586a82e8c82SStefano Zampini 
587a82e8c82SStefano Zampini   Input Parameter:
588a82e8c82SStefano Zampini . tao - the Tao context
589a82e8c82SStefano Zampini 
590a82e8c82SStefano Zampini   Output Parameters:
591817da375SSatish Balay + g - the vector to internally hold the gradient computation
592a82e8c82SStefano Zampini . func - the gradient function
593a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
594a82e8c82SStefano Zampini 
595a82e8c82SStefano Zampini   Calling sequence of func:
596a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
597a82e8c82SStefano Zampini 
598a82e8c82SStefano Zampini + x - input vector
599a82e8c82SStefano Zampini . f - objective value (output)
600a82e8c82SStefano Zampini . g - gradient value (output)
601a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
602a82e8c82SStefano Zampini 
603a82e8c82SStefano Zampini   Level: beginner
604a82e8c82SStefano Zampini 
605a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetGradient(), TaoSetHessian(), TaoSetObjectiveAndGradient()
606a82e8c82SStefano Zampini @*/
607a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx)
608a7e14dcfSSatish Balay {
609a7e14dcfSSatish Balay   PetscFunctionBegin;
610441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
611a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
612a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjectiveandgradient;
613a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objgradP;
614a7e14dcfSSatish Balay   PetscFunctionReturn(0);
615a7e14dcfSSatish Balay }
616a7e14dcfSSatish Balay 
617a7e14dcfSSatish Balay /*@
618a82e8c82SStefano Zampini   TaoIsObjectiveDefined - Checks to see if the user has
619a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
620a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
621a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
622a7e14dcfSSatish Balay 
623a82e8c82SStefano Zampini   Not collective
624a7e14dcfSSatish Balay 
625a82e8c82SStefano Zampini   Input Parameter:
626a82e8c82SStefano Zampini . tao - the Tao context
627a82e8c82SStefano Zampini 
628a82e8c82SStefano Zampini   Output Parameter:
629f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
630a82e8c82SStefano Zampini 
631a7e14dcfSSatish Balay   Level: developer
632a7e14dcfSSatish Balay 
633a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoIsGradientDefined(), TaoIsObjectiveAndGradientDefined()
634a7e14dcfSSatish Balay @*/
635441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg)
636a7e14dcfSSatish Balay {
637a7e14dcfSSatish Balay   PetscFunctionBegin;
638441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
63983c8fe1dSLisandro Dalcin   if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE;
64045cf516eSBarry Smith   else *flg = PETSC_TRUE;
641a7e14dcfSSatish Balay   PetscFunctionReturn(0);
642a7e14dcfSSatish Balay }
643a7e14dcfSSatish Balay 
644a7e14dcfSSatish Balay /*@
645a82e8c82SStefano Zampini   TaoIsGradientDefined - Checks to see if the user has
646a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
647a7e14dcfSSatish Balay   it is appropriate to call TaoComputeGradient() or
648a7e14dcfSSatish Balay   TaoComputeGradientAndGradient()
649a7e14dcfSSatish Balay 
650a7e14dcfSSatish Balay   Not Collective
651a7e14dcfSSatish Balay 
652a82e8c82SStefano Zampini   Input Parameter:
653a82e8c82SStefano Zampini . tao - the Tao context
654a82e8c82SStefano Zampini 
655a82e8c82SStefano Zampini   Output Parameter:
656f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
657a82e8c82SStefano Zampini 
658a7e14dcfSSatish Balay   Level: developer
659a7e14dcfSSatish Balay 
660a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoIsObjectiveDefined(), TaoIsObjectiveAndGradientDefined()
661a7e14dcfSSatish Balay @*/
662441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg)
663a7e14dcfSSatish Balay {
664a7e14dcfSSatish Balay   PetscFunctionBegin;
665441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
66683c8fe1dSLisandro Dalcin   if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE;
66745cf516eSBarry Smith   else *flg = PETSC_TRUE;
668a7e14dcfSSatish Balay   PetscFunctionReturn(0);
669a7e14dcfSSatish Balay }
670a7e14dcfSSatish Balay 
671a7e14dcfSSatish Balay /*@
672a82e8c82SStefano Zampini   TaoIsObjectiveAndGradientDefined - Checks to see if the user has
673a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
674a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
675a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
676a7e14dcfSSatish Balay 
677a7e14dcfSSatish Balay   Not Collective
678a7e14dcfSSatish Balay 
679a82e8c82SStefano Zampini   Input Parameter:
680a82e8c82SStefano Zampini . tao - the Tao context
681a82e8c82SStefano Zampini 
682a82e8c82SStefano Zampini   Output Parameter:
683f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
684a82e8c82SStefano Zampini 
685a7e14dcfSSatish Balay   Level: developer
686a7e14dcfSSatish Balay 
687a82e8c82SStefano Zampini .seealso: TaoSetObjectiveAndGradient(), TaoIsObjectiveDefined(), TaoIsGradientDefined()
688a7e14dcfSSatish Balay @*/
689441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg)
690a7e14dcfSSatish Balay {
691a7e14dcfSSatish Balay   PetscFunctionBegin;
692441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
69383c8fe1dSLisandro Dalcin   if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE;
69445cf516eSBarry Smith   else *flg = PETSC_TRUE;
695a7e14dcfSSatish Balay   PetscFunctionReturn(0);
696a7e14dcfSSatish Balay }
697