1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/ 2a7e14dcfSSatish Balay 3a7e14dcfSSatish Balay /*@ 4a82e8c82SStefano Zampini TaoSetSolution - Sets the vector holding the initial guess for the solve 5a7e14dcfSSatish Balay 665ba42b6SBarry Smith Logically collective on tao 7a7e14dcfSSatish Balay 8a7e14dcfSSatish Balay Input Parameters: 9441846f8SBarry Smith + tao - the Tao context 10a7e14dcfSSatish Balay - x0 - the initial guess 11a7e14dcfSSatish Balay 12a7e14dcfSSatish Balay Level: beginner 1365ba42b6SBarry Smith .seealso: `Tao`, `TaoCreate()`, `TaoSolve()`, `TaoGetSolution()` 14a7e14dcfSSatish Balay @*/ 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 } 641baa6e33SBarry 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 10765ba42b6SBarry 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 12065ba42b6SBarry Smith Note: 12165ba42b6SBarry Smith `TaoComputeGradient()` is typically used within the implementation of the optimization method, 122a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 123a7e14dcfSSatish Balay 12465ba42b6SBarry Smith Level: developer 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)); 141*792fecdfSBarry Smith PetscCallBack("Tao callback gradient",(*tao->ops->computegradient)(tao,X,G,tao->user_gradP)); 1429566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL)); 143a7e14dcfSSatish Balay tao->ngrads++; 144a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 1459566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL)); 146*792fecdfSBarry Smith PetscCallBack("Tao callback objective/gradient",(*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP)); 1479566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL)); 148a7e14dcfSSatish Balay tao->nfuncgrads++; 149a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradient() has not been called"); 1509566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 15109baa881SHong Zhang 1529566063dSJacob Faibussowitsch PetscCall(TaoTestGradient(tao,X,G)); 153a7e14dcfSSatish Balay PetscFunctionReturn(0); 154a7e14dcfSSatish Balay } 155a7e14dcfSSatish Balay 156a7e14dcfSSatish Balay /*@ 157a7e14dcfSSatish Balay TaoComputeObjective - Computes the objective function value at a given point 158a7e14dcfSSatish Balay 15965ba42b6SBarry Smith Collective on tao 160a7e14dcfSSatish Balay 161a7e14dcfSSatish Balay Input Parameters: 162441846f8SBarry Smith + tao - the Tao context 163a7e14dcfSSatish Balay - X - input vector 164a7e14dcfSSatish Balay 165a7e14dcfSSatish Balay Output Parameter: 166a7e14dcfSSatish Balay . f - Objective value at X 167a7e14dcfSSatish Balay 16865ba42b6SBarry Smith Note: 16965ba42b6SBarry Smith `TaoComputeObjective()` is typically used within the implementation of the optimization algorithm 170a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 171a7e14dcfSSatish Balay 17265ba42b6SBarry Smith Level: developer 173a7e14dcfSSatish Balay 17465ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()` 175a7e14dcfSSatish Balay @*/ 176441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f) 177a7e14dcfSSatish Balay { 178a7e14dcfSSatish Balay Vec temp; 17987f595a5SBarry Smith 180a7e14dcfSSatish Balay PetscFunctionBegin; 181441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 182a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 183a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 1849566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 185a7e14dcfSSatish Balay if (tao->ops->computeobjective) { 1869566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 187*792fecdfSBarry Smith PetscCallBack("Tao callback objective",(*tao->ops->computeobjective)(tao,X,f,tao->user_objP)); 1889566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 189a7e14dcfSSatish Balay tao->nfuncs++; 190a7e14dcfSSatish Balay } else if (tao->ops->computeobjectiveandgradient) { 1919566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n")); 1929566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X,&temp)); 1939566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,NULL,NULL)); 194*792fecdfSBarry Smith PetscCallBack("Tao callback objective/gradient",(*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP)); 1959566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,NULL,NULL)); 1969566063dSJacob Faibussowitsch PetscCall(VecDestroy(&temp)); 197a7e14dcfSSatish Balay tao->nfuncgrads++; 198a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() has not been called"); 1999566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f))); 2009566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 201a7e14dcfSSatish Balay PetscFunctionReturn(0); 202a7e14dcfSSatish Balay } 203a7e14dcfSSatish Balay 204a7e14dcfSSatish Balay /*@ 205a7e14dcfSSatish Balay TaoComputeObjectiveAndGradient - Computes the objective function value at a given point 206a7e14dcfSSatish Balay 20765ba42b6SBarry Smith Collective on tao 208a7e14dcfSSatish Balay 209a7e14dcfSSatish Balay Input Parameters: 210441846f8SBarry Smith + tao - the Tao context 211a7e14dcfSSatish Balay - X - input vector 212a7e14dcfSSatish Balay 213d8d19677SJose E. Roman Output Parameters: 214a7e14dcfSSatish Balay + f - Objective value at X 215a7e14dcfSSatish Balay - g - Gradient vector at X 216a7e14dcfSSatish Balay 21765ba42b6SBarry Smith Note: 21865ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` is typically used within the implementation of the optimization algorithm, 219a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 220a7e14dcfSSatish Balay 22165ba42b6SBarry Smith Level: developer 222a7e14dcfSSatish Balay 223db781477SPatrick Sanan .seealso: `TaoComputeGradient()`, `TaoComputeObjectiveAndGradient()`, `TaoSetObjective()` 224a7e14dcfSSatish Balay @*/ 225441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G) 226a7e14dcfSSatish Balay { 227a7e14dcfSSatish Balay PetscFunctionBegin; 228441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 229a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 230a7e14dcfSSatish Balay PetscValidHeaderSpecific(G,VEC_CLASSID,4); 231a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 232a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,G,4); 2339566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 234a7e14dcfSSatish Balay if (tao->ops->computeobjectiveandgradient) { 2359566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL)); 236f4c1ad5cSStefano Zampini if (tao->ops->computegradient == TaoDefaultComputeGradient) { 2379566063dSJacob Faibussowitsch PetscCall(TaoComputeObjective(tao,X,f)); 2389566063dSJacob Faibussowitsch PetscCall(TaoDefaultComputeGradient(tao,X,G,NULL)); 239f4c1ad5cSStefano Zampini } else { 240*792fecdfSBarry Smith PetscCallBack("Tao callback objective/gradient",(*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP)); 241a7e14dcfSSatish Balay } 2429566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL)); 243a7e14dcfSSatish Balay tao->nfuncgrads++; 244a7e14dcfSSatish Balay } else if (tao->ops->computeobjective && tao->ops->computegradient) { 2459566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 246*792fecdfSBarry Smith PetscCallBack("Tao callback objective",(*tao->ops->computeobjective)(tao,X,f,tao->user_objP)); 2479566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 248a7e14dcfSSatish Balay tao->nfuncs++; 2499566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL)); 250*792fecdfSBarry Smith PetscCallBack("Tao callback gradient",(*tao->ops->computegradient)(tao,X,G,tao->user_gradP)); 2519566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL)); 252a7e14dcfSSatish Balay tao->ngrads++; 253a82e8c82SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() or TaoSetGradient() not set"); 2549566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f))); 2559566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 2561657496cSHong Zhang 2579566063dSJacob Faibussowitsch PetscCall(TaoTestGradient(tao,X,G)); 258a7e14dcfSSatish Balay PetscFunctionReturn(0); 259a7e14dcfSSatish Balay } 260a7e14dcfSSatish Balay 261a7e14dcfSSatish Balay /*@C 262a82e8c82SStefano Zampini TaoSetObjective - Sets the function evaluation routine for minimization 263a7e14dcfSSatish Balay 26465ba42b6SBarry Smith Logically collective on tao 265a7e14dcfSSatish Balay 266d8d19677SJose E. Roman Input Parameters: 267441846f8SBarry Smith + tao - the Tao context 268a7e14dcfSSatish Balay . func - the objective function 269a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 2706c23d075SBarry Smith routine (may be NULL) 271a7e14dcfSSatish Balay 272a7e14dcfSSatish Balay Calling sequence of func: 273441846f8SBarry Smith $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 274a7e14dcfSSatish Balay 275a7e14dcfSSatish Balay + x - input vector 276a7e14dcfSSatish Balay . f - function value 277a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 278a7e14dcfSSatish Balay 279a7e14dcfSSatish Balay Level: beginner 280a7e14dcfSSatish Balay 281db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetObjective()` 282a7e14dcfSSatish Balay @*/ 283a82e8c82SStefano Zampini PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx) 284a7e14dcfSSatish Balay { 285a7e14dcfSSatish Balay PetscFunctionBegin; 286441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 287a82e8c82SStefano Zampini if (ctx) tao->user_objP = ctx; 288a82e8c82SStefano Zampini if (func) tao->ops->computeobjective = func; 289a82e8c82SStefano Zampini PetscFunctionReturn(0); 290a82e8c82SStefano Zampini } 291a82e8c82SStefano Zampini 292a82e8c82SStefano Zampini /*@C 29365ba42b6SBarry Smith TaoGetObjective - Gets the function evaluation routine for the function to be minimized 294a82e8c82SStefano Zampini 295a82e8c82SStefano Zampini Not collective 296a82e8c82SStefano Zampini 297a82e8c82SStefano Zampini Input Parameter: 298a82e8c82SStefano Zampini . tao - the Tao context 299a82e8c82SStefano Zampini 300a82e8c82SStefano Zampini Output Parameters 301a82e8c82SStefano Zampini + func - the objective function 302a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation 303a82e8c82SStefano Zampini 304a82e8c82SStefano Zampini Calling sequence of func: 305a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, void *ctx); 306a82e8c82SStefano Zampini 307a82e8c82SStefano Zampini + x - input vector 308a82e8c82SStefano Zampini . f - function value 309a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 310a82e8c82SStefano Zampini 311a82e8c82SStefano Zampini Level: beginner 312a82e8c82SStefano Zampini 31365ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjective()` 314a82e8c82SStefano Zampini @*/ 315a82e8c82SStefano Zampini PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal*,void*),void **ctx) 316a82e8c82SStefano Zampini { 317a82e8c82SStefano Zampini PetscFunctionBegin; 318a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 319a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjective; 320a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objP; 321a7e14dcfSSatish Balay PetscFunctionReturn(0); 322a7e14dcfSSatish Balay } 323a7e14dcfSSatish Balay 324a7e14dcfSSatish Balay /*@C 3254a48860cSAlp Dener TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications 326a7e14dcfSSatish Balay 32765ba42b6SBarry Smith Logically collective on tao 328a7e14dcfSSatish Balay 329d8d19677SJose E. Roman Input Parameters: 330441846f8SBarry Smith + tao - the Tao context 3314a48860cSAlp Dener . func - the residual evaluation routine 332a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation 3336c23d075SBarry Smith routine (may be NULL) 334a7e14dcfSSatish Balay 335a7e14dcfSSatish Balay Calling sequence of func: 336441846f8SBarry Smith $ func (Tao tao, Vec x, Vec f, void *ctx); 337a7e14dcfSSatish Balay 338a7e14dcfSSatish Balay + x - input vector 339a7e14dcfSSatish Balay . f - function value vector 340a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 341a7e14dcfSSatish Balay 342a7e14dcfSSatish Balay Level: beginner 343a7e14dcfSSatish Balay 34465ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoSetJacobianRoutine()` 345a7e14dcfSSatish Balay @*/ 3464a48860cSAlp Dener PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 347a7e14dcfSSatish Balay { 348a7e14dcfSSatish Balay PetscFunctionBegin; 349441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 3504a48860cSAlp Dener PetscValidHeaderSpecific(res,VEC_CLASSID,2); 3519566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)res)); 352737f463aSAlp Dener if (tao->ls_res) { 3539566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->ls_res)); 354737f463aSAlp Dener } 3554a48860cSAlp Dener tao->ls_res = res; 3564ffbe8acSAlp Dener tao->user_lsresP = ctx; 3574a48860cSAlp Dener tao->ops->computeresidual = func; 358737f463aSAlp Dener 359737f463aSAlp Dener PetscFunctionReturn(0); 360737f463aSAlp Dener } 361737f463aSAlp Dener 362737f463aSAlp Dener /*@ 36365ba42b6SBarry 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. 36465ba42b6SBarry Smith If this function is not provided, or if sigma_v and sigma_w are both NULL, then the identity matrix will be used for weights. 365737f463aSAlp Dener 36665ba42b6SBarry Smith Collective on tao 367737f463aSAlp Dener 368737f463aSAlp Dener Input Parameters: 369737f463aSAlp Dener + tao - the Tao context 370737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only) 371737f463aSAlp Dener . n - the number of weights (if using off-diagonal) 372737f463aSAlp Dener . rows - index list of rows for sigma_w 373737f463aSAlp Dener . cols - index list of columns for sigma_w 374737f463aSAlp Dener - vals - array of weights 375737f463aSAlp Dener 376737f463aSAlp Dener Note: Either sigma_v or sigma_w (or both) should be NULL 377737f463aSAlp Dener 378737f463aSAlp Dener Level: intermediate 379737f463aSAlp Dener 38065ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()` 381737f463aSAlp Dener @*/ 382737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals) 383737f463aSAlp Dener { 384737f463aSAlp Dener PetscInt i; 385a82e8c82SStefano Zampini 386737f463aSAlp Dener PetscFunctionBegin; 387737f463aSAlp Dener PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 388a82e8c82SStefano Zampini if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2); 3899566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sigma_v)); 3909566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->res_weights_v)); 3914ffbe8acSAlp Dener tao->res_weights_v = sigma_v; 392737f463aSAlp Dener if (vals) { 3939566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_rows)); 3949566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_cols)); 3959566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_w)); 3969566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_rows)); 3979566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_cols)); 3989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_w)); 399737f463aSAlp Dener tao->res_weights_n = n; 400737f463aSAlp Dener for (i=0;i<n;i++) { 401737f463aSAlp Dener tao->res_weights_rows[i] = rows[i]; 402737f463aSAlp Dener tao->res_weights_cols[i] = cols[i]; 403737f463aSAlp Dener tao->res_weights_w[i] = vals[i]; 404737f463aSAlp Dener } 405737f463aSAlp Dener } else { 406737f463aSAlp Dener tao->res_weights_n = 0; 40783c8fe1dSLisandro Dalcin tao->res_weights_rows = NULL; 40883c8fe1dSLisandro Dalcin tao->res_weights_cols = NULL; 409737f463aSAlp Dener } 410a7e14dcfSSatish Balay PetscFunctionReturn(0); 411a7e14dcfSSatish Balay } 412a7e14dcfSSatish Balay 4138b7a9b22SJason Sarich /*@ 4144a48860cSAlp Dener TaoComputeResidual - Computes a least-squares residual vector at a given point 415a7e14dcfSSatish Balay 41665ba42b6SBarry Smith Collective on tao 417a7e14dcfSSatish Balay 418a7e14dcfSSatish Balay Input Parameters: 419441846f8SBarry Smith + tao - the Tao context 420a7e14dcfSSatish Balay - X - input vector 421a7e14dcfSSatish Balay 422a7e14dcfSSatish Balay Output Parameter: 423a7e14dcfSSatish Balay . f - Objective vector at X 424a7e14dcfSSatish Balay 42595452b02SPatrick Sanan Notes: 42665ba42b6SBarry Smith `TaoComputeResidual()` is typically used within the implementation of the optimization algorithm, 427a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 428a7e14dcfSSatish Balay 429a7e14dcfSSatish Balay Level: advanced 430a7e14dcfSSatish Balay 43165ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()` 432a7e14dcfSSatish Balay @*/ 4334a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F) 434a7e14dcfSSatish Balay { 435a7e14dcfSSatish Balay PetscFunctionBegin; 436441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 437a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 438a7e14dcfSSatish Balay PetscValidHeaderSpecific(F,VEC_CLASSID,3); 439a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 440a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,F,3); 4414a48860cSAlp Dener if (tao->ops->computeresidual) { 4429566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 443*792fecdfSBarry Smith PetscCallBack("Tao callback least-squares residual",(*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP)); 4449566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 445a7e14dcfSSatish Balay tao->nfuncs++; 446691b26d3SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called"); 4479566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO least-squares residual evaluation.\n")); 448a7e14dcfSSatish Balay PetscFunctionReturn(0); 449a7e14dcfSSatish Balay } 450a7e14dcfSSatish Balay 451a7e14dcfSSatish Balay /*@C 45265ba42b6SBarry Smith TaoSetGradient - Sets the gradient evaluation routine for the function to be optimized 453a7e14dcfSSatish Balay 45465ba42b6SBarry Smith Logically collective on tao 455a7e14dcfSSatish Balay 456d8d19677SJose E. Roman Input Parameters: 457441846f8SBarry Smith + tao - the Tao context 458a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 459a7e14dcfSSatish Balay . func - the gradient function 460a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 4616c23d075SBarry Smith routine (may be NULL) 462a7e14dcfSSatish Balay 463a7e14dcfSSatish Balay Calling sequence of func: 464441846f8SBarry Smith $ func (Tao tao, Vec x, Vec g, void *ctx); 465a7e14dcfSSatish Balay 466a7e14dcfSSatish Balay + x - input vector 467a7e14dcfSSatish Balay . g - gradient value (output) 468a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 469a7e14dcfSSatish Balay 470a7e14dcfSSatish Balay Level: beginner 471a7e14dcfSSatish Balay 47265ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()` 473a7e14dcfSSatish Balay @*/ 474a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 475a7e14dcfSSatish Balay { 476a7e14dcfSSatish Balay PetscFunctionBegin; 477441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 478a82e8c82SStefano Zampini if (g) { 479a82e8c82SStefano Zampini PetscValidHeaderSpecific(g,VEC_CLASSID,2); 480a82e8c82SStefano Zampini PetscCheckSameComm(tao,1,g,2); 4819566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 4829566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 483a82e8c82SStefano Zampini tao->gradient = g; 484a82e8c82SStefano Zampini } 485a82e8c82SStefano Zampini if (func) tao->ops->computegradient = func; 486a82e8c82SStefano Zampini if (ctx) tao->user_gradP = ctx; 487a7e14dcfSSatish Balay PetscFunctionReturn(0); 488a7e14dcfSSatish Balay } 489a7e14dcfSSatish Balay 490a7e14dcfSSatish Balay /*@C 49165ba42b6SBarry Smith TaoGetGradient - Gets the gradient evaluation routine for the function being optimized 492a82e8c82SStefano Zampini 493a82e8c82SStefano Zampini Not collective 494a82e8c82SStefano Zampini 495a82e8c82SStefano Zampini Input Parameter: 496a82e8c82SStefano Zampini . tao - the Tao context 497a82e8c82SStefano Zampini 498a82e8c82SStefano Zampini Output Parameters: 499a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation 500a82e8c82SStefano Zampini . func - the gradient function 501a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 502a82e8c82SStefano Zampini 503a82e8c82SStefano Zampini Calling sequence of func: 504a82e8c82SStefano Zampini $ func (Tao tao, Vec x, Vec g, void *ctx); 505a82e8c82SStefano Zampini 506a82e8c82SStefano Zampini + x - input vector 507a82e8c82SStefano Zampini . g - gradient value (output) 508a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 509a82e8c82SStefano Zampini 510a82e8c82SStefano Zampini Level: beginner 511a82e8c82SStefano Zampini 51265ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()` 513a82e8c82SStefano Zampini @*/ 514a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx) 515a82e8c82SStefano Zampini { 516a82e8c82SStefano Zampini PetscFunctionBegin; 517a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 518a82e8c82SStefano Zampini if (g) *g = tao->gradient; 519a82e8c82SStefano Zampini if (func) *func = tao->ops->computegradient; 520a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_gradP; 521a82e8c82SStefano Zampini PetscFunctionReturn(0); 522a82e8c82SStefano Zampini } 523a82e8c82SStefano Zampini 524a82e8c82SStefano Zampini /*@C 52565ba42b6SBarry Smith TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for the function to be optimized 526a7e14dcfSSatish Balay 52765ba42b6SBarry Smith Logically collective on tao 528a7e14dcfSSatish Balay 529d8d19677SJose E. Roman Input Parameters: 530441846f8SBarry Smith + tao - the Tao context 531a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 532a7e14dcfSSatish Balay . func - the gradient function 533a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 5346c23d075SBarry Smith routine (may be NULL) 535a7e14dcfSSatish Balay 536a7e14dcfSSatish Balay Calling sequence of func: 53717477c02SJason Sarich $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 538a7e14dcfSSatish Balay 539a7e14dcfSSatish Balay + x - input vector 54017477c02SJason Sarich . f - objective value (output) 541a7e14dcfSSatish Balay . g - gradient value (output) 542a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 543a7e14dcfSSatish Balay 544a7e14dcfSSatish Balay Level: beginner 545a7e14dcfSSatish Balay 54665ba42b6SBarry Smith Note: 54765ba42b6SBarry Smith For some optimization methods using a combined function can be more eifficient. 54865ba42b6SBarry Smith 54965ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()` 550a7e14dcfSSatish Balay @*/ 551a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx) 552a82e8c82SStefano Zampini { 553a82e8c82SStefano Zampini PetscFunctionBegin; 554a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 555a82e8c82SStefano Zampini if (g) { 556a82e8c82SStefano Zampini PetscValidHeaderSpecific(g,VEC_CLASSID,2); 557a82e8c82SStefano Zampini PetscCheckSameComm(tao,1,g,2); 5589566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 5599566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 560a82e8c82SStefano Zampini tao->gradient = g; 561a82e8c82SStefano Zampini } 562a82e8c82SStefano Zampini if (ctx) tao->user_objgradP = ctx; 563a82e8c82SStefano Zampini if (func) tao->ops->computeobjectiveandgradient = func; 564a82e8c82SStefano Zampini PetscFunctionReturn(0); 565a82e8c82SStefano Zampini } 566a82e8c82SStefano Zampini 567a82e8c82SStefano Zampini /*@C 56865ba42b6SBarry Smith TaoGetObjectiveAndGradient - Gets the combined objective function and gradient evaluation routine for the function to be optimized 569a82e8c82SStefano Zampini 570a82e8c82SStefano Zampini Not collective 571a82e8c82SStefano Zampini 572a82e8c82SStefano Zampini Input Parameter: 573a82e8c82SStefano Zampini . tao - the Tao context 574a82e8c82SStefano Zampini 575a82e8c82SStefano Zampini Output Parameters: 576817da375SSatish Balay + g - the vector to internally hold the gradient computation 577a82e8c82SStefano Zampini . func - the gradient function 578a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 579a82e8c82SStefano Zampini 580a82e8c82SStefano Zampini Calling sequence of func: 581a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 582a82e8c82SStefano Zampini 583a82e8c82SStefano Zampini + x - input vector 584a82e8c82SStefano Zampini . f - objective value (output) 585a82e8c82SStefano Zampini . g - gradient value (output) 586a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 587a82e8c82SStefano Zampini 588a82e8c82SStefano Zampini Level: beginner 589a82e8c82SStefano Zampini 59065ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()` 591a82e8c82SStefano Zampini @*/ 592a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx) 593a7e14dcfSSatish Balay { 594a7e14dcfSSatish Balay PetscFunctionBegin; 595441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 596a82e8c82SStefano Zampini if (g) *g = tao->gradient; 597a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjectiveandgradient; 598a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objgradP; 599a7e14dcfSSatish Balay PetscFunctionReturn(0); 600a7e14dcfSSatish Balay } 601a7e14dcfSSatish Balay 602a7e14dcfSSatish Balay /*@ 603a82e8c82SStefano Zampini TaoIsObjectiveDefined - Checks to see if the user has 604a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 60565ba42b6SBarry Smith it is appropriate to call `TaoComputeObjective()` or 60665ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` 607a7e14dcfSSatish Balay 608a82e8c82SStefano Zampini Not collective 609a7e14dcfSSatish Balay 610a82e8c82SStefano Zampini Input Parameter: 611a82e8c82SStefano Zampini . tao - the Tao context 612a82e8c82SStefano Zampini 613a82e8c82SStefano Zampini Output Parameter: 61465ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 615a82e8c82SStefano Zampini 616a7e14dcfSSatish Balay Level: developer 617a7e14dcfSSatish Balay 61865ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()` 619a7e14dcfSSatish Balay @*/ 620441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg) 621a7e14dcfSSatish Balay { 622a7e14dcfSSatish Balay PetscFunctionBegin; 623441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 62483c8fe1dSLisandro Dalcin if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE; 62545cf516eSBarry Smith else *flg = PETSC_TRUE; 626a7e14dcfSSatish Balay PetscFunctionReturn(0); 627a7e14dcfSSatish Balay } 628a7e14dcfSSatish Balay 629a7e14dcfSSatish Balay /*@ 630a82e8c82SStefano Zampini TaoIsGradientDefined - Checks to see if the user has 631a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 63265ba42b6SBarry Smith it is appropriate to call `TaoComputeGradient()` or 63365ba42b6SBarry Smith `TaoComputeGradientAndGradient()` 634a7e14dcfSSatish Balay 635a7e14dcfSSatish Balay Not Collective 636a7e14dcfSSatish Balay 637a82e8c82SStefano Zampini Input Parameter: 638a82e8c82SStefano Zampini . tao - the Tao context 639a82e8c82SStefano Zampini 640a82e8c82SStefano Zampini Output Parameter: 64165ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 642a82e8c82SStefano Zampini 643a7e14dcfSSatish Balay Level: developer 644a7e14dcfSSatish Balay 645db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()` 646a7e14dcfSSatish Balay @*/ 647441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg) 648a7e14dcfSSatish Balay { 649a7e14dcfSSatish Balay PetscFunctionBegin; 650441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 65183c8fe1dSLisandro Dalcin if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE; 65245cf516eSBarry Smith else *flg = PETSC_TRUE; 653a7e14dcfSSatish Balay PetscFunctionReturn(0); 654a7e14dcfSSatish Balay } 655a7e14dcfSSatish Balay 656a7e14dcfSSatish Balay /*@ 657a82e8c82SStefano Zampini TaoIsObjectiveAndGradientDefined - Checks to see if the user has 658a7e14dcfSSatish Balay declared a joint objective/gradient routine. Useful for determining when 65965ba42b6SBarry Smith it is appropriate to call `TaoComputeObjective()` or 66065ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` 661a7e14dcfSSatish Balay 662a7e14dcfSSatish Balay Not Collective 663a7e14dcfSSatish Balay 664a82e8c82SStefano Zampini Input Parameter: 665a82e8c82SStefano Zampini . tao - the Tao context 666a82e8c82SStefano Zampini 667a82e8c82SStefano Zampini Output Parameter: 66865ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 669a82e8c82SStefano Zampini 670a7e14dcfSSatish Balay Level: developer 671a7e14dcfSSatish Balay 672db781477SPatrick Sanan .seealso: `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()` 673a7e14dcfSSatish Balay @*/ 674441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg) 675a7e14dcfSSatish Balay { 676a7e14dcfSSatish Balay PetscFunctionBegin; 677441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 67883c8fe1dSLisandro Dalcin if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE; 67945cf516eSBarry Smith else *flg = PETSC_TRUE; 680a7e14dcfSSatish Balay PetscFunctionReturn(0); 681a7e14dcfSSatish Balay } 682