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: 9*47450a7bSBarry Smith + tao - the `Tao` context 10a7e14dcfSSatish Balay - x0 - the initial guess 11a7e14dcfSSatish Balay 12a7e14dcfSSatish Balay Level: beginner 13*47450a7bSBarry Smith 14*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoCreate()`, `TaoSolve()`, `TaoGetSolution()` 15a7e14dcfSSatish Balay @*/ 16d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetSolution(Tao tao, Vec x0) 17d71ae5a4SJacob Faibussowitsch { 18a7e14dcfSSatish Balay PetscFunctionBegin; 19441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 20a82e8c82SStefano Zampini if (x0) PetscValidHeaderSpecific(x0, VEC_CLASSID, 2); 219566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x0)); 229566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->solution)); 23a7e14dcfSSatish Balay tao->solution = x0; 243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25a7e14dcfSSatish Balay } 26a7e14dcfSSatish Balay 27d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoTestGradient(Tao tao, Vec x, Vec g1) 28d71ae5a4SJacob Faibussowitsch { 29412cdd55SHong Zhang Vec g2, g3; 3009baa881SHong Zhang PetscBool complete_print = PETSC_FALSE, test = PETSC_FALSE; 3109baa881SHong Zhang PetscReal hcnorm, fdnorm, hcmax, fdmax, diffmax, diffnorm; 3209baa881SHong Zhang PetscScalar dot; 3309baa881SHong Zhang MPI_Comm comm; 34913eda9aSHong Zhang PetscViewer viewer, mviewer; 35913eda9aSHong Zhang PetscViewerFormat format; 3609baa881SHong Zhang PetscInt tabs; 3709baa881SHong Zhang static PetscBool directionsprinted = PETSC_FALSE; 3809baa881SHong Zhang 3909baa881SHong Zhang PetscFunctionBegin; 40d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)tao); 419566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-tao_test_gradient", "Compare hand-coded and finite difference Gradients", "None", &test)); 429566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-tao_test_gradient_view", "View difference between hand-coded and finite difference Gradients element entries", "None", &mviewer, &format, &complete_print)); 43d0609cedSBarry Smith PetscOptionsEnd(); 442f4b6201SAlp Dener if (!test) { 4548a46eb9SPierre Jolivet if (complete_print) PetscCall(PetscViewerDestroy(&mviewer)); 463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 472f4b6201SAlp Dener } 4809baa881SHong Zhang 499566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)tao, &comm)); 509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel)); 539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Gradient -------------\n")); 5409baa881SHong Zhang if (!complete_print && !directionsprinted) { 559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -tao_test_gradient_view and optionally -tao_test_gradient <threshold> to show difference\n")); 569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference gradient entries greater than <threshold>.\n")); 5709baa881SHong Zhang } 5809baa881SHong Zhang if (!directionsprinted) { 599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Gradient, if (for double precision runs) ||G - Gfd||/||G|| is\n")); 609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Gradient is probably correct.\n")); 6109baa881SHong Zhang directionsprinted = PETSC_TRUE; 6209baa881SHong Zhang } 631baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 6409baa881SHong Zhang 659566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &g2)); 669566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &g3)); 6709baa881SHong Zhang 6809baa881SHong Zhang /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */ 699566063dSJacob Faibussowitsch PetscCall(TaoDefaultComputeGradient(tao, x, g2, NULL)); 7009baa881SHong Zhang 719566063dSJacob Faibussowitsch PetscCall(VecNorm(g2, NORM_2, &fdnorm)); 729566063dSJacob Faibussowitsch PetscCall(VecNorm(g1, NORM_2, &hcnorm)); 739566063dSJacob Faibussowitsch PetscCall(VecNorm(g2, NORM_INFINITY, &fdmax)); 749566063dSJacob Faibussowitsch PetscCall(VecNorm(g1, NORM_INFINITY, &hcmax)); 759566063dSJacob Faibussowitsch PetscCall(VecDot(g1, g2, &dot)); 769566063dSJacob Faibussowitsch PetscCall(VecCopy(g1, g3)); 779566063dSJacob Faibussowitsch PetscCall(VecAXPY(g3, -1.0, g2)); 789566063dSJacob Faibussowitsch PetscCall(VecNorm(g3, NORM_2, &diffnorm)); 799566063dSJacob Faibussowitsch PetscCall(VecNorm(g3, NORM_INFINITY, &diffmax)); 809566063dSJacob 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)))); 819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " 2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n", (double)(diffnorm / PetscMax(hcnorm, fdnorm)), (double)diffnorm)); 829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n", (double)(diffmax / PetscMax(hcmax, fdmax)), (double)diffmax)); 8309baa881SHong Zhang 8409baa881SHong Zhang if (complete_print) { 859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded gradient ----------\n")); 869566063dSJacob Faibussowitsch PetscCall(VecView(g1, mviewer)); 879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference gradient ----------\n")); 889566063dSJacob Faibussowitsch PetscCall(VecView(g2, mviewer)); 899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded minus finite-difference gradient ----------\n")); 909566063dSJacob Faibussowitsch PetscCall(VecView(g3, mviewer)); 9109baa881SHong Zhang } 929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&g2)); 939566063dSJacob Faibussowitsch PetscCall(VecDestroy(&g3)); 94913eda9aSHong Zhang 95913eda9aSHong Zhang if (complete_print) { 969566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(mviewer)); 979566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&mviewer)); 98913eda9aSHong Zhang } 999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 1003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10109baa881SHong Zhang } 10209baa881SHong Zhang 103a7e14dcfSSatish Balay /*@ 104a7e14dcfSSatish Balay TaoComputeGradient - Computes the gradient of the objective function 105a7e14dcfSSatish Balay 106c3339decSBarry Smith Collective 107a7e14dcfSSatish Balay 108a7e14dcfSSatish Balay Input Parameters: 109*47450a7bSBarry Smith + tao - the `Tao` context 110a7e14dcfSSatish Balay - X - input vector 111a7e14dcfSSatish Balay 112a7e14dcfSSatish Balay Output Parameter: 113a7e14dcfSSatish Balay . G - gradient vector 114a7e14dcfSSatish Balay 11509baa881SHong Zhang Options Database Keys: 11609baa881SHong Zhang + -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors 117dfe02fe6SHong 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 11809baa881SHong Zhang 119*47450a7bSBarry Smith Level: developer 120*47450a7bSBarry Smith 12165ba42b6SBarry Smith Note: 12265ba42b6SBarry Smith `TaoComputeGradient()` is typically used within the implementation of the optimization method, 123a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 124a7e14dcfSSatish Balay 125*47450a7bSBarry Smith .seealso: [](chapter_tao), `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetGradient()` 126a7e14dcfSSatish Balay @*/ 127d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G) 128d71ae5a4SJacob Faibussowitsch { 129a7e14dcfSSatish Balay PetscReal dummy; 13087f595a5SBarry Smith 131a7e14dcfSSatish Balay PetscFunctionBegin; 132441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 133a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 134064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(G, VEC_CLASSID, 3); 135a7e14dcfSSatish Balay PetscCheckSameComm(tao, 1, X, 2); 136a7e14dcfSSatish Balay PetscCheckSameComm(tao, 1, G, 3); 1379566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 138a7e14dcfSSatish Balay if (tao->ops->computegradient) { 1399566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_GradientEval, tao, X, G, NULL)); 140792fecdfSBarry Smith PetscCallBack("Tao callback gradient", (*tao->ops->computegradient)(tao, X, G, tao->user_gradP)); 1419566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_GradientEval, tao, X, G, NULL)); 142a7e14dcfSSatish Balay tao->ngrads++; 143a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 1449566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, G, NULL)); 145792fecdfSBarry Smith PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, &dummy, G, tao->user_objgradP)); 1469566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, G, NULL)); 147a7e14dcfSSatish Balay tao->nfuncgrads++; 148a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetGradient() has not been called"); 1499566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 15009baa881SHong Zhang 1519566063dSJacob Faibussowitsch PetscCall(TaoTestGradient(tao, X, G)); 1523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 153a7e14dcfSSatish Balay } 154a7e14dcfSSatish Balay 155a7e14dcfSSatish Balay /*@ 156a7e14dcfSSatish Balay TaoComputeObjective - Computes the objective function value at a given point 157a7e14dcfSSatish Balay 158c3339decSBarry Smith Collective 159a7e14dcfSSatish Balay 160a7e14dcfSSatish Balay Input Parameters: 161*47450a7bSBarry Smith + tao - the `Tao` context 162a7e14dcfSSatish Balay - X - input vector 163a7e14dcfSSatish Balay 164a7e14dcfSSatish Balay Output Parameter: 165a7e14dcfSSatish Balay . f - Objective value at X 166a7e14dcfSSatish Balay 167*47450a7bSBarry Smith Level: developer 168*47450a7bSBarry Smith 16965ba42b6SBarry Smith Note: 17065ba42b6SBarry Smith `TaoComputeObjective()` is typically used within the implementation of the optimization algorithm 171a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 172a7e14dcfSSatish Balay 173*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()` 174a7e14dcfSSatish Balay @*/ 175d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f) 176d71ae5a4SJacob Faibussowitsch { 177a7e14dcfSSatish Balay Vec temp; 17887f595a5SBarry Smith 179a7e14dcfSSatish Balay PetscFunctionBegin; 180441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 181a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 182a7e14dcfSSatish Balay PetscCheckSameComm(tao, 1, X, 2); 1839566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 184a7e14dcfSSatish Balay if (tao->ops->computeobjective) { 1859566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL)); 186792fecdfSBarry Smith PetscCallBack("Tao callback objective", (*tao->ops->computeobjective)(tao, X, f, tao->user_objP)); 1879566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL)); 188a7e14dcfSSatish Balay tao->nfuncs++; 189a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 1909566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao, "Duplicating variable vector in order to call func/grad routine\n")); 1919566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &temp)); 1929566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, NULL, NULL)); 193792fecdfSBarry Smith PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, f, temp, tao->user_objgradP)); 1949566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, NULL, NULL)); 1959566063dSJacob Faibussowitsch PetscCall(VecDestroy(&temp)); 196a7e14dcfSSatish Balay tao->nfuncgrads++; 197a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetObjective() has not been called"); 1989566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao, "TAO Function evaluation: %20.19e\n", (double)(*f))); 1999566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 2003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 201a7e14dcfSSatish Balay } 202a7e14dcfSSatish Balay 203a7e14dcfSSatish Balay /*@ 204a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient - Computes the objective function value at a given point 205a7e14dcfSSatish Balay 206c3339decSBarry Smith Collective 207a7e14dcfSSatish Balay 208a7e14dcfSSatish Balay Input Parameters: 209*47450a7bSBarry Smith + tao - the `Tao` context 210a7e14dcfSSatish Balay - X - input vector 211a7e14dcfSSatish Balay 212d8d19677SJose E. Roman Output Parameters: 213a7e14dcfSSatish Balay + f - Objective value at X 214a7e14dcfSSatish Balay - g - Gradient vector at X 215a7e14dcfSSatish Balay 216*47450a7bSBarry Smith Level: developer 217*47450a7bSBarry Smith 21865ba42b6SBarry Smith Note: 21965ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` is typically used within the implementation of the optimization algorithm, 220a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 221a7e14dcfSSatish Balay 222*47450a7bSBarry Smith .seealso: [](chapter_tao), `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()` 223a7e14dcfSSatish Balay @*/ 224d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G) 225d71ae5a4SJacob Faibussowitsch { 226a7e14dcfSSatish Balay PetscFunctionBegin; 227441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 228a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 229a7e14dcfSSatish Balay PetscValidHeaderSpecific(G, VEC_CLASSID, 4); 230a7e14dcfSSatish Balay PetscCheckSameComm(tao, 1, X, 2); 231a7e14dcfSSatish Balay PetscCheckSameComm(tao, 1, G, 4); 2329566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 233a7e14dcfSSatish Balay if (tao->ops->computeobjectiveandgradient) { 2349566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval, tao, X, G, NULL)); 235f4c1ad5cSStefano Zampini if (tao->ops->computegradient == TaoDefaultComputeGradient) { 2369566063dSJacob Faibussowitsch PetscCall(TaoComputeObjective(tao, X, f)); 2379566063dSJacob Faibussowitsch PetscCall(TaoDefaultComputeGradient(tao, X, G, NULL)); 238794dad8cSStefano Zampini } else PetscCallBack("Tao callback objective/gradient", (*tao->ops->computeobjectiveandgradient)(tao, X, f, G, tao->user_objgradP)); 2399566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval, tao, X, G, NULL)); 240a7e14dcfSSatish Balay tao->nfuncgrads++; 241a7e14dcfSSatish Balay } else if (tao->ops->computeobjective && tao->ops->computegradient) { 2429566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL)); 243792fecdfSBarry Smith PetscCallBack("Tao callback objective", (*tao->ops->computeobjective)(tao, X, f, tao->user_objP)); 2449566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL)); 245a7e14dcfSSatish Balay tao->nfuncs++; 2469566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_GradientEval, tao, X, G, NULL)); 247792fecdfSBarry Smith PetscCallBack("Tao callback gradient", (*tao->ops->computegradient)(tao, X, G, tao->user_gradP)); 2489566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_GradientEval, tao, X, G, NULL)); 249a7e14dcfSSatish Balay tao->ngrads++; 250a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetObjective() or TaoSetGradient() not set"); 2519566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao, "TAO Function evaluation: %20.19e\n", (double)(*f))); 2529566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 2531657496cSHong Zhang 2549566063dSJacob Faibussowitsch PetscCall(TaoTestGradient(tao, X, G)); 2553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 256a7e14dcfSSatish Balay } 257a7e14dcfSSatish Balay 258a7e14dcfSSatish Balay /*@C 259a82e8c82SStefano Zampini TaoSetObjective - Sets the function evaluation routine for minimization 260a7e14dcfSSatish Balay 261c3339decSBarry Smith Logically collective 262a7e14dcfSSatish Balay 263d8d19677SJose E. Roman Input Parameters: 264*47450a7bSBarry Smith + tao - the `Tao` context 265a7e14dcfSSatish Balay . func - the objective function 266a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 267*47450a7bSBarry Smith routine (may be `NULL`) 268a7e14dcfSSatish Balay 269a7e14dcfSSatish Balay Calling sequence of func: 270441846f8SBarry Smith $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 271a7e14dcfSSatish Balay 272a7e14dcfSSatish Balay + x - input vector 273a7e14dcfSSatish Balay . f - function value 274a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 275a7e14dcfSSatish Balay 276a7e14dcfSSatish Balay Level: beginner 277a7e14dcfSSatish Balay 278*47450a7bSBarry Smith .seealso: [](chapter_tao), `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetObjective()` 279a7e14dcfSSatish Balay @*/ 280d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal *, void *), void *ctx) 281d71ae5a4SJacob Faibussowitsch { 282a7e14dcfSSatish Balay PetscFunctionBegin; 283441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 284a82e8c82SStefano Zampini if (ctx) tao->user_objP = ctx; 285a82e8c82SStefano Zampini if (func) tao->ops->computeobjective = func; 2863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 287a82e8c82SStefano Zampini } 288a82e8c82SStefano Zampini 289a82e8c82SStefano Zampini /*@C 29065ba42b6SBarry Smith TaoGetObjective - Gets the function evaluation routine for the function to be minimized 291a82e8c82SStefano Zampini 292a82e8c82SStefano Zampini Not collective 293a82e8c82SStefano Zampini 294a82e8c82SStefano Zampini Input Parameter: 295*47450a7bSBarry Smith . tao - the `Tao` context 296a82e8c82SStefano Zampini 297a82e8c82SStefano Zampini Output Parameters 298a82e8c82SStefano Zampini + func - the objective function 299a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation 300a82e8c82SStefano Zampini 301a82e8c82SStefano Zampini Calling sequence of func: 302a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 303a82e8c82SStefano Zampini 304a82e8c82SStefano Zampini + x - input vector 305a82e8c82SStefano Zampini . f - function value 306a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 307a82e8c82SStefano Zampini 308a82e8c82SStefano Zampini Level: beginner 309a82e8c82SStefano Zampini 310*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjective()` 311a82e8c82SStefano Zampini @*/ 312d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal *, void *), void **ctx) 313d71ae5a4SJacob Faibussowitsch { 314a82e8c82SStefano Zampini PetscFunctionBegin; 315a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 316a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjective; 317a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objP; 3183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 319a7e14dcfSSatish Balay } 320a7e14dcfSSatish Balay 321a7e14dcfSSatish Balay /*@C 3224a48860cSAlp Dener TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications 323a7e14dcfSSatish Balay 324c3339decSBarry Smith Logically collective 325a7e14dcfSSatish Balay 326d8d19677SJose E. Roman Input Parameters: 327*47450a7bSBarry Smith + tao - the `Tao` context 3284a48860cSAlp Dener . func - the residual evaluation routine 329a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 330*47450a7bSBarry Smith routine (may be `NULL`) 331a7e14dcfSSatish Balay 332a7e14dcfSSatish Balay Calling sequence of func: 333441846f8SBarry Smith $ func (Tao tao, Vec x, Vec f, void *ctx); 334a7e14dcfSSatish Balay 335a7e14dcfSSatish Balay + x - input vector 336a7e14dcfSSatish Balay . f - function value vector 337a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 338a7e14dcfSSatish Balay 339a7e14dcfSSatish Balay Level: beginner 340a7e14dcfSSatish Balay 341*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetObjective()`, `TaoSetJacobianRoutine()` 342a7e14dcfSSatish Balay @*/ 343d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx) 344d71ae5a4SJacob Faibussowitsch { 345a7e14dcfSSatish Balay PetscFunctionBegin; 346441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 3474a48860cSAlp Dener PetscValidHeaderSpecific(res, VEC_CLASSID, 2); 3489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)res)); 34948a46eb9SPierre Jolivet if (tao->ls_res) PetscCall(VecDestroy(&tao->ls_res)); 3504a48860cSAlp Dener tao->ls_res = res; 3514ffbe8acSAlp Dener tao->user_lsresP = ctx; 3524a48860cSAlp Dener tao->ops->computeresidual = func; 353737f463aSAlp Dener 3543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 355737f463aSAlp Dener } 356737f463aSAlp Dener 357737f463aSAlp Dener /*@ 35865ba42b6SBarry 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. 359*47450a7bSBarry Smith If this function is not provided, or if `sigma_v` and `vals` are both `NULL`, then the identity matrix will be used for weights. 360737f463aSAlp Dener 361c3339decSBarry Smith Collective 362737f463aSAlp Dener 363737f463aSAlp Dener Input Parameters: 364*47450a7bSBarry Smith + tao - the `Tao` context 365737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only) 366737f463aSAlp Dener . n - the number of weights (if using off-diagonal) 367*47450a7bSBarry Smith . rows - index list of rows for `sigma_v` 368*47450a7bSBarry Smith . cols - index list of columns for `sigma_v` 369737f463aSAlp Dener - vals - array of weights 370737f463aSAlp Dener 371737f463aSAlp Dener Level: intermediate 372737f463aSAlp Dener 373*47450a7bSBarry Smith Note: 374*47450a7bSBarry Smith Either `sigma_v` or `vals` should be `NULL` 375*47450a7bSBarry Smith 376*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetResidualRoutine()` 377737f463aSAlp Dener @*/ 378d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals) 379d71ae5a4SJacob Faibussowitsch { 380737f463aSAlp Dener PetscInt i; 381a82e8c82SStefano Zampini 382737f463aSAlp Dener PetscFunctionBegin; 383737f463aSAlp Dener PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 384a82e8c82SStefano Zampini if (sigma_v) PetscValidHeaderSpecific(sigma_v, VEC_CLASSID, 2); 3859566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sigma_v)); 3869566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->res_weights_v)); 3874ffbe8acSAlp Dener tao->res_weights_v = sigma_v; 388737f463aSAlp Dener if (vals) { 3899566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_rows)); 3909566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_cols)); 3919566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_w)); 3929566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &tao->res_weights_rows)); 3939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &tao->res_weights_cols)); 3949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &tao->res_weights_w)); 395737f463aSAlp Dener tao->res_weights_n = n; 396737f463aSAlp Dener for (i = 0; i < n; i++) { 397737f463aSAlp Dener tao->res_weights_rows[i] = rows[i]; 398737f463aSAlp Dener tao->res_weights_cols[i] = cols[i]; 399737f463aSAlp Dener tao->res_weights_w[i] = vals[i]; 400737f463aSAlp Dener } 401737f463aSAlp Dener } else { 402737f463aSAlp Dener tao->res_weights_n = 0; 40383c8fe1dSLisandro Dalcin tao->res_weights_rows = NULL; 40483c8fe1dSLisandro Dalcin tao->res_weights_cols = NULL; 405737f463aSAlp Dener } 4063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 407a7e14dcfSSatish Balay } 408a7e14dcfSSatish Balay 4098b7a9b22SJason Sarich /*@ 4104a48860cSAlp Dener TaoComputeResidual - Computes a least-squares residual vector at a given point 411a7e14dcfSSatish Balay 412c3339decSBarry Smith Collective 413a7e14dcfSSatish Balay 414a7e14dcfSSatish Balay Input Parameters: 415*47450a7bSBarry Smith + tao - the `Tao` context 416a7e14dcfSSatish Balay - X - input vector 417a7e14dcfSSatish Balay 418a7e14dcfSSatish Balay Output Parameter: 419a7e14dcfSSatish Balay . f - Objective vector at X 420a7e14dcfSSatish Balay 421*47450a7bSBarry Smith Level: advanced 422*47450a7bSBarry Smith 42395452b02SPatrick Sanan Notes: 42465ba42b6SBarry Smith `TaoComputeResidual()` is typically used within the implementation of the optimization algorithm, 425a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 426a7e14dcfSSatish Balay 427*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetResidualRoutine()` 428a7e14dcfSSatish Balay @*/ 429d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F) 430d71ae5a4SJacob Faibussowitsch { 431a7e14dcfSSatish Balay PetscFunctionBegin; 432441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 433a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 434a7e14dcfSSatish Balay PetscValidHeaderSpecific(F, VEC_CLASSID, 3); 435a7e14dcfSSatish Balay PetscCheckSameComm(tao, 1, X, 2); 436a7e14dcfSSatish Balay PetscCheckSameComm(tao, 1, F, 3); 4374a48860cSAlp Dener if (tao->ops->computeresidual) { 4389566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval, tao, X, NULL, NULL)); 439792fecdfSBarry Smith PetscCallBack("Tao callback least-squares residual", (*tao->ops->computeresidual)(tao, X, F, tao->user_lsresP)); 4409566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval, tao, X, NULL, NULL)); 441a7e14dcfSSatish Balay tao->nfuncs++; 442691b26d3SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetResidualRoutine() has not been called"); 4439566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao, "TAO least-squares residual evaluation.\n")); 4443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 445a7e14dcfSSatish Balay } 446a7e14dcfSSatish Balay 447a7e14dcfSSatish Balay /*@C 44865ba42b6SBarry Smith TaoSetGradient - Sets the gradient evaluation routine for the function to be optimized 449a7e14dcfSSatish Balay 450c3339decSBarry Smith Logically collective 451a7e14dcfSSatish Balay 452d8d19677SJose E. Roman Input Parameters: 453*47450a7bSBarry Smith + tao - the `Tao` context 454a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 455a7e14dcfSSatish Balay . func - the gradient function 456a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 457*47450a7bSBarry Smith routine (may be `NULL`) 458a7e14dcfSSatish Balay 459a7e14dcfSSatish Balay Calling sequence of func: 460441846f8SBarry Smith $ func (Tao tao, Vec x, Vec g, void *ctx); 461a7e14dcfSSatish Balay 462a7e14dcfSSatish Balay + x - input vector 463a7e14dcfSSatish Balay . g - gradient value (output) 464a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 465a7e14dcfSSatish Balay 466a7e14dcfSSatish Balay Level: beginner 467a7e14dcfSSatish Balay 468*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()` 469a7e14dcfSSatish Balay @*/ 470d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx) 471d71ae5a4SJacob Faibussowitsch { 472a7e14dcfSSatish Balay PetscFunctionBegin; 473441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 474a82e8c82SStefano Zampini if (g) { 475a82e8c82SStefano Zampini PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 476a82e8c82SStefano Zampini PetscCheckSameComm(tao, 1, g, 2); 4779566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 4789566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 479a82e8c82SStefano Zampini tao->gradient = g; 480a82e8c82SStefano Zampini } 481a82e8c82SStefano Zampini if (func) tao->ops->computegradient = func; 482a82e8c82SStefano Zampini if (ctx) tao->user_gradP = ctx; 4833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 484a7e14dcfSSatish Balay } 485a7e14dcfSSatish Balay 486a7e14dcfSSatish Balay /*@C 48765ba42b6SBarry Smith TaoGetGradient - Gets the gradient evaluation routine for the function being optimized 488a82e8c82SStefano Zampini 489a82e8c82SStefano Zampini Not collective 490a82e8c82SStefano Zampini 491a82e8c82SStefano Zampini Input Parameter: 492*47450a7bSBarry Smith . tao - the `Tao` context 493a82e8c82SStefano Zampini 494a82e8c82SStefano Zampini Output Parameters: 495a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation 496a82e8c82SStefano Zampini . func - the gradient function 497a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 498a82e8c82SStefano Zampini 499a82e8c82SStefano Zampini Calling sequence of func: 500a82e8c82SStefano Zampini $ func (Tao tao, Vec x, Vec g, void *ctx); 501a82e8c82SStefano Zampini 502a82e8c82SStefano Zampini + x - input vector 503a82e8c82SStefano Zampini . g - gradient value (output) 504a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 505a82e8c82SStefano Zampini 506a82e8c82SStefano Zampini Level: beginner 507a82e8c82SStefano Zampini 508*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()` 509a82e8c82SStefano Zampini @*/ 510d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void *), void **ctx) 511d71ae5a4SJacob Faibussowitsch { 512a82e8c82SStefano Zampini PetscFunctionBegin; 513a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 514a82e8c82SStefano Zampini if (g) *g = tao->gradient; 515a82e8c82SStefano Zampini if (func) *func = tao->ops->computegradient; 516a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_gradP; 5173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 518a82e8c82SStefano Zampini } 519a82e8c82SStefano Zampini 520a82e8c82SStefano Zampini /*@C 52165ba42b6SBarry Smith TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for the function to be optimized 522a7e14dcfSSatish Balay 523c3339decSBarry Smith Logically collective 524a7e14dcfSSatish Balay 525d8d19677SJose E. Roman Input Parameters: 526*47450a7bSBarry Smith + tao - the `Tao` context 527a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 528a7e14dcfSSatish Balay . func - the gradient function 529a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 530*47450a7bSBarry Smith routine (may be `NULL`) 531a7e14dcfSSatish Balay 532a7e14dcfSSatish Balay Calling sequence of func: 53317477c02SJason Sarich $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 534a7e14dcfSSatish Balay 535a7e14dcfSSatish Balay + x - input vector 53617477c02SJason Sarich . f - objective value (output) 537a7e14dcfSSatish Balay . g - gradient value (output) 538a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 539a7e14dcfSSatish Balay 540a7e14dcfSSatish Balay Level: beginner 541a7e14dcfSSatish Balay 54265ba42b6SBarry Smith Note: 54365ba42b6SBarry Smith For some optimization methods using a combined function can be more eifficient. 54465ba42b6SBarry Smith 545*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()` 546a7e14dcfSSatish Balay @*/ 547d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal *, Vec, void *), void *ctx) 548d71ae5a4SJacob Faibussowitsch { 549a82e8c82SStefano Zampini PetscFunctionBegin; 550a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 551a82e8c82SStefano Zampini if (g) { 552a82e8c82SStefano Zampini PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 553a82e8c82SStefano Zampini PetscCheckSameComm(tao, 1, g, 2); 5549566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 5559566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 556a82e8c82SStefano Zampini tao->gradient = g; 557a82e8c82SStefano Zampini } 558a82e8c82SStefano Zampini if (ctx) tao->user_objgradP = ctx; 559a82e8c82SStefano Zampini if (func) tao->ops->computeobjectiveandgradient = func; 5603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 561a82e8c82SStefano Zampini } 562a82e8c82SStefano Zampini 563a82e8c82SStefano Zampini /*@C 56465ba42b6SBarry Smith TaoGetObjectiveAndGradient - Gets the combined objective function and gradient evaluation routine for the function to be optimized 565a82e8c82SStefano Zampini 566a82e8c82SStefano Zampini Not collective 567a82e8c82SStefano Zampini 568a82e8c82SStefano Zampini Input Parameter: 569*47450a7bSBarry Smith . tao - the `Tao` context 570a82e8c82SStefano Zampini 571a82e8c82SStefano Zampini Output Parameters: 572817da375SSatish Balay + g - the vector to internally hold the gradient computation 573a82e8c82SStefano Zampini . func - the gradient function 574a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 575a82e8c82SStefano Zampini 576a82e8c82SStefano Zampini Calling sequence of func: 577a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 578a82e8c82SStefano Zampini 579a82e8c82SStefano Zampini + x - input vector 580a82e8c82SStefano Zampini . f - objective value (output) 581a82e8c82SStefano Zampini . g - gradient value (output) 582a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 583a82e8c82SStefano Zampini 584a82e8c82SStefano Zampini Level: beginner 585a82e8c82SStefano Zampini 586*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()` 587a82e8c82SStefano Zampini @*/ 588d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal *, Vec, void *), void **ctx) 589d71ae5a4SJacob Faibussowitsch { 590a7e14dcfSSatish Balay PetscFunctionBegin; 591441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 592a82e8c82SStefano Zampini if (g) *g = tao->gradient; 593a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjectiveandgradient; 594a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objgradP; 5953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 596a7e14dcfSSatish Balay } 597a7e14dcfSSatish Balay 598a7e14dcfSSatish Balay /*@ 599a82e8c82SStefano Zampini TaoIsObjectiveDefined - Checks to see if the user has 600a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 60165ba42b6SBarry Smith it is appropriate to call `TaoComputeObjective()` or 60265ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` 603a7e14dcfSSatish Balay 604a82e8c82SStefano Zampini Not collective 605a7e14dcfSSatish Balay 606a82e8c82SStefano Zampini Input Parameter: 607*47450a7bSBarry Smith . tao - the `Tao` context 608a82e8c82SStefano Zampini 609a82e8c82SStefano Zampini Output Parameter: 61065ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 611a82e8c82SStefano Zampini 612a7e14dcfSSatish Balay Level: developer 613a7e14dcfSSatish Balay 614*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()` 615a7e14dcfSSatish Balay @*/ 616d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg) 617d71ae5a4SJacob Faibussowitsch { 618a7e14dcfSSatish Balay PetscFunctionBegin; 619441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 62083c8fe1dSLisandro Dalcin if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE; 62145cf516eSBarry Smith else *flg = PETSC_TRUE; 6223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 623a7e14dcfSSatish Balay } 624a7e14dcfSSatish Balay 625a7e14dcfSSatish Balay /*@ 626a82e8c82SStefano Zampini TaoIsGradientDefined - Checks to see if the user has 627a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 62865ba42b6SBarry Smith it is appropriate to call `TaoComputeGradient()` or 62965ba42b6SBarry Smith `TaoComputeGradientAndGradient()` 630a7e14dcfSSatish Balay 631a7e14dcfSSatish Balay Not Collective 632a7e14dcfSSatish Balay 633a82e8c82SStefano Zampini Input Parameter: 634*47450a7bSBarry Smith . tao - the `Tao` context 635a82e8c82SStefano Zampini 636a82e8c82SStefano Zampini Output Parameter: 63765ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 638a82e8c82SStefano Zampini 639a7e14dcfSSatish Balay Level: developer 640a7e14dcfSSatish Balay 641*47450a7bSBarry Smith .seealso: [](chapter_tao), `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()` 642a7e14dcfSSatish Balay @*/ 643d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg) 644d71ae5a4SJacob Faibussowitsch { 645a7e14dcfSSatish Balay PetscFunctionBegin; 646441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 64783c8fe1dSLisandro Dalcin if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE; 64845cf516eSBarry Smith else *flg = PETSC_TRUE; 6493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 650a7e14dcfSSatish Balay } 651a7e14dcfSSatish Balay 652a7e14dcfSSatish Balay /*@ 653a82e8c82SStefano Zampini TaoIsObjectiveAndGradientDefined - Checks to see if the user has 654a7e14dcfSSatish Balay declared a joint objective/gradient routine. Useful for determining when 65565ba42b6SBarry Smith it is appropriate to call `TaoComputeObjective()` or 65665ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` 657a7e14dcfSSatish Balay 658a7e14dcfSSatish Balay Not Collective 659a7e14dcfSSatish Balay 660a82e8c82SStefano Zampini Input Parameter: 661*47450a7bSBarry Smith . tao - the `Tao` context 662a82e8c82SStefano Zampini 663a82e8c82SStefano Zampini Output Parameter: 66465ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 665a82e8c82SStefano Zampini 666a7e14dcfSSatish Balay Level: developer 667a7e14dcfSSatish Balay 668*47450a7bSBarry Smith .seealso: [](chapter_tao), `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()` 669a7e14dcfSSatish Balay @*/ 670d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg) 671d71ae5a4SJacob Faibussowitsch { 672a7e14dcfSSatish Balay PetscFunctionBegin; 673441846f8SBarry Smith PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 67483c8fe1dSLisandro Dalcin if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE; 67545cf516eSBarry Smith else *flg = PETSC_TRUE; 6763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 677a7e14dcfSSatish Balay } 678