xref: /petsc/src/tao/interface/taosolver_fg.c (revision 65ba42b6ab3ec006bc8f22d89b4121d18fc8be1b)
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 
6*65ba42b6SBarry 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
13*65ba42b6SBarry Smith .seealso: `Tao`, `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   }
641baa6e33SBarry 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 
107*65ba42b6SBarry 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 
120*65ba42b6SBarry Smith   Note:
121*65ba42b6SBarry Smith     `TaoComputeGradient()` is typically used within the implementation of the optimization method,
122a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
123a7e14dcfSSatish Balay 
124*65ba42b6SBarry Smith   Level: developer
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 
163*65ba42b6SBarry 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 
172*65ba42b6SBarry Smith   Note:
173*65ba42b6SBarry Smith     `TaoComputeObjective()` is typically used within the implementation of the optimization algorithm
174a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
175a7e14dcfSSatish Balay 
176*65ba42b6SBarry Smith   Level: developer
177a7e14dcfSSatish Balay 
178*65ba42b6SBarry Smith .seealso: `Tao`, `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 
215*65ba42b6SBarry 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 
225*65ba42b6SBarry Smith   Note:
226*65ba42b6SBarry Smith     `TaoComputeObjectiveAndGradient()` is typically used within the implementation of the optimization algorithm,
227a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
228a7e14dcfSSatish Balay 
229*65ba42b6SBarry Smith   Level: developer
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 
278*65ba42b6SBarry 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
307*65ba42b6SBarry Smith   TaoGetObjective - Gets the function evaluation routine for the function to be minimized
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 
327*65ba42b6SBarry Smith .seealso: `Tao`, `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 
341*65ba42b6SBarry 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 
358*65ba42b6SBarry Smith .seealso: `Tao`, `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 /*@
377*65ba42b6SBarry Smith   TaoSetResidualWeights - Give weights for the residual values. A vector can be used if only diagonal terms are used, otherwise a matrix can be give.
378*65ba42b6SBarry Smith    If this function is not provided, or if sigma_v and sigma_w are both NULL, then the identity matrix will be used for weights.
379737f463aSAlp Dener 
380*65ba42b6SBarry Smith   Collective on tao
381737f463aSAlp Dener 
382737f463aSAlp Dener   Input Parameters:
383737f463aSAlp Dener + tao - the Tao context
384737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only)
385737f463aSAlp Dener . n       - the number of weights (if using off-diagonal)
386737f463aSAlp Dener . rows    - index list of rows for sigma_w
387737f463aSAlp Dener . cols    - index list of columns for sigma_w
388737f463aSAlp Dener - vals - array of weights
389737f463aSAlp Dener 
390737f463aSAlp Dener   Note: Either sigma_v or sigma_w (or both) should be NULL
391737f463aSAlp Dener 
392737f463aSAlp Dener   Level: intermediate
393737f463aSAlp Dener 
394*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()`
395737f463aSAlp Dener @*/
396737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals)
397737f463aSAlp Dener {
398737f463aSAlp Dener   PetscInt       i;
399a82e8c82SStefano Zampini 
400737f463aSAlp Dener   PetscFunctionBegin;
401737f463aSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
402a82e8c82SStefano Zampini   if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2);
4039566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)sigma_v));
4049566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tao->res_weights_v));
4054ffbe8acSAlp Dener   tao->res_weights_v = sigma_v;
406737f463aSAlp Dener   if (vals) {
4079566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_rows));
4089566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_cols));
4099566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_w));
4109566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_rows));
4119566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_cols));
4129566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&tao->res_weights_w));
413737f463aSAlp Dener     tao->res_weights_n = n;
414737f463aSAlp Dener     for (i=0;i<n;i++) {
415737f463aSAlp Dener       tao->res_weights_rows[i] = rows[i];
416737f463aSAlp Dener       tao->res_weights_cols[i] = cols[i];
417737f463aSAlp Dener       tao->res_weights_w[i] = vals[i];
418737f463aSAlp Dener     }
419737f463aSAlp Dener   } else {
420737f463aSAlp Dener     tao->res_weights_n = 0;
42183c8fe1dSLisandro Dalcin     tao->res_weights_rows = NULL;
42283c8fe1dSLisandro Dalcin     tao->res_weights_cols = NULL;
423737f463aSAlp Dener   }
424a7e14dcfSSatish Balay   PetscFunctionReturn(0);
425a7e14dcfSSatish Balay }
426a7e14dcfSSatish Balay 
4278b7a9b22SJason Sarich /*@
4284a48860cSAlp Dener   TaoComputeResidual - Computes a least-squares residual vector at a given point
429a7e14dcfSSatish Balay 
430*65ba42b6SBarry Smith   Collective on tao
431a7e14dcfSSatish Balay 
432a7e14dcfSSatish Balay   Input Parameters:
433441846f8SBarry Smith + tao - the Tao context
434a7e14dcfSSatish Balay - X - input vector
435a7e14dcfSSatish Balay 
436a7e14dcfSSatish Balay   Output Parameter:
437a7e14dcfSSatish Balay . f - Objective vector at X
438a7e14dcfSSatish Balay 
43995452b02SPatrick Sanan   Notes:
440*65ba42b6SBarry Smith     `TaoComputeResidual()` is typically used within the implementation of the optimization algorithm,
441a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
442a7e14dcfSSatish Balay 
443a7e14dcfSSatish Balay   Level: advanced
444a7e14dcfSSatish Balay 
445*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()`
446a7e14dcfSSatish Balay @*/
4474a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F)
448a7e14dcfSSatish Balay {
449a7e14dcfSSatish Balay   PetscFunctionBegin;
450441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
451a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
452a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
453a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
454a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,F,3);
4554a48860cSAlp Dener   if (tao->ops->computeresidual) {
4569566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL));
4574a48860cSAlp Dener     PetscStackPush("Tao user least-squares residual evaluation routine");
4589566063dSJacob Faibussowitsch     PetscCall((*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP));
459a7e14dcfSSatish Balay     PetscStackPop;
4609566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL));
461a7e14dcfSSatish Balay     tao->nfuncs++;
462691b26d3SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called");
4639566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao,"TAO least-squares residual evaluation.\n"));
464a7e14dcfSSatish Balay   PetscFunctionReturn(0);
465a7e14dcfSSatish Balay }
466a7e14dcfSSatish Balay 
467a7e14dcfSSatish Balay /*@C
468*65ba42b6SBarry Smith   TaoSetGradient - Sets the gradient evaluation routine for the function to be optimized
469a7e14dcfSSatish Balay 
470*65ba42b6SBarry Smith   Logically collective on tao
471a7e14dcfSSatish Balay 
472d8d19677SJose E. Roman   Input Parameters:
473441846f8SBarry Smith + tao - the Tao context
474a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
475a7e14dcfSSatish Balay . func - the gradient function
476a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
4776c23d075SBarry Smith         routine (may be NULL)
478a7e14dcfSSatish Balay 
479a7e14dcfSSatish Balay   Calling sequence of func:
480441846f8SBarry Smith $      func (Tao tao, Vec x, Vec g, void *ctx);
481a7e14dcfSSatish Balay 
482a7e14dcfSSatish Balay + x - input vector
483a7e14dcfSSatish Balay . g - gradient value (output)
484a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
485a7e14dcfSSatish Balay 
486a7e14dcfSSatish Balay   Level: beginner
487a7e14dcfSSatish Balay 
488*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()`
489a7e14dcfSSatish Balay @*/
490a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
491a7e14dcfSSatish Balay {
492a7e14dcfSSatish Balay   PetscFunctionBegin;
493441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
494a82e8c82SStefano Zampini   if (g) {
495a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
496a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
4979566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
4989566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
499a82e8c82SStefano Zampini     tao->gradient = g;
500a82e8c82SStefano Zampini   }
501a82e8c82SStefano Zampini   if (func) tao->ops->computegradient = func;
502a82e8c82SStefano Zampini   if (ctx) tao->user_gradP = ctx;
503a7e14dcfSSatish Balay   PetscFunctionReturn(0);
504a7e14dcfSSatish Balay }
505a7e14dcfSSatish Balay 
506a7e14dcfSSatish Balay /*@C
507*65ba42b6SBarry Smith   TaoGetGradient - Gets the gradient evaluation routine for the function being optimized
508a82e8c82SStefano Zampini 
509a82e8c82SStefano Zampini   Not collective
510a82e8c82SStefano Zampini 
511a82e8c82SStefano Zampini   Input Parameter:
512a82e8c82SStefano Zampini . tao - the Tao context
513a82e8c82SStefano Zampini 
514a82e8c82SStefano Zampini   Output Parameters:
515a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation
516a82e8c82SStefano Zampini . func - the gradient function
517a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
518a82e8c82SStefano Zampini 
519a82e8c82SStefano Zampini   Calling sequence of func:
520a82e8c82SStefano Zampini $      func (Tao tao, Vec x, Vec g, void *ctx);
521a82e8c82SStefano Zampini 
522a82e8c82SStefano Zampini + x - input vector
523a82e8c82SStefano Zampini . g - gradient value (output)
524a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
525a82e8c82SStefano Zampini 
526a82e8c82SStefano Zampini   Level: beginner
527a82e8c82SStefano Zampini 
528*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()`
529a82e8c82SStefano Zampini @*/
530a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx)
531a82e8c82SStefano Zampini {
532a82e8c82SStefano Zampini   PetscFunctionBegin;
533a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
534a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
535a82e8c82SStefano Zampini   if (func) *func = tao->ops->computegradient;
536a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_gradP;
537a82e8c82SStefano Zampini   PetscFunctionReturn(0);
538a82e8c82SStefano Zampini }
539a82e8c82SStefano Zampini 
540a82e8c82SStefano Zampini /*@C
541*65ba42b6SBarry Smith   TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for the function to be optimized
542a7e14dcfSSatish Balay 
543*65ba42b6SBarry Smith   Logically collective on tao
544a7e14dcfSSatish Balay 
545d8d19677SJose E. Roman   Input Parameters:
546441846f8SBarry Smith + tao - the Tao context
547a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
548a7e14dcfSSatish Balay . func - the gradient function
549a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
5506c23d075SBarry Smith         routine (may be NULL)
551a7e14dcfSSatish Balay 
552a7e14dcfSSatish Balay   Calling sequence of func:
55317477c02SJason Sarich $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
554a7e14dcfSSatish Balay 
555a7e14dcfSSatish Balay + x - input vector
55617477c02SJason Sarich . f - objective value (output)
557a7e14dcfSSatish Balay . g - gradient value (output)
558a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
559a7e14dcfSSatish Balay 
560a7e14dcfSSatish Balay   Level: beginner
561a7e14dcfSSatish Balay 
562*65ba42b6SBarry Smith   Note:
563*65ba42b6SBarry Smith   For some optimization methods using a combined function can be more eifficient.
564*65ba42b6SBarry Smith 
565*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()`
566a7e14dcfSSatish Balay @*/
567a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx)
568a82e8c82SStefano Zampini {
569a82e8c82SStefano Zampini   PetscFunctionBegin;
570a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
571a82e8c82SStefano Zampini   if (g) {
572a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
573a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
5749566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
5759566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
576a82e8c82SStefano Zampini     tao->gradient = g;
577a82e8c82SStefano Zampini   }
578a82e8c82SStefano Zampini   if (ctx) tao->user_objgradP = ctx;
579a82e8c82SStefano Zampini   if (func) tao->ops->computeobjectiveandgradient = func;
580a82e8c82SStefano Zampini   PetscFunctionReturn(0);
581a82e8c82SStefano Zampini }
582a82e8c82SStefano Zampini 
583a82e8c82SStefano Zampini /*@C
584*65ba42b6SBarry Smith   TaoGetObjectiveAndGradient - Gets the combined objective function and gradient evaluation routine for the function to be optimized
585a82e8c82SStefano Zampini 
586a82e8c82SStefano Zampini   Not collective
587a82e8c82SStefano Zampini 
588a82e8c82SStefano Zampini   Input Parameter:
589a82e8c82SStefano Zampini . tao - the Tao context
590a82e8c82SStefano Zampini 
591a82e8c82SStefano Zampini   Output Parameters:
592817da375SSatish Balay + g - the vector to internally hold the gradient computation
593a82e8c82SStefano Zampini . func - the gradient function
594a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
595a82e8c82SStefano Zampini 
596a82e8c82SStefano Zampini   Calling sequence of func:
597a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
598a82e8c82SStefano Zampini 
599a82e8c82SStefano Zampini + x - input vector
600a82e8c82SStefano Zampini . f - objective value (output)
601a82e8c82SStefano Zampini . g - gradient value (output)
602a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
603a82e8c82SStefano Zampini 
604a82e8c82SStefano Zampini   Level: beginner
605a82e8c82SStefano Zampini 
606*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`
607a82e8c82SStefano Zampini @*/
608a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx)
609a7e14dcfSSatish Balay {
610a7e14dcfSSatish Balay   PetscFunctionBegin;
611441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
612a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
613a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjectiveandgradient;
614a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objgradP;
615a7e14dcfSSatish Balay   PetscFunctionReturn(0);
616a7e14dcfSSatish Balay }
617a7e14dcfSSatish Balay 
618a7e14dcfSSatish Balay /*@
619a82e8c82SStefano Zampini   TaoIsObjectiveDefined - Checks to see if the user has
620a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
621*65ba42b6SBarry Smith   it is appropriate to call `TaoComputeObjective()` or
622*65ba42b6SBarry Smith   `TaoComputeObjectiveAndGradient()`
623a7e14dcfSSatish Balay 
624a82e8c82SStefano Zampini   Not collective
625a7e14dcfSSatish Balay 
626a82e8c82SStefano Zampini   Input Parameter:
627a82e8c82SStefano Zampini . tao - the Tao context
628a82e8c82SStefano Zampini 
629a82e8c82SStefano Zampini   Output Parameter:
630*65ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
631a82e8c82SStefano Zampini 
632a7e14dcfSSatish Balay   Level: developer
633a7e14dcfSSatish Balay 
634*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()`
635a7e14dcfSSatish Balay @*/
636441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg)
637a7e14dcfSSatish Balay {
638a7e14dcfSSatish Balay   PetscFunctionBegin;
639441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
64083c8fe1dSLisandro Dalcin   if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE;
64145cf516eSBarry Smith   else *flg = PETSC_TRUE;
642a7e14dcfSSatish Balay   PetscFunctionReturn(0);
643a7e14dcfSSatish Balay }
644a7e14dcfSSatish Balay 
645a7e14dcfSSatish Balay /*@
646a82e8c82SStefano Zampini   TaoIsGradientDefined - Checks to see if the user has
647a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
648*65ba42b6SBarry Smith   it is appropriate to call `TaoComputeGradient()` or
649*65ba42b6SBarry Smith   `TaoComputeGradientAndGradient()`
650a7e14dcfSSatish Balay 
651a7e14dcfSSatish Balay   Not Collective
652a7e14dcfSSatish Balay 
653a82e8c82SStefano Zampini   Input Parameter:
654a82e8c82SStefano Zampini . tao - the Tao context
655a82e8c82SStefano Zampini 
656a82e8c82SStefano Zampini   Output Parameter:
657*65ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
658a82e8c82SStefano Zampini 
659a7e14dcfSSatish Balay   Level: developer
660a7e14dcfSSatish Balay 
661db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()`
662a7e14dcfSSatish Balay @*/
663441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg)
664a7e14dcfSSatish Balay {
665a7e14dcfSSatish Balay   PetscFunctionBegin;
666441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
66783c8fe1dSLisandro Dalcin   if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE;
66845cf516eSBarry Smith   else *flg = PETSC_TRUE;
669a7e14dcfSSatish Balay   PetscFunctionReturn(0);
670a7e14dcfSSatish Balay }
671a7e14dcfSSatish Balay 
672a7e14dcfSSatish Balay /*@
673a82e8c82SStefano Zampini   TaoIsObjectiveAndGradientDefined - Checks to see if the user has
674a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
675*65ba42b6SBarry Smith   it is appropriate to call `TaoComputeObjective()` or
676*65ba42b6SBarry Smith   `TaoComputeObjectiveAndGradient()`
677a7e14dcfSSatish Balay 
678a7e14dcfSSatish Balay   Not Collective
679a7e14dcfSSatish Balay 
680a82e8c82SStefano Zampini   Input Parameter:
681a82e8c82SStefano Zampini . tao - the Tao context
682a82e8c82SStefano Zampini 
683a82e8c82SStefano Zampini   Output Parameter:
684*65ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
685a82e8c82SStefano Zampini 
686a7e14dcfSSatish Balay   Level: developer
687a7e14dcfSSatish Balay 
688db781477SPatrick Sanan .seealso: `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()`
689a7e14dcfSSatish Balay @*/
690441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg)
691a7e14dcfSSatish Balay {
692a7e14dcfSSatish Balay   PetscFunctionBegin;
693441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
69483c8fe1dSLisandro Dalcin   if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE;
69545cf516eSBarry Smith   else *flg = PETSC_TRUE;
696a7e14dcfSSatish Balay   PetscFunctionReturn(0);
697a7e14dcfSSatish Balay }
698