xref: /petsc/src/tao/interface/taosolver_fg.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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 
665ba42b6SBarry 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
1365ba42b6SBarry Smith .seealso: `Tao`, `TaoCreate()`, `TaoSolve()`, `TaoGetSolution()`
14a7e14dcfSSatish Balay @*/
159371c9d4SSatish Balay PetscErrorCode TaoSetSolution(Tao tao, Vec x0) {
16a7e14dcfSSatish Balay   PetscFunctionBegin;
17441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
18a82e8c82SStefano Zampini   if (x0) PetscValidHeaderSpecific(x0, VEC_CLASSID, 2);
199566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)x0));
209566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tao->solution));
21a7e14dcfSSatish Balay   tao->solution = x0;
22a7e14dcfSSatish Balay   PetscFunctionReturn(0);
23a7e14dcfSSatish Balay }
24a7e14dcfSSatish Balay 
259371c9d4SSatish Balay PetscErrorCode TaoTestGradient(Tao tao, Vec x, Vec g1) {
26412cdd55SHong Zhang   Vec               g2, g3;
2709baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE, test = PETSC_FALSE;
2809baa881SHong Zhang   PetscReal         hcnorm, fdnorm, hcmax, fdmax, diffmax, diffnorm;
2909baa881SHong Zhang   PetscScalar       dot;
3009baa881SHong Zhang   MPI_Comm          comm;
31913eda9aSHong Zhang   PetscViewer       viewer, mviewer;
32913eda9aSHong Zhang   PetscViewerFormat format;
3309baa881SHong Zhang   PetscInt          tabs;
3409baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
3509baa881SHong Zhang 
3609baa881SHong Zhang   PetscFunctionBegin;
37d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)tao);
389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-tao_test_gradient", "Compare hand-coded and finite difference Gradients", "None", &test));
399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-tao_test_gradient_view", "View difference between hand-coded and finite difference Gradients element entries", "None", &mviewer, &format, &complete_print));
40d0609cedSBarry Smith   PetscOptionsEnd();
412f4b6201SAlp Dener   if (!test) {
42*48a46eb9SPierre Jolivet     if (complete_print) PetscCall(PetscViewerDestroy(&mviewer));
432f4b6201SAlp Dener     PetscFunctionReturn(0);
442f4b6201SAlp Dener   }
4509baa881SHong Zhang 
469566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
479566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
489566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
499566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
509566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Gradient -------------\n"));
5109baa881SHong Zhang   if (!complete_print && !directionsprinted) {
529566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Run with -tao_test_gradient_view and optionally -tao_test_gradient <threshold> to show difference\n"));
539566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    of hand-coded and finite difference gradient entries greater than <threshold>.\n"));
5409baa881SHong Zhang   }
5509baa881SHong Zhang   if (!directionsprinted) {
569566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Testing hand-coded Gradient, if (for double precision runs) ||G - Gfd||/||G|| is\n"));
579566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    O(1.e-8), the hand-coded Gradient is probably correct.\n"));
5809baa881SHong Zhang     directionsprinted = PETSC_TRUE;
5909baa881SHong Zhang   }
601baa6e33SBarry Smith   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
6109baa881SHong Zhang 
629566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x, &g2));
639566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(x, &g3));
6409baa881SHong Zhang 
6509baa881SHong Zhang   /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */
669566063dSJacob Faibussowitsch   PetscCall(TaoDefaultComputeGradient(tao, x, g2, NULL));
6709baa881SHong Zhang 
689566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2, NORM_2, &fdnorm));
699566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1, NORM_2, &hcnorm));
709566063dSJacob Faibussowitsch   PetscCall(VecNorm(g2, NORM_INFINITY, &fdmax));
719566063dSJacob Faibussowitsch   PetscCall(VecNorm(g1, NORM_INFINITY, &hcmax));
729566063dSJacob Faibussowitsch   PetscCall(VecDot(g1, g2, &dot));
739566063dSJacob Faibussowitsch   PetscCall(VecCopy(g1, g3));
749566063dSJacob Faibussowitsch   PetscCall(VecAXPY(g3, -1.0, g2));
759566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3, NORM_2, &diffnorm));
769566063dSJacob Faibussowitsch   PetscCall(VecNorm(g3, NORM_INFINITY, &diffmax));
779566063dSJacob 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))));
789566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n", (double)(diffnorm / PetscMax(hcnorm, fdnorm)), (double)diffnorm));
799566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n", (double)(diffmax / PetscMax(hcmax, fdmax)), (double)diffmax));
8009baa881SHong Zhang 
8109baa881SHong Zhang   if (complete_print) {
829566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded gradient ----------\n"));
839566063dSJacob Faibussowitsch     PetscCall(VecView(g1, mviewer));
849566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite difference gradient ----------\n"));
859566063dSJacob Faibussowitsch     PetscCall(VecView(g2, mviewer));
869566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded minus finite-difference gradient ----------\n"));
879566063dSJacob Faibussowitsch     PetscCall(VecView(g3, mviewer));
8809baa881SHong Zhang   }
899566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g2));
909566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&g3));
91913eda9aSHong Zhang 
92913eda9aSHong Zhang   if (complete_print) {
939566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
949566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
95913eda9aSHong Zhang   }
969566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
9709baa881SHong Zhang   PetscFunctionReturn(0);
9809baa881SHong Zhang }
9909baa881SHong Zhang 
100a7e14dcfSSatish Balay /*@
101a7e14dcfSSatish Balay   TaoComputeGradient - Computes the gradient of the objective function
102a7e14dcfSSatish Balay 
10365ba42b6SBarry Smith   Collective on tao
104a7e14dcfSSatish Balay 
105a7e14dcfSSatish Balay   Input Parameters:
106441846f8SBarry Smith + tao - the Tao context
107a7e14dcfSSatish Balay - X - input vector
108a7e14dcfSSatish Balay 
109a7e14dcfSSatish Balay   Output Parameter:
110a7e14dcfSSatish Balay . G - gradient vector
111a7e14dcfSSatish Balay 
11209baa881SHong Zhang   Options Database Keys:
11309baa881SHong Zhang +    -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors
114dfe02fe6SHong 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
11509baa881SHong Zhang 
11665ba42b6SBarry Smith   Note:
11765ba42b6SBarry Smith     `TaoComputeGradient()` is typically used within the implementation of the optimization method,
118a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
119a7e14dcfSSatish Balay 
12065ba42b6SBarry Smith   Level: developer
121a7e14dcfSSatish Balay 
122db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetGradient()`
123a7e14dcfSSatish Balay @*/
1249371c9d4SSatish Balay PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G) {
125a7e14dcfSSatish Balay   PetscReal dummy;
12687f595a5SBarry Smith 
127a7e14dcfSSatish Balay   PetscFunctionBegin;
128441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
129a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
130064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(G, VEC_CLASSID, 3);
131a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
132a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, G, 3);
1339566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
134a7e14dcfSSatish Balay   if (tao->ops->computegradient) {
1359566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval, tao, X, G, NULL));
136792fecdfSBarry Smith     PetscCallBack("Tao callback gradient", (*tao->ops->computegradient)(tao, X, G, tao->user_gradP));
1379566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval, tao, X, G, NULL));
138a7e14dcfSSatish Balay     tao->ngrads++;
139a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1409566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, G, NULL));
141792fecdfSBarry Smith     PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, &dummy, G, tao->user_objgradP));
1429566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, G, NULL));
143a7e14dcfSSatish Balay     tao->nfuncgrads++;
144a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetGradient() has not been called");
1459566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
14609baa881SHong Zhang 
1479566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao, X, G));
148a7e14dcfSSatish Balay   PetscFunctionReturn(0);
149a7e14dcfSSatish Balay }
150a7e14dcfSSatish Balay 
151a7e14dcfSSatish Balay /*@
152a7e14dcfSSatish Balay   TaoComputeObjective - Computes the objective function value at a given point
153a7e14dcfSSatish Balay 
15465ba42b6SBarry Smith   Collective on tao
155a7e14dcfSSatish Balay 
156a7e14dcfSSatish Balay   Input Parameters:
157441846f8SBarry Smith + tao - the Tao context
158a7e14dcfSSatish Balay - X - input vector
159a7e14dcfSSatish Balay 
160a7e14dcfSSatish Balay   Output Parameter:
161a7e14dcfSSatish Balay . f - Objective value at X
162a7e14dcfSSatish Balay 
16365ba42b6SBarry Smith   Note:
16465ba42b6SBarry Smith     `TaoComputeObjective()` is typically used within the implementation of the optimization algorithm
165a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
166a7e14dcfSSatish Balay 
16765ba42b6SBarry Smith   Level: developer
168a7e14dcfSSatish Balay 
16965ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()`
170a7e14dcfSSatish Balay @*/
1719371c9d4SSatish Balay PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f) {
172a7e14dcfSSatish Balay   Vec temp;
17387f595a5SBarry Smith 
174a7e14dcfSSatish Balay   PetscFunctionBegin;
175441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
176a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
177a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
1789566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
179a7e14dcfSSatish Balay   if (tao->ops->computeobjective) {
1809566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL));
181792fecdfSBarry Smith     PetscCallBack("Tao callback objective", (*tao->ops->computeobjective)(tao, X, f, tao->user_objP));
1829566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL));
183a7e14dcfSSatish Balay     tao->nfuncs++;
184a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1859566063dSJacob Faibussowitsch     PetscCall(PetscInfo(tao, "Duplicating variable vector in order to call func/grad routine\n"));
1869566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(X, &temp));
1879566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, NULL, NULL));
188792fecdfSBarry Smith     PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, f, temp, tao->user_objgradP));
1899566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, NULL, NULL));
1909566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&temp));
191a7e14dcfSSatish Balay     tao->nfuncgrads++;
192a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetObjective() has not been called");
1939566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao, "TAO Function evaluation: %20.19e\n", (double)(*f)));
1949566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
195a7e14dcfSSatish Balay   PetscFunctionReturn(0);
196a7e14dcfSSatish Balay }
197a7e14dcfSSatish Balay 
198a7e14dcfSSatish Balay /*@
199a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point
200a7e14dcfSSatish Balay 
20165ba42b6SBarry Smith   Collective on tao
202a7e14dcfSSatish Balay 
203a7e14dcfSSatish Balay   Input Parameters:
204441846f8SBarry Smith + tao - the Tao context
205a7e14dcfSSatish Balay - X - input vector
206a7e14dcfSSatish Balay 
207d8d19677SJose E. Roman   Output Parameters:
208a7e14dcfSSatish Balay + f - Objective value at X
209a7e14dcfSSatish Balay - g - Gradient vector at X
210a7e14dcfSSatish Balay 
21165ba42b6SBarry Smith   Note:
21265ba42b6SBarry Smith     `TaoComputeObjectiveAndGradient()` is typically used within the implementation of the optimization algorithm,
213a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
214a7e14dcfSSatish Balay 
21565ba42b6SBarry Smith   Level: developer
216a7e14dcfSSatish Balay 
217db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()`
218a7e14dcfSSatish Balay @*/
2199371c9d4SSatish Balay PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G) {
220a7e14dcfSSatish Balay   PetscFunctionBegin;
221441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
222a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
223a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G, VEC_CLASSID, 4);
224a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
225a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, G, 4);
2269566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
227a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient) {
2289566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, G, NULL));
229f4c1ad5cSStefano Zampini     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
2309566063dSJacob Faibussowitsch       PetscCall(TaoComputeObjective(tao, X, f));
2319566063dSJacob Faibussowitsch       PetscCall(TaoDefaultComputeGradient(tao, X, G, NULL));
232f4c1ad5cSStefano Zampini     } else {
233792fecdfSBarry Smith       PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, f, G, tao->user_objgradP));
234a7e14dcfSSatish Balay     }
2359566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, G, NULL));
236a7e14dcfSSatish Balay     tao->nfuncgrads++;
237a7e14dcfSSatish Balay   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
2389566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL));
239792fecdfSBarry Smith     PetscCallBack("Tao callback objective", (*tao->ops->computeobjective)(tao, X, f, tao->user_objP));
2409566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL));
241a7e14dcfSSatish Balay     tao->nfuncs++;
2429566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_GradientEval, tao, X, G, NULL));
243792fecdfSBarry Smith     PetscCallBack("Tao callback gradient", (*tao->ops->computegradient)(tao, X, G, tao->user_gradP));
2449566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_GradientEval, tao, X, G, NULL));
245a7e14dcfSSatish Balay     tao->ngrads++;
246a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetObjective() or TaoSetGradient() not set");
2479566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao, "TAO Function evaluation: %20.19e\n", (double)(*f)));
2489566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
2491657496cSHong Zhang 
2509566063dSJacob Faibussowitsch   PetscCall(TaoTestGradient(tao, X, G));
251a7e14dcfSSatish Balay   PetscFunctionReturn(0);
252a7e14dcfSSatish Balay }
253a7e14dcfSSatish Balay 
254a7e14dcfSSatish Balay /*@C
255a82e8c82SStefano Zampini   TaoSetObjective - Sets the function evaluation routine for minimization
256a7e14dcfSSatish Balay 
25765ba42b6SBarry Smith   Logically collective on tao
258a7e14dcfSSatish Balay 
259d8d19677SJose E. Roman   Input Parameters:
260441846f8SBarry Smith + tao - the Tao context
261a7e14dcfSSatish Balay . func - the objective function
262a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2636c23d075SBarry Smith         routine (may be NULL)
264a7e14dcfSSatish Balay 
265a7e14dcfSSatish Balay   Calling sequence of func:
266441846f8SBarry Smith $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
267a7e14dcfSSatish Balay 
268a7e14dcfSSatish Balay + x - input vector
269a7e14dcfSSatish Balay . f - function value
270a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
271a7e14dcfSSatish Balay 
272a7e14dcfSSatish Balay   Level: beginner
273a7e14dcfSSatish Balay 
274db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetObjective()`
275a7e14dcfSSatish Balay @*/
2769371c9d4SSatish Balay PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal *, void *), void *ctx) {
277a7e14dcfSSatish Balay   PetscFunctionBegin;
278441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
279a82e8c82SStefano Zampini   if (ctx) tao->user_objP = ctx;
280a82e8c82SStefano Zampini   if (func) tao->ops->computeobjective = func;
281a82e8c82SStefano Zampini   PetscFunctionReturn(0);
282a82e8c82SStefano Zampini }
283a82e8c82SStefano Zampini 
284a82e8c82SStefano Zampini /*@C
28565ba42b6SBarry Smith   TaoGetObjective - Gets the function evaluation routine for the function to be minimized
286a82e8c82SStefano Zampini 
287a82e8c82SStefano Zampini   Not collective
288a82e8c82SStefano Zampini 
289a82e8c82SStefano Zampini   Input Parameter:
290a82e8c82SStefano Zampini . tao - the Tao context
291a82e8c82SStefano Zampini 
292a82e8c82SStefano Zampini   Output Parameters
293a82e8c82SStefano Zampini + func - the objective function
294a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation
295a82e8c82SStefano Zampini 
296a82e8c82SStefano Zampini   Calling sequence of func:
297a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
298a82e8c82SStefano Zampini 
299a82e8c82SStefano Zampini + x - input vector
300a82e8c82SStefano Zampini . f - function value
301a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
302a82e8c82SStefano Zampini 
303a82e8c82SStefano Zampini   Level: beginner
304a82e8c82SStefano Zampini 
30565ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjective()`
306a82e8c82SStefano Zampini @*/
3079371c9d4SSatish Balay PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal *, void *), void **ctx) {
308a82e8c82SStefano Zampini   PetscFunctionBegin;
309a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
310a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjective;
311a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objP;
312a7e14dcfSSatish Balay   PetscFunctionReturn(0);
313a7e14dcfSSatish Balay }
314a7e14dcfSSatish Balay 
315a7e14dcfSSatish Balay /*@C
3164a48860cSAlp Dener   TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications
317a7e14dcfSSatish Balay 
31865ba42b6SBarry Smith   Logically collective on tao
319a7e14dcfSSatish Balay 
320d8d19677SJose E. Roman   Input Parameters:
321441846f8SBarry Smith + tao - the Tao context
3224a48860cSAlp Dener . func - the residual evaluation routine
323a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
3246c23d075SBarry Smith         routine (may be NULL)
325a7e14dcfSSatish Balay 
326a7e14dcfSSatish Balay   Calling sequence of func:
327441846f8SBarry Smith $      func (Tao tao, Vec x, Vec f, void *ctx);
328a7e14dcfSSatish Balay 
329a7e14dcfSSatish Balay + x - input vector
330a7e14dcfSSatish Balay . f - function value vector
331a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
332a7e14dcfSSatish Balay 
333a7e14dcfSSatish Balay   Level: beginner
334a7e14dcfSSatish Balay 
33565ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoSetJacobianRoutine()`
336a7e14dcfSSatish Balay @*/
3379371c9d4SSatish Balay PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx) {
338a7e14dcfSSatish Balay   PetscFunctionBegin;
339441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
3404a48860cSAlp Dener   PetscValidHeaderSpecific(res, VEC_CLASSID, 2);
3419566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)res));
342*48a46eb9SPierre Jolivet   if (tao->ls_res) PetscCall(VecDestroy(&tao->ls_res));
3434a48860cSAlp Dener   tao->ls_res               = res;
3444ffbe8acSAlp Dener   tao->user_lsresP          = ctx;
3454a48860cSAlp Dener   tao->ops->computeresidual = func;
346737f463aSAlp Dener 
347737f463aSAlp Dener   PetscFunctionReturn(0);
348737f463aSAlp Dener }
349737f463aSAlp Dener 
350737f463aSAlp Dener /*@
35165ba42b6SBarry 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.
35265ba42b6SBarry 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.
353737f463aSAlp Dener 
35465ba42b6SBarry Smith   Collective on tao
355737f463aSAlp Dener 
356737f463aSAlp Dener   Input Parameters:
357737f463aSAlp Dener + tao - the Tao context
358737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only)
359737f463aSAlp Dener . n       - the number of weights (if using off-diagonal)
360737f463aSAlp Dener . rows    - index list of rows for sigma_w
361737f463aSAlp Dener . cols    - index list of columns for sigma_w
362737f463aSAlp Dener - vals - array of weights
363737f463aSAlp Dener 
364737f463aSAlp Dener   Note: Either sigma_v or sigma_w (or both) should be NULL
365737f463aSAlp Dener 
366737f463aSAlp Dener   Level: intermediate
367737f463aSAlp Dener 
36865ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()`
369737f463aSAlp Dener @*/
3709371c9d4SSatish Balay PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals) {
371737f463aSAlp Dener   PetscInt i;
372a82e8c82SStefano Zampini 
373737f463aSAlp Dener   PetscFunctionBegin;
374737f463aSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
375a82e8c82SStefano Zampini   if (sigma_v) PetscValidHeaderSpecific(sigma_v, VEC_CLASSID, 2);
3769566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)sigma_v));
3779566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tao->res_weights_v));
3784ffbe8acSAlp Dener   tao->res_weights_v = sigma_v;
379737f463aSAlp Dener   if (vals) {
3809566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_rows));
3819566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_cols));
3829566063dSJacob Faibussowitsch     PetscCall(PetscFree(tao->res_weights_w));
3839566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &tao->res_weights_rows));
3849566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &tao->res_weights_cols));
3859566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &tao->res_weights_w));
386737f463aSAlp Dener     tao->res_weights_n = n;
387737f463aSAlp Dener     for (i = 0; i < n; i++) {
388737f463aSAlp Dener       tao->res_weights_rows[i] = rows[i];
389737f463aSAlp Dener       tao->res_weights_cols[i] = cols[i];
390737f463aSAlp Dener       tao->res_weights_w[i]    = vals[i];
391737f463aSAlp Dener     }
392737f463aSAlp Dener   } else {
393737f463aSAlp Dener     tao->res_weights_n    = 0;
39483c8fe1dSLisandro Dalcin     tao->res_weights_rows = NULL;
39583c8fe1dSLisandro Dalcin     tao->res_weights_cols = NULL;
396737f463aSAlp Dener   }
397a7e14dcfSSatish Balay   PetscFunctionReturn(0);
398a7e14dcfSSatish Balay }
399a7e14dcfSSatish Balay 
4008b7a9b22SJason Sarich /*@
4014a48860cSAlp Dener   TaoComputeResidual - Computes a least-squares residual vector at a given point
402a7e14dcfSSatish Balay 
40365ba42b6SBarry Smith   Collective on tao
404a7e14dcfSSatish Balay 
405a7e14dcfSSatish Balay   Input Parameters:
406441846f8SBarry Smith + tao - the Tao context
407a7e14dcfSSatish Balay - X - input vector
408a7e14dcfSSatish Balay 
409a7e14dcfSSatish Balay   Output Parameter:
410a7e14dcfSSatish Balay . f - Objective vector at X
411a7e14dcfSSatish Balay 
41295452b02SPatrick Sanan   Notes:
41365ba42b6SBarry Smith     `TaoComputeResidual()` is typically used within the implementation of the optimization algorithm,
414a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
415a7e14dcfSSatish Balay 
416a7e14dcfSSatish Balay   Level: advanced
417a7e14dcfSSatish Balay 
41865ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()`
419a7e14dcfSSatish Balay @*/
4209371c9d4SSatish Balay PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F) {
421a7e14dcfSSatish Balay   PetscFunctionBegin;
422441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
423a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
424a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
425a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
426a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, F, 3);
4274a48860cSAlp Dener   if (tao->ops->computeresidual) {
4289566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL));
429792fecdfSBarry Smith     PetscCallBack("Tao callback least-squares residual", (*tao->ops->computeresidual)(tao, X, F, tao->user_lsresP));
4309566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL));
431a7e14dcfSSatish Balay     tao->nfuncs++;
432691b26d3SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetResidualRoutine() has not been called");
4339566063dSJacob Faibussowitsch   PetscCall(PetscInfo(tao, "TAO least-squares residual evaluation.\n"));
434a7e14dcfSSatish Balay   PetscFunctionReturn(0);
435a7e14dcfSSatish Balay }
436a7e14dcfSSatish Balay 
437a7e14dcfSSatish Balay /*@C
43865ba42b6SBarry Smith   TaoSetGradient - Sets the gradient evaluation routine for the function to be optimized
439a7e14dcfSSatish Balay 
44065ba42b6SBarry Smith   Logically collective on tao
441a7e14dcfSSatish Balay 
442d8d19677SJose E. Roman   Input Parameters:
443441846f8SBarry Smith + tao - the Tao context
444a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
445a7e14dcfSSatish Balay . func - the gradient function
446a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
4476c23d075SBarry Smith         routine (may be NULL)
448a7e14dcfSSatish Balay 
449a7e14dcfSSatish Balay   Calling sequence of func:
450441846f8SBarry Smith $      func (Tao tao, Vec x, Vec g, void *ctx);
451a7e14dcfSSatish Balay 
452a7e14dcfSSatish Balay + x - input vector
453a7e14dcfSSatish Balay . g - gradient value (output)
454a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
455a7e14dcfSSatish Balay 
456a7e14dcfSSatish Balay   Level: beginner
457a7e14dcfSSatish Balay 
45865ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()`
459a7e14dcfSSatish Balay @*/
4609371c9d4SSatish Balay PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx) {
461a7e14dcfSSatish Balay   PetscFunctionBegin;
462441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
463a82e8c82SStefano Zampini   if (g) {
464a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g, VEC_CLASSID, 2);
465a82e8c82SStefano Zampini     PetscCheckSameComm(tao, 1, g, 2);
4669566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
4679566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
468a82e8c82SStefano Zampini     tao->gradient = g;
469a82e8c82SStefano Zampini   }
470a82e8c82SStefano Zampini   if (func) tao->ops->computegradient = func;
471a82e8c82SStefano Zampini   if (ctx) tao->user_gradP = ctx;
472a7e14dcfSSatish Balay   PetscFunctionReturn(0);
473a7e14dcfSSatish Balay }
474a7e14dcfSSatish Balay 
475a7e14dcfSSatish Balay /*@C
47665ba42b6SBarry Smith   TaoGetGradient - Gets the gradient evaluation routine for the function being optimized
477a82e8c82SStefano Zampini 
478a82e8c82SStefano Zampini   Not collective
479a82e8c82SStefano Zampini 
480a82e8c82SStefano Zampini   Input Parameter:
481a82e8c82SStefano Zampini . tao - the Tao context
482a82e8c82SStefano Zampini 
483a82e8c82SStefano Zampini   Output Parameters:
484a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation
485a82e8c82SStefano Zampini . func - the gradient function
486a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
487a82e8c82SStefano Zampini 
488a82e8c82SStefano Zampini   Calling sequence of func:
489a82e8c82SStefano Zampini $      func (Tao tao, Vec x, Vec g, void *ctx);
490a82e8c82SStefano Zampini 
491a82e8c82SStefano Zampini + x - input vector
492a82e8c82SStefano Zampini . g - gradient value (output)
493a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
494a82e8c82SStefano Zampini 
495a82e8c82SStefano Zampini   Level: beginner
496a82e8c82SStefano Zampini 
49765ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()`
498a82e8c82SStefano Zampini @*/
4999371c9d4SSatish Balay PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void *), void **ctx) {
500a82e8c82SStefano Zampini   PetscFunctionBegin;
501a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
502a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
503a82e8c82SStefano Zampini   if (func) *func = tao->ops->computegradient;
504a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_gradP;
505a82e8c82SStefano Zampini   PetscFunctionReturn(0);
506a82e8c82SStefano Zampini }
507a82e8c82SStefano Zampini 
508a82e8c82SStefano Zampini /*@C
50965ba42b6SBarry Smith   TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for the function to be optimized
510a7e14dcfSSatish Balay 
51165ba42b6SBarry Smith   Logically collective on tao
512a7e14dcfSSatish Balay 
513d8d19677SJose E. Roman   Input Parameters:
514441846f8SBarry Smith + tao - the Tao context
515a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
516a7e14dcfSSatish Balay . func - the gradient function
517a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
5186c23d075SBarry Smith         routine (may be NULL)
519a7e14dcfSSatish Balay 
520a7e14dcfSSatish Balay   Calling sequence of func:
52117477c02SJason Sarich $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
522a7e14dcfSSatish Balay 
523a7e14dcfSSatish Balay + x - input vector
52417477c02SJason Sarich . f - objective value (output)
525a7e14dcfSSatish Balay . g - gradient value (output)
526a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
527a7e14dcfSSatish Balay 
528a7e14dcfSSatish Balay   Level: beginner
529a7e14dcfSSatish Balay 
53065ba42b6SBarry Smith   Note:
53165ba42b6SBarry Smith   For some optimization methods using a combined function can be more eifficient.
53265ba42b6SBarry Smith 
53365ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()`
534a7e14dcfSSatish Balay @*/
5359371c9d4SSatish Balay PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal *, Vec, void *), void *ctx) {
536a82e8c82SStefano Zampini   PetscFunctionBegin;
537a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
538a82e8c82SStefano Zampini   if (g) {
539a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g, VEC_CLASSID, 2);
540a82e8c82SStefano Zampini     PetscCheckSameComm(tao, 1, g, 2);
5419566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)g));
5429566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&tao->gradient));
543a82e8c82SStefano Zampini     tao->gradient = g;
544a82e8c82SStefano Zampini   }
545a82e8c82SStefano Zampini   if (ctx) tao->user_objgradP = ctx;
546a82e8c82SStefano Zampini   if (func) tao->ops->computeobjectiveandgradient = func;
547a82e8c82SStefano Zampini   PetscFunctionReturn(0);
548a82e8c82SStefano Zampini }
549a82e8c82SStefano Zampini 
550a82e8c82SStefano Zampini /*@C
55165ba42b6SBarry Smith   TaoGetObjectiveAndGradient - Gets the combined objective function and gradient evaluation routine for the function to be optimized
552a82e8c82SStefano Zampini 
553a82e8c82SStefano Zampini   Not collective
554a82e8c82SStefano Zampini 
555a82e8c82SStefano Zampini   Input Parameter:
556a82e8c82SStefano Zampini . tao - the Tao context
557a82e8c82SStefano Zampini 
558a82e8c82SStefano Zampini   Output Parameters:
559817da375SSatish Balay + g - the vector to internally hold the gradient computation
560a82e8c82SStefano Zampini . func - the gradient function
561a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
562a82e8c82SStefano Zampini 
563a82e8c82SStefano Zampini   Calling sequence of func:
564a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
565a82e8c82SStefano Zampini 
566a82e8c82SStefano Zampini + x - input vector
567a82e8c82SStefano Zampini . f - objective value (output)
568a82e8c82SStefano Zampini . g - gradient value (output)
569a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
570a82e8c82SStefano Zampini 
571a82e8c82SStefano Zampini   Level: beginner
572a82e8c82SStefano Zampini 
57365ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`
574a82e8c82SStefano Zampini @*/
5759371c9d4SSatish Balay PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal *, Vec, void *), void **ctx) {
576a7e14dcfSSatish Balay   PetscFunctionBegin;
577441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
578a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
579a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjectiveandgradient;
580a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objgradP;
581a7e14dcfSSatish Balay   PetscFunctionReturn(0);
582a7e14dcfSSatish Balay }
583a7e14dcfSSatish Balay 
584a7e14dcfSSatish Balay /*@
585a82e8c82SStefano Zampini   TaoIsObjectiveDefined - Checks to see if the user has
586a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
58765ba42b6SBarry Smith   it is appropriate to call `TaoComputeObjective()` or
58865ba42b6SBarry Smith   `TaoComputeObjectiveAndGradient()`
589a7e14dcfSSatish Balay 
590a82e8c82SStefano Zampini   Not collective
591a7e14dcfSSatish Balay 
592a82e8c82SStefano Zampini   Input Parameter:
593a82e8c82SStefano Zampini . tao - the Tao context
594a82e8c82SStefano Zampini 
595a82e8c82SStefano Zampini   Output Parameter:
59665ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
597a82e8c82SStefano Zampini 
598a7e14dcfSSatish Balay   Level: developer
599a7e14dcfSSatish Balay 
60065ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()`
601a7e14dcfSSatish Balay @*/
6029371c9d4SSatish Balay PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg) {
603a7e14dcfSSatish Balay   PetscFunctionBegin;
604441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
60583c8fe1dSLisandro Dalcin   if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE;
60645cf516eSBarry Smith   else *flg = PETSC_TRUE;
607a7e14dcfSSatish Balay   PetscFunctionReturn(0);
608a7e14dcfSSatish Balay }
609a7e14dcfSSatish Balay 
610a7e14dcfSSatish Balay /*@
611a82e8c82SStefano Zampini   TaoIsGradientDefined - Checks to see if the user has
612a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
61365ba42b6SBarry Smith   it is appropriate to call `TaoComputeGradient()` or
61465ba42b6SBarry Smith   `TaoComputeGradientAndGradient()`
615a7e14dcfSSatish Balay 
616a7e14dcfSSatish Balay   Not Collective
617a7e14dcfSSatish Balay 
618a82e8c82SStefano Zampini   Input Parameter:
619a82e8c82SStefano Zampini . tao - the Tao context
620a82e8c82SStefano Zampini 
621a82e8c82SStefano Zampini   Output Parameter:
62265ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
623a82e8c82SStefano Zampini 
624a7e14dcfSSatish Balay   Level: developer
625a7e14dcfSSatish Balay 
626db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()`
627a7e14dcfSSatish Balay @*/
6289371c9d4SSatish Balay PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg) {
629a7e14dcfSSatish Balay   PetscFunctionBegin;
630441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
63183c8fe1dSLisandro Dalcin   if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE;
63245cf516eSBarry Smith   else *flg = PETSC_TRUE;
633a7e14dcfSSatish Balay   PetscFunctionReturn(0);
634a7e14dcfSSatish Balay }
635a7e14dcfSSatish Balay 
636a7e14dcfSSatish Balay /*@
637a82e8c82SStefano Zampini   TaoIsObjectiveAndGradientDefined - Checks to see if the user has
638a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
63965ba42b6SBarry Smith   it is appropriate to call `TaoComputeObjective()` or
64065ba42b6SBarry Smith   `TaoComputeObjectiveAndGradient()`
641a7e14dcfSSatish Balay 
642a7e14dcfSSatish Balay   Not Collective
643a7e14dcfSSatish Balay 
644a82e8c82SStefano Zampini   Input Parameter:
645a82e8c82SStefano Zampini . tao - the Tao context
646a82e8c82SStefano Zampini 
647a82e8c82SStefano Zampini   Output Parameter:
64865ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise
649a82e8c82SStefano Zampini 
650a7e14dcfSSatish Balay   Level: developer
651a7e14dcfSSatish Balay 
652db781477SPatrick Sanan .seealso: `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()`
653a7e14dcfSSatish Balay @*/
6549371c9d4SSatish Balay PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg) {
655a7e14dcfSSatish Balay   PetscFunctionBegin;
656441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
65783c8fe1dSLisandro Dalcin   if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE;
65845cf516eSBarry Smith   else *flg = PETSC_TRUE;
659a7e14dcfSSatish Balay   PetscFunctionReturn(0);
660a7e14dcfSSatish Balay }
661