xref: /petsc/src/tao/interface/taosolver_fg.c (revision d0609ced746bc51b019815ca91d747429db24893)
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);
209566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)x0));
219566063dSJacob 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 
3809baa881SHong Zhang   PetscFunctionBegin;
39*d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)tao);
409566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-tao_test_gradient","Compare hand-coded and finite difference Gradients","None",&test));
419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-tao_test_gradient_view","View difference between hand-coded and finite difference Gradients element entries","None",&mviewer,&format,&complete_print));
42*d0609cedSBarry Smith   PetscOptionsEnd();
432f4b6201SAlp Dener   if (!test) {
442f4b6201SAlp Dener     if (complete_print) {
459566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&mviewer));
462f4b6201SAlp Dener     }
472f4b6201SAlp Dener     PetscFunctionReturn(0);
482f4b6201SAlp Dener   }
4909baa881SHong Zhang 
509566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao,&comm));
519566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm,&viewer));
529566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
539566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
549566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Gradient -------------\n"));
5509baa881SHong Zhang   if (!complete_print && !directionsprinted) {
569566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_gradient_view and optionally -tao_test_gradient <threshold> to show difference\n"));
579566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference gradient entries greater than <threshold>.\n"));
5809baa881SHong Zhang   }
5909baa881SHong Zhang   if (!directionsprinted) {
609566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Gradient, if (for double precision runs) ||G - Gfd||/||G|| is\n"));
619566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Gradient is probably correct.\n"));
6209baa881SHong Zhang     directionsprinted = PETSC_TRUE;
6309baa881SHong Zhang   }
64913eda9aSHong Zhang   if (complete_print) {
659566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(mviewer,format));
66913eda9aSHong Zhang   }
6709baa881SHong Zhang 
689566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x,&g2));
699566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x,&g3));
7009baa881SHong Zhang 
7109baa881SHong Zhang   /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */
729566063dSJacob Faibussowitsch   PetscCall(TaoDefaultComputeGradient(tao,x,g2,NULL));
7309baa881SHong Zhang 
749566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2,NORM_2,&fdnorm));
759566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1,NORM_2,&hcnorm));
769566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2,NORM_INFINITY,&fdmax));
779566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1,NORM_INFINITY,&hcmax));
789566063dSJacob Faibussowitsch   PetscCall(VecDot(g1,g2,&dot));
799566063dSJacob Faibussowitsch   PetscCall(VecCopy(g1,g3));
809566063dSJacob Faibussowitsch   PetscCall(VecAXPY(g3,-1.0,g2));
819566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3,NORM_2,&diffnorm));
829566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3,NORM_INFINITY,&diffmax));
839566063dSJacob 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))));
849566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffnorm/PetscMax(hcnorm,fdnorm)),(double)diffnorm));
859566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffmax/PetscMax(hcmax,fdmax)),(double)diffmax));
8609baa881SHong Zhang 
8709baa881SHong Zhang   if (complete_print) {
889566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded gradient ----------\n"));
899566063dSJacob Faibussowitsch     PetscCall(VecView(g1,mviewer));
909566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite difference gradient ----------\n"));
919566063dSJacob Faibussowitsch     PetscCall(VecView(g2,mviewer));
929566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference gradient ----------\n"));
939566063dSJacob Faibussowitsch     PetscCall(VecView(g3,mviewer));
9409baa881SHong Zhang   }
959566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g2));
969566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g3));
97913eda9aSHong Zhang 
98913eda9aSHong Zhang   if (complete_print) {
999566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
1009566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
101913eda9aSHong Zhang   }
1029566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer,tabs));
10309baa881SHong Zhang   PetscFunctionReturn(0);
10409baa881SHong Zhang }
10509baa881SHong Zhang 
106a7e14dcfSSatish Balay /*@
107a7e14dcfSSatish Balay   TaoComputeGradient - Computes the gradient of the objective function
108a7e14dcfSSatish Balay 
109441846f8SBarry Smith   Collective on Tao
110a7e14dcfSSatish Balay 
111a7e14dcfSSatish Balay   Input Parameters:
112441846f8SBarry Smith + tao - the Tao context
113a7e14dcfSSatish Balay - X - input vector
114a7e14dcfSSatish Balay 
115a7e14dcfSSatish Balay   Output Parameter:
116a7e14dcfSSatish Balay . G - gradient vector
117a7e14dcfSSatish Balay 
11809baa881SHong Zhang   Options Database Keys:
11909baa881SHong Zhang +    -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors
120dfe02fe6SHong 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
12109baa881SHong Zhang 
12295452b02SPatrick Sanan   Notes:
12395452b02SPatrick Sanan     TaoComputeGradient() is typically used within minimization implementations,
124a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
125a7e14dcfSSatish Balay 
126a7e14dcfSSatish Balay   Level: advanced
127a7e14dcfSSatish Balay 
128a82e8c82SStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetGradient()
129a7e14dcfSSatish Balay @*/
130441846f8SBarry Smith PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G)
131a7e14dcfSSatish Balay {
132a7e14dcfSSatish Balay   PetscReal      dummy;
13387f595a5SBarry Smith 
134a7e14dcfSSatish Balay   PetscFunctionBegin;
135441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
136a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
137064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(G,VEC_CLASSID,3);
138a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
139a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,3);
1409566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
141a7e14dcfSSatish Balay   if (tao->ops->computegradient) {
1429566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL));
143441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
1449566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP));
145a7e14dcfSSatish Balay     PetscStackPop;
1469566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL));
147a7e14dcfSSatish Balay     tao->ngrads++;
148a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1499566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL));
150a7e14dcfSSatish Balay     PetscStackPush("Tao user objective/gradient evaluation routine");
1519566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP));
152a7e14dcfSSatish Balay     PetscStackPop;
1539566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL));
154a7e14dcfSSatish Balay     tao->nfuncgrads++;
155a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradient() has not been called");
1569566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
15709baa881SHong Zhang 
1589566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao,X,G));
159a7e14dcfSSatish Balay   PetscFunctionReturn(0);
160a7e14dcfSSatish Balay }
161a7e14dcfSSatish Balay 
162a7e14dcfSSatish Balay /*@
163a7e14dcfSSatish Balay   TaoComputeObjective - Computes the objective function value at a given point
164a7e14dcfSSatish Balay 
165441846f8SBarry Smith   Collective on Tao
166a7e14dcfSSatish Balay 
167a7e14dcfSSatish Balay   Input Parameters:
168441846f8SBarry Smith + tao - the Tao context
169a7e14dcfSSatish Balay - X - input vector
170a7e14dcfSSatish Balay 
171a7e14dcfSSatish Balay   Output Parameter:
172a7e14dcfSSatish Balay . f - Objective value at X
173a7e14dcfSSatish Balay 
17495452b02SPatrick Sanan   Notes:
17595452b02SPatrick Sanan     TaoComputeObjective() is typically used within minimization implementations,
176a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
177a7e14dcfSSatish Balay 
178a7e14dcfSSatish Balay   Level: advanced
179a7e14dcfSSatish Balay 
180a82e8c82SStefano Zampini .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjective()
181a7e14dcfSSatish Balay @*/
182441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f)
183a7e14dcfSSatish Balay {
184a7e14dcfSSatish Balay   Vec            temp;
18587f595a5SBarry Smith 
186a7e14dcfSSatish Balay   PetscFunctionBegin;
187441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
188a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
189a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
1909566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
191a7e14dcfSSatish Balay   if (tao->ops->computeobjective) {
1929566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
193441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
1949566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP));
195a7e14dcfSSatish Balay     PetscStackPop;
1969566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
197a7e14dcfSSatish Balay     tao->nfuncs++;
198a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1999566063dSJacob Faibussowitsch     PetscCall(PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n"));
2009566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(X,&temp));
2019566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,NULL,NULL));
202441846f8SBarry Smith     PetscStackPush("Tao user objective/gradient evaluation routine");
2039566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP));
204a7e14dcfSSatish Balay     PetscStackPop;
2059566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,NULL,NULL));
2069566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&temp));
207a7e14dcfSSatish Balay     tao->nfuncgrads++;
208a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() has not been called");
2099566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f)));
2109566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
211a7e14dcfSSatish Balay   PetscFunctionReturn(0);
212a7e14dcfSSatish Balay }
213a7e14dcfSSatish Balay 
214a7e14dcfSSatish Balay /*@
215a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point
216a7e14dcfSSatish Balay 
217441846f8SBarry Smith   Collective on Tao
218a7e14dcfSSatish Balay 
219a7e14dcfSSatish Balay   Input Parameters:
220441846f8SBarry Smith + tao - the Tao context
221a7e14dcfSSatish Balay - X - input vector
222a7e14dcfSSatish Balay 
223d8d19677SJose E. Roman   Output Parameters:
224a7e14dcfSSatish Balay + f - Objective value at X
225a7e14dcfSSatish Balay - g - Gradient vector at X
226a7e14dcfSSatish Balay 
22795452b02SPatrick Sanan   Notes:
22895452b02SPatrick Sanan     TaoComputeObjectiveAndGradient() is typically used within minimization implementations,
229a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
230a7e14dcfSSatish Balay 
231a7e14dcfSSatish Balay   Level: advanced
232a7e14dcfSSatish Balay 
233a82e8c82SStefano Zampini .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjective()
234a7e14dcfSSatish Balay @*/
235441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G)
236a7e14dcfSSatish Balay {
237a7e14dcfSSatish Balay   PetscFunctionBegin;
238441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
239a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
240a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G,VEC_CLASSID,4);
241a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
242a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,4);
2439566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
244a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient) {
2459566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL));
246f4c1ad5cSStefano Zampini     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
2479566063dSJacob Faibussowitsch       PetscCall(TaoComputeObjective(tao,X,f));
2489566063dSJacob Faibussowitsch       PetscCall(TaoDefaultComputeGradient(tao,X,G,NULL));
249f4c1ad5cSStefano Zampini     } else {
250441846f8SBarry Smith       PetscStackPush("Tao user objective/gradient evaluation routine");
2519566063dSJacob Faibussowitsch       PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP));
2520cbffdbaSBarry Smith       PetscStackPop;
253a7e14dcfSSatish Balay     }
2549566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL));
255a7e14dcfSSatish Balay     tao->nfuncgrads++;
256a7e14dcfSSatish Balay   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
2579566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
258441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
2599566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP));
260a7e14dcfSSatish Balay     PetscStackPop;
2619566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
262a7e14dcfSSatish Balay     tao->nfuncs++;
2639566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL));
264441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
2659566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP));
266a7e14dcfSSatish Balay     PetscStackPop;
2679566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL));
268a7e14dcfSSatish Balay     tao->ngrads++;
269a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() or TaoSetGradient() not set");
2709566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f)));
2719566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
2721657496cSHong Zhang 
2739566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao,X,G));
274a7e14dcfSSatish Balay   PetscFunctionReturn(0);
275a7e14dcfSSatish Balay }
276a7e14dcfSSatish Balay 
277a7e14dcfSSatish Balay /*@C
278a82e8c82SStefano Zampini   TaoSetObjective - Sets the function evaluation routine for minimization
279a7e14dcfSSatish Balay 
280441846f8SBarry Smith   Logically collective on Tao
281a7e14dcfSSatish Balay 
282d8d19677SJose E. Roman   Input Parameters:
283441846f8SBarry Smith + tao - the Tao context
284a7e14dcfSSatish Balay . func - the objective function
285a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2866c23d075SBarry Smith         routine (may be NULL)
287a7e14dcfSSatish Balay 
288a7e14dcfSSatish Balay   Calling sequence of func:
289441846f8SBarry Smith $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
290a7e14dcfSSatish Balay 
291a7e14dcfSSatish Balay + x - input vector
292a7e14dcfSSatish Balay . f - function value
293a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
294a7e14dcfSSatish Balay 
295a7e14dcfSSatish Balay   Level: beginner
296a7e14dcfSSatish Balay 
297a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoGetObjective()
298a7e14dcfSSatish Balay @*/
299a82e8c82SStefano Zampini PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx)
300a7e14dcfSSatish Balay {
301a7e14dcfSSatish Balay   PetscFunctionBegin;
302441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
303a82e8c82SStefano Zampini   if (ctx) tao->user_objP = ctx;
304a82e8c82SStefano Zampini   if (func) tao->ops->computeobjective = func;
305a82e8c82SStefano Zampini   PetscFunctionReturn(0);
306a82e8c82SStefano Zampini }
307a82e8c82SStefano Zampini 
308a82e8c82SStefano Zampini /*@C
309a82e8c82SStefano Zampini   TaoGetObjective - Gets the function evaluation routine for minimization
310a82e8c82SStefano Zampini 
311a82e8c82SStefano Zampini   Not collective
312a82e8c82SStefano Zampini 
313a82e8c82SStefano Zampini   Input Parameter:
314a82e8c82SStefano Zampini . tao - the Tao context
315a82e8c82SStefano Zampini 
316a82e8c82SStefano Zampini   Output Parameters
317a82e8c82SStefano Zampini + func - the objective function
318a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation
319a82e8c82SStefano Zampini 
320a82e8c82SStefano Zampini   Calling sequence of func:
321a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
322a82e8c82SStefano Zampini 
323a82e8c82SStefano Zampini + x - input vector
324a82e8c82SStefano Zampini . f - function value
325a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
326a82e8c82SStefano Zampini 
327a82e8c82SStefano Zampini   Level: beginner
328a82e8c82SStefano Zampini 
329a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoSetHessian(), TaoSetObjective()
330a82e8c82SStefano Zampini @*/
331a82e8c82SStefano Zampini PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal*,void*),void **ctx)
332a82e8c82SStefano Zampini {
333a82e8c82SStefano Zampini   PetscFunctionBegin;
334a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
335a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjective;
336a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objP;
337a7e14dcfSSatish Balay   PetscFunctionReturn(0);
338a7e14dcfSSatish Balay }
339a7e14dcfSSatish Balay 
340a7e14dcfSSatish Balay /*@C
3414a48860cSAlp Dener   TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications
342a7e14dcfSSatish Balay 
343441846f8SBarry Smith   Logically collective on Tao
344a7e14dcfSSatish Balay 
345d8d19677SJose E. Roman   Input Parameters:
346441846f8SBarry Smith + tao - the Tao context
3474a48860cSAlp Dener . func - the residual evaluation routine
348a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
3496c23d075SBarry Smith         routine (may be NULL)
350a7e14dcfSSatish Balay 
351a7e14dcfSSatish Balay   Calling sequence of func:
352441846f8SBarry Smith $      func (Tao tao, Vec x, Vec f, void *ctx);
353a7e14dcfSSatish Balay 
354a7e14dcfSSatish Balay + x - input vector
355a7e14dcfSSatish Balay . f - function value vector
356a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
357a7e14dcfSSatish Balay 
358a7e14dcfSSatish Balay   Level: beginner
359a7e14dcfSSatish Balay 
360a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetJacobianRoutine()
361a7e14dcfSSatish Balay @*/
3624a48860cSAlp Dener PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
363a7e14dcfSSatish Balay {
364a7e14dcfSSatish Balay   PetscFunctionBegin;
365441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3664a48860cSAlp Dener   PetscValidHeaderSpecific(res,VEC_CLASSID,2);
3679566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)res));
368737f463aSAlp Dener   if (tao->ls_res) {
3699566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->ls_res));
370737f463aSAlp Dener   }
3714a48860cSAlp Dener   tao->ls_res = res;
3724ffbe8acSAlp Dener   tao->user_lsresP = ctx;
3734a48860cSAlp Dener   tao->ops->computeresidual = func;
374737f463aSAlp Dener 
375737f463aSAlp Dener   PetscFunctionReturn(0);
376737f463aSAlp Dener }
377737f463aSAlp Dener 
378737f463aSAlp Dener /*@
379737f463aSAlp 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.
380737f463aSAlp Dener 
381737f463aSAlp Dener   Collective on Tao
382737f463aSAlp Dener 
383737f463aSAlp Dener   Input Parameters:
384737f463aSAlp Dener + tao - the Tao context
385737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only)
386737f463aSAlp Dener . n       - the number of weights (if using off-diagonal)
387737f463aSAlp Dener . rows    - index list of rows for sigma_w
388737f463aSAlp Dener . cols    - index list of columns for sigma_w
389737f463aSAlp Dener - vals - array of weights
390737f463aSAlp Dener 
391737f463aSAlp Dener   Note: Either sigma_v or sigma_w (or both) should be NULL
392737f463aSAlp Dener 
393737f463aSAlp Dener   Level: intermediate
394737f463aSAlp Dener 
395737f463aSAlp Dener .seealso: TaoSetResidualRoutine()
396737f463aSAlp Dener @*/
397737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals)
398737f463aSAlp Dener {
399737f463aSAlp Dener   PetscInt       i;
400a82e8c82SStefano Zampini 
401737f463aSAlp Dener   PetscFunctionBegin;
402737f463aSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
403a82e8c82SStefano Zampini   if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2);
4049566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)sigma_v));
4059566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tao->res_weights_v));
4064ffbe8acSAlp Dener   tao->res_weights_v = sigma_v;
407737f463aSAlp Dener   if (vals) {
4089566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_rows));
4099566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_cols));
4109566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_w));
4119566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_rows));
4129566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_cols));
4139566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_w));
414737f463aSAlp Dener     tao->res_weights_n = n;
415737f463aSAlp Dener     for (i=0;i<n;i++) {
416737f463aSAlp Dener       tao->res_weights_rows[i] = rows[i];
417737f463aSAlp Dener       tao->res_weights_cols[i] = cols[i];
418737f463aSAlp Dener       tao->res_weights_w[i] = vals[i];
419737f463aSAlp Dener     }
420737f463aSAlp Dener   } else {
421737f463aSAlp Dener     tao->res_weights_n = 0;
42283c8fe1dSLisandro Dalcin     tao->res_weights_rows = NULL;
42383c8fe1dSLisandro Dalcin     tao->res_weights_cols = NULL;
424737f463aSAlp Dener   }
425a7e14dcfSSatish Balay   PetscFunctionReturn(0);
426a7e14dcfSSatish Balay }
427a7e14dcfSSatish Balay 
4288b7a9b22SJason Sarich /*@
4294a48860cSAlp Dener   TaoComputeResidual - Computes a least-squares residual vector at a given point
430a7e14dcfSSatish Balay 
431441846f8SBarry Smith   Collective on Tao
432a7e14dcfSSatish Balay 
433a7e14dcfSSatish Balay   Input Parameters:
434441846f8SBarry Smith + tao - the Tao context
435a7e14dcfSSatish Balay - X - input vector
436a7e14dcfSSatish Balay 
437a7e14dcfSSatish Balay   Output Parameter:
438a7e14dcfSSatish Balay . f - Objective vector at X
439a7e14dcfSSatish Balay 
44095452b02SPatrick Sanan   Notes:
4414a48860cSAlp Dener     TaoComputeResidual() is typically used within minimization implementations,
442a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
443a7e14dcfSSatish Balay 
444a7e14dcfSSatish Balay   Level: advanced
445a7e14dcfSSatish Balay 
4464a48860cSAlp Dener .seealso: TaoSetResidualRoutine()
447a7e14dcfSSatish Balay @*/
4484a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F)
449a7e14dcfSSatish Balay {
450a7e14dcfSSatish Balay   PetscFunctionBegin;
451441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
452a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
453a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
454a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
455a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,F,3);
4564a48860cSAlp Dener   if (tao->ops->computeresidual) {
4579566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
4584a48860cSAlp Dener     PetscStackPush("Tao user least-squares residual evaluation routine");
4599566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP));
460a7e14dcfSSatish Balay     PetscStackPop;
4619566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
462a7e14dcfSSatish Balay     tao->nfuncs++;
463691b26d3SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called");
4649566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO least-squares residual evaluation.\n"));
465a7e14dcfSSatish Balay   PetscFunctionReturn(0);
466a7e14dcfSSatish Balay }
467a7e14dcfSSatish Balay 
468a7e14dcfSSatish Balay /*@C
469a82e8c82SStefano Zampini   TaoSetGradient - Sets the gradient evaluation routine for minimization
470a7e14dcfSSatish Balay 
471441846f8SBarry Smith   Logically collective on Tao
472a7e14dcfSSatish Balay 
473d8d19677SJose E. Roman   Input Parameters:
474441846f8SBarry Smith + tao - the Tao context
475a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
476a7e14dcfSSatish Balay . func - the gradient function
477a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
4786c23d075SBarry Smith         routine (may be NULL)
479a7e14dcfSSatish Balay 
480a7e14dcfSSatish Balay   Calling sequence of func:
481441846f8SBarry Smith $      func (Tao tao, Vec x, Vec g, void *ctx);
482a7e14dcfSSatish Balay 
483a7e14dcfSSatish Balay + x - input vector
484a7e14dcfSSatish Balay . g - gradient value (output)
485a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
486a7e14dcfSSatish Balay 
487a7e14dcfSSatish Balay   Level: beginner
488a7e14dcfSSatish Balay 
489a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoGetGradient()
490a7e14dcfSSatish Balay @*/
491a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
492a7e14dcfSSatish Balay {
493a7e14dcfSSatish Balay   PetscFunctionBegin;
494441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
495a82e8c82SStefano Zampini   if (g) {
496a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
497a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
4989566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
4999566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
500a82e8c82SStefano Zampini     tao->gradient = g;
501a82e8c82SStefano Zampini   }
502a82e8c82SStefano Zampini   if (func) tao->ops->computegradient = func;
503a82e8c82SStefano Zampini   if (ctx) tao->user_gradP = ctx;
504a7e14dcfSSatish Balay   PetscFunctionReturn(0);
505a7e14dcfSSatish Balay }
506a7e14dcfSSatish Balay 
507a7e14dcfSSatish Balay /*@C
508a82e8c82SStefano Zampini   TaoGetGradient - Gets the gradient evaluation routine for minimization
509a82e8c82SStefano Zampini 
510a82e8c82SStefano Zampini   Not collective
511a82e8c82SStefano Zampini 
512a82e8c82SStefano Zampini   Input Parameter:
513a82e8c82SStefano Zampini . tao - the Tao context
514a82e8c82SStefano Zampini 
515a82e8c82SStefano Zampini   Output Parameters:
516a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation
517a82e8c82SStefano Zampini . func - the gradient function
518a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
519a82e8c82SStefano Zampini 
520a82e8c82SStefano Zampini   Calling sequence of func:
521a82e8c82SStefano Zampini $      func (Tao tao, Vec x, Vec g, void *ctx);
522a82e8c82SStefano Zampini 
523a82e8c82SStefano Zampini + x - input vector
524a82e8c82SStefano Zampini . g - gradient value (output)
525a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
526a82e8c82SStefano Zampini 
527a82e8c82SStefano Zampini   Level: beginner
528a82e8c82SStefano Zampini 
529a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoSetGradient()
530a82e8c82SStefano Zampini @*/
531a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx)
532a82e8c82SStefano Zampini {
533a82e8c82SStefano Zampini   PetscFunctionBegin;
534a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
535a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
536a82e8c82SStefano Zampini   if (func) *func = tao->ops->computegradient;
537a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_gradP;
538a82e8c82SStefano Zampini   PetscFunctionReturn(0);
539a82e8c82SStefano Zampini }
540a82e8c82SStefano Zampini 
541a82e8c82SStefano Zampini /*@C
542a82e8c82SStefano Zampini   TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for minimization
543a7e14dcfSSatish Balay 
544441846f8SBarry Smith   Logically collective on Tao
545a7e14dcfSSatish Balay 
546d8d19677SJose E. Roman   Input Parameters:
547441846f8SBarry Smith + tao - the Tao context
548a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
549a7e14dcfSSatish Balay . func - the gradient function
550a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
5516c23d075SBarry Smith         routine (may be NULL)
552a7e14dcfSSatish Balay 
553a7e14dcfSSatish Balay   Calling sequence of func:
55417477c02SJason Sarich $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
555a7e14dcfSSatish Balay 
556a7e14dcfSSatish Balay + x - input vector
55717477c02SJason Sarich . f - objective value (output)
558a7e14dcfSSatish Balay . g - gradient value (output)
559a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
560a7e14dcfSSatish Balay 
561a7e14dcfSSatish Balay   Level: beginner
562a7e14dcfSSatish Balay 
563a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetGradient(), TaoGetObjectiveAndGradient()
564a7e14dcfSSatish Balay @*/
565a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx)
566a82e8c82SStefano Zampini {
567a82e8c82SStefano Zampini   PetscFunctionBegin;
568a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
569a82e8c82SStefano Zampini   if (g) {
570a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
571a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
5729566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
5739566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
574a82e8c82SStefano Zampini     tao->gradient = g;
575a82e8c82SStefano Zampini   }
576a82e8c82SStefano Zampini   if (ctx) tao->user_objgradP = ctx;
577a82e8c82SStefano Zampini   if (func) tao->ops->computeobjectiveandgradient = func;
578a82e8c82SStefano Zampini   PetscFunctionReturn(0);
579a82e8c82SStefano Zampini }
580a82e8c82SStefano Zampini 
581a82e8c82SStefano Zampini /*@C
582a82e8c82SStefano Zampini   TaoGetObjectiveAndGradient - Gets a combined objective function and gradient evaluation routine for minimization
583a82e8c82SStefano Zampini 
584a82e8c82SStefano Zampini   Not collective
585a82e8c82SStefano Zampini 
586a82e8c82SStefano Zampini   Input Parameter:
587a82e8c82SStefano Zampini . tao - the Tao context
588a82e8c82SStefano Zampini 
589a82e8c82SStefano Zampini   Output Parameters:
590817da375SSatish Balay + g - the vector to internally hold the gradient computation
591a82e8c82SStefano Zampini . func - the gradient function
592a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
593a82e8c82SStefano Zampini 
594a82e8c82SStefano Zampini   Calling sequence of func:
595a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
596a82e8c82SStefano Zampini 
597a82e8c82SStefano Zampini + x - input vector
598a82e8c82SStefano Zampini . f - objective value (output)
599a82e8c82SStefano Zampini . g - gradient value (output)
600a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
601a82e8c82SStefano Zampini 
602a82e8c82SStefano Zampini   Level: beginner
603a82e8c82SStefano Zampini 
604a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetGradient(), TaoSetHessian(), TaoSetObjectiveAndGradient()
605a82e8c82SStefano Zampini @*/
606a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx)
607a7e14dcfSSatish Balay {
608a7e14dcfSSatish Balay   PetscFunctionBegin;
609441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
610a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
611a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjectiveandgradient;
612a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objgradP;
613a7e14dcfSSatish Balay   PetscFunctionReturn(0);
614a7e14dcfSSatish Balay }
615a7e14dcfSSatish Balay 
616a7e14dcfSSatish Balay /*@
617a82e8c82SStefano Zampini   TaoIsObjectiveDefined - Checks to see if the user has
618a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
619a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
620a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
621a7e14dcfSSatish Balay 
622a82e8c82SStefano Zampini   Not collective
623a7e14dcfSSatish Balay 
624a82e8c82SStefano Zampini   Input Parameter:
625a82e8c82SStefano Zampini . tao - the Tao context
626a82e8c82SStefano Zampini 
627a82e8c82SStefano Zampini   Output Parameter:
628f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
629a82e8c82SStefano Zampini 
630a7e14dcfSSatish Balay   Level: developer
631a7e14dcfSSatish Balay 
632a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoIsGradientDefined(), TaoIsObjectiveAndGradientDefined()
633a7e14dcfSSatish Balay @*/
634441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg)
635a7e14dcfSSatish Balay {
636a7e14dcfSSatish Balay   PetscFunctionBegin;
637441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
63883c8fe1dSLisandro Dalcin   if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE;
63945cf516eSBarry Smith   else *flg = PETSC_TRUE;
640a7e14dcfSSatish Balay   PetscFunctionReturn(0);
641a7e14dcfSSatish Balay }
642a7e14dcfSSatish Balay 
643a7e14dcfSSatish Balay /*@
644a82e8c82SStefano Zampini   TaoIsGradientDefined - Checks to see if the user has
645a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
646a7e14dcfSSatish Balay   it is appropriate to call TaoComputeGradient() or
647a7e14dcfSSatish Balay   TaoComputeGradientAndGradient()
648a7e14dcfSSatish Balay 
649a7e14dcfSSatish Balay   Not Collective
650a7e14dcfSSatish Balay 
651a82e8c82SStefano Zampini   Input Parameter:
652a82e8c82SStefano Zampini . tao - the Tao context
653a82e8c82SStefano Zampini 
654a82e8c82SStefano Zampini   Output Parameter:
655f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
656a82e8c82SStefano Zampini 
657a7e14dcfSSatish Balay   Level: developer
658a7e14dcfSSatish Balay 
659a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoIsObjectiveDefined(), TaoIsObjectiveAndGradientDefined()
660a7e14dcfSSatish Balay @*/
661441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg)
662a7e14dcfSSatish Balay {
663a7e14dcfSSatish Balay   PetscFunctionBegin;
664441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
66583c8fe1dSLisandro Dalcin   if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE;
66645cf516eSBarry Smith   else *flg = PETSC_TRUE;
667a7e14dcfSSatish Balay   PetscFunctionReturn(0);
668a7e14dcfSSatish Balay }
669a7e14dcfSSatish Balay 
670a7e14dcfSSatish Balay /*@
671a82e8c82SStefano Zampini   TaoIsObjectiveAndGradientDefined - Checks to see if the user has
672a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
673a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
674a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
675a7e14dcfSSatish Balay 
676a7e14dcfSSatish Balay   Not Collective
677a7e14dcfSSatish Balay 
678a82e8c82SStefano Zampini   Input Parameter:
679a82e8c82SStefano Zampini . tao - the Tao context
680a82e8c82SStefano Zampini 
681a82e8c82SStefano Zampini   Output Parameter:
682f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
683a82e8c82SStefano Zampini 
684a7e14dcfSSatish Balay   Level: developer
685a7e14dcfSSatish Balay 
686a82e8c82SStefano Zampini .seealso: TaoSetObjectiveAndGradient(), TaoIsObjectiveDefined(), TaoIsGradientDefined()
687a7e14dcfSSatish Balay @*/
688441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg)
689a7e14dcfSSatish Balay {
690a7e14dcfSSatish Balay   PetscFunctionBegin;
691441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
69283c8fe1dSLisandro Dalcin   if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE;
69345cf516eSBarry Smith   else *flg = PETSC_TRUE;
694a7e14dcfSSatish Balay   PetscFunctionReturn(0);
695a7e14dcfSSatish Balay }
696