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 6*65ba42b6SBarry 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*65ba42b6SBarry 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 107*65ba42b6SBarry 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 120*65ba42b6SBarry Smith Note: 121*65ba42b6SBarry 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 124*65ba42b6SBarry 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)); 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 163*65ba42b6SBarry 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 172*65ba42b6SBarry Smith Note: 173*65ba42b6SBarry Smith `TaoComputeObjective()` is typically used within the implementation of the optimization algorithm 174a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 175a7e14dcfSSatish Balay 176*65ba42b6SBarry Smith Level: developer 177a7e14dcfSSatish Balay 178*65ba42b6SBarry Smith .seealso: `Tao`, `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 215*65ba42b6SBarry 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 225*65ba42b6SBarry Smith Note: 226*65ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` is typically used within the implementation of the optimization algorithm, 227a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 228a7e14dcfSSatish Balay 229*65ba42b6SBarry Smith Level: developer 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 278*65ba42b6SBarry 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 307*65ba42b6SBarry Smith TaoGetObjective - Gets the function evaluation routine for the function to be minimized 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 327*65ba42b6SBarry Smith .seealso: `Tao`, `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 341*65ba42b6SBarry 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 358*65ba42b6SBarry Smith .seealso: `Tao`, `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 /*@ 377*65ba42b6SBarry 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. 378*65ba42b6SBarry 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. 379737f463aSAlp Dener 380*65ba42b6SBarry Smith Collective on tao 381737f463aSAlp Dener 382737f463aSAlp Dener Input Parameters: 383737f463aSAlp Dener + tao - the Tao context 384737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only) 385737f463aSAlp Dener . n - the number of weights (if using off-diagonal) 386737f463aSAlp Dener . rows - index list of rows for sigma_w 387737f463aSAlp Dener . cols - index list of columns for sigma_w 388737f463aSAlp Dener - vals - array of weights 389737f463aSAlp Dener 390737f463aSAlp Dener Note: Either sigma_v or sigma_w (or both) should be NULL 391737f463aSAlp Dener 392737f463aSAlp Dener Level: intermediate 393737f463aSAlp Dener 394*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()` 395737f463aSAlp Dener @*/ 396737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals) 397737f463aSAlp Dener { 398737f463aSAlp Dener PetscInt i; 399a82e8c82SStefano Zampini 400737f463aSAlp Dener PetscFunctionBegin; 401737f463aSAlp Dener PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 402a82e8c82SStefano Zampini if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2); 4039566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sigma_v)); 4049566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->res_weights_v)); 4054ffbe8acSAlp Dener tao->res_weights_v = sigma_v; 406737f463aSAlp Dener if (vals) { 4079566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_rows)); 4089566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_cols)); 4099566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->res_weights_w)); 4109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_rows)); 4119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_cols)); 4129566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&tao->res_weights_w)); 413737f463aSAlp Dener tao->res_weights_n = n; 414737f463aSAlp Dener for (i=0;i<n;i++) { 415737f463aSAlp Dener tao->res_weights_rows[i] = rows[i]; 416737f463aSAlp Dener tao->res_weights_cols[i] = cols[i]; 417737f463aSAlp Dener tao->res_weights_w[i] = vals[i]; 418737f463aSAlp Dener } 419737f463aSAlp Dener } else { 420737f463aSAlp Dener tao->res_weights_n = 0; 42183c8fe1dSLisandro Dalcin tao->res_weights_rows = NULL; 42283c8fe1dSLisandro Dalcin tao->res_weights_cols = NULL; 423737f463aSAlp Dener } 424a7e14dcfSSatish Balay PetscFunctionReturn(0); 425a7e14dcfSSatish Balay } 426a7e14dcfSSatish Balay 4278b7a9b22SJason Sarich /*@ 4284a48860cSAlp Dener TaoComputeResidual - Computes a least-squares residual vector at a given point 429a7e14dcfSSatish Balay 430*65ba42b6SBarry Smith Collective on tao 431a7e14dcfSSatish Balay 432a7e14dcfSSatish Balay Input Parameters: 433441846f8SBarry Smith + tao - the Tao context 434a7e14dcfSSatish Balay - X - input vector 435a7e14dcfSSatish Balay 436a7e14dcfSSatish Balay Output Parameter: 437a7e14dcfSSatish Balay . f - Objective vector at X 438a7e14dcfSSatish Balay 43995452b02SPatrick Sanan Notes: 440*65ba42b6SBarry Smith `TaoComputeResidual()` is typically used within the implementation of the optimization algorithm, 441a7e14dcfSSatish Balay so most users would not generally call this routine themselves. 442a7e14dcfSSatish Balay 443a7e14dcfSSatish Balay Level: advanced 444a7e14dcfSSatish Balay 445*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetResidualRoutine()` 446a7e14dcfSSatish Balay @*/ 4474a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F) 448a7e14dcfSSatish Balay { 449a7e14dcfSSatish Balay PetscFunctionBegin; 450441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 451a7e14dcfSSatish Balay PetscValidHeaderSpecific(X,VEC_CLASSID,2); 452a7e14dcfSSatish Balay PetscValidHeaderSpecific(F,VEC_CLASSID,3); 453a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,X,2); 454a7e14dcfSSatish Balay PetscCheckSameComm(tao,1,F,3); 4554a48860cSAlp Dener if (tao->ops->computeresidual) { 4569566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL)); 4574a48860cSAlp Dener PetscStackPush("Tao user least-squares residual evaluation routine"); 4589566063dSJacob Faibussowitsch PetscCall((*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP)); 459a7e14dcfSSatish Balay PetscStackPop; 4609566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL)); 461a7e14dcfSSatish Balay tao->nfuncs++; 462691b26d3SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called"); 4639566063dSJacob Faibussowitsch PetscCall(PetscInfo(tao,"TAO least-squares residual evaluation.\n")); 464a7e14dcfSSatish Balay PetscFunctionReturn(0); 465a7e14dcfSSatish Balay } 466a7e14dcfSSatish Balay 467a7e14dcfSSatish Balay /*@C 468*65ba42b6SBarry Smith TaoSetGradient - Sets the gradient evaluation routine for the function to be optimized 469a7e14dcfSSatish Balay 470*65ba42b6SBarry Smith Logically collective on tao 471a7e14dcfSSatish Balay 472d8d19677SJose E. Roman Input Parameters: 473441846f8SBarry Smith + tao - the Tao context 474a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 475a7e14dcfSSatish Balay . func - the gradient function 476a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 4776c23d075SBarry Smith routine (may be NULL) 478a7e14dcfSSatish Balay 479a7e14dcfSSatish Balay Calling sequence of func: 480441846f8SBarry Smith $ func (Tao tao, Vec x, Vec g, void *ctx); 481a7e14dcfSSatish Balay 482a7e14dcfSSatish Balay + x - input vector 483a7e14dcfSSatish Balay . g - gradient value (output) 484a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 485a7e14dcfSSatish Balay 486a7e14dcfSSatish Balay Level: beginner 487a7e14dcfSSatish Balay 488*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetGradient()` 489a7e14dcfSSatish Balay @*/ 490a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx) 491a7e14dcfSSatish Balay { 492a7e14dcfSSatish Balay PetscFunctionBegin; 493441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 494a82e8c82SStefano Zampini if (g) { 495a82e8c82SStefano Zampini PetscValidHeaderSpecific(g,VEC_CLASSID,2); 496a82e8c82SStefano Zampini PetscCheckSameComm(tao,1,g,2); 4979566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 4989566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 499a82e8c82SStefano Zampini tao->gradient = g; 500a82e8c82SStefano Zampini } 501a82e8c82SStefano Zampini if (func) tao->ops->computegradient = func; 502a82e8c82SStefano Zampini if (ctx) tao->user_gradP = ctx; 503a7e14dcfSSatish Balay PetscFunctionReturn(0); 504a7e14dcfSSatish Balay } 505a7e14dcfSSatish Balay 506a7e14dcfSSatish Balay /*@C 507*65ba42b6SBarry Smith TaoGetGradient - Gets the gradient evaluation routine for the function being optimized 508a82e8c82SStefano Zampini 509a82e8c82SStefano Zampini Not collective 510a82e8c82SStefano Zampini 511a82e8c82SStefano Zampini Input Parameter: 512a82e8c82SStefano Zampini . tao - the Tao context 513a82e8c82SStefano Zampini 514a82e8c82SStefano Zampini Output Parameters: 515a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation 516a82e8c82SStefano Zampini . func - the gradient function 517a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 518a82e8c82SStefano Zampini 519a82e8c82SStefano Zampini Calling sequence of func: 520a82e8c82SStefano Zampini $ func (Tao tao, Vec x, Vec g, void *ctx); 521a82e8c82SStefano Zampini 522a82e8c82SStefano Zampini + x - input vector 523a82e8c82SStefano Zampini . g - gradient value (output) 524a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 525a82e8c82SStefano Zampini 526a82e8c82SStefano Zampini Level: beginner 527a82e8c82SStefano Zampini 528*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetGradient()` 529a82e8c82SStefano Zampini @*/ 530a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx) 531a82e8c82SStefano Zampini { 532a82e8c82SStefano Zampini PetscFunctionBegin; 533a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 534a82e8c82SStefano Zampini if (g) *g = tao->gradient; 535a82e8c82SStefano Zampini if (func) *func = tao->ops->computegradient; 536a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_gradP; 537a82e8c82SStefano Zampini PetscFunctionReturn(0); 538a82e8c82SStefano Zampini } 539a82e8c82SStefano Zampini 540a82e8c82SStefano Zampini /*@C 541*65ba42b6SBarry Smith TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for the function to be optimized 542a7e14dcfSSatish Balay 543*65ba42b6SBarry Smith Logically collective on tao 544a7e14dcfSSatish Balay 545d8d19677SJose E. Roman Input Parameters: 546441846f8SBarry Smith + tao - the Tao context 547a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation 548a7e14dcfSSatish Balay . func - the gradient function 549a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation 5506c23d075SBarry Smith routine (may be NULL) 551a7e14dcfSSatish Balay 552a7e14dcfSSatish Balay Calling sequence of func: 55317477c02SJason Sarich $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 554a7e14dcfSSatish Balay 555a7e14dcfSSatish Balay + x - input vector 55617477c02SJason Sarich . f - objective value (output) 557a7e14dcfSSatish Balay . g - gradient value (output) 558a7e14dcfSSatish Balay - ctx - [optional] user-defined function context 559a7e14dcfSSatish Balay 560a7e14dcfSSatish Balay Level: beginner 561a7e14dcfSSatish Balay 562*65ba42b6SBarry Smith Note: 563*65ba42b6SBarry Smith For some optimization methods using a combined function can be more eifficient. 564*65ba42b6SBarry Smith 565*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetGradient()`, `TaoGetObjectiveAndGradient()` 566a7e14dcfSSatish Balay @*/ 567a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx) 568a82e8c82SStefano Zampini { 569a82e8c82SStefano Zampini PetscFunctionBegin; 570a82e8c82SStefano Zampini PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 571a82e8c82SStefano Zampini if (g) { 572a82e8c82SStefano Zampini PetscValidHeaderSpecific(g,VEC_CLASSID,2); 573a82e8c82SStefano Zampini PetscCheckSameComm(tao,1,g,2); 5749566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)g)); 5759566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tao->gradient)); 576a82e8c82SStefano Zampini tao->gradient = g; 577a82e8c82SStefano Zampini } 578a82e8c82SStefano Zampini if (ctx) tao->user_objgradP = ctx; 579a82e8c82SStefano Zampini if (func) tao->ops->computeobjectiveandgradient = func; 580a82e8c82SStefano Zampini PetscFunctionReturn(0); 581a82e8c82SStefano Zampini } 582a82e8c82SStefano Zampini 583a82e8c82SStefano Zampini /*@C 584*65ba42b6SBarry Smith TaoGetObjectiveAndGradient - Gets the combined objective function and gradient evaluation routine for the function to be optimized 585a82e8c82SStefano Zampini 586a82e8c82SStefano Zampini Not collective 587a82e8c82SStefano Zampini 588a82e8c82SStefano Zampini Input Parameter: 589a82e8c82SStefano Zampini . tao - the Tao context 590a82e8c82SStefano Zampini 591a82e8c82SStefano Zampini Output Parameters: 592817da375SSatish Balay + g - the vector to internally hold the gradient computation 593a82e8c82SStefano Zampini . func - the gradient function 594a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine 595a82e8c82SStefano Zampini 596a82e8c82SStefano Zampini Calling sequence of func: 597a82e8c82SStefano Zampini $ func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx); 598a82e8c82SStefano Zampini 599a82e8c82SStefano Zampini + x - input vector 600a82e8c82SStefano Zampini . f - objective value (output) 601a82e8c82SStefano Zampini . g - gradient value (output) 602a82e8c82SStefano Zampini - ctx - [optional] user-defined function context 603a82e8c82SStefano Zampini 604a82e8c82SStefano Zampini Level: beginner 605a82e8c82SStefano Zampini 606*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSolve()`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()` 607a82e8c82SStefano Zampini @*/ 608a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx) 609a7e14dcfSSatish Balay { 610a7e14dcfSSatish Balay PetscFunctionBegin; 611441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 612a82e8c82SStefano Zampini if (g) *g = tao->gradient; 613a82e8c82SStefano Zampini if (func) *func = tao->ops->computeobjectiveandgradient; 614a82e8c82SStefano Zampini if (ctx) *ctx = tao->user_objgradP; 615a7e14dcfSSatish Balay PetscFunctionReturn(0); 616a7e14dcfSSatish Balay } 617a7e14dcfSSatish Balay 618a7e14dcfSSatish Balay /*@ 619a82e8c82SStefano Zampini TaoIsObjectiveDefined - Checks to see if the user has 620a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 621*65ba42b6SBarry Smith it is appropriate to call `TaoComputeObjective()` or 622*65ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` 623a7e14dcfSSatish Balay 624a82e8c82SStefano Zampini Not collective 625a7e14dcfSSatish Balay 626a82e8c82SStefano Zampini Input Parameter: 627a82e8c82SStefano Zampini . tao - the Tao context 628a82e8c82SStefano Zampini 629a82e8c82SStefano Zampini Output Parameter: 630*65ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 631a82e8c82SStefano Zampini 632a7e14dcfSSatish Balay Level: developer 633a7e14dcfSSatish Balay 634*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetObjective()`, `TaoIsGradientDefined()`, `TaoIsObjectiveAndGradientDefined()` 635a7e14dcfSSatish Balay @*/ 636441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg) 637a7e14dcfSSatish Balay { 638a7e14dcfSSatish Balay PetscFunctionBegin; 639441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 64083c8fe1dSLisandro Dalcin if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE; 64145cf516eSBarry Smith else *flg = PETSC_TRUE; 642a7e14dcfSSatish Balay PetscFunctionReturn(0); 643a7e14dcfSSatish Balay } 644a7e14dcfSSatish Balay 645a7e14dcfSSatish Balay /*@ 646a82e8c82SStefano Zampini TaoIsGradientDefined - Checks to see if the user has 647a7e14dcfSSatish Balay declared an objective-only routine. Useful for determining when 648*65ba42b6SBarry Smith it is appropriate to call `TaoComputeGradient()` or 649*65ba42b6SBarry Smith `TaoComputeGradientAndGradient()` 650a7e14dcfSSatish Balay 651a7e14dcfSSatish Balay Not Collective 652a7e14dcfSSatish Balay 653a82e8c82SStefano Zampini Input Parameter: 654a82e8c82SStefano Zampini . tao - the Tao context 655a82e8c82SStefano Zampini 656a82e8c82SStefano Zampini Output Parameter: 657*65ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 658a82e8c82SStefano Zampini 659a7e14dcfSSatish Balay Level: developer 660a7e14dcfSSatish Balay 661db781477SPatrick Sanan .seealso: `TaoSetGradient()`, `TaoIsObjectiveDefined()`, `TaoIsObjectiveAndGradientDefined()` 662a7e14dcfSSatish Balay @*/ 663441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg) 664a7e14dcfSSatish Balay { 665a7e14dcfSSatish Balay PetscFunctionBegin; 666441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 66783c8fe1dSLisandro Dalcin if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE; 66845cf516eSBarry Smith else *flg = PETSC_TRUE; 669a7e14dcfSSatish Balay PetscFunctionReturn(0); 670a7e14dcfSSatish Balay } 671a7e14dcfSSatish Balay 672a7e14dcfSSatish Balay /*@ 673a82e8c82SStefano Zampini TaoIsObjectiveAndGradientDefined - Checks to see if the user has 674a7e14dcfSSatish Balay declared a joint objective/gradient routine. Useful for determining when 675*65ba42b6SBarry Smith it is appropriate to call `TaoComputeObjective()` or 676*65ba42b6SBarry Smith `TaoComputeObjectiveAndGradient()` 677a7e14dcfSSatish Balay 678a7e14dcfSSatish Balay Not Collective 679a7e14dcfSSatish Balay 680a82e8c82SStefano Zampini Input Parameter: 681a82e8c82SStefano Zampini . tao - the Tao context 682a82e8c82SStefano Zampini 683a82e8c82SStefano Zampini Output Parameter: 684*65ba42b6SBarry Smith . flg - `PETSC_TRUE` if function routine is set by user, `PETSC_FALSE` otherwise 685a82e8c82SStefano Zampini 686a7e14dcfSSatish Balay Level: developer 687a7e14dcfSSatish Balay 688db781477SPatrick Sanan .seealso: `TaoSetObjectiveAndGradient()`, `TaoIsObjectiveDefined()`, `TaoIsGradientDefined()` 689a7e14dcfSSatish Balay @*/ 690441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg) 691a7e14dcfSSatish Balay { 692a7e14dcfSSatish Balay PetscFunctionBegin; 693441846f8SBarry Smith PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 69483c8fe1dSLisandro Dalcin if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE; 69545cf516eSBarry Smith else *flg = PETSC_TRUE; 696a7e14dcfSSatish Balay PetscFunctionReturn(0); 697a7e14dcfSSatish Balay } 698