xref: /petsc/src/tao/interface/taosolver_fg.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
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 
6c3339decSBarry Smith   Logically collective
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay   Input Parameters:
9441846f8SBarry Smith + tao - the Tao context
10a7e14dcfSSatish Balay - x0  - the initial guess
11a7e14dcfSSatish Balay 
12a7e14dcfSSatish Balay   Level: beginner
1365ba42b6SBarry Smith .seealso: `Tao`, `TaoCreate()`, `TaoSolve()`, `TaoGetSolution()`
14a7e14dcfSSatish Balay @*/
15d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetSolution(Tao tao, Vec x0)
16d71ae5a4SJacob Faibussowitsch {
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;
23*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24a7e14dcfSSatish Balay }
25a7e14dcfSSatish Balay 
26d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoTestGradient(Tao tao, Vec x, Vec g1)
27d71ae5a4SJacob Faibussowitsch {
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) {
4448a46eb9SPierre Jolivet     if (complete_print) PetscCall(PetscViewerDestroy(&mviewer));
45*3ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
462f4b6201SAlp Dener   }
4709baa881SHong Zhang 
489566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
499566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
509566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
519566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
529566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Gradient -------------\n"));
5309baa881SHong Zhang   if (!complete_print && !directionsprinted) {
549566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Run with -tao_test_gradient_view and optionally -tao_test_gradient <threshold> to show difference\n"));
559566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    of hand-coded and finite difference gradient entries greater than <threshold>.\n"));
5609baa881SHong Zhang   }
5709baa881SHong Zhang   if (!directionsprinted) {
589566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Testing hand-coded Gradient, if (for double precision runs) ||G - Gfd||/||G|| is\n"));
599566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    O(1.e-8), the hand-coded Gradient is probably correct.\n"));
6009baa881SHong Zhang     directionsprinted = PETSC_TRUE;
6109baa881SHong Zhang   }
621baa6e33SBarry Smith   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
6309baa881SHong Zhang 
649566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x, &g2));
659566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x, &g3));
6609baa881SHong Zhang 
6709baa881SHong Zhang   /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */
689566063dSJacob Faibussowitsch   PetscCall(TaoDefaultComputeGradient(tao, x, g2, NULL));
6909baa881SHong Zhang 
709566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2, NORM_2, &fdnorm));
719566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1, NORM_2, &hcnorm));
729566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2, NORM_INFINITY, &fdmax));
739566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1, NORM_INFINITY, &hcmax));
749566063dSJacob Faibussowitsch   PetscCall(VecDot(g1, g2, &dot));
759566063dSJacob Faibussowitsch   PetscCall(VecCopy(g1, g3));
769566063dSJacob Faibussowitsch   PetscCall(VecAXPY(g3, -1.0, g2));
779566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3, NORM_2, &diffnorm));
789566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3, NORM_INFINITY, &diffmax));
799566063dSJacob 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))));
809566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n", (double)(diffnorm / PetscMax(hcnorm, fdnorm)), (double)diffnorm));
819566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n", (double)(diffmax / PetscMax(hcmax, fdmax)), (double)diffmax));
8209baa881SHong Zhang 
8309baa881SHong Zhang   if (complete_print) {
849566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded gradient ----------\n"));
859566063dSJacob Faibussowitsch     PetscCall(VecView(g1, mviewer));
869566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite difference gradient ----------\n"));
879566063dSJacob Faibussowitsch     PetscCall(VecView(g2, mviewer));
889566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded minus finite-difference gradient ----------\n"));
899566063dSJacob Faibussowitsch     PetscCall(VecView(g3, mviewer));
9009baa881SHong Zhang   }
919566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g2));
929566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g3));
93913eda9aSHong Zhang 
94913eda9aSHong Zhang   if (complete_print) {
959566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
969566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
97913eda9aSHong Zhang   }
989566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
99*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10009baa881SHong Zhang }
10109baa881SHong Zhang 
102a7e14dcfSSatish Balay /*@
103a7e14dcfSSatish Balay   TaoComputeGradient - Computes the gradient of the objective function
104a7e14dcfSSatish Balay 
105c3339decSBarry Smith   Collective
106a7e14dcfSSatish Balay 
107a7e14dcfSSatish Balay   Input Parameters:
108441846f8SBarry Smith + tao - the Tao context
109a7e14dcfSSatish Balay - X - input vector
110a7e14dcfSSatish Balay 
111a7e14dcfSSatish Balay   Output Parameter:
112a7e14dcfSSatish Balay . G - gradient vector
113a7e14dcfSSatish Balay 
11409baa881SHong Zhang   Options Database Keys:
11509baa881SHong Zhang +    -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors
116dfe02fe6SHong 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
11709baa881SHong Zhang 
11865ba42b6SBarry Smith   Note:
11965ba42b6SBarry Smith     `TaoComputeGradient()` is typically used within the implementation of the optimization method,
120a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
121a7e14dcfSSatish Balay 
12265ba42b6SBarry Smith   Level: developer
123a7e14dcfSSatish Balay 
124db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetGradient()`
125a7e14dcfSSatish Balay @*/
126d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G)
127d71ae5a4SJacob Faibussowitsch {
128a7e14dcfSSatish Balay   PetscReal dummy;
12987f595a5SBarry Smith 
130a7e14dcfSSatish Balay   PetscFunctionBegin;
131441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
132a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
133064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(G, VEC_CLASSID, 3);
134a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
135a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, G, 3);
1369566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
137a7e14dcfSSatish Balay   if (tao->ops->computegradient) {
1389566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval, tao, X, G, NULL));
139792fecdfSBarry Smith     PetscCallBack("Tao callback gradient", (*tao->ops->computegradient)(tao, X, G, tao->user_gradP));
1409566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval, tao, X, G, NULL));
141a7e14dcfSSatish Balay     tao->ngrads++;
142a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1439566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, G, NULL));
144792fecdfSBarry Smith     PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, &dummy, G, tao->user_objgradP));
1459566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, G, NULL));
146a7e14dcfSSatish Balay     tao->nfuncgrads++;
147a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetGradient() has not been called");
1489566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
14909baa881SHong Zhang 
1509566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao, X, G));
151*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
152a7e14dcfSSatish Balay }
153a7e14dcfSSatish Balay 
154a7e14dcfSSatish Balay /*@
155a7e14dcfSSatish Balay   TaoComputeObjective - Computes the objective function value at a given point
156a7e14dcfSSatish Balay 
157c3339decSBarry Smith   Collective
158a7e14dcfSSatish Balay 
159a7e14dcfSSatish Balay   Input Parameters:
160441846f8SBarry Smith + tao - the Tao context
161a7e14dcfSSatish Balay - X - input vector
162a7e14dcfSSatish Balay 
163a7e14dcfSSatish Balay   Output Parameter:
164a7e14dcfSSatish Balay . f - Objective value at X
165a7e14dcfSSatish Balay 
16665ba42b6SBarry Smith   Note:
16765ba42b6SBarry Smith     `TaoComputeObjective()` is typically used within the implementation of the optimization algorithm
168a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
169a7e14dcfSSatish Balay 
17065ba42b6SBarry Smith   Level: developer
171a7e14dcfSSatish Balay 
17265ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()`
173a7e14dcfSSatish Balay @*/
174d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f)
175d71ae5a4SJacob Faibussowitsch {
176a7e14dcfSSatish Balay   Vec temp;
17787f595a5SBarry Smith 
178a7e14dcfSSatish Balay   PetscFunctionBegin;
179441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
180a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
181a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
1829566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
183a7e14dcfSSatish Balay   if (tao->ops->computeobjective) {
1849566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL));
185792fecdfSBarry Smith     PetscCallBack("Tao callback objective", (*tao->ops->computeobjective)(tao, X, f, tao->user_objP));
1869566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL));
187a7e14dcfSSatish Balay     tao->nfuncs++;
188a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1899566063dSJacob Faibussowitsch     PetscCall(PetscInfo(tao, "Duplicating variable vector in order to call func/grad routine\n"));
1909566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(X, &temp));
1919566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, NULL, NULL));
192792fecdfSBarry Smith     PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, f, temp, tao->user_objgradP));
1939566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, NULL, NULL));
1949566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&temp));
195a7e14dcfSSatish Balay     tao->nfuncgrads++;
196a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetObjective() has not been called");
1979566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao, "TAO Function evaluation: %20.19e\n", (double)(*f)));
1989566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
199*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
200a7e14dcfSSatish Balay }
201a7e14dcfSSatish Balay 
202a7e14dcfSSatish Balay /*@
203a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point
204a7e14dcfSSatish Balay 
205c3339decSBarry Smith   Collective
206a7e14dcfSSatish Balay 
207a7e14dcfSSatish Balay   Input Parameters:
208441846f8SBarry Smith + tao - the Tao context
209a7e14dcfSSatish Balay - X - input vector
210a7e14dcfSSatish Balay 
211d8d19677SJose E. Roman   Output Parameters:
212a7e14dcfSSatish Balay + f - Objective value at X
213a7e14dcfSSatish Balay - g - Gradient vector at X
214a7e14dcfSSatish Balay 
21565ba42b6SBarry Smith   Note:
21665ba42b6SBarry Smith     `TaoComputeObjectiveAndGradient()` is typically used within the implementation of the optimization algorithm,
217a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
218a7e14dcfSSatish Balay 
21965ba42b6SBarry Smith   Level: developer
220a7e14dcfSSatish Balay 
221db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()`
222a7e14dcfSSatish Balay @*/
223d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G)
224d71ae5a4SJacob Faibussowitsch {
225a7e14dcfSSatish Balay   PetscFunctionBegin;
226441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
227a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
228a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G, VEC_CLASSID, 4);
229a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
230a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, G, 4);
2319566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
232a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient) {
2339566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, G, NULL));
234f4c1ad5cSStefano Zampini     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
2359566063dSJacob Faibussowitsch       PetscCall(TaoComputeObjective(tao, X, f));
2369566063dSJacob Faibussowitsch       PetscCall(TaoDefaultComputeGradient(tao, X, G, NULL));
237794dad8cSStefano Zampini     } else PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, f, G, tao->user_objgradP));
2389566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, G, NULL));
239a7e14dcfSSatish Balay     tao->nfuncgrads++;
240a7e14dcfSSatish Balay   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
2419566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL));
242792fecdfSBarry Smith     PetscCallBack("Tao callback objective", (*tao->ops->computeobjective)(tao, X, f, tao->user_objP));
2439566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL));
244a7e14dcfSSatish Balay     tao->nfuncs++;
2459566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval, tao, X, G, NULL));
246792fecdfSBarry Smith     PetscCallBack("Tao callback gradient", (*tao->ops->computegradient)(tao, X, G, tao->user_gradP));
2479566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval, tao, X, G, NULL));
248a7e14dcfSSatish Balay     tao->ngrads++;
249a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetObjective() or TaoSetGradient() not set");
2509566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao, "TAO Function evaluation: %20.19e\n", (double)(*f)));
2519566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
2521657496cSHong Zhang 
2539566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao, X, G));
254*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
255a7e14dcfSSatish Balay }
256a7e14dcfSSatish Balay 
257a7e14dcfSSatish Balay /*@C
258a82e8c82SStefano Zampini   TaoSetObjective - Sets the function evaluation routine for minimization
259a7e14dcfSSatish Balay 
260c3339decSBarry Smith   Logically collective
261a7e14dcfSSatish Balay 
262d8d19677SJose E. Roman   Input Parameters:
263441846f8SBarry Smith + tao - the Tao context
264a7e14dcfSSatish Balay . func - the objective function
265a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2666c23d075SBarry Smith         routine (may be NULL)
267a7e14dcfSSatish Balay 
268a7e14dcfSSatish Balay   Calling sequence of func:
269441846f8SBarry Smith $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
270a7e14dcfSSatish Balay 
271a7e14dcfSSatish Balay + x - input vector
272a7e14dcfSSatish Balay . f - function value
273a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
274a7e14dcfSSatish Balay 
275a7e14dcfSSatish Balay   Level: beginner
276a7e14dcfSSatish Balay 
277db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetObjective()`
278a7e14dcfSSatish Balay @*/
279d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal *, void *), void *ctx)
280d71ae5a4SJacob Faibussowitsch {
281a7e14dcfSSatish Balay   PetscFunctionBegin;
282441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
283a82e8c82SStefano Zampini   if (ctx) tao->user_objP = ctx;
284a82e8c82SStefano Zampini   if (func) tao->ops->computeobjective = func;
285*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
286a82e8c82SStefano Zampini }
287a82e8c82SStefano Zampini 
288a82e8c82SStefano Zampini /*@C
28965ba42b6SBarry Smith   TaoGetObjective - Gets the function evaluation routine for the function to be minimized
290a82e8c82SStefano Zampini 
291a82e8c82SStefano Zampini   Not collective
292a82e8c82SStefano Zampini 
293a82e8c82SStefano Zampini   Input Parameter:
294a82e8c82SStefano Zampini . tao - the Tao context
295a82e8c82SStefano Zampini 
296a82e8c82SStefano Zampini   Output Parameters
297a82e8c82SStefano Zampini + func - the objective function
298a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation
299a82e8c82SStefano Zampini 
300a82e8c82SStefano Zampini   Calling sequence of func:
301a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
302a82e8c82SStefano Zampini 
303a82e8c82SStefano Zampini + x - input vector
304a82e8c82SStefano Zampini . f - function value
305a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
306a82e8c82SStefano Zampini 
307a82e8c82SStefano Zampini   Level: beginner
308a82e8c82SStefano Zampini 
30965ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjective()`
310a82e8c82SStefano Zampini @*/
311d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal *, void *), void **ctx)
312d71ae5a4SJacob Faibussowitsch {
313a82e8c82SStefano Zampini   PetscFunctionBegin;
314a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
315a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjective;
316a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objP;
317*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
318a7e14dcfSSatish Balay }
319a7e14dcfSSatish Balay 
320a7e14dcfSSatish Balay /*@C
3214a48860cSAlp Dener   TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications
322a7e14dcfSSatish Balay 
323c3339decSBarry Smith   Logically collective
324a7e14dcfSSatish Balay 
325d8d19677SJose E. Roman   Input Parameters:
326441846f8SBarry Smith + tao - the Tao context
3274a48860cSAlp Dener . func - the residual evaluation routine
328a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
3296c23d075SBarry Smith         routine (may be NULL)
330a7e14dcfSSatish Balay 
331a7e14dcfSSatish Balay   Calling sequence of func:
332441846f8SBarry Smith $      func (Tao tao, Vec x, Vec f, void *ctx);
333a7e14dcfSSatish Balay 
334a7e14dcfSSatish Balay + x - input vector
335a7e14dcfSSatish Balay . f - function value vector
336a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
337a7e14dcfSSatish Balay 
338a7e14dcfSSatish Balay   Level: beginner
339a7e14dcfSSatish Balay 
34065ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoSetJacobianRoutine()`
341a7e14dcfSSatish Balay @*/
342d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx)
343d71ae5a4SJacob Faibussowitsch {
344a7e14dcfSSatish Balay   PetscFunctionBegin;
345441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
3464a48860cSAlp Dener   PetscValidHeaderSpecific(res, VEC_CLASSID, 2);
3479566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)res));
34848a46eb9SPierre Jolivet   if (tao->ls_res) PetscCall(VecDestroy(&tao->ls_res));
3494a48860cSAlp Dener   tao->ls_res               = res;
3504ffbe8acSAlp Dener   tao->user_lsresP          = ctx;
3514a48860cSAlp Dener   tao->ops->computeresidual = func;
352737f463aSAlp Dener 
353*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
354737f463aSAlp Dener }
355737f463aSAlp Dener 
356737f463aSAlp Dener /*@
35765ba42b6SBarry 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.
35865ba42b6SBarry 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.
359737f463aSAlp Dener 
360c3339decSBarry Smith   Collective
361737f463aSAlp Dener 
362737f463aSAlp Dener   Input Parameters:
363737f463aSAlp Dener + tao - the Tao context
364737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only)
365737f463aSAlp Dener . n       - the number of weights (if using off-diagonal)
366737f463aSAlp Dener . rows    - index list of rows for sigma_w
367737f463aSAlp Dener . cols    - index list of columns for sigma_w
368737f463aSAlp Dener - vals - array of weights
369737f463aSAlp Dener 
370737f463aSAlp Dener   Note: Either sigma_v or sigma_w (or both) should be NULL
371737f463aSAlp Dener 
372737f463aSAlp Dener   Level: intermediate
373737f463aSAlp Dener 
37465ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()`
375737f463aSAlp Dener @*/
376d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals)
377d71ae5a4SJacob Faibussowitsch {
378737f463aSAlp Dener   PetscInt i;
379a82e8c82SStefano Zampini 
380737f463aSAlp Dener   PetscFunctionBegin;
381737f463aSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
382a82e8c82SStefano Zampini   if (sigma_v) PetscValidHeaderSpecific(sigma_v, VEC_CLASSID, 2);
3839566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)sigma_v));
3849566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tao->res_weights_v));
3854ffbe8acSAlp Dener   tao->res_weights_v = sigma_v;
386737f463aSAlp Dener   if (vals) {
3879566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_rows));
3889566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_cols));
3899566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_w));
3909566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &tao->res_weights_rows));
3919566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &tao->res_weights_cols));
3929566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &tao->res_weights_w));
393737f463aSAlp Dener     tao->res_weights_n = n;
394737f463aSAlp Dener     for (i = 0; i < n; i++) {
395737f463aSAlp Dener       tao->res_weights_rows[i] = rows[i];
396737f463aSAlp Dener       tao->res_weights_cols[i] = cols[i];
397737f463aSAlp Dener       tao->res_weights_w[i]    = vals[i];
398737f463aSAlp Dener     }
399737f463aSAlp Dener   } else {
400737f463aSAlp Dener     tao->res_weights_n    = 0;
40183c8fe1dSLisandro Dalcin     tao->res_weights_rows = NULL;
40283c8fe1dSLisandro Dalcin     tao->res_weights_cols = NULL;
403737f463aSAlp Dener   }
404*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
405a7e14dcfSSatish Balay }
406a7e14dcfSSatish Balay 
4078b7a9b22SJason Sarich /*@
4084a48860cSAlp Dener   TaoComputeResidual - Computes a least-squares residual vector at a given point
409a7e14dcfSSatish Balay 
410c3339decSBarry Smith   Collective
411a7e14dcfSSatish Balay 
412a7e14dcfSSatish Balay   Input Parameters:
413441846f8SBarry Smith + tao - the Tao context
414a7e14dcfSSatish Balay - X - input vector
415a7e14dcfSSatish Balay 
416a7e14dcfSSatish Balay   Output Parameter:
417a7e14dcfSSatish Balay . f - Objective vector at X
418a7e14dcfSSatish Balay 
41995452b02SPatrick Sanan   Notes:
42065ba42b6SBarry Smith     `TaoComputeResidual()` is typically used within the implementation of the optimization algorithm,
421a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
422a7e14dcfSSatish Balay 
423a7e14dcfSSatish Balay   Level: advanced
424a7e14dcfSSatish Balay 
42565ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()`
426a7e14dcfSSatish Balay @*/
427d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F)
428d71ae5a4SJacob Faibussowitsch {
429a7e14dcfSSatish Balay   PetscFunctionBegin;
430441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
431a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
432a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
433a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
434a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, F, 3);
4354a48860cSAlp Dener   if (tao->ops->computeresidual) {
4369566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL));
437792fecdfSBarry Smith     PetscCallBack("Tao callback least-squares residual", (*tao->ops->computeresidual)(tao, X, F, tao->user_lsresP));
4389566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL));
439a7e14dcfSSatish Balay     tao->nfuncs++;
440691b26d3SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetResidualRoutine() has not been called");
4419566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao, "TAO least-squares residual evaluation.\n"));
442*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
443a7e14dcfSSatish Balay }
444a7e14dcfSSatish Balay 
445a7e14dcfSSatish Balay /*@C
44665ba42b6SBarry Smith   TaoSetGradient - Sets the gradient evaluation routine for the function to be optimized
447a7e14dcfSSatish Balay 
448c3339decSBarry Smith   Logically collective
449a7e14dcfSSatish Balay 
450d8d19677SJose E. Roman   Input Parameters:
451441846f8SBarry Smith + tao - the Tao context
452a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
453a7e14dcfSSatish Balay . func - the gradient function
454a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
4556c23d075SBarry Smith         routine (may be NULL)
456a7e14dcfSSatish Balay 
457a7e14dcfSSatish Balay   Calling sequence of func:
458441846f8SBarry Smith $      func (Tao tao, Vec x, Vec g, void *ctx);
459a7e14dcfSSatish Balay 
460a7e14dcfSSatish Balay + x - input vector
461a7e14dcfSSatish Balay . g - gradient value (output)
462a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
463a7e14dcfSSatish Balay 
464a7e14dcfSSatish Balay   Level: beginner
465a7e14dcfSSatish Balay 
46665ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()`
467a7e14dcfSSatish Balay @*/
468d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx)
469d71ae5a4SJacob Faibussowitsch {
470a7e14dcfSSatish Balay   PetscFunctionBegin;
471441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
472a82e8c82SStefano Zampini   if (g) {
473a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g, VEC_CLASSID, 2);
474a82e8c82SStefano Zampini     PetscCheckSameComm(tao, 1, g, 2);
4759566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
4769566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
477a82e8c82SStefano Zampini     tao->gradient = g;
478a82e8c82SStefano Zampini   }
479a82e8c82SStefano Zampini   if (func) tao->ops->computegradient = func;
480a82e8c82SStefano Zampini   if (ctx) tao->user_gradP = ctx;
481*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
482a7e14dcfSSatish Balay }
483a7e14dcfSSatish Balay 
484a7e14dcfSSatish Balay /*@C
48565ba42b6SBarry Smith   TaoGetGradient - Gets the gradient evaluation routine for the function being optimized
486a82e8c82SStefano Zampini 
487a82e8c82SStefano Zampini   Not collective
488a82e8c82SStefano Zampini 
489a82e8c82SStefano Zampini   Input Parameter:
490a82e8c82SStefano Zampini . tao - the Tao context
491a82e8c82SStefano Zampini 
492a82e8c82SStefano Zampini   Output Parameters:
493a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation
494a82e8c82SStefano Zampini . func - the gradient function
495a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
496a82e8c82SStefano Zampini 
497a82e8c82SStefano Zampini   Calling sequence of func:
498a82e8c82SStefano Zampini $      func (Tao tao, Vec x, Vec g, void *ctx);
499a82e8c82SStefano Zampini 
500a82e8c82SStefano Zampini + x - input vector
501a82e8c82SStefano Zampini . g - gradient value (output)
502a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
503a82e8c82SStefano Zampini 
504a82e8c82SStefano Zampini   Level: beginner
505a82e8c82SStefano Zampini 
50665ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()`
507a82e8c82SStefano Zampini @*/
508d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void *), void **ctx)
509d71ae5a4SJacob Faibussowitsch {
510a82e8c82SStefano Zampini   PetscFunctionBegin;
511a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
512a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
513a82e8c82SStefano Zampini   if (func) *func = tao->ops->computegradient;
514a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_gradP;
515*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
516a82e8c82SStefano Zampini }
517a82e8c82SStefano Zampini 
518a82e8c82SStefano Zampini /*@C
51965ba42b6SBarry Smith   TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for the function to be optimized
520a7e14dcfSSatish Balay 
521c3339decSBarry Smith   Logically collective
522a7e14dcfSSatish Balay 
523d8d19677SJose E. Roman   Input Parameters:
524441846f8SBarry Smith + tao - the Tao context
525a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
526a7e14dcfSSatish Balay . func - the gradient function
527a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
5286c23d075SBarry Smith         routine (may be NULL)
529a7e14dcfSSatish Balay 
530a7e14dcfSSatish Balay   Calling sequence of func:
53117477c02SJason Sarich $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
532a7e14dcfSSatish Balay 
533a7e14dcfSSatish Balay + x - input vector
53417477c02SJason Sarich . f - objective value (output)
535a7e14dcfSSatish Balay . g - gradient value (output)
536a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
537a7e14dcfSSatish Balay 
538a7e14dcfSSatish Balay   Level: beginner
539a7e14dcfSSatish Balay 
54065ba42b6SBarry Smith   Note:
54165ba42b6SBarry Smith   For some optimization methods using a combined function can be more eifficient.
54265ba42b6SBarry Smith 
54365ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()`
544a7e14dcfSSatish Balay @*/
545d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal *, Vec, void *), void *ctx)
546d71ae5a4SJacob Faibussowitsch {
547a82e8c82SStefano Zampini   PetscFunctionBegin;
548a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
549a82e8c82SStefano Zampini   if (g) {
550a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g, VEC_CLASSID, 2);
551a82e8c82SStefano Zampini     PetscCheckSameComm(tao, 1, g, 2);
5529566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
5539566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
554a82e8c82SStefano Zampini     tao->gradient = g;
555a82e8c82SStefano Zampini   }
556a82e8c82SStefano Zampini   if (ctx) tao->user_objgradP = ctx;
557a82e8c82SStefano Zampini   if (func) tao->ops->computeobjectiveandgradient = func;
558*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
559a82e8c82SStefano Zampini }
560a82e8c82SStefano Zampini 
561a82e8c82SStefano Zampini /*@C
56265ba42b6SBarry Smith   TaoGetObjectiveAndGradient - Gets the combined objective function and gradient evaluation routine for the function to be optimized
563a82e8c82SStefano Zampini 
564a82e8c82SStefano Zampini   Not collective
565a82e8c82SStefano Zampini 
566a82e8c82SStefano Zampini   Input Parameter:
567a82e8c82SStefano Zampini . tao - the Tao context
568a82e8c82SStefano Zampini 
569a82e8c82SStefano Zampini   Output Parameters:
570817da375SSatish Balay + g - the vector to internally hold the gradient computation
571a82e8c82SStefano Zampini . func - the gradient function
572a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
573a82e8c82SStefano Zampini 
574a82e8c82SStefano Zampini   Calling sequence of func:
575a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
576a82e8c82SStefano Zampini 
577a82e8c82SStefano Zampini + x - input vector
578a82e8c82SStefano Zampini . f - objective value (output)
579a82e8c82SStefano Zampini . g - gradient value (output)
580a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
581a82e8c82SStefano Zampini 
582a82e8c82SStefano Zampini   Level: beginner
583a82e8c82SStefano Zampini 
58465ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`
585a82e8c82SStefano Zampini @*/
586d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal *, Vec, void *), void **ctx)
587d71ae5a4SJacob Faibussowitsch {
588a7e14dcfSSatish Balay   PetscFunctionBegin;
589441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
590a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
591a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjectiveandgradient;
592a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objgradP;
593*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
594a7e14dcfSSatish Balay }
595a7e14dcfSSatish Balay 
596a7e14dcfSSatish Balay /*@
597a82e8c82SStefano Zampini   TaoIsObjectiveDefined - Checks to see if the user has
598a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
59965ba42b6SBarry Smith   it is appropriate to call `TaoComputeObjective()` or
60065ba42b6SBarry Smith   `TaoComputeObjectiveAndGradient()`
601a7e14dcfSSatish Balay 
602a82e8c82SStefano Zampini   Not collective
603a7e14dcfSSatish Balay 
604a82e8c82SStefano Zampini   Input Parameter:
605a82e8c82SStefano Zampini . tao - the Tao context
606a82e8c82SStefano Zampini 
607a82e8c82SStefano Zampini   Output Parameter:
60865ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
609a82e8c82SStefano Zampini 
610a7e14dcfSSatish Balay   Level: developer
611a7e14dcfSSatish Balay 
61265ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()`
613a7e14dcfSSatish Balay @*/
614d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg)
615d71ae5a4SJacob Faibussowitsch {
616a7e14dcfSSatish Balay   PetscFunctionBegin;
617441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
61883c8fe1dSLisandro Dalcin   if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE;
61945cf516eSBarry Smith   else *flg = PETSC_TRUE;
620*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
621a7e14dcfSSatish Balay }
622a7e14dcfSSatish Balay 
623a7e14dcfSSatish Balay /*@
624a82e8c82SStefano Zampini   TaoIsGradientDefined - Checks to see if the user has
625a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
62665ba42b6SBarry Smith   it is appropriate to call `TaoComputeGradient()` or
62765ba42b6SBarry Smith   `TaoComputeGradientAndGradient()`
628a7e14dcfSSatish Balay 
629a7e14dcfSSatish Balay   Not Collective
630a7e14dcfSSatish Balay 
631a82e8c82SStefano Zampini   Input Parameter:
632a82e8c82SStefano Zampini . tao - the Tao context
633a82e8c82SStefano Zampini 
634a82e8c82SStefano Zampini   Output Parameter:
63565ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
636a82e8c82SStefano Zampini 
637a7e14dcfSSatish Balay   Level: developer
638a7e14dcfSSatish Balay 
639db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()`
640a7e14dcfSSatish Balay @*/
641d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg)
642d71ae5a4SJacob Faibussowitsch {
643a7e14dcfSSatish Balay   PetscFunctionBegin;
644441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
64583c8fe1dSLisandro Dalcin   if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE;
64645cf516eSBarry Smith   else *flg = PETSC_TRUE;
647*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
648a7e14dcfSSatish Balay }
649a7e14dcfSSatish Balay 
650a7e14dcfSSatish Balay /*@
651a82e8c82SStefano Zampini   TaoIsObjectiveAndGradientDefined - Checks to see if the user has
652a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
65365ba42b6SBarry Smith   it is appropriate to call `TaoComputeObjective()` or
65465ba42b6SBarry Smith   `TaoComputeObjectiveAndGradient()`
655a7e14dcfSSatish Balay 
656a7e14dcfSSatish Balay   Not Collective
657a7e14dcfSSatish Balay 
658a82e8c82SStefano Zampini   Input Parameter:
659a82e8c82SStefano Zampini . tao - the Tao context
660a82e8c82SStefano Zampini 
661a82e8c82SStefano Zampini   Output Parameter:
66265ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
663a82e8c82SStefano Zampini 
664a7e14dcfSSatish Balay   Level: developer
665a7e14dcfSSatish Balay 
666db781477SPatrick Sanan .seealso: `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()`
667a7e14dcfSSatish Balay @*/
668d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg)
669d71ae5a4SJacob Faibussowitsch {
670a7e14dcfSSatish Balay   PetscFunctionBegin;
671441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
67283c8fe1dSLisandro Dalcin   if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE;
67345cf516eSBarry Smith   else *flg = PETSC_TRUE;
674*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
675a7e14dcfSSatish Balay }
676