xref: /petsc/src/tao/interface/taosolver_fg.c (revision 1baa6e3354bfe224b33a0c158f482508792a8a6e)
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
13db781477SPatrick Sanan .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;
39d0609cedSBarry 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));
42d0609cedSBarry 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   }
64*1baa6e33SBarry Smith   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer,format));
6509baa881SHong Zhang 
669566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x,&g2));
679566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x,&g3));
6809baa881SHong Zhang 
6909baa881SHong Zhang   /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */
709566063dSJacob Faibussowitsch   PetscCall(TaoDefaultComputeGradient(tao,x,g2,NULL));
7109baa881SHong Zhang 
729566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2,NORM_2,&fdnorm));
739566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1,NORM_2,&hcnorm));
749566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2,NORM_INFINITY,&fdmax));
759566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1,NORM_INFINITY,&hcmax));
769566063dSJacob Faibussowitsch   PetscCall(VecDot(g1,g2,&dot));
779566063dSJacob Faibussowitsch   PetscCall(VecCopy(g1,g3));
789566063dSJacob Faibussowitsch   PetscCall(VecAXPY(g3,-1.0,g2));
799566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3,NORM_2,&diffnorm));
809566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3,NORM_INFINITY,&diffmax));
819566063dSJacob 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))));
829566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffnorm/PetscMax(hcnorm,fdnorm)),(double)diffnorm));
839566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffmax/PetscMax(hcmax,fdmax)),(double)diffmax));
8409baa881SHong Zhang 
8509baa881SHong Zhang   if (complete_print) {
869566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded gradient ----------\n"));
879566063dSJacob Faibussowitsch     PetscCall(VecView(g1,mviewer));
889566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite difference gradient ----------\n"));
899566063dSJacob Faibussowitsch     PetscCall(VecView(g2,mviewer));
909566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference gradient ----------\n"));
919566063dSJacob Faibussowitsch     PetscCall(VecView(g3,mviewer));
9209baa881SHong Zhang   }
939566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g2));
949566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g3));
95913eda9aSHong Zhang 
96913eda9aSHong Zhang   if (complete_print) {
979566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
989566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
99913eda9aSHong Zhang   }
1009566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer,tabs));
10109baa881SHong Zhang   PetscFunctionReturn(0);
10209baa881SHong Zhang }
10309baa881SHong Zhang 
104a7e14dcfSSatish Balay /*@
105a7e14dcfSSatish Balay   TaoComputeGradient - Computes the gradient of the objective function
106a7e14dcfSSatish Balay 
107441846f8SBarry Smith   Collective on Tao
108a7e14dcfSSatish Balay 
109a7e14dcfSSatish Balay   Input Parameters:
110441846f8SBarry Smith + tao - the Tao context
111a7e14dcfSSatish Balay - X - input vector
112a7e14dcfSSatish Balay 
113a7e14dcfSSatish Balay   Output Parameter:
114a7e14dcfSSatish Balay . G - gradient vector
115a7e14dcfSSatish Balay 
11609baa881SHong Zhang   Options Database Keys:
11709baa881SHong Zhang +    -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors
118dfe02fe6SHong 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
11909baa881SHong Zhang 
12095452b02SPatrick Sanan   Notes:
12195452b02SPatrick Sanan     TaoComputeGradient() is typically used within minimization implementations,
122a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
123a7e14dcfSSatish Balay 
124a7e14dcfSSatish Balay   Level: advanced
125a7e14dcfSSatish Balay 
126db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetGradient()`
127a7e14dcfSSatish Balay @*/
128441846f8SBarry Smith PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G)
129a7e14dcfSSatish Balay {
130a7e14dcfSSatish Balay   PetscReal      dummy;
13187f595a5SBarry Smith 
132a7e14dcfSSatish Balay   PetscFunctionBegin;
133441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
134a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
135064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(G,VEC_CLASSID,3);
136a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
137a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,3);
1389566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
139a7e14dcfSSatish Balay   if (tao->ops->computegradient) {
1409566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL));
141441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
1429566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP));
143a7e14dcfSSatish Balay     PetscStackPop;
1449566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL));
145a7e14dcfSSatish Balay     tao->ngrads++;
146a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1479566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL));
148a7e14dcfSSatish Balay     PetscStackPush("Tao user objective/gradient evaluation routine");
1499566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP));
150a7e14dcfSSatish Balay     PetscStackPop;
1519566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL));
152a7e14dcfSSatish Balay     tao->nfuncgrads++;
153a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradient() has not been called");
1549566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
15509baa881SHong Zhang 
1569566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao,X,G));
157a7e14dcfSSatish Balay   PetscFunctionReturn(0);
158a7e14dcfSSatish Balay }
159a7e14dcfSSatish Balay 
160a7e14dcfSSatish Balay /*@
161a7e14dcfSSatish Balay   TaoComputeObjective - Computes the objective function value at a given point
162a7e14dcfSSatish Balay 
163441846f8SBarry Smith   Collective on Tao
164a7e14dcfSSatish Balay 
165a7e14dcfSSatish Balay   Input Parameters:
166441846f8SBarry Smith + tao - the Tao context
167a7e14dcfSSatish Balay - X - input vector
168a7e14dcfSSatish Balay 
169a7e14dcfSSatish Balay   Output Parameter:
170a7e14dcfSSatish Balay . f - Objective value at X
171a7e14dcfSSatish Balay 
17295452b02SPatrick Sanan   Notes:
17395452b02SPatrick Sanan     TaoComputeObjective() is typically used within minimization implementations,
174a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
175a7e14dcfSSatish Balay 
176a7e14dcfSSatish Balay   Level: advanced
177a7e14dcfSSatish Balay 
178db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()`
179a7e14dcfSSatish Balay @*/
180441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f)
181a7e14dcfSSatish Balay {
182a7e14dcfSSatish Balay   Vec            temp;
18387f595a5SBarry Smith 
184a7e14dcfSSatish Balay   PetscFunctionBegin;
185441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
186a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
187a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
1889566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
189a7e14dcfSSatish Balay   if (tao->ops->computeobjective) {
1909566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
191441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
1929566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP));
193a7e14dcfSSatish Balay     PetscStackPop;
1949566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
195a7e14dcfSSatish Balay     tao->nfuncs++;
196a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1979566063dSJacob Faibussowitsch     PetscCall(PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n"));
1989566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(X,&temp));
1999566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,NULL,NULL));
200441846f8SBarry Smith     PetscStackPush("Tao user objective/gradient evaluation routine");
2019566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP));
202a7e14dcfSSatish Balay     PetscStackPop;
2039566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,NULL,NULL));
2049566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&temp));
205a7e14dcfSSatish Balay     tao->nfuncgrads++;
206a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() has not been called");
2079566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f)));
2089566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
209a7e14dcfSSatish Balay   PetscFunctionReturn(0);
210a7e14dcfSSatish Balay }
211a7e14dcfSSatish Balay 
212a7e14dcfSSatish Balay /*@
213a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point
214a7e14dcfSSatish Balay 
215441846f8SBarry Smith   Collective on Tao
216a7e14dcfSSatish Balay 
217a7e14dcfSSatish Balay   Input Parameters:
218441846f8SBarry Smith + tao - the Tao context
219a7e14dcfSSatish Balay - X - input vector
220a7e14dcfSSatish Balay 
221d8d19677SJose E. Roman   Output Parameters:
222a7e14dcfSSatish Balay + f - Objective value at X
223a7e14dcfSSatish Balay - g - Gradient vector at X
224a7e14dcfSSatish Balay 
22595452b02SPatrick Sanan   Notes:
22695452b02SPatrick Sanan     TaoComputeObjectiveAndGradient() is typically used within minimization implementations,
227a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
228a7e14dcfSSatish Balay 
229a7e14dcfSSatish Balay   Level: advanced
230a7e14dcfSSatish Balay 
231db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()`
232a7e14dcfSSatish Balay @*/
233441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G)
234a7e14dcfSSatish Balay {
235a7e14dcfSSatish Balay   PetscFunctionBegin;
236441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
237a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
238a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G,VEC_CLASSID,4);
239a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
240a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,4);
2419566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
242a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient) {
2439566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL));
244f4c1ad5cSStefano Zampini     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
2459566063dSJacob Faibussowitsch       PetscCall(TaoComputeObjective(tao,X,f));
2469566063dSJacob Faibussowitsch       PetscCall(TaoDefaultComputeGradient(tao,X,G,NULL));
247f4c1ad5cSStefano Zampini     } else {
248441846f8SBarry Smith       PetscStackPush("Tao user objective/gradient evaluation routine");
2499566063dSJacob Faibussowitsch       PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP));
2500cbffdbaSBarry Smith       PetscStackPop;
251a7e14dcfSSatish Balay     }
2529566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL));
253a7e14dcfSSatish Balay     tao->nfuncgrads++;
254a7e14dcfSSatish Balay   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
2559566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
256441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
2579566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP));
258a7e14dcfSSatish Balay     PetscStackPop;
2599566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
260a7e14dcfSSatish Balay     tao->nfuncs++;
2619566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL));
262441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
2639566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP));
264a7e14dcfSSatish Balay     PetscStackPop;
2659566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL));
266a7e14dcfSSatish Balay     tao->ngrads++;
267a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() or TaoSetGradient() not set");
2689566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f)));
2699566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
2701657496cSHong Zhang 
2719566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao,X,G));
272a7e14dcfSSatish Balay   PetscFunctionReturn(0);
273a7e14dcfSSatish Balay }
274a7e14dcfSSatish Balay 
275a7e14dcfSSatish Balay /*@C
276a82e8c82SStefano Zampini   TaoSetObjective - Sets the function evaluation routine for minimization
277a7e14dcfSSatish Balay 
278441846f8SBarry Smith   Logically collective on Tao
279a7e14dcfSSatish Balay 
280d8d19677SJose E. Roman   Input Parameters:
281441846f8SBarry Smith + tao - the Tao context
282a7e14dcfSSatish Balay . func - the objective function
283a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2846c23d075SBarry Smith         routine (may be NULL)
285a7e14dcfSSatish Balay 
286a7e14dcfSSatish Balay   Calling sequence of func:
287441846f8SBarry Smith $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
288a7e14dcfSSatish Balay 
289a7e14dcfSSatish Balay + x - input vector
290a7e14dcfSSatish Balay . f - function value
291a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
292a7e14dcfSSatish Balay 
293a7e14dcfSSatish Balay   Level: beginner
294a7e14dcfSSatish Balay 
295db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetObjective()`
296a7e14dcfSSatish Balay @*/
297a82e8c82SStefano Zampini PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx)
298a7e14dcfSSatish Balay {
299a7e14dcfSSatish Balay   PetscFunctionBegin;
300441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
301a82e8c82SStefano Zampini   if (ctx) tao->user_objP = ctx;
302a82e8c82SStefano Zampini   if (func) tao->ops->computeobjective = func;
303a82e8c82SStefano Zampini   PetscFunctionReturn(0);
304a82e8c82SStefano Zampini }
305a82e8c82SStefano Zampini 
306a82e8c82SStefano Zampini /*@C
307a82e8c82SStefano Zampini   TaoGetObjective - Gets the function evaluation routine for minimization
308a82e8c82SStefano Zampini 
309a82e8c82SStefano Zampini   Not collective
310a82e8c82SStefano Zampini 
311a82e8c82SStefano Zampini   Input Parameter:
312a82e8c82SStefano Zampini . tao - the Tao context
313a82e8c82SStefano Zampini 
314a82e8c82SStefano Zampini   Output Parameters
315a82e8c82SStefano Zampini + func - the objective function
316a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation
317a82e8c82SStefano Zampini 
318a82e8c82SStefano Zampini   Calling sequence of func:
319a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
320a82e8c82SStefano Zampini 
321a82e8c82SStefano Zampini + x - input vector
322a82e8c82SStefano Zampini . f - function value
323a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
324a82e8c82SStefano Zampini 
325a82e8c82SStefano Zampini   Level: beginner
326a82e8c82SStefano Zampini 
327db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjective()`
328a82e8c82SStefano Zampini @*/
329a82e8c82SStefano Zampini PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal*,void*),void **ctx)
330a82e8c82SStefano Zampini {
331a82e8c82SStefano Zampini   PetscFunctionBegin;
332a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
333a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjective;
334a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objP;
335a7e14dcfSSatish Balay   PetscFunctionReturn(0);
336a7e14dcfSSatish Balay }
337a7e14dcfSSatish Balay 
338a7e14dcfSSatish Balay /*@C
3394a48860cSAlp Dener   TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications
340a7e14dcfSSatish Balay 
341441846f8SBarry Smith   Logically collective on Tao
342a7e14dcfSSatish Balay 
343d8d19677SJose E. Roman   Input Parameters:
344441846f8SBarry Smith + tao - the Tao context
3454a48860cSAlp Dener . func - the residual evaluation routine
346a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
3476c23d075SBarry Smith         routine (may be NULL)
348a7e14dcfSSatish Balay 
349a7e14dcfSSatish Balay   Calling sequence of func:
350441846f8SBarry Smith $      func (Tao tao, Vec x, Vec f, void *ctx);
351a7e14dcfSSatish Balay 
352a7e14dcfSSatish Balay + x - input vector
353a7e14dcfSSatish Balay . f - function value vector
354a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
355a7e14dcfSSatish Balay 
356a7e14dcfSSatish Balay   Level: beginner
357a7e14dcfSSatish Balay 
358db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetJacobianRoutine()`
359a7e14dcfSSatish Balay @*/
3604a48860cSAlp Dener PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
361a7e14dcfSSatish Balay {
362a7e14dcfSSatish Balay   PetscFunctionBegin;
363441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3644a48860cSAlp Dener   PetscValidHeaderSpecific(res,VEC_CLASSID,2);
3659566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)res));
366737f463aSAlp Dener   if (tao->ls_res) {
3679566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->ls_res));
368737f463aSAlp Dener   }
3694a48860cSAlp Dener   tao->ls_res = res;
3704ffbe8acSAlp Dener   tao->user_lsresP = ctx;
3714a48860cSAlp Dener   tao->ops->computeresidual = func;
372737f463aSAlp Dener 
373737f463aSAlp Dener   PetscFunctionReturn(0);
374737f463aSAlp Dener }
375737f463aSAlp Dener 
376737f463aSAlp Dener /*@
377737f463aSAlp 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.
378737f463aSAlp Dener 
379737f463aSAlp Dener   Collective on Tao
380737f463aSAlp Dener 
381737f463aSAlp Dener   Input Parameters:
382737f463aSAlp Dener + tao - the Tao context
383737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only)
384737f463aSAlp Dener . n       - the number of weights (if using off-diagonal)
385737f463aSAlp Dener . rows    - index list of rows for sigma_w
386737f463aSAlp Dener . cols    - index list of columns for sigma_w
387737f463aSAlp Dener - vals - array of weights
388737f463aSAlp Dener 
389737f463aSAlp Dener   Note: Either sigma_v or sigma_w (or both) should be NULL
390737f463aSAlp Dener 
391737f463aSAlp Dener   Level: intermediate
392737f463aSAlp Dener 
393db781477SPatrick Sanan .seealso: `TaoSetResidualRoutine()`
394737f463aSAlp Dener @*/
395737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals)
396737f463aSAlp Dener {
397737f463aSAlp Dener   PetscInt       i;
398a82e8c82SStefano Zampini 
399737f463aSAlp Dener   PetscFunctionBegin;
400737f463aSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
401a82e8c82SStefano Zampini   if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2);
4029566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)sigma_v));
4039566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tao->res_weights_v));
4044ffbe8acSAlp Dener   tao->res_weights_v = sigma_v;
405737f463aSAlp Dener   if (vals) {
4069566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_rows));
4079566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_cols));
4089566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_w));
4099566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_rows));
4109566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_cols));
4119566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_w));
412737f463aSAlp Dener     tao->res_weights_n = n;
413737f463aSAlp Dener     for (i=0;i<n;i++) {
414737f463aSAlp Dener       tao->res_weights_rows[i] = rows[i];
415737f463aSAlp Dener       tao->res_weights_cols[i] = cols[i];
416737f463aSAlp Dener       tao->res_weights_w[i] = vals[i];
417737f463aSAlp Dener     }
418737f463aSAlp Dener   } else {
419737f463aSAlp Dener     tao->res_weights_n = 0;
42083c8fe1dSLisandro Dalcin     tao->res_weights_rows = NULL;
42183c8fe1dSLisandro Dalcin     tao->res_weights_cols = NULL;
422737f463aSAlp Dener   }
423a7e14dcfSSatish Balay   PetscFunctionReturn(0);
424a7e14dcfSSatish Balay }
425a7e14dcfSSatish Balay 
4268b7a9b22SJason Sarich /*@
4274a48860cSAlp Dener   TaoComputeResidual - Computes a least-squares residual vector at a given point
428a7e14dcfSSatish Balay 
429441846f8SBarry Smith   Collective on Tao
430a7e14dcfSSatish Balay 
431a7e14dcfSSatish Balay   Input Parameters:
432441846f8SBarry Smith + tao - the Tao context
433a7e14dcfSSatish Balay - X - input vector
434a7e14dcfSSatish Balay 
435a7e14dcfSSatish Balay   Output Parameter:
436a7e14dcfSSatish Balay . f - Objective vector at X
437a7e14dcfSSatish Balay 
43895452b02SPatrick Sanan   Notes:
4394a48860cSAlp Dener     TaoComputeResidual() is typically used within minimization implementations,
440a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
441a7e14dcfSSatish Balay 
442a7e14dcfSSatish Balay   Level: advanced
443a7e14dcfSSatish Balay 
444db781477SPatrick Sanan .seealso: `TaoSetResidualRoutine()`
445a7e14dcfSSatish Balay @*/
4464a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F)
447a7e14dcfSSatish Balay {
448a7e14dcfSSatish Balay   PetscFunctionBegin;
449441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
450a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
451a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
452a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
453a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,F,3);
4544a48860cSAlp Dener   if (tao->ops->computeresidual) {
4559566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
4564a48860cSAlp Dener     PetscStackPush("Tao user least-squares residual evaluation routine");
4579566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP));
458a7e14dcfSSatish Balay     PetscStackPop;
4599566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
460a7e14dcfSSatish Balay     tao->nfuncs++;
461691b26d3SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called");
4629566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO least-squares residual evaluation.\n"));
463a7e14dcfSSatish Balay   PetscFunctionReturn(0);
464a7e14dcfSSatish Balay }
465a7e14dcfSSatish Balay 
466a7e14dcfSSatish Balay /*@C
467a82e8c82SStefano Zampini   TaoSetGradient - Sets the gradient evaluation routine for minimization
468a7e14dcfSSatish Balay 
469441846f8SBarry Smith   Logically collective on Tao
470a7e14dcfSSatish Balay 
471d8d19677SJose E. Roman   Input Parameters:
472441846f8SBarry Smith + tao - the Tao context
473a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
474a7e14dcfSSatish Balay . func - the gradient function
475a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
4766c23d075SBarry Smith         routine (may be NULL)
477a7e14dcfSSatish Balay 
478a7e14dcfSSatish Balay   Calling sequence of func:
479441846f8SBarry Smith $      func (Tao tao, Vec x, Vec g, void *ctx);
480a7e14dcfSSatish Balay 
481a7e14dcfSSatish Balay + x - input vector
482a7e14dcfSSatish Balay . g - gradient value (output)
483a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
484a7e14dcfSSatish Balay 
485a7e14dcfSSatish Balay   Level: beginner
486a7e14dcfSSatish Balay 
487db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()`
488a7e14dcfSSatish Balay @*/
489a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
490a7e14dcfSSatish Balay {
491a7e14dcfSSatish Balay   PetscFunctionBegin;
492441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
493a82e8c82SStefano Zampini   if (g) {
494a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
495a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
4969566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
4979566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
498a82e8c82SStefano Zampini     tao->gradient = g;
499a82e8c82SStefano Zampini   }
500a82e8c82SStefano Zampini   if (func) tao->ops->computegradient = func;
501a82e8c82SStefano Zampini   if (ctx) tao->user_gradP = ctx;
502a7e14dcfSSatish Balay   PetscFunctionReturn(0);
503a7e14dcfSSatish Balay }
504a7e14dcfSSatish Balay 
505a7e14dcfSSatish Balay /*@C
506a82e8c82SStefano Zampini   TaoGetGradient - Gets the gradient evaluation routine for minimization
507a82e8c82SStefano Zampini 
508a82e8c82SStefano Zampini   Not collective
509a82e8c82SStefano Zampini 
510a82e8c82SStefano Zampini   Input Parameter:
511a82e8c82SStefano Zampini . tao - the Tao context
512a82e8c82SStefano Zampini 
513a82e8c82SStefano Zampini   Output Parameters:
514a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation
515a82e8c82SStefano Zampini . func - the gradient function
516a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
517a82e8c82SStefano Zampini 
518a82e8c82SStefano Zampini   Calling sequence of func:
519a82e8c82SStefano Zampini $      func (Tao tao, Vec x, Vec g, void *ctx);
520a82e8c82SStefano Zampini 
521a82e8c82SStefano Zampini + x - input vector
522a82e8c82SStefano Zampini . g - gradient value (output)
523a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
524a82e8c82SStefano Zampini 
525a82e8c82SStefano Zampini   Level: beginner
526a82e8c82SStefano Zampini 
527db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()`
528a82e8c82SStefano Zampini @*/
529a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx)
530a82e8c82SStefano Zampini {
531a82e8c82SStefano Zampini   PetscFunctionBegin;
532a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
533a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
534a82e8c82SStefano Zampini   if (func) *func = tao->ops->computegradient;
535a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_gradP;
536a82e8c82SStefano Zampini   PetscFunctionReturn(0);
537a82e8c82SStefano Zampini }
538a82e8c82SStefano Zampini 
539a82e8c82SStefano Zampini /*@C
540a82e8c82SStefano Zampini   TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for minimization
541a7e14dcfSSatish Balay 
542441846f8SBarry Smith   Logically collective on Tao
543a7e14dcfSSatish Balay 
544d8d19677SJose E. Roman   Input Parameters:
545441846f8SBarry Smith + tao - the Tao context
546a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
547a7e14dcfSSatish Balay . func - the gradient function
548a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
5496c23d075SBarry Smith         routine (may be NULL)
550a7e14dcfSSatish Balay 
551a7e14dcfSSatish Balay   Calling sequence of func:
55217477c02SJason Sarich $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
553a7e14dcfSSatish Balay 
554a7e14dcfSSatish Balay + x - input vector
55517477c02SJason Sarich . f - objective value (output)
556a7e14dcfSSatish Balay . g - gradient value (output)
557a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
558a7e14dcfSSatish Balay 
559a7e14dcfSSatish Balay   Level: beginner
560a7e14dcfSSatish Balay 
561db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()`
562a7e14dcfSSatish Balay @*/
563a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx)
564a82e8c82SStefano Zampini {
565a82e8c82SStefano Zampini   PetscFunctionBegin;
566a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
567a82e8c82SStefano Zampini   if (g) {
568a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
569a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
5709566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
5719566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
572a82e8c82SStefano Zampini     tao->gradient = g;
573a82e8c82SStefano Zampini   }
574a82e8c82SStefano Zampini   if (ctx) tao->user_objgradP = ctx;
575a82e8c82SStefano Zampini   if (func) tao->ops->computeobjectiveandgradient = func;
576a82e8c82SStefano Zampini   PetscFunctionReturn(0);
577a82e8c82SStefano Zampini }
578a82e8c82SStefano Zampini 
579a82e8c82SStefano Zampini /*@C
580a82e8c82SStefano Zampini   TaoGetObjectiveAndGradient - Gets a combined objective function and gradient evaluation routine for minimization
581a82e8c82SStefano Zampini 
582a82e8c82SStefano Zampini   Not collective
583a82e8c82SStefano Zampini 
584a82e8c82SStefano Zampini   Input Parameter:
585a82e8c82SStefano Zampini . tao - the Tao context
586a82e8c82SStefano Zampini 
587a82e8c82SStefano Zampini   Output Parameters:
588817da375SSatish Balay + g - the vector to internally hold the gradient computation
589a82e8c82SStefano Zampini . func - the gradient function
590a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
591a82e8c82SStefano Zampini 
592a82e8c82SStefano Zampini   Calling sequence of func:
593a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
594a82e8c82SStefano Zampini 
595a82e8c82SStefano Zampini + x - input vector
596a82e8c82SStefano Zampini . f - objective value (output)
597a82e8c82SStefano Zampini . g - gradient value (output)
598a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
599a82e8c82SStefano Zampini 
600a82e8c82SStefano Zampini   Level: beginner
601a82e8c82SStefano Zampini 
602db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`
603a82e8c82SStefano Zampini @*/
604a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx)
605a7e14dcfSSatish Balay {
606a7e14dcfSSatish Balay   PetscFunctionBegin;
607441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
608a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
609a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjectiveandgradient;
610a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objgradP;
611a7e14dcfSSatish Balay   PetscFunctionReturn(0);
612a7e14dcfSSatish Balay }
613a7e14dcfSSatish Balay 
614a7e14dcfSSatish Balay /*@
615a82e8c82SStefano Zampini   TaoIsObjectiveDefined - Checks to see if the user has
616a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
617a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
618a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
619a7e14dcfSSatish Balay 
620a82e8c82SStefano Zampini   Not collective
621a7e14dcfSSatish Balay 
622a82e8c82SStefano Zampini   Input Parameter:
623a82e8c82SStefano Zampini . tao - the Tao context
624a82e8c82SStefano Zampini 
625a82e8c82SStefano Zampini   Output Parameter:
626f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
627a82e8c82SStefano Zampini 
628a7e14dcfSSatish Balay   Level: developer
629a7e14dcfSSatish Balay 
630db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()`
631a7e14dcfSSatish Balay @*/
632441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg)
633a7e14dcfSSatish Balay {
634a7e14dcfSSatish Balay   PetscFunctionBegin;
635441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
63683c8fe1dSLisandro Dalcin   if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE;
63745cf516eSBarry Smith   else *flg = PETSC_TRUE;
638a7e14dcfSSatish Balay   PetscFunctionReturn(0);
639a7e14dcfSSatish Balay }
640a7e14dcfSSatish Balay 
641a7e14dcfSSatish Balay /*@
642a82e8c82SStefano Zampini   TaoIsGradientDefined - Checks to see if the user has
643a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
644a7e14dcfSSatish Balay   it is appropriate to call TaoComputeGradient() or
645a7e14dcfSSatish Balay   TaoComputeGradientAndGradient()
646a7e14dcfSSatish Balay 
647a7e14dcfSSatish Balay   Not Collective
648a7e14dcfSSatish Balay 
649a82e8c82SStefano Zampini   Input Parameter:
650a82e8c82SStefano Zampini . tao - the Tao context
651a82e8c82SStefano Zampini 
652a82e8c82SStefano Zampini   Output Parameter:
653f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
654a82e8c82SStefano Zampini 
655a7e14dcfSSatish Balay   Level: developer
656a7e14dcfSSatish Balay 
657db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()`
658a7e14dcfSSatish Balay @*/
659441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg)
660a7e14dcfSSatish Balay {
661a7e14dcfSSatish Balay   PetscFunctionBegin;
662441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
66383c8fe1dSLisandro Dalcin   if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE;
66445cf516eSBarry Smith   else *flg = PETSC_TRUE;
665a7e14dcfSSatish Balay   PetscFunctionReturn(0);
666a7e14dcfSSatish Balay }
667a7e14dcfSSatish Balay 
668a7e14dcfSSatish Balay /*@
669a82e8c82SStefano Zampini   TaoIsObjectiveAndGradientDefined - Checks to see if the user has
670a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
671a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
672a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
673a7e14dcfSSatish Balay 
674a7e14dcfSSatish Balay   Not Collective
675a7e14dcfSSatish Balay 
676a82e8c82SStefano Zampini   Input Parameter:
677a82e8c82SStefano Zampini . tao - the Tao context
678a82e8c82SStefano Zampini 
679a82e8c82SStefano Zampini   Output Parameter:
680f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
681a82e8c82SStefano Zampini 
682a7e14dcfSSatish Balay   Level: developer
683a7e14dcfSSatish Balay 
684db781477SPatrick Sanan .seealso: `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()`
685a7e14dcfSSatish Balay @*/
686441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg)
687a7e14dcfSSatish Balay {
688a7e14dcfSSatish Balay   PetscFunctionBegin;
689441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
69083c8fe1dSLisandro Dalcin   if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE;
69145cf516eSBarry Smith   else *flg = PETSC_TRUE;
692a7e14dcfSSatish Balay   PetscFunctionReturn(0);
693a7e14dcfSSatish Balay }
694