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 13db781477SPatrick 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 } 64*1baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer,format)); 6509baa881SHong Zhang 669566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x,&g2)); 679566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x,&g3)); 6809baa881SHong Zhang 6909baa881SHong Zhang /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */ 709566063dSJacob Faibussowitsch PetscCall(TaoDefaultComputeGradient(tao,x,g2,NULL)); 7109baa881SHong Zhang 729566063dSJacob Faibussowitsch PetscCall(VecNorm(g2,NORM_2,&fdnorm)); 739566063dSJacob Faibussowitsch PetscCall(VecNorm(g1,NORM_2,&hcnorm)); 749566063dSJacob Faibussowitsch PetscCall(VecNorm(g2,NORM_INFINITY,&fdmax)); 759566063dSJacob Faibussowitsch PetscCall(VecNorm(g1,NORM_INFINITY,&hcmax)); 769566063dSJacob Faibussowitsch PetscCall(VecDot(g1,g2,&dot)); 779566063dSJacob Faibussowitsch PetscCall(VecCopy(g1,g3)); 789566063dSJacob Faibussowitsch PetscCall(VecAXPY(g3,-1.0,g2)); 799566063dSJacob Faibussowitsch PetscCall(VecNorm(g3,NORM_2,&diffnorm)); 809566063dSJacob Faibussowitsch PetscCall(VecNorm(g3,NORM_INFINITY,&diffmax)); 819566063dSJacob 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)))); 829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," 2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffnorm/PetscMax(hcnorm,fdnorm)),(double)diffnorm)); 839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffmax/PetscMax(hcmax,fdmax)),(double)diffmax)); 8409baa881SHong Zhang 8509baa881SHong Zhang if (complete_print) { 869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Hand-coded gradient ----------\n")); 879566063dSJacob Faibussowitsch PetscCall(VecView(g1,mviewer)); 889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Finite difference gradient ----------\n")); 899566063dSJacob Faibussowitsch PetscCall(VecView(g2,mviewer)); 909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference gradient ----------\n")); 919566063dSJacob Faibussowitsch PetscCall(VecView(g3,mviewer)); 9209baa881SHong Zhang } 939566063dSJacob Faibussowitsch PetscCall(VecDestroy(&g2)); 949566063dSJacob Faibussowitsch PetscCall(VecDestroy(&g3)); 95913eda9aSHong Zhang 96913eda9aSHong Zhang if (complete_print) { 979566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(mviewer)); 989566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&mviewer)); 99913eda9aSHong Zhang } 1009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,tabs)); 10109baa881SHong Zhang PetscFunctionReturn(0); 10209baa881SHong Zhang } 10309baa881SHong Zhang 104a7e14dcfSSatish Balay /*@ 105a7e14dcfSSatish Balay TaoComputeGradient - Computes the gradient of the objective function 106a7e14dcfSSatish Balay 107441846f8SBarry Smith Collective on Tao 108a7e14dcfSSatish Balay 109a7e14dcfSSatish Balay Input Parameters: 110441846f8SBarry Smith + tao - the Tao context 111a7e14dcfSSatish Balay - X - input vector 112a7e14dcfSSatish Balay 113a7e14dcfSSatish Balay Output Parameter: 114a7e14dcfSSatish Balay . G - gradient vector 115a7e14dcfSSatish Balay 11609baa881SHong Zhang Options Database Keys: 11709baa881SHong Zhang + -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors 118dfe02fe6SHong 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 11909baa881SHong Zhang 12095452b02SPatrick Sanan Notes: 12195452b02SPatrick Sanan TaoComputeGradient() is typically used within minimization implementations, 122a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 123a7e14dcfSSatish Balay 124a7e14dcfSSatish Balay Level: advanced 125a7e14dcfSSatish Balay 126db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetGradient()` 127a7e14dcfSSatish Balay @*/ 128441846f8SBarry Smith PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G) 129a7e14dcfSSatish Balay { 130a7e14dcfSSatish Balay PetscReal dummy; 13187f595a5SBarry Smith 132a7e14dcfSSatish Balay PetscFunctionBegin; 133441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 134a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 135064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(G,VEC_CLASSID,3); 136a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 137a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,G,3); 1389566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 139a7e14dcfSSatish Balay if (tao->ops->computegradient) { 1409566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL)); 141441846f8SBarry Smith PetscStackPush("Tao user gradient evaluation routine"); 1429566063dSJacob Faibussowitsch PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP)); 143a7e14dcfSSatish Balay PetscStackPop; 1449566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL)); 145a7e14dcfSSatish Balay tao->ngrads++; 146a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 1479566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL)); 148a7e14dcfSSatish Balay PetscStackPush("Tao user objective/gradient evaluation routine"); 1499566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP)); 150a7e14dcfSSatish Balay PetscStackPop; 1519566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL)); 152a7e14dcfSSatish Balay tao->nfuncgrads++; 153a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradient() has not been called"); 1549566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 15509baa881SHong Zhang 1569566063dSJacob Faibussowitsch PetscCall(TaoTestGradient(tao,X,G)); 157a7e14dcfSSatish Balay PetscFunctionReturn(0); 158a7e14dcfSSatish Balay } 159a7e14dcfSSatish Balay 160a7e14dcfSSatish Balay /*@ 161a7e14dcfSSatish Balay TaoComputeObjective - Computes the objective function value at a given point 162a7e14dcfSSatish Balay 163441846f8SBarry Smith Collective on Tao 164a7e14dcfSSatish Balay 165a7e14dcfSSatish Balay Input Parameters: 166441846f8SBarry Smith + tao - the Tao context 167a7e14dcfSSatish Balay - X - input vector 168a7e14dcfSSatish Balay 169a7e14dcfSSatish Balay Output Parameter: 170a7e14dcfSSatish Balay . f - Objective value at X 171a7e14dcfSSatish Balay 17295452b02SPatrick Sanan Notes: 17395452b02SPatrick Sanan TaoComputeObjective() is typically used within minimization implementations, 174a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 175a7e14dcfSSatish Balay 176a7e14dcfSSatish Balay Level: advanced 177a7e14dcfSSatish Balay 178db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()` 179a7e14dcfSSatish Balay @*/ 180441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f) 181a7e14dcfSSatish Balay { 182a7e14dcfSSatish Balay Vec temp; 18387f595a5SBarry Smith 184a7e14dcfSSatish Balay PetscFunctionBegin; 185441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 186a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 187a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 1889566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 189a7e14dcfSSatish Balay if (tao->ops->computeobjective) { 1909566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 191441846f8SBarry Smith PetscStackPush("Tao user objective evaluation routine"); 1929566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP)); 193a7e14dcfSSatish Balay PetscStackPop; 1949566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 195a7e14dcfSSatish Balay tao->nfuncs++; 196a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 1979566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n")); 1989566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X,&temp)); 1999566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,NULL,NULL)); 200441846f8SBarry Smith PetscStackPush("Tao user objective/gradient evaluation routine"); 2019566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP)); 202a7e14dcfSSatish Balay PetscStackPop; 2039566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,NULL,NULL)); 2049566063dSJacob Faibussowitsch PetscCall(VecDestroy(&temp)); 205a7e14dcfSSatish Balay tao->nfuncgrads++; 206a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() has not been called"); 2079566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f))); 2089566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 209a7e14dcfSSatish Balay PetscFunctionReturn(0); 210a7e14dcfSSatish Balay } 211a7e14dcfSSatish Balay 212a7e14dcfSSatish Balay /*@ 213a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient - Computes the objective function value at a given point 214a7e14dcfSSatish Balay 215441846f8SBarry Smith Collective on Tao 216a7e14dcfSSatish Balay 217a7e14dcfSSatish Balay Input Parameters: 218441846f8SBarry Smith + tao - the Tao context 219a7e14dcfSSatish Balay - X - input vector 220a7e14dcfSSatish Balay 221d8d19677SJose E. Roman Output Parameters: 222a7e14dcfSSatish Balay + f - Objective value at X 223a7e14dcfSSatish Balay - g - Gradient vector at X 224a7e14dcfSSatish Balay 22595452b02SPatrick Sanan Notes: 22695452b02SPatrick Sanan TaoComputeObjectiveAndGradient() is typically used within minimization implementations, 227a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 228a7e14dcfSSatish Balay 229a7e14dcfSSatish Balay Level: advanced 230a7e14dcfSSatish Balay 231db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()` 232a7e14dcfSSatish Balay @*/ 233441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G) 234a7e14dcfSSatish Balay { 235a7e14dcfSSatish Balay PetscFunctionBegin; 236441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 237a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 238a7e14dcfSSatish Balay PetscValidHeaderSpecific(G,VEC_CLASSID,4); 239a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 240a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,G,4); 2419566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 242a7e14dcfSSatish Balay if (tao->ops->computeobjectiveandgradient) { 2439566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL)); 244f4c1ad5cSStefano Zampini if (tao->ops->computegradient == TaoDefaultComputeGradient) { 2459566063dSJacob Faibussowitsch PetscCall(TaoComputeObjective(tao,X,f)); 2469566063dSJacob Faibussowitsch PetscCall(TaoDefaultComputeGradient(tao,X,G,NULL)); 247f4c1ad5cSStefano Zampini } else { 248441846f8SBarry Smith PetscStackPush("Tao user objective/gradient evaluation routine"); 2499566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP)); 2500cbffdbaSBarry Smith PetscStackPop; 251a7e14dcfSSatish Balay } 2529566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL)); 253a7e14dcfSSatish Balay tao->nfuncgrads++; 254a7e14dcfSSatish Balay } else if (tao->ops->computeobjective && tao->ops->computegradient) { 2559566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 256441846f8SBarry Smith PetscStackPush("Tao user objective evaluation routine"); 2579566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeobjective)(tao,X,f,tao->user_objP)); 258a7e14dcfSSatish Balay PetscStackPop; 2599566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 260a7e14dcfSSatish Balay tao->nfuncs++; 2619566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL)); 262441846f8SBarry Smith PetscStackPush("Tao user gradient evaluation routine"); 2639566063dSJacob Faibussowitsch PetscCall((*tao->ops->computegradient)(tao,X,G,tao->user_gradP)); 264a7e14dcfSSatish Balay PetscStackPop; 2659566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL)); 266a7e14dcfSSatish Balay tao->ngrads++; 267a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() or TaoSetGradient() not set"); 2689566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f))); 2699566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 2701657496cSHong Zhang 2719566063dSJacob Faibussowitsch PetscCall(TaoTestGradient(tao,X,G)); 272a7e14dcfSSatish Balay PetscFunctionReturn(0); 273a7e14dcfSSatish Balay } 274a7e14dcfSSatish Balay 275a7e14dcfSSatish Balay /*@C 276a82e8c82SStefano Zampini TaoSetObjective - Sets the function evaluation routine for minimization 277a7e14dcfSSatish Balay 278441846f8SBarry Smith Logically collective on Tao 279a7e14dcfSSatish Balay 280d8d19677SJose E. Roman Input Parameters: 281441846f8SBarry Smith + tao - the Tao context 282a7e14dcfSSatish Balay . func - the objective function 283a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 2846c23d075SBarry Smith routine (may be NULL) 285a7e14dcfSSatish Balay 286a7e14dcfSSatish Balay Calling sequence of func: 287441846f8SBarry Smith $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 288a7e14dcfSSatish Balay 289a7e14dcfSSatish Balay + x - input vector 290a7e14dcfSSatish Balay . f - function value 291a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 292a7e14dcfSSatish Balay 293a7e14dcfSSatish Balay Level: beginner 294a7e14dcfSSatish Balay 295db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetObjective()` 296a7e14dcfSSatish Balay @*/ 297a82e8c82SStefano Zampini PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx) 298a7e14dcfSSatish Balay { 299a7e14dcfSSatish Balay PetscFunctionBegin; 300441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 301a82e8c82SStefano Zampini if (ctx) tao->user_objP = ctx; 302a82e8c82SStefano Zampini if (func) tao->ops->computeobjective = func; 303a82e8c82SStefano Zampini PetscFunctionReturn(0); 304a82e8c82SStefano Zampini } 305a82e8c82SStefano Zampini 306a82e8c82SStefano Zampini /*@C 307a82e8c82SStefano Zampini TaoGetObjective - Gets the function evaluation routine for minimization 308a82e8c82SStefano Zampini 309a82e8c82SStefano Zampini Not collective 310a82e8c82SStefano Zampini 311a82e8c82SStefano Zampini Input Parameter: 312a82e8c82SStefano Zampini . tao - the Tao context 313a82e8c82SStefano Zampini 314a82e8c82SStefano Zampini Output Parameters 315a82e8c82SStefano Zampini + func - the objective function 316a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation 317a82e8c82SStefano Zampini 318a82e8c82SStefano Zampini Calling sequence of func: 319a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 320a82e8c82SStefano Zampini 321a82e8c82SStefano Zampini + x - input vector 322a82e8c82SStefano Zampini . f - function value 323a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 324a82e8c82SStefano Zampini 325a82e8c82SStefano Zampini Level: beginner 326a82e8c82SStefano Zampini 327db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjective()` 328a82e8c82SStefano Zampini @*/ 329a82e8c82SStefano Zampini PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal*,void*),void **ctx) 330a82e8c82SStefano Zampini { 331a82e8c82SStefano Zampini PetscFunctionBegin; 332a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 333a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjective; 334a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objP; 335a7e14dcfSSatish Balay PetscFunctionReturn(0); 336a7e14dcfSSatish Balay } 337a7e14dcfSSatish Balay 338a7e14dcfSSatish Balay /*@C 3394a48860cSAlp Dener TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications 340a7e14dcfSSatish Balay 341441846f8SBarry Smith Logically collective on Tao 342a7e14dcfSSatish Balay 343d8d19677SJose E. Roman Input Parameters: 344441846f8SBarry Smith + tao - the Tao context 3454a48860cSAlp Dener . func - the residual evaluation routine 346a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 3476c23d075SBarry Smith routine (may be NULL) 348a7e14dcfSSatish Balay 349a7e14dcfSSatish Balay Calling sequence of func: 350441846f8SBarry Smith $ func (Tao tao, Vec x, Vec f, void *ctx); 351a7e14dcfSSatish Balay 352a7e14dcfSSatish Balay + x - input vector 353a7e14dcfSSatish Balay . f - function value vector 354a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 355a7e14dcfSSatish Balay 356a7e14dcfSSatish Balay Level: beginner 357a7e14dcfSSatish Balay 358db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetJacobianRoutine()` 359a7e14dcfSSatish Balay @*/ 3604a48860cSAlp Dener PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 361a7e14dcfSSatish Balay { 362a7e14dcfSSatish Balay PetscFunctionBegin; 363441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 3644a48860cSAlp Dener PetscValidHeaderSpecific(res,VEC_CLASSID,2); 3659566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)res)); 366737f463aSAlp Dener if (tao->ls_res) { 3679566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->ls_res)); 368737f463aSAlp Dener } 3694a48860cSAlp Dener tao->ls_res = res; 3704ffbe8acSAlp Dener tao->user_lsresP = ctx; 3714a48860cSAlp Dener tao->ops->computeresidual = func; 372737f463aSAlp Dener 373737f463aSAlp Dener PetscFunctionReturn(0); 374737f463aSAlp Dener } 375737f463aSAlp Dener 376737f463aSAlp Dener /*@ 377737f463aSAlp 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. 378737f463aSAlp Dener 379737f463aSAlp Dener Collective on Tao 380737f463aSAlp Dener 381737f463aSAlp Dener Input Parameters: 382737f463aSAlp Dener + tao - the Tao context 383737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only) 384737f463aSAlp Dener . n - the number of weights (if using off-diagonal) 385737f463aSAlp Dener . rows - index list of rows for sigma_w 386737f463aSAlp Dener . cols - index list of columns for sigma_w 387737f463aSAlp Dener - vals - array of weights 388737f463aSAlp Dener 389737f463aSAlp Dener Note: Either sigma_v or sigma_w (or both) should be NULL 390737f463aSAlp Dener 391737f463aSAlp Dener Level: intermediate 392737f463aSAlp Dener 393db781477SPatrick Sanan .seealso: `TaoSetResidualRoutine()` 394737f463aSAlp Dener @*/ 395737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals) 396737f463aSAlp Dener { 397737f463aSAlp Dener PetscInt i; 398a82e8c82SStefano Zampini 399737f463aSAlp Dener PetscFunctionBegin; 400737f463aSAlp Dener PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 401a82e8c82SStefano Zampini if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2); 4029566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sigma_v)); 4039566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->res_weights_v)); 4044ffbe8acSAlp Dener tao->res_weights_v = sigma_v; 405737f463aSAlp Dener if (vals) { 4069566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_rows)); 4079566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_cols)); 4089566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_w)); 4099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_rows)); 4109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_cols)); 4119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_w)); 412737f463aSAlp Dener tao->res_weights_n = n; 413737f463aSAlp Dener for (i=0;i<n;i++) { 414737f463aSAlp Dener tao->res_weights_rows[i] = rows[i]; 415737f463aSAlp Dener tao->res_weights_cols[i] = cols[i]; 416737f463aSAlp Dener tao->res_weights_w[i] = vals[i]; 417737f463aSAlp Dener } 418737f463aSAlp Dener } else { 419737f463aSAlp Dener tao->res_weights_n = 0; 42083c8fe1dSLisandro Dalcin tao->res_weights_rows = NULL; 42183c8fe1dSLisandro Dalcin tao->res_weights_cols = NULL; 422737f463aSAlp Dener } 423a7e14dcfSSatish Balay PetscFunctionReturn(0); 424a7e14dcfSSatish Balay } 425a7e14dcfSSatish Balay 4268b7a9b22SJason Sarich /*@ 4274a48860cSAlp Dener TaoComputeResidual - Computes a least-squares residual vector at a given point 428a7e14dcfSSatish Balay 429441846f8SBarry Smith Collective on Tao 430a7e14dcfSSatish Balay 431a7e14dcfSSatish Balay Input Parameters: 432441846f8SBarry Smith + tao - the Tao context 433a7e14dcfSSatish Balay - X - input vector 434a7e14dcfSSatish Balay 435a7e14dcfSSatish Balay Output Parameter: 436a7e14dcfSSatish Balay . f - Objective vector at X 437a7e14dcfSSatish Balay 43895452b02SPatrick Sanan Notes: 4394a48860cSAlp Dener TaoComputeResidual() is typically used within minimization implementations, 440a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 441a7e14dcfSSatish Balay 442a7e14dcfSSatish Balay Level: advanced 443a7e14dcfSSatish Balay 444db781477SPatrick Sanan .seealso: `TaoSetResidualRoutine()` 445a7e14dcfSSatish Balay @*/ 4464a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F) 447a7e14dcfSSatish Balay { 448a7e14dcfSSatish Balay PetscFunctionBegin; 449441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 450a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 451a7e14dcfSSatish Balay PetscValidHeaderSpecific(F,VEC_CLASSID,3); 452a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 453a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,F,3); 4544a48860cSAlp Dener if (tao->ops->computeresidual) { 4559566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 4564a48860cSAlp Dener PetscStackPush("Tao user least-squares residual evaluation routine"); 4579566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP)); 458a7e14dcfSSatish Balay PetscStackPop; 4599566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 460a7e14dcfSSatish Balay tao->nfuncs++; 461691b26d3SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called"); 4629566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO least-squares residual evaluation.\n")); 463a7e14dcfSSatish Balay PetscFunctionReturn(0); 464a7e14dcfSSatish Balay } 465a7e14dcfSSatish Balay 466a7e14dcfSSatish Balay /*@C 467a82e8c82SStefano Zampini TaoSetGradient - Sets the gradient evaluation routine for minimization 468a7e14dcfSSatish Balay 469441846f8SBarry Smith Logically collective on Tao 470a7e14dcfSSatish Balay 471d8d19677SJose E. Roman Input Parameters: 472441846f8SBarry Smith + tao - the Tao context 473a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 474a7e14dcfSSatish Balay . func - the gradient function 475a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 4766c23d075SBarry Smith routine (may be NULL) 477a7e14dcfSSatish Balay 478a7e14dcfSSatish Balay Calling sequence of func: 479441846f8SBarry Smith $ func (Tao tao, Vec x, Vec g, void *ctx); 480a7e14dcfSSatish Balay 481a7e14dcfSSatish Balay + x - input vector 482a7e14dcfSSatish Balay . g - gradient value (output) 483a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 484a7e14dcfSSatish Balay 485a7e14dcfSSatish Balay Level: beginner 486a7e14dcfSSatish Balay 487db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()` 488a7e14dcfSSatish Balay @*/ 489a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 490a7e14dcfSSatish Balay { 491a7e14dcfSSatish Balay PetscFunctionBegin; 492441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 493a82e8c82SStefano Zampini if (g) { 494a82e8c82SStefano Zampini PetscValidHeaderSpecific(g,VEC_CLASSID,2); 495a82e8c82SStefano Zampini PetscCheckSameComm(tao,1,g,2); 4969566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 4979566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 498a82e8c82SStefano Zampini tao->gradient = g; 499a82e8c82SStefano Zampini } 500a82e8c82SStefano Zampini if (func) tao->ops->computegradient = func; 501a82e8c82SStefano Zampini if (ctx) tao->user_gradP = ctx; 502a7e14dcfSSatish Balay PetscFunctionReturn(0); 503a7e14dcfSSatish Balay } 504a7e14dcfSSatish Balay 505a7e14dcfSSatish Balay /*@C 506a82e8c82SStefano Zampini TaoGetGradient - Gets the gradient evaluation routine for minimization 507a82e8c82SStefano Zampini 508a82e8c82SStefano Zampini Not collective 509a82e8c82SStefano Zampini 510a82e8c82SStefano Zampini Input Parameter: 511a82e8c82SStefano Zampini . tao - the Tao context 512a82e8c82SStefano Zampini 513a82e8c82SStefano Zampini Output Parameters: 514a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation 515a82e8c82SStefano Zampini . func - the gradient function 516a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 517a82e8c82SStefano Zampini 518a82e8c82SStefano Zampini Calling sequence of func: 519a82e8c82SStefano Zampini $ func (Tao tao, Vec x, Vec g, void *ctx); 520a82e8c82SStefano Zampini 521a82e8c82SStefano Zampini + x - input vector 522a82e8c82SStefano Zampini . g - gradient value (output) 523a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 524a82e8c82SStefano Zampini 525a82e8c82SStefano Zampini Level: beginner 526a82e8c82SStefano Zampini 527db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()` 528a82e8c82SStefano Zampini @*/ 529a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx) 530a82e8c82SStefano Zampini { 531a82e8c82SStefano Zampini PetscFunctionBegin; 532a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 533a82e8c82SStefano Zampini if (g) *g = tao->gradient; 534a82e8c82SStefano Zampini if (func) *func = tao->ops->computegradient; 535a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_gradP; 536a82e8c82SStefano Zampini PetscFunctionReturn(0); 537a82e8c82SStefano Zampini } 538a82e8c82SStefano Zampini 539a82e8c82SStefano Zampini /*@C 540a82e8c82SStefano Zampini TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for minimization 541a7e14dcfSSatish Balay 542441846f8SBarry Smith Logically collective on Tao 543a7e14dcfSSatish Balay 544d8d19677SJose E. Roman Input Parameters: 545441846f8SBarry Smith + tao - the Tao context 546a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 547a7e14dcfSSatish Balay . func - the gradient function 548a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 5496c23d075SBarry Smith routine (may be NULL) 550a7e14dcfSSatish Balay 551a7e14dcfSSatish Balay Calling sequence of func: 55217477c02SJason Sarich $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 553a7e14dcfSSatish Balay 554a7e14dcfSSatish Balay + x - input vector 55517477c02SJason Sarich . f - objective value (output) 556a7e14dcfSSatish Balay . g - gradient value (output) 557a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 558a7e14dcfSSatish Balay 559a7e14dcfSSatish Balay Level: beginner 560a7e14dcfSSatish Balay 561db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()` 562a7e14dcfSSatish Balay @*/ 563a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx) 564a82e8c82SStefano Zampini { 565a82e8c82SStefano Zampini PetscFunctionBegin; 566a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 567a82e8c82SStefano Zampini if (g) { 568a82e8c82SStefano Zampini PetscValidHeaderSpecific(g,VEC_CLASSID,2); 569a82e8c82SStefano Zampini PetscCheckSameComm(tao,1,g,2); 5709566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 5719566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 572a82e8c82SStefano Zampini tao->gradient = g; 573a82e8c82SStefano Zampini } 574a82e8c82SStefano Zampini if (ctx) tao->user_objgradP = ctx; 575a82e8c82SStefano Zampini if (func) tao->ops->computeobjectiveandgradient = func; 576a82e8c82SStefano Zampini PetscFunctionReturn(0); 577a82e8c82SStefano Zampini } 578a82e8c82SStefano Zampini 579a82e8c82SStefano Zampini /*@C 580a82e8c82SStefano Zampini TaoGetObjectiveAndGradient - Gets a combined objective function and gradient evaluation routine for minimization 581a82e8c82SStefano Zampini 582a82e8c82SStefano Zampini Not collective 583a82e8c82SStefano Zampini 584a82e8c82SStefano Zampini Input Parameter: 585a82e8c82SStefano Zampini . tao - the Tao context 586a82e8c82SStefano Zampini 587a82e8c82SStefano Zampini Output Parameters: 588817da375SSatish Balay + g - the vector to internally hold the gradient computation 589a82e8c82SStefano Zampini . func - the gradient function 590a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 591a82e8c82SStefano Zampini 592a82e8c82SStefano Zampini Calling sequence of func: 593a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 594a82e8c82SStefano Zampini 595a82e8c82SStefano Zampini + x - input vector 596a82e8c82SStefano Zampini . f - objective value (output) 597a82e8c82SStefano Zampini . g - gradient value (output) 598a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 599a82e8c82SStefano Zampini 600a82e8c82SStefano Zampini Level: beginner 601a82e8c82SStefano Zampini 602db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()` 603a82e8c82SStefano Zampini @*/ 604a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx) 605a7e14dcfSSatish Balay { 606a7e14dcfSSatish Balay PetscFunctionBegin; 607441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 608a82e8c82SStefano Zampini if (g) *g = tao->gradient; 609a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjectiveandgradient; 610a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objgradP; 611a7e14dcfSSatish Balay PetscFunctionReturn(0); 612a7e14dcfSSatish Balay } 613a7e14dcfSSatish Balay 614a7e14dcfSSatish Balay /*@ 615a82e8c82SStefano Zampini TaoIsObjectiveDefined - Checks to see if the user has 616a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 617a7e14dcfSSatish Balay it is appropriate to call TaoComputeObjective() or 618a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient() 619a7e14dcfSSatish Balay 620a82e8c82SStefano Zampini Not collective 621a7e14dcfSSatish Balay 622a82e8c82SStefano Zampini Input Parameter: 623a82e8c82SStefano Zampini . tao - the Tao context 624a82e8c82SStefano Zampini 625a82e8c82SStefano Zampini Output Parameter: 626f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise 627a82e8c82SStefano Zampini 628a7e14dcfSSatish Balay Level: developer 629a7e14dcfSSatish Balay 630db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()` 631a7e14dcfSSatish Balay @*/ 632441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg) 633a7e14dcfSSatish Balay { 634a7e14dcfSSatish Balay PetscFunctionBegin; 635441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 63683c8fe1dSLisandro Dalcin if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE; 63745cf516eSBarry Smith else *flg = PETSC_TRUE; 638a7e14dcfSSatish Balay PetscFunctionReturn(0); 639a7e14dcfSSatish Balay } 640a7e14dcfSSatish Balay 641a7e14dcfSSatish Balay /*@ 642a82e8c82SStefano Zampini TaoIsGradientDefined - Checks to see if the user has 643a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 644a7e14dcfSSatish Balay it is appropriate to call TaoComputeGradient() or 645a7e14dcfSSatish Balay TaoComputeGradientAndGradient() 646a7e14dcfSSatish Balay 647a7e14dcfSSatish Balay Not Collective 648a7e14dcfSSatish Balay 649a82e8c82SStefano Zampini Input Parameter: 650a82e8c82SStefano Zampini . tao - the Tao context 651a82e8c82SStefano Zampini 652a82e8c82SStefano Zampini Output Parameter: 653f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise 654a82e8c82SStefano Zampini 655a7e14dcfSSatish Balay Level: developer 656a7e14dcfSSatish Balay 657db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()` 658a7e14dcfSSatish Balay @*/ 659441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg) 660a7e14dcfSSatish Balay { 661a7e14dcfSSatish Balay PetscFunctionBegin; 662441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 66383c8fe1dSLisandro Dalcin if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE; 66445cf516eSBarry Smith else *flg = PETSC_TRUE; 665a7e14dcfSSatish Balay PetscFunctionReturn(0); 666a7e14dcfSSatish Balay } 667a7e14dcfSSatish Balay 668a7e14dcfSSatish Balay /*@ 669a82e8c82SStefano Zampini TaoIsObjectiveAndGradientDefined - Checks to see if the user has 670a7e14dcfSSatish Balay declared a joint objective/gradient routine. Useful for determining when 671a7e14dcfSSatish Balay it is appropriate to call TaoComputeObjective() or 672a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient() 673a7e14dcfSSatish Balay 674a7e14dcfSSatish Balay Not Collective 675a7e14dcfSSatish Balay 676a82e8c82SStefano Zampini Input Parameter: 677a82e8c82SStefano Zampini . tao - the Tao context 678a82e8c82SStefano Zampini 679a82e8c82SStefano Zampini Output Parameter: 680f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise 681a82e8c82SStefano Zampini 682a7e14dcfSSatish Balay Level: developer 683a7e14dcfSSatish Balay 684db781477SPatrick Sanan .seealso: `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()` 685a7e14dcfSSatish Balay @*/ 686441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg) 687a7e14dcfSSatish Balay { 688a7e14dcfSSatish Balay PetscFunctionBegin; 689441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 69083c8fe1dSLisandro Dalcin if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE; 69145cf516eSBarry Smith else *flg = PETSC_TRUE; 692a7e14dcfSSatish Balay PetscFunctionReturn(0); 693a7e14dcfSSatish Balay } 694