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