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 6441846f8SBarry Smith Logically collective on Tao 7a7e14dcfSSatish Balay 8a7e14dcfSSatish Balay Input Parameters: 9441846f8SBarry Smith + tao - the Tao context 10a7e14dcfSSatish Balay - x0 - the initial guess 11a7e14dcfSSatish Balay 12a7e14dcfSSatish Balay Level: beginner 13*db781477SPatrick Sanan .seealso: `TaoCreate()`, `TaoSolve()`, `TaoGetSolution()` 14a7e14dcfSSatish Balay @*/ 15a82e8c82SStefano Zampini PetscErrorCode TaoSetSolution(Tao tao, Vec x0) 1645cf516eSBarry Smith { 17a7e14dcfSSatish Balay PetscFunctionBegin; 18441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 19a82e8c82SStefano Zampini if (x0) PetscValidHeaderSpecific(x0,VEC_CLASSID,2); 209566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x0)); 219566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->solution)); 22a7e14dcfSSatish Balay tao->solution = x0; 23a7e14dcfSSatish Balay PetscFunctionReturn(0); 24a7e14dcfSSatish Balay } 25a7e14dcfSSatish Balay 26412cdd55SHong Zhang PetscErrorCode TaoTestGradient(Tao tao,Vec x,Vec g1) 2709baa881SHong Zhang { 28412cdd55SHong Zhang Vec g2,g3; 2909baa881SHong Zhang PetscBool complete_print = PETSC_FALSE,test = PETSC_FALSE; 3009baa881SHong Zhang PetscReal hcnorm,fdnorm,hcmax,fdmax,diffmax,diffnorm; 3109baa881SHong Zhang PetscScalar dot; 3209baa881SHong Zhang MPI_Comm comm; 33913eda9aSHong Zhang PetscViewer viewer,mviewer; 34913eda9aSHong Zhang PetscViewerFormat format; 3509baa881SHong Zhang PetscInt tabs; 3609baa881SHong Zhang static PetscBool directionsprinted = PETSC_FALSE; 3709baa881SHong Zhang 3809baa881SHong Zhang PetscFunctionBegin; 39d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)tao); 409566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-tao_test_gradient","Compare hand-coded and finite difference Gradients","None",&test)); 419566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-tao_test_gradient_view","View difference between hand-coded and finite difference Gradients element entries","None",&mviewer,&format,&complete_print)); 42d0609cedSBarry Smith PetscOptionsEnd(); 432f4b6201SAlp Dener if (!test) { 442f4b6201SAlp Dener if (complete_print) { 459566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&mviewer)); 462f4b6201SAlp Dener } 472f4b6201SAlp Dener PetscFunctionReturn(0); 482f4b6201SAlp Dener } 4909baa881SHong Zhang 509566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)tao,&comm)); 519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm,&viewer)); 529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel)); 549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," ---------- Testing Gradient -------------\n")); 5509baa881SHong Zhang if (!complete_print && !directionsprinted) { 569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Run with -tao_test_gradient_view and optionally -tao_test_gradient <threshold> to show difference\n")); 579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference gradient entries greater than <threshold>.\n")); 5809baa881SHong Zhang } 5909baa881SHong Zhang if (!directionsprinted) { 609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Testing hand-coded Gradient, if (for double precision runs) ||G - Gfd||/||G|| is\n")); 619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Gradient is probably correct.\n")); 6209baa881SHong Zhang directionsprinted = PETSC_TRUE; 6309baa881SHong Zhang } 64913eda9aSHong Zhang if (complete_print) { 659566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(mviewer,format)); 66913eda9aSHong Zhang } 6709baa881SHong Zhang 689566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x,&g2)); 699566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x,&g3)); 7009baa881SHong Zhang 7109baa881SHong Zhang /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */ 729566063dSJacob Faibussowitsch PetscCall(TaoDefaultComputeGradient(tao,x,g2,NULL)); 7309baa881SHong Zhang 749566063dSJacob Faibussowitsch PetscCall(VecNorm(g2,NORM_2,&fdnorm)); 759566063dSJacob Faibussowitsch PetscCall(VecNorm(g1,NORM_2,&hcnorm)); 769566063dSJacob Faibussowitsch PetscCall(VecNorm(g2,NORM_INFINITY,&fdmax)); 779566063dSJacob Faibussowitsch PetscCall(VecNorm(g1,NORM_INFINITY,&hcmax)); 789566063dSJacob Faibussowitsch PetscCall(VecDot(g1,g2,&dot)); 799566063dSJacob Faibussowitsch PetscCall(VecCopy(g1,g3)); 809566063dSJacob Faibussowitsch PetscCall(VecAXPY(g3,-1.0,g2)); 819566063dSJacob Faibussowitsch PetscCall(VecNorm(g3,NORM_2,&diffnorm)); 829566063dSJacob Faibussowitsch PetscCall(VecNorm(g3,NORM_INFINITY,&diffmax)); 839566063dSJacob 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)))); 849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," 2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffnorm/PetscMax(hcnorm,fdnorm)),(double)diffnorm)); 859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffmax/PetscMax(hcmax,fdmax)),(double)diffmax)); 8609baa881SHong Zhang 8709baa881SHong Zhang if (complete_print) { 889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Hand-coded gradient ----------\n")); 899566063dSJacob Faibussowitsch PetscCall(VecView(g1,mviewer)); 909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Finite difference gradient ----------\n")); 919566063dSJacob Faibussowitsch PetscCall(VecView(g2,mviewer)); 929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference gradient ----------\n")); 939566063dSJacob Faibussowitsch PetscCall(VecView(g3,mviewer)); 9409baa881SHong Zhang } 959566063dSJacob Faibussowitsch PetscCall(VecDestroy(&g2)); 969566063dSJacob Faibussowitsch PetscCall(VecDestroy(&g3)); 97913eda9aSHong Zhang 98913eda9aSHong Zhang if (complete_print) { 999566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(mviewer)); 1009566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&mviewer)); 101913eda9aSHong Zhang } 1029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,tabs)); 10309baa881SHong Zhang PetscFunctionReturn(0); 10409baa881SHong Zhang } 10509baa881SHong Zhang 106a7e14dcfSSatish Balay /*@ 107a7e14dcfSSatish Balay TaoComputeGradient - Computes the gradient of the objective function 108a7e14dcfSSatish Balay 109441846f8SBarry Smith Collective on Tao 110a7e14dcfSSatish Balay 111a7e14dcfSSatish Balay Input Parameters: 112441846f8SBarry Smith + tao - the Tao context 113a7e14dcfSSatish Balay - X - input vector 114a7e14dcfSSatish Balay 115a7e14dcfSSatish Balay Output Parameter: 116a7e14dcfSSatish Balay . G - gradient vector 117a7e14dcfSSatish Balay 11809baa881SHong Zhang Options Database Keys: 11909baa881SHong Zhang + -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors 120dfe02fe6SHong 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 12109baa881SHong Zhang 12295452b02SPatrick Sanan Notes: 12395452b02SPatrick Sanan TaoComputeGradient() is typically used within minimization implementations, 124a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 125a7e14dcfSSatish Balay 126a7e14dcfSSatish Balay Level: advanced 127a7e14dcfSSatish Balay 128*db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetGradient()` 129a7e14dcfSSatish Balay @*/ 130441846f8SBarry Smith PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G) 131a7e14dcfSSatish Balay { 132a7e14dcfSSatish Balay PetscReal dummy; 13387f595a5SBarry Smith 134a7e14dcfSSatish Balay PetscFunctionBegin; 135441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 136a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 137064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(G,VEC_CLASSID,3); 138a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 139a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,G,3); 1409566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 141a7e14dcfSSatish Balay if (tao->ops->computegradient) { 1429566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL)); 143441846f8SBarry Smith PetscStackPush("Tao user gradient evaluation routine"); 1449566063dSJacob Faibussowitsch PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP)); 145a7e14dcfSSatish Balay PetscStackPop; 1469566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL)); 147a7e14dcfSSatish Balay tao->ngrads++; 148a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 1499566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL)); 150a7e14dcfSSatish Balay PetscStackPush("Tao user objective/gradient evaluation routine"); 1519566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP)); 152a7e14dcfSSatish Balay PetscStackPop; 1539566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL)); 154a7e14dcfSSatish Balay tao->nfuncgrads++; 155a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradient() has not been called"); 1569566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 15709baa881SHong Zhang 1589566063dSJacob Faibussowitsch PetscCall(TaoTestGradient(tao,X,G)); 159a7e14dcfSSatish Balay PetscFunctionReturn(0); 160a7e14dcfSSatish Balay } 161a7e14dcfSSatish Balay 162a7e14dcfSSatish Balay /*@ 163a7e14dcfSSatish Balay TaoComputeObjective - Computes the objective function value at a given point 164a7e14dcfSSatish Balay 165441846f8SBarry Smith Collective on Tao 166a7e14dcfSSatish Balay 167a7e14dcfSSatish Balay Input Parameters: 168441846f8SBarry Smith + tao - the Tao context 169a7e14dcfSSatish Balay - X - input vector 170a7e14dcfSSatish Balay 171a7e14dcfSSatish Balay Output Parameter: 172a7e14dcfSSatish Balay . f - Objective value at X 173a7e14dcfSSatish Balay 17495452b02SPatrick Sanan Notes: 17595452b02SPatrick Sanan TaoComputeObjective() is typically used within minimization implementations, 176a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 177a7e14dcfSSatish Balay 178a7e14dcfSSatish Balay Level: advanced 179a7e14dcfSSatish Balay 180*db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()` 181a7e14dcfSSatish Balay @*/ 182441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f) 183a7e14dcfSSatish Balay { 184a7e14dcfSSatish Balay Vec temp; 18587f595a5SBarry Smith 186a7e14dcfSSatish Balay PetscFunctionBegin; 187441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 188a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 189a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 1909566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 191a7e14dcfSSatish Balay if (tao->ops->computeobjective) { 1929566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 193441846f8SBarry Smith PetscStackPush("Tao user objective evaluation routine"); 1949566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP)); 195a7e14dcfSSatish Balay PetscStackPop; 1969566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 197a7e14dcfSSatish Balay tao->nfuncs++; 198a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 1999566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n")); 2009566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X,&temp)); 2019566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,NULL,NULL)); 202441846f8SBarry Smith PetscStackPush("Tao user objective/gradient evaluation routine"); 2039566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP)); 204a7e14dcfSSatish Balay PetscStackPop; 2059566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,NULL,NULL)); 2069566063dSJacob Faibussowitsch PetscCall(VecDestroy(&temp)); 207a7e14dcfSSatish Balay tao->nfuncgrads++; 208a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() has not been called"); 2099566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f))); 2109566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 211a7e14dcfSSatish Balay PetscFunctionReturn(0); 212a7e14dcfSSatish Balay } 213a7e14dcfSSatish Balay 214a7e14dcfSSatish Balay /*@ 215a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient - Computes the objective function value at a given point 216a7e14dcfSSatish Balay 217441846f8SBarry Smith Collective on Tao 218a7e14dcfSSatish Balay 219a7e14dcfSSatish Balay Input Parameters: 220441846f8SBarry Smith + tao - the Tao context 221a7e14dcfSSatish Balay - X - input vector 222a7e14dcfSSatish Balay 223d8d19677SJose E. Roman Output Parameters: 224a7e14dcfSSatish Balay + f - Objective value at X 225a7e14dcfSSatish Balay - g - Gradient vector at X 226a7e14dcfSSatish Balay 22795452b02SPatrick Sanan Notes: 22895452b02SPatrick Sanan TaoComputeObjectiveAndGradient() is typically used within minimization implementations, 229a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 230a7e14dcfSSatish Balay 231a7e14dcfSSatish Balay Level: advanced 232a7e14dcfSSatish Balay 233*db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()` 234a7e14dcfSSatish Balay @*/ 235441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G) 236a7e14dcfSSatish Balay { 237a7e14dcfSSatish Balay PetscFunctionBegin; 238441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 239a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 240a7e14dcfSSatish Balay PetscValidHeaderSpecific(G,VEC_CLASSID,4); 241a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 242a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,G,4); 2439566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 244a7e14dcfSSatish Balay if (tao->ops->computeobjectiveandgradient) { 2459566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL)); 246f4c1ad5cSStefano Zampini if (tao->ops->computegradient == TaoDefaultComputeGradient) { 2479566063dSJacob Faibussowitsch PetscCall(TaoComputeObjective(tao,X,f)); 2489566063dSJacob Faibussowitsch PetscCall(TaoDefaultComputeGradient(tao,X,G,NULL)); 249f4c1ad5cSStefano Zampini } else { 250441846f8SBarry Smith PetscStackPush("Tao user objective/gradient evaluation routine"); 2519566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP)); 2520cbffdbaSBarry Smith PetscStackPop; 253a7e14dcfSSatish Balay } 2549566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL)); 255a7e14dcfSSatish Balay tao->nfuncgrads++; 256a7e14dcfSSatish Balay } else if (tao->ops->computeobjective && tao->ops->computegradient) { 2579566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 258441846f8SBarry Smith PetscStackPush("Tao user objective evaluation routine"); 2599566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP)); 260a7e14dcfSSatish Balay PetscStackPop; 2619566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 262a7e14dcfSSatish Balay tao->nfuncs++; 2639566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL)); 264441846f8SBarry Smith PetscStackPush("Tao user gradient evaluation routine"); 2659566063dSJacob Faibussowitsch PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP)); 266a7e14dcfSSatish Balay PetscStackPop; 2679566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL)); 268a7e14dcfSSatish Balay tao->ngrads++; 269a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() or TaoSetGradient() not set"); 2709566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f))); 2719566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 2721657496cSHong Zhang 2739566063dSJacob Faibussowitsch PetscCall(TaoTestGradient(tao,X,G)); 274a7e14dcfSSatish Balay PetscFunctionReturn(0); 275a7e14dcfSSatish Balay } 276a7e14dcfSSatish Balay 277a7e14dcfSSatish Balay /*@C 278a82e8c82SStefano Zampini TaoSetObjective - Sets the function evaluation routine for minimization 279a7e14dcfSSatish Balay 280441846f8SBarry Smith Logically collective on Tao 281a7e14dcfSSatish Balay 282d8d19677SJose E. Roman Input Parameters: 283441846f8SBarry Smith + tao - the Tao context 284a7e14dcfSSatish Balay . func - the objective function 285a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 2866c23d075SBarry Smith routine (may be NULL) 287a7e14dcfSSatish Balay 288a7e14dcfSSatish Balay Calling sequence of func: 289441846f8SBarry Smith $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 290a7e14dcfSSatish Balay 291a7e14dcfSSatish Balay + x - input vector 292a7e14dcfSSatish Balay . f - function value 293a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 294a7e14dcfSSatish Balay 295a7e14dcfSSatish Balay Level: beginner 296a7e14dcfSSatish Balay 297*db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetObjective()` 298a7e14dcfSSatish Balay @*/ 299a82e8c82SStefano Zampini PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx) 300a7e14dcfSSatish Balay { 301a7e14dcfSSatish Balay PetscFunctionBegin; 302441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 303a82e8c82SStefano Zampini if (ctx) tao->user_objP = ctx; 304a82e8c82SStefano Zampini if (func) tao->ops->computeobjective = func; 305a82e8c82SStefano Zampini PetscFunctionReturn(0); 306a82e8c82SStefano Zampini } 307a82e8c82SStefano Zampini 308a82e8c82SStefano Zampini /*@C 309a82e8c82SStefano Zampini TaoGetObjective - Gets the function evaluation routine for minimization 310a82e8c82SStefano Zampini 311a82e8c82SStefano Zampini Not collective 312a82e8c82SStefano Zampini 313a82e8c82SStefano Zampini Input Parameter: 314a82e8c82SStefano Zampini . tao - the Tao context 315a82e8c82SStefano Zampini 316a82e8c82SStefano Zampini Output Parameters 317a82e8c82SStefano Zampini + func - the objective function 318a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation 319a82e8c82SStefano Zampini 320a82e8c82SStefano Zampini Calling sequence of func: 321a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 322a82e8c82SStefano Zampini 323a82e8c82SStefano Zampini + x - input vector 324a82e8c82SStefano Zampini . f - function value 325a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 326a82e8c82SStefano Zampini 327a82e8c82SStefano Zampini Level: beginner 328a82e8c82SStefano Zampini 329*db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjective()` 330a82e8c82SStefano Zampini @*/ 331a82e8c82SStefano Zampini PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal*,void*),void **ctx) 332a82e8c82SStefano Zampini { 333a82e8c82SStefano Zampini PetscFunctionBegin; 334a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 335a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjective; 336a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objP; 337a7e14dcfSSatish Balay PetscFunctionReturn(0); 338a7e14dcfSSatish Balay } 339a7e14dcfSSatish Balay 340a7e14dcfSSatish Balay /*@C 3414a48860cSAlp Dener TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications 342a7e14dcfSSatish Balay 343441846f8SBarry Smith Logically collective on Tao 344a7e14dcfSSatish Balay 345d8d19677SJose E. Roman Input Parameters: 346441846f8SBarry Smith + tao - the Tao context 3474a48860cSAlp Dener . func - the residual evaluation routine 348a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 3496c23d075SBarry Smith routine (may be NULL) 350a7e14dcfSSatish Balay 351a7e14dcfSSatish Balay Calling sequence of func: 352441846f8SBarry Smith $ func (Tao tao, Vec x, Vec f, void *ctx); 353a7e14dcfSSatish Balay 354a7e14dcfSSatish Balay + x - input vector 355a7e14dcfSSatish Balay . f - function value vector 356a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 357a7e14dcfSSatish Balay 358a7e14dcfSSatish Balay Level: beginner 359a7e14dcfSSatish Balay 360*db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetJacobianRoutine()` 361a7e14dcfSSatish Balay @*/ 3624a48860cSAlp Dener PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 363a7e14dcfSSatish Balay { 364a7e14dcfSSatish Balay PetscFunctionBegin; 365441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 3664a48860cSAlp Dener PetscValidHeaderSpecific(res,VEC_CLASSID,2); 3679566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)res)); 368737f463aSAlp Dener if (tao->ls_res) { 3699566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->ls_res)); 370737f463aSAlp Dener } 3714a48860cSAlp Dener tao->ls_res = res; 3724ffbe8acSAlp Dener tao->user_lsresP = ctx; 3734a48860cSAlp Dener tao->ops->computeresidual = func; 374737f463aSAlp Dener 375737f463aSAlp Dener PetscFunctionReturn(0); 376737f463aSAlp Dener } 377737f463aSAlp Dener 378737f463aSAlp Dener /*@ 379737f463aSAlp Dener TaoSetResidualWeights - Give weights for the residual values. A vector can be used if only diagonal terms are used, otherwise a matrix can be give. If this function is not used, or if sigma_v and sigma_w are both NULL, then the default identity matrix will be used for weights. 380737f463aSAlp Dener 381737f463aSAlp Dener Collective on Tao 382737f463aSAlp Dener 383737f463aSAlp Dener Input Parameters: 384737f463aSAlp Dener + tao - the Tao context 385737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only) 386737f463aSAlp Dener . n - the number of weights (if using off-diagonal) 387737f463aSAlp Dener . rows - index list of rows for sigma_w 388737f463aSAlp Dener . cols - index list of columns for sigma_w 389737f463aSAlp Dener - vals - array of weights 390737f463aSAlp Dener 391737f463aSAlp Dener Note: Either sigma_v or sigma_w (or both) should be NULL 392737f463aSAlp Dener 393737f463aSAlp Dener Level: intermediate 394737f463aSAlp Dener 395*db781477SPatrick Sanan .seealso: `TaoSetResidualRoutine()` 396737f463aSAlp Dener @*/ 397737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals) 398737f463aSAlp Dener { 399737f463aSAlp Dener PetscInt i; 400a82e8c82SStefano Zampini 401737f463aSAlp Dener PetscFunctionBegin; 402737f463aSAlp Dener PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 403a82e8c82SStefano Zampini if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2); 4049566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sigma_v)); 4059566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->res_weights_v)); 4064ffbe8acSAlp Dener tao->res_weights_v = sigma_v; 407737f463aSAlp Dener if (vals) { 4089566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_rows)); 4099566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_cols)); 4109566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_w)); 4119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_rows)); 4129566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_cols)); 4139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_w)); 414737f463aSAlp Dener tao->res_weights_n = n; 415737f463aSAlp Dener for (i=0;i<n;i++) { 416737f463aSAlp Dener tao->res_weights_rows[i] = rows[i]; 417737f463aSAlp Dener tao->res_weights_cols[i] = cols[i]; 418737f463aSAlp Dener tao->res_weights_w[i] = vals[i]; 419737f463aSAlp Dener } 420737f463aSAlp Dener } else { 421737f463aSAlp Dener tao->res_weights_n = 0; 42283c8fe1dSLisandro Dalcin tao->res_weights_rows = NULL; 42383c8fe1dSLisandro Dalcin tao->res_weights_cols = NULL; 424737f463aSAlp Dener } 425a7e14dcfSSatish Balay PetscFunctionReturn(0); 426a7e14dcfSSatish Balay } 427a7e14dcfSSatish Balay 4288b7a9b22SJason Sarich /*@ 4294a48860cSAlp Dener TaoComputeResidual - Computes a least-squares residual vector at a given point 430a7e14dcfSSatish Balay 431441846f8SBarry Smith Collective on Tao 432a7e14dcfSSatish Balay 433a7e14dcfSSatish Balay Input Parameters: 434441846f8SBarry Smith + tao - the Tao context 435a7e14dcfSSatish Balay - X - input vector 436a7e14dcfSSatish Balay 437a7e14dcfSSatish Balay Output Parameter: 438a7e14dcfSSatish Balay . f - Objective vector at X 439a7e14dcfSSatish Balay 44095452b02SPatrick Sanan Notes: 4414a48860cSAlp Dener TaoComputeResidual() is typically used within minimization implementations, 442a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 443a7e14dcfSSatish Balay 444a7e14dcfSSatish Balay Level: advanced 445a7e14dcfSSatish Balay 446*db781477SPatrick Sanan .seealso: `TaoSetResidualRoutine()` 447a7e14dcfSSatish Balay @*/ 4484a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F) 449a7e14dcfSSatish Balay { 450a7e14dcfSSatish Balay PetscFunctionBegin; 451441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 452a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 453a7e14dcfSSatish Balay PetscValidHeaderSpecific(F,VEC_CLASSID,3); 454a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 455a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,F,3); 4564a48860cSAlp Dener if (tao->ops->computeresidual) { 4579566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 4584a48860cSAlp Dener PetscStackPush("Tao user least-squares residual evaluation routine"); 4599566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP)); 460a7e14dcfSSatish Balay PetscStackPop; 4619566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 462a7e14dcfSSatish Balay tao->nfuncs++; 463691b26d3SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called"); 4649566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO least-squares residual evaluation.\n")); 465a7e14dcfSSatish Balay PetscFunctionReturn(0); 466a7e14dcfSSatish Balay } 467a7e14dcfSSatish Balay 468a7e14dcfSSatish Balay /*@C 469a82e8c82SStefano Zampini TaoSetGradient - Sets the gradient evaluation routine for minimization 470a7e14dcfSSatish Balay 471441846f8SBarry Smith Logically collective on Tao 472a7e14dcfSSatish Balay 473d8d19677SJose E. Roman Input Parameters: 474441846f8SBarry Smith + tao - the Tao context 475a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 476a7e14dcfSSatish Balay . func - the gradient function 477a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 4786c23d075SBarry Smith routine (may be NULL) 479a7e14dcfSSatish Balay 480a7e14dcfSSatish Balay Calling sequence of func: 481441846f8SBarry Smith $ func (Tao tao, Vec x, Vec g, void *ctx); 482a7e14dcfSSatish Balay 483a7e14dcfSSatish Balay + x - input vector 484a7e14dcfSSatish Balay . g - gradient value (output) 485a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 486a7e14dcfSSatish Balay 487a7e14dcfSSatish Balay Level: beginner 488a7e14dcfSSatish Balay 489*db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()` 490a7e14dcfSSatish Balay @*/ 491a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 492a7e14dcfSSatish Balay { 493a7e14dcfSSatish Balay PetscFunctionBegin; 494441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 495a82e8c82SStefano Zampini if (g) { 496a82e8c82SStefano Zampini PetscValidHeaderSpecific(g,VEC_CLASSID,2); 497a82e8c82SStefano Zampini PetscCheckSameComm(tao,1,g,2); 4989566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 4999566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 500a82e8c82SStefano Zampini tao->gradient = g; 501a82e8c82SStefano Zampini } 502a82e8c82SStefano Zampini if (func) tao->ops->computegradient = func; 503a82e8c82SStefano Zampini if (ctx) tao->user_gradP = ctx; 504a7e14dcfSSatish Balay PetscFunctionReturn(0); 505a7e14dcfSSatish Balay } 506a7e14dcfSSatish Balay 507a7e14dcfSSatish Balay /*@C 508a82e8c82SStefano Zampini TaoGetGradient - Gets the gradient evaluation routine for minimization 509a82e8c82SStefano Zampini 510a82e8c82SStefano Zampini Not collective 511a82e8c82SStefano Zampini 512a82e8c82SStefano Zampini Input Parameter: 513a82e8c82SStefano Zampini . tao - the Tao context 514a82e8c82SStefano Zampini 515a82e8c82SStefano Zampini Output Parameters: 516a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation 517a82e8c82SStefano Zampini . func - the gradient function 518a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 519a82e8c82SStefano Zampini 520a82e8c82SStefano Zampini Calling sequence of func: 521a82e8c82SStefano Zampini $ func (Tao tao, Vec x, Vec g, void *ctx); 522a82e8c82SStefano Zampini 523a82e8c82SStefano Zampini + x - input vector 524a82e8c82SStefano Zampini . g - gradient value (output) 525a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 526a82e8c82SStefano Zampini 527a82e8c82SStefano Zampini Level: beginner 528a82e8c82SStefano Zampini 529*db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()` 530a82e8c82SStefano Zampini @*/ 531a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx) 532a82e8c82SStefano Zampini { 533a82e8c82SStefano Zampini PetscFunctionBegin; 534a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 535a82e8c82SStefano Zampini if (g) *g = tao->gradient; 536a82e8c82SStefano Zampini if (func) *func = tao->ops->computegradient; 537a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_gradP; 538a82e8c82SStefano Zampini PetscFunctionReturn(0); 539a82e8c82SStefano Zampini } 540a82e8c82SStefano Zampini 541a82e8c82SStefano Zampini /*@C 542a82e8c82SStefano Zampini TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for minimization 543a7e14dcfSSatish Balay 544441846f8SBarry Smith Logically collective on Tao 545a7e14dcfSSatish Balay 546d8d19677SJose E. Roman Input Parameters: 547441846f8SBarry Smith + tao - the Tao context 548a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 549a7e14dcfSSatish Balay . func - the gradient function 550a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 5516c23d075SBarry Smith routine (may be NULL) 552a7e14dcfSSatish Balay 553a7e14dcfSSatish Balay Calling sequence of func: 55417477c02SJason Sarich $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 555a7e14dcfSSatish Balay 556a7e14dcfSSatish Balay + x - input vector 55717477c02SJason Sarich . f - objective value (output) 558a7e14dcfSSatish Balay . g - gradient value (output) 559a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 560a7e14dcfSSatish Balay 561a7e14dcfSSatish Balay Level: beginner 562a7e14dcfSSatish Balay 563*db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()` 564a7e14dcfSSatish Balay @*/ 565a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx) 566a82e8c82SStefano Zampini { 567a82e8c82SStefano Zampini PetscFunctionBegin; 568a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 569a82e8c82SStefano Zampini if (g) { 570a82e8c82SStefano Zampini PetscValidHeaderSpecific(g,VEC_CLASSID,2); 571a82e8c82SStefano Zampini PetscCheckSameComm(tao,1,g,2); 5729566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 5739566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 574a82e8c82SStefano Zampini tao->gradient = g; 575a82e8c82SStefano Zampini } 576a82e8c82SStefano Zampini if (ctx) tao->user_objgradP = ctx; 577a82e8c82SStefano Zampini if (func) tao->ops->computeobjectiveandgradient = func; 578a82e8c82SStefano Zampini PetscFunctionReturn(0); 579a82e8c82SStefano Zampini } 580a82e8c82SStefano Zampini 581a82e8c82SStefano Zampini /*@C 582a82e8c82SStefano Zampini TaoGetObjectiveAndGradient - Gets a combined objective function and gradient evaluation routine for minimization 583a82e8c82SStefano Zampini 584a82e8c82SStefano Zampini Not collective 585a82e8c82SStefano Zampini 586a82e8c82SStefano Zampini Input Parameter: 587a82e8c82SStefano Zampini . tao - the Tao context 588a82e8c82SStefano Zampini 589a82e8c82SStefano Zampini Output Parameters: 590817da375SSatish Balay + g - the vector to internally hold the gradient computation 591a82e8c82SStefano Zampini . func - the gradient function 592a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 593a82e8c82SStefano Zampini 594a82e8c82SStefano Zampini Calling sequence of func: 595a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 596a82e8c82SStefano Zampini 597a82e8c82SStefano Zampini + x - input vector 598a82e8c82SStefano Zampini . f - objective value (output) 599a82e8c82SStefano Zampini . g - gradient value (output) 600a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 601a82e8c82SStefano Zampini 602a82e8c82SStefano Zampini Level: beginner 603a82e8c82SStefano Zampini 604*db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()` 605a82e8c82SStefano Zampini @*/ 606a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx) 607a7e14dcfSSatish Balay { 608a7e14dcfSSatish Balay PetscFunctionBegin; 609441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 610a82e8c82SStefano Zampini if (g) *g = tao->gradient; 611a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjectiveandgradient; 612a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objgradP; 613a7e14dcfSSatish Balay PetscFunctionReturn(0); 614a7e14dcfSSatish Balay } 615a7e14dcfSSatish Balay 616a7e14dcfSSatish Balay /*@ 617a82e8c82SStefano Zampini TaoIsObjectiveDefined - Checks to see if the user has 618a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 619a7e14dcfSSatish Balay it is appropriate to call TaoComputeObjective() or 620a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient() 621a7e14dcfSSatish Balay 622a82e8c82SStefano Zampini Not collective 623a7e14dcfSSatish Balay 624a82e8c82SStefano Zampini Input Parameter: 625a82e8c82SStefano Zampini . tao - the Tao context 626a82e8c82SStefano Zampini 627a82e8c82SStefano Zampini Output Parameter: 628f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise 629a82e8c82SStefano Zampini 630a7e14dcfSSatish Balay Level: developer 631a7e14dcfSSatish Balay 632*db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()` 633a7e14dcfSSatish Balay @*/ 634441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg) 635a7e14dcfSSatish Balay { 636a7e14dcfSSatish Balay PetscFunctionBegin; 637441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 63883c8fe1dSLisandro Dalcin if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE; 63945cf516eSBarry Smith else *flg = PETSC_TRUE; 640a7e14dcfSSatish Balay PetscFunctionReturn(0); 641a7e14dcfSSatish Balay } 642a7e14dcfSSatish Balay 643a7e14dcfSSatish Balay /*@ 644a82e8c82SStefano Zampini TaoIsGradientDefined - Checks to see if the user has 645a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 646a7e14dcfSSatish Balay it is appropriate to call TaoComputeGradient() or 647a7e14dcfSSatish Balay TaoComputeGradientAndGradient() 648a7e14dcfSSatish Balay 649a7e14dcfSSatish Balay Not Collective 650a7e14dcfSSatish Balay 651a82e8c82SStefano Zampini Input Parameter: 652a82e8c82SStefano Zampini . tao - the Tao context 653a82e8c82SStefano Zampini 654a82e8c82SStefano Zampini Output Parameter: 655f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise 656a82e8c82SStefano Zampini 657a7e14dcfSSatish Balay Level: developer 658a7e14dcfSSatish Balay 659*db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()` 660a7e14dcfSSatish Balay @*/ 661441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg) 662a7e14dcfSSatish Balay { 663a7e14dcfSSatish Balay PetscFunctionBegin; 664441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 66583c8fe1dSLisandro Dalcin if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE; 66645cf516eSBarry Smith else *flg = PETSC_TRUE; 667a7e14dcfSSatish Balay PetscFunctionReturn(0); 668a7e14dcfSSatish Balay } 669a7e14dcfSSatish Balay 670a7e14dcfSSatish Balay /*@ 671a82e8c82SStefano Zampini TaoIsObjectiveAndGradientDefined - Checks to see if the user has 672a7e14dcfSSatish Balay declared a joint objective/gradient routine. Useful for determining when 673a7e14dcfSSatish Balay it is appropriate to call TaoComputeObjective() or 674a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient() 675a7e14dcfSSatish Balay 676a7e14dcfSSatish Balay Not Collective 677a7e14dcfSSatish Balay 678a82e8c82SStefano Zampini Input Parameter: 679a82e8c82SStefano Zampini . tao - the Tao context 680a82e8c82SStefano Zampini 681a82e8c82SStefano Zampini Output Parameter: 682f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise 683a82e8c82SStefano Zampini 684a7e14dcfSSatish Balay Level: developer 685a7e14dcfSSatish Balay 686*db781477SPatrick Sanan .seealso: `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()` 687a7e14dcfSSatish Balay @*/ 688441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg) 689a7e14dcfSSatish Balay { 690a7e14dcfSSatish Balay PetscFunctionBegin; 691441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 69283c8fe1dSLisandro Dalcin if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE; 69345cf516eSBarry Smith else *flg = PETSC_TRUE; 694a7e14dcfSSatish Balay PetscFunctionReturn(0); 695a7e14dcfSSatish Balay } 696