xref: /petsc/src/tao/interface/taosolver_fg.c (revision 817da375e672db5c7e13659b00b476f4f84762da)
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
13a82e8c82SStefano Zampini .seealso: TaoCreate(), TaoSolve(), TaoGetSolution()
14a7e14dcfSSatish Balay @*/
15a82e8c82SStefano Zampini PetscErrorCode TaoSetSolution(Tao tao, Vec x0)
1645cf516eSBarry Smith {
17a7e14dcfSSatish Balay   PetscErrorCode ierr;
18a7e14dcfSSatish Balay 
19a7e14dcfSSatish Balay   PetscFunctionBegin;
20441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
21a82e8c82SStefano Zampini   if (x0) PetscValidHeaderSpecific(x0,VEC_CLASSID,2);
22a82e8c82SStefano Zampini   ierr = PetscObjectReference((PetscObject)x0);CHKERRQ(ierr);
23a7e14dcfSSatish Balay   ierr = VecDestroy(&tao->solution);CHKERRQ(ierr);
24a7e14dcfSSatish Balay   tao->solution = x0;
25a7e14dcfSSatish Balay   PetscFunctionReturn(0);
26a7e14dcfSSatish Balay }
27a7e14dcfSSatish Balay 
28412cdd55SHong Zhang PetscErrorCode TaoTestGradient(Tao tao,Vec x,Vec g1)
2909baa881SHong Zhang {
30412cdd55SHong Zhang   Vec               g2,g3;
3109baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE;
3209baa881SHong Zhang   PetscReal         hcnorm,fdnorm,hcmax,fdmax,diffmax,diffnorm;
3309baa881SHong Zhang   PetscScalar       dot;
3409baa881SHong Zhang   MPI_Comm          comm;
35913eda9aSHong Zhang   PetscViewer       viewer,mviewer;
36913eda9aSHong Zhang   PetscViewerFormat format;
3709baa881SHong Zhang   PetscInt          tabs;
3809baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
3909baa881SHong Zhang   PetscErrorCode    ierr;
4009baa881SHong Zhang 
4109baa881SHong Zhang   PetscFunctionBegin;
4209baa881SHong Zhang   ierr = PetscObjectOptionsBegin((PetscObject)tao);CHKERRQ(ierr);
4309baa881SHong Zhang   ierr = PetscOptionsName("-tao_test_gradient","Compare hand-coded and finite difference Gradients","None",&test);CHKERRQ(ierr);
44913eda9aSHong Zhang   ierr = PetscOptionsViewer("-tao_test_gradient_view","View difference between hand-coded and finite difference Gradients element entries","None",&mviewer,&format,&complete_print);CHKERRQ(ierr);
4509baa881SHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
462f4b6201SAlp Dener   if (!test) {
472f4b6201SAlp Dener     if (complete_print) {
482f4b6201SAlp Dener       ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr);
492f4b6201SAlp Dener     }
502f4b6201SAlp Dener     PetscFunctionReturn(0);
512f4b6201SAlp Dener   }
5209baa881SHong Zhang 
5309baa881SHong Zhang   ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr);
5409baa881SHong Zhang   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
5509baa881SHong Zhang   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
5609baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);CHKERRQ(ierr);
5709baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Gradient -------------\n");CHKERRQ(ierr);
5809baa881SHong Zhang   if (!complete_print && !directionsprinted) {
5909baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_gradient_view and optionally -tao_test_gradient <threshold> to show difference\n");CHKERRQ(ierr);
6009baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference gradient entries greater than <threshold>.\n");CHKERRQ(ierr);
6109baa881SHong Zhang   }
6209baa881SHong Zhang   if (!directionsprinted) {
6387cb359fSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Gradient, if (for double precision runs) ||G - Gfd||/||G|| is\n");CHKERRQ(ierr);
64ae75128cSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Gradient is probably correct.\n");CHKERRQ(ierr);
6509baa881SHong Zhang     directionsprinted = PETSC_TRUE;
6609baa881SHong Zhang   }
67913eda9aSHong Zhang   if (complete_print) {
68913eda9aSHong Zhang     ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr);
69913eda9aSHong Zhang   }
7009baa881SHong Zhang 
7109baa881SHong Zhang   ierr = VecDuplicate(x,&g2);CHKERRQ(ierr);
7209baa881SHong Zhang   ierr = VecDuplicate(x,&g3);CHKERRQ(ierr);
7309baa881SHong Zhang 
7409baa881SHong Zhang   /* Compute finite difference gradient, assume the gradient is already computed by TaoComputeGradient() and put into g1 */
7509baa881SHong Zhang   ierr = TaoDefaultComputeGradient(tao,x,g2,NULL);CHKERRQ(ierr);
7609baa881SHong Zhang 
7709baa881SHong Zhang   ierr = VecNorm(g2,NORM_2,&fdnorm);CHKERRQ(ierr);
7809baa881SHong Zhang   ierr = VecNorm(g1,NORM_2,&hcnorm);CHKERRQ(ierr);
7909baa881SHong Zhang   ierr = VecNorm(g2,NORM_INFINITY,&fdmax);CHKERRQ(ierr);
8009baa881SHong Zhang   ierr = VecNorm(g1,NORM_INFINITY,&hcmax);CHKERRQ(ierr);
8109baa881SHong Zhang   ierr = VecDot(g1,g2,&dot);CHKERRQ(ierr);
8209baa881SHong Zhang   ierr = VecCopy(g1,g3);CHKERRQ(ierr);
8309baa881SHong Zhang   ierr = VecAXPY(g3,-1.0,g2);CHKERRQ(ierr);
8409baa881SHong Zhang   ierr = VecNorm(g3,NORM_2,&diffnorm);CHKERRQ(ierr);
8509baa881SHong Zhang   ierr = VecNorm(g3,NORM_INFINITY,&diffmax);CHKERRQ(ierr);
8609baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ||Gfd|| %g, ||G|| = %g, angle cosine = (Gfd'G)/||Gfd||||G|| = %g\n", (double)fdnorm, (double)hcnorm, (double)(PetscRealPart(dot)/(fdnorm*hcnorm)));CHKERRQ(ierr);
8709baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  2-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffnorm/PetscMax(hcnorm,fdnorm)),(double)diffnorm);CHKERRQ(ierr);
8809baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  max-norm ||G - Gfd||/||G|| = %g, ||G - Gfd|| = %g\n",(double)(diffmax/PetscMax(hcmax,fdmax)),(double)diffmax);CHKERRQ(ierr);
8909baa881SHong Zhang 
9009baa881SHong Zhang   if (complete_print) {
9109baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded gradient ----------\n");CHKERRQ(ierr);
92913eda9aSHong Zhang     ierr = VecView(g1,mviewer);CHKERRQ(ierr);
9309baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference gradient ----------\n");CHKERRQ(ierr);
94913eda9aSHong Zhang     ierr = VecView(g2,mviewer);CHKERRQ(ierr);
9509baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference gradient ----------\n");CHKERRQ(ierr);
96913eda9aSHong Zhang     ierr = VecView(g3,mviewer);CHKERRQ(ierr);
9709baa881SHong Zhang   }
9809baa881SHong Zhang   ierr = VecDestroy(&g2);CHKERRQ(ierr);
9909baa881SHong Zhang   ierr = VecDestroy(&g3);CHKERRQ(ierr);
100913eda9aSHong Zhang 
101913eda9aSHong Zhang   if (complete_print) {
102913eda9aSHong Zhang     ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr);
1032f4b6201SAlp Dener     ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr);
104913eda9aSHong Zhang   }
105913eda9aSHong Zhang   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
10609baa881SHong Zhang   PetscFunctionReturn(0);
10709baa881SHong Zhang }
10809baa881SHong Zhang 
109a7e14dcfSSatish Balay /*@
110a7e14dcfSSatish Balay   TaoComputeGradient - Computes the gradient of the objective function
111a7e14dcfSSatish Balay 
112441846f8SBarry Smith   Collective on Tao
113a7e14dcfSSatish Balay 
114a7e14dcfSSatish Balay   Input Parameters:
115441846f8SBarry Smith + tao - the Tao context
116a7e14dcfSSatish Balay - X - input vector
117a7e14dcfSSatish Balay 
118a7e14dcfSSatish Balay   Output Parameter:
119a7e14dcfSSatish Balay . G - gradient vector
120a7e14dcfSSatish Balay 
12109baa881SHong Zhang   Options Database Keys:
12209baa881SHong Zhang +    -tao_test_gradient - compare the user provided gradient with one compute via finite differences to check for errors
123dfe02fe6SHong 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
12409baa881SHong Zhang 
12595452b02SPatrick Sanan   Notes:
12695452b02SPatrick Sanan     TaoComputeGradient() is typically used within minimization implementations,
127a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
128a7e14dcfSSatish Balay 
129a7e14dcfSSatish Balay   Level: advanced
130a7e14dcfSSatish Balay 
131a82e8c82SStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetGradient()
132a7e14dcfSSatish Balay @*/
133441846f8SBarry Smith PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G)
134a7e14dcfSSatish Balay {
135a7e14dcfSSatish Balay   PetscErrorCode ierr;
136a7e14dcfSSatish Balay   PetscReal      dummy;
13787f595a5SBarry Smith 
138a7e14dcfSSatish Balay   PetscFunctionBegin;
139441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
140a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
141064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(G,VEC_CLASSID,3);
142a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
143a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,3);
1448860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
145a7e14dcfSSatish Balay   if (tao->ops->computegradient) {
1460ebee16dSLisandro Dalcin     ierr = PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL);CHKERRQ(ierr);
147441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
148a7e14dcfSSatish Balay     ierr = (*tao->ops->computegradient)(tao,X,G,tao->user_gradP);CHKERRQ(ierr);
149a7e14dcfSSatish Balay     PetscStackPop;
1500ebee16dSLisandro Dalcin     ierr = PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL);CHKERRQ(ierr);
151a7e14dcfSSatish Balay     tao->ngrads++;
152a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
1530ebee16dSLisandro Dalcin     ierr = PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL);CHKERRQ(ierr);
154a7e14dcfSSatish Balay     PetscStackPush("Tao user objective/gradient evaluation routine");
155a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP);CHKERRQ(ierr);
156a7e14dcfSSatish Balay     PetscStackPop;
1570ebee16dSLisandro Dalcin     ierr = PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL);CHKERRQ(ierr);
158a7e14dcfSSatish Balay     tao->nfuncgrads++;
159a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradient() has not been called");
1608860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
16109baa881SHong Zhang 
162412cdd55SHong Zhang   ierr = TaoTestGradient(tao,X,G);CHKERRQ(ierr);
163a7e14dcfSSatish Balay   PetscFunctionReturn(0);
164a7e14dcfSSatish Balay }
165a7e14dcfSSatish Balay 
166a7e14dcfSSatish Balay /*@
167a7e14dcfSSatish Balay   TaoComputeObjective - Computes the objective function value at a given point
168a7e14dcfSSatish Balay 
169441846f8SBarry Smith   Collective on Tao
170a7e14dcfSSatish Balay 
171a7e14dcfSSatish Balay   Input Parameters:
172441846f8SBarry Smith + tao - the Tao context
173a7e14dcfSSatish Balay - X - input vector
174a7e14dcfSSatish Balay 
175a7e14dcfSSatish Balay   Output Parameter:
176a7e14dcfSSatish Balay . f - Objective value at X
177a7e14dcfSSatish Balay 
17895452b02SPatrick Sanan   Notes:
17995452b02SPatrick Sanan     TaoComputeObjective() is typically used within minimization implementations,
180a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
181a7e14dcfSSatish Balay 
182a7e14dcfSSatish Balay   Level: advanced
183a7e14dcfSSatish Balay 
184a82e8c82SStefano Zampini .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjective()
185a7e14dcfSSatish Balay @*/
186441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f)
187a7e14dcfSSatish Balay {
188a7e14dcfSSatish Balay   PetscErrorCode ierr;
189a7e14dcfSSatish Balay   Vec            temp;
19087f595a5SBarry Smith 
191a7e14dcfSSatish Balay   PetscFunctionBegin;
192441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
193a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
194a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
1958860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
196a7e14dcfSSatish Balay   if (tao->ops->computeobjective) {
1970ebee16dSLisandro Dalcin     ierr = PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
198441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
199a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjective)(tao,X,f,tao->user_objP);CHKERRQ(ierr);
200a7e14dcfSSatish Balay     PetscStackPop;
2010ebee16dSLisandro Dalcin     ierr = PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
202a7e14dcfSSatish Balay     tao->nfuncs++;
203a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
204955c1f14SBarry Smith     ierr = PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n");CHKERRQ(ierr);
205a7e14dcfSSatish Balay     ierr = VecDuplicate(X,&temp);CHKERRQ(ierr);
2060ebee16dSLisandro Dalcin     ierr = PetscLogEventBegin(TAO_ObjGradEval,tao,X,NULL,NULL);CHKERRQ(ierr);
207441846f8SBarry Smith     PetscStackPush("Tao user objective/gradient evaluation routine");
208a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP);CHKERRQ(ierr);
209a7e14dcfSSatish Balay     PetscStackPop;
2100ebee16dSLisandro Dalcin     ierr = PetscLogEventEnd(TAO_ObjGradEval,tao,X,NULL,NULL);CHKERRQ(ierr);
211a7e14dcfSSatish Balay     ierr = VecDestroy(&temp);CHKERRQ(ierr);
212a7e14dcfSSatish Balay     tao->nfuncgrads++;
213a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() has not been called");
2147d3de750SJacob Faibussowitsch   ierr = PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f));CHKERRQ(ierr);
2158860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
216a7e14dcfSSatish Balay   PetscFunctionReturn(0);
217a7e14dcfSSatish Balay }
218a7e14dcfSSatish Balay 
219a7e14dcfSSatish Balay /*@
220a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point
221a7e14dcfSSatish Balay 
222441846f8SBarry Smith   Collective on Tao
223a7e14dcfSSatish Balay 
224a7e14dcfSSatish Balay   Input Parameters:
225441846f8SBarry Smith + tao - the Tao context
226a7e14dcfSSatish Balay - X - input vector
227a7e14dcfSSatish Balay 
228d8d19677SJose E. Roman   Output Parameters:
229a7e14dcfSSatish Balay + f - Objective value at X
230a7e14dcfSSatish Balay - g - Gradient vector at X
231a7e14dcfSSatish Balay 
23295452b02SPatrick Sanan   Notes:
23395452b02SPatrick Sanan     TaoComputeObjectiveAndGradient() is typically used within minimization implementations,
234a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
235a7e14dcfSSatish Balay 
236a7e14dcfSSatish Balay   Level: advanced
237a7e14dcfSSatish Balay 
238a82e8c82SStefano Zampini .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjective()
239a7e14dcfSSatish Balay @*/
240441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G)
241a7e14dcfSSatish Balay {
242a7e14dcfSSatish Balay   PetscErrorCode ierr;
24387f595a5SBarry Smith 
244a7e14dcfSSatish Balay   PetscFunctionBegin;
245441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
246a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
247a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G,VEC_CLASSID,4);
248a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
249a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,4);
2508860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
251a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient) {
2520ebee16dSLisandro Dalcin     ierr = PetscLogEventBegin(TAO_ObjGradEval,tao,X,G,NULL);CHKERRQ(ierr);
253f4c1ad5cSStefano Zampini     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
254f4c1ad5cSStefano Zampini       ierr = TaoComputeObjective(tao,X,f);CHKERRQ(ierr);
255f4c1ad5cSStefano Zampini       ierr = TaoDefaultComputeGradient(tao,X,G,NULL);CHKERRQ(ierr);
256f4c1ad5cSStefano Zampini     } else {
257441846f8SBarry Smith       PetscStackPush("Tao user objective/gradient evaluation routine");
258a7e14dcfSSatish Balay       ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP);CHKERRQ(ierr);
2590cbffdbaSBarry Smith       PetscStackPop;
260a7e14dcfSSatish Balay     }
2610ebee16dSLisandro Dalcin     ierr = PetscLogEventEnd(TAO_ObjGradEval,tao,X,G,NULL);CHKERRQ(ierr);
262a7e14dcfSSatish Balay     tao->nfuncgrads++;
263a7e14dcfSSatish Balay   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
2640ebee16dSLisandro Dalcin     ierr = PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
265441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
266a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjective)(tao,X,f,tao->user_objP);CHKERRQ(ierr);
267a7e14dcfSSatish Balay     PetscStackPop;
2680ebee16dSLisandro Dalcin     ierr = PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
269a7e14dcfSSatish Balay     tao->nfuncs++;
2700ebee16dSLisandro Dalcin     ierr = PetscLogEventBegin(TAO_GradientEval,tao,X,G,NULL);CHKERRQ(ierr);
271441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
272a7e14dcfSSatish Balay     ierr = (*tao->ops->computegradient)(tao,X,G,tao->user_gradP);CHKERRQ(ierr);
273a7e14dcfSSatish Balay     PetscStackPop;
2740ebee16dSLisandro Dalcin     ierr = PetscLogEventEnd(TAO_GradientEval,tao,X,G,NULL);CHKERRQ(ierr);
275a7e14dcfSSatish Balay     tao->ngrads++;
276a82e8c82SStefano Zampini   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjective() or TaoSetGradient() not set");
2777d3de750SJacob Faibussowitsch   ierr = PetscInfo(tao,"TAO Function evaluation: %20.19e\n",(double)(*f));CHKERRQ(ierr);
2788860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
2791657496cSHong Zhang 
280412cdd55SHong Zhang   ierr = TaoTestGradient(tao,X,G);CHKERRQ(ierr);
281a7e14dcfSSatish Balay   PetscFunctionReturn(0);
282a7e14dcfSSatish Balay }
283a7e14dcfSSatish Balay 
284a7e14dcfSSatish Balay /*@C
285a82e8c82SStefano Zampini   TaoSetObjective - Sets the function evaluation routine for minimization
286a7e14dcfSSatish Balay 
287441846f8SBarry Smith   Logically collective on Tao
288a7e14dcfSSatish Balay 
289d8d19677SJose E. Roman   Input Parameters:
290441846f8SBarry Smith + tao - the Tao context
291a7e14dcfSSatish Balay . func - the objective function
292a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2936c23d075SBarry Smith         routine (may be NULL)
294a7e14dcfSSatish Balay 
295a7e14dcfSSatish Balay   Calling sequence of func:
296441846f8SBarry Smith $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
297a7e14dcfSSatish Balay 
298a7e14dcfSSatish Balay + x - input vector
299a7e14dcfSSatish Balay . f - function value
300a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
301a7e14dcfSSatish Balay 
302a7e14dcfSSatish Balay   Level: beginner
303a7e14dcfSSatish Balay 
304a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoGetObjective()
305a7e14dcfSSatish Balay @*/
306a82e8c82SStefano Zampini PetscErrorCode TaoSetObjective(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx)
307a7e14dcfSSatish Balay {
308a7e14dcfSSatish Balay   PetscFunctionBegin;
309441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
310a82e8c82SStefano Zampini   if (ctx) tao->user_objP = ctx;
311a82e8c82SStefano Zampini   if (func) tao->ops->computeobjective = func;
312a82e8c82SStefano Zampini   PetscFunctionReturn(0);
313a82e8c82SStefano Zampini }
314a82e8c82SStefano Zampini 
315a82e8c82SStefano Zampini /*@C
316a82e8c82SStefano Zampini   TaoGetObjective - Gets the function evaluation routine for minimization
317a82e8c82SStefano Zampini 
318a82e8c82SStefano Zampini   Not collective
319a82e8c82SStefano Zampini 
320a82e8c82SStefano Zampini   Input Parameter:
321a82e8c82SStefano Zampini . tao - the Tao context
322a82e8c82SStefano Zampini 
323a82e8c82SStefano Zampini   Output Parameters
324a82e8c82SStefano Zampini + func - the objective function
325a82e8c82SStefano Zampini - ctx - the user-defined context for private data for the function evaluation
326a82e8c82SStefano Zampini 
327a82e8c82SStefano Zampini   Calling sequence of func:
328a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
329a82e8c82SStefano Zampini 
330a82e8c82SStefano Zampini + x - input vector
331a82e8c82SStefano Zampini . f - function value
332a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
333a82e8c82SStefano Zampini 
334a82e8c82SStefano Zampini   Level: beginner
335a82e8c82SStefano Zampini 
336a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoSetHessian(), TaoSetObjective()
337a82e8c82SStefano Zampini @*/
338a82e8c82SStefano Zampini PetscErrorCode TaoGetObjective(Tao tao, PetscErrorCode (**func)(Tao, Vec, PetscReal*,void*),void **ctx)
339a82e8c82SStefano Zampini {
340a82e8c82SStefano Zampini   PetscFunctionBegin;
341a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
342a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjective;
343a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objP;
344a7e14dcfSSatish Balay   PetscFunctionReturn(0);
345a7e14dcfSSatish Balay }
346a7e14dcfSSatish Balay 
347a7e14dcfSSatish Balay /*@C
3484a48860cSAlp Dener   TaoSetResidualRoutine - Sets the residual evaluation routine for least-square applications
349a7e14dcfSSatish Balay 
350441846f8SBarry Smith   Logically collective on Tao
351a7e14dcfSSatish Balay 
352d8d19677SJose E. Roman   Input Parameters:
353441846f8SBarry Smith + tao - the Tao context
3544a48860cSAlp Dener . func - the residual evaluation routine
355a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
3566c23d075SBarry Smith         routine (may be NULL)
357a7e14dcfSSatish Balay 
358a7e14dcfSSatish Balay   Calling sequence of func:
359441846f8SBarry Smith $      func (Tao tao, Vec x, Vec f, void *ctx);
360a7e14dcfSSatish Balay 
361a7e14dcfSSatish Balay + x - input vector
362a7e14dcfSSatish Balay . f - function value vector
363a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
364a7e14dcfSSatish Balay 
365a7e14dcfSSatish Balay   Level: beginner
366a7e14dcfSSatish Balay 
367a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetJacobianRoutine()
368a7e14dcfSSatish Balay @*/
3694a48860cSAlp Dener PetscErrorCode TaoSetResidualRoutine(Tao tao, Vec res, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
370a7e14dcfSSatish Balay {
371737f463aSAlp Dener   PetscErrorCode ierr;
372737f463aSAlp Dener 
373a7e14dcfSSatish Balay   PetscFunctionBegin;
374441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3754a48860cSAlp Dener   PetscValidHeaderSpecific(res,VEC_CLASSID,2);
3764ffbe8acSAlp Dener   ierr = PetscObjectReference((PetscObject)res);CHKERRQ(ierr);
377737f463aSAlp Dener   if (tao->ls_res) {
378737f463aSAlp Dener     ierr = VecDestroy(&tao->ls_res);CHKERRQ(ierr);
379737f463aSAlp Dener   }
3804a48860cSAlp Dener   tao->ls_res = res;
3814ffbe8acSAlp Dener   tao->user_lsresP = ctx;
3824a48860cSAlp Dener   tao->ops->computeresidual = func;
383737f463aSAlp Dener 
384737f463aSAlp Dener   PetscFunctionReturn(0);
385737f463aSAlp Dener }
386737f463aSAlp Dener 
387737f463aSAlp Dener /*@
388737f463aSAlp 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.
389737f463aSAlp Dener 
390737f463aSAlp Dener   Collective on Tao
391737f463aSAlp Dener 
392737f463aSAlp Dener   Input Parameters:
393737f463aSAlp Dener + tao - the Tao context
394737f463aSAlp Dener . sigma_v - vector of weights (diagonal terms only)
395737f463aSAlp Dener . n       - the number of weights (if using off-diagonal)
396737f463aSAlp Dener . rows    - index list of rows for sigma_w
397737f463aSAlp Dener . cols    - index list of columns for sigma_w
398737f463aSAlp Dener - vals - array of weights
399737f463aSAlp Dener 
400737f463aSAlp Dener   Note: Either sigma_v or sigma_w (or both) should be NULL
401737f463aSAlp Dener 
402737f463aSAlp Dener   Level: intermediate
403737f463aSAlp Dener 
404737f463aSAlp Dener .seealso: TaoSetResidualRoutine()
405737f463aSAlp Dener @*/
406737f463aSAlp Dener PetscErrorCode TaoSetResidualWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals)
407737f463aSAlp Dener {
408737f463aSAlp Dener   PetscErrorCode ierr;
409737f463aSAlp Dener   PetscInt       i;
410a82e8c82SStefano Zampini 
411737f463aSAlp Dener   PetscFunctionBegin;
412737f463aSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
413a82e8c82SStefano Zampini   if (sigma_v) PetscValidHeaderSpecific(sigma_v,VEC_CLASSID,2);
414737f463aSAlp Dener   ierr = PetscObjectReference((PetscObject)sigma_v);CHKERRQ(ierr);
4154ffbe8acSAlp Dener   ierr = VecDestroy(&tao->res_weights_v);CHKERRQ(ierr);
4164ffbe8acSAlp Dener   tao->res_weights_v = sigma_v;
417737f463aSAlp Dener   if (vals) {
418737f463aSAlp Dener     ierr = PetscFree(tao->res_weights_rows);CHKERRQ(ierr);
419737f463aSAlp Dener     ierr = PetscFree(tao->res_weights_cols);CHKERRQ(ierr);
420737f463aSAlp Dener     ierr = PetscFree(tao->res_weights_w);CHKERRQ(ierr);
421737f463aSAlp Dener     ierr = PetscMalloc1(n,&tao->res_weights_rows);CHKERRQ(ierr);
422737f463aSAlp Dener     ierr = PetscMalloc1(n,&tao->res_weights_cols);CHKERRQ(ierr);
423737f463aSAlp Dener     ierr = PetscMalloc1(n,&tao->res_weights_w);CHKERRQ(ierr);
424737f463aSAlp Dener     tao->res_weights_n = n;
425737f463aSAlp Dener     for (i=0;i<n;i++) {
426737f463aSAlp Dener       tao->res_weights_rows[i] = rows[i];
427737f463aSAlp Dener       tao->res_weights_cols[i] = cols[i];
428737f463aSAlp Dener       tao->res_weights_w[i] = vals[i];
429737f463aSAlp Dener     }
430737f463aSAlp Dener   } else {
431737f463aSAlp Dener     tao->res_weights_n = 0;
43283c8fe1dSLisandro Dalcin     tao->res_weights_rows = NULL;
43383c8fe1dSLisandro Dalcin     tao->res_weights_cols = NULL;
434737f463aSAlp Dener   }
435a7e14dcfSSatish Balay   PetscFunctionReturn(0);
436a7e14dcfSSatish Balay }
437a7e14dcfSSatish Balay 
4388b7a9b22SJason Sarich /*@
4394a48860cSAlp Dener   TaoComputeResidual - Computes a least-squares residual vector at a given point
440a7e14dcfSSatish Balay 
441441846f8SBarry Smith   Collective on Tao
442a7e14dcfSSatish Balay 
443a7e14dcfSSatish Balay   Input Parameters:
444441846f8SBarry Smith + tao - the Tao context
445a7e14dcfSSatish Balay - X - input vector
446a7e14dcfSSatish Balay 
447a7e14dcfSSatish Balay   Output Parameter:
448a7e14dcfSSatish Balay . f - Objective vector at X
449a7e14dcfSSatish Balay 
45095452b02SPatrick Sanan   Notes:
4514a48860cSAlp Dener     TaoComputeResidual() is typically used within minimization implementations,
452a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
453a7e14dcfSSatish Balay 
454a7e14dcfSSatish Balay   Level: advanced
455a7e14dcfSSatish Balay 
4564a48860cSAlp Dener .seealso: TaoSetResidualRoutine()
457a7e14dcfSSatish Balay @*/
4584a48860cSAlp Dener PetscErrorCode TaoComputeResidual(Tao tao, Vec X, Vec F)
459a7e14dcfSSatish Balay {
460a7e14dcfSSatish Balay   PetscErrorCode ierr;
46187f595a5SBarry Smith 
462a7e14dcfSSatish Balay   PetscFunctionBegin;
463441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
464a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
465a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
466a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
467a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,F,3);
4684a48860cSAlp Dener   if (tao->ops->computeresidual) {
4690ebee16dSLisandro Dalcin     ierr = PetscLogEventBegin(TAO_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
4704a48860cSAlp Dener     PetscStackPush("Tao user least-squares residual evaluation routine");
4714a48860cSAlp Dener     ierr = (*tao->ops->computeresidual)(tao,X,F,tao->user_lsresP);CHKERRQ(ierr);
472a7e14dcfSSatish Balay     PetscStackPop;
4730ebee16dSLisandro Dalcin     ierr = PetscLogEventEnd(TAO_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
474a7e14dcfSSatish Balay     tao->nfuncs++;
475691b26d3SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetResidualRoutine() has not been called");
4764a48860cSAlp Dener   ierr = PetscInfo(tao,"TAO least-squares residual evaluation.\n");CHKERRQ(ierr);
477a7e14dcfSSatish Balay   PetscFunctionReturn(0);
478a7e14dcfSSatish Balay }
479a7e14dcfSSatish Balay 
480a7e14dcfSSatish Balay /*@C
481a82e8c82SStefano Zampini   TaoSetGradient - Sets the gradient evaluation routine for minimization
482a7e14dcfSSatish Balay 
483441846f8SBarry Smith   Logically collective on Tao
484a7e14dcfSSatish Balay 
485d8d19677SJose E. Roman   Input Parameters:
486441846f8SBarry Smith + tao - the Tao context
487a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
488a7e14dcfSSatish Balay . func - the gradient function
489a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
4906c23d075SBarry Smith         routine (may be NULL)
491a7e14dcfSSatish Balay 
492a7e14dcfSSatish Balay   Calling sequence of func:
493441846f8SBarry Smith $      func (Tao tao, Vec x, Vec g, void *ctx);
494a7e14dcfSSatish Balay 
495a7e14dcfSSatish Balay + x - input vector
496a7e14dcfSSatish Balay . g - gradient value (output)
497a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
498a7e14dcfSSatish Balay 
499a7e14dcfSSatish Balay   Level: beginner
500a7e14dcfSSatish Balay 
501a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoGetGradient()
502a7e14dcfSSatish Balay @*/
503a82e8c82SStefano Zampini PetscErrorCode TaoSetGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
504a7e14dcfSSatish Balay {
505a82e8c82SStefano Zampini   PetscErrorCode ierr;
506a82e8c82SStefano Zampini 
507a7e14dcfSSatish Balay   PetscFunctionBegin;
508441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
509a82e8c82SStefano Zampini   if (g) {
510a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
511a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
512a82e8c82SStefano Zampini     ierr = PetscObjectReference((PetscObject)g);CHKERRQ(ierr);
513a82e8c82SStefano Zampini     ierr = VecDestroy(&tao->gradient);CHKERRQ(ierr);
514a82e8c82SStefano Zampini     tao->gradient = g;
515a82e8c82SStefano Zampini   }
516a82e8c82SStefano Zampini   if (func) tao->ops->computegradient = func;
517a82e8c82SStefano Zampini   if (ctx) tao->user_gradP = ctx;
518a7e14dcfSSatish Balay   PetscFunctionReturn(0);
519a7e14dcfSSatish Balay }
520a7e14dcfSSatish Balay 
521a7e14dcfSSatish Balay /*@C
522a82e8c82SStefano Zampini   TaoGetGradient - Gets the gradient evaluation routine for minimization
523a82e8c82SStefano Zampini 
524a82e8c82SStefano Zampini   Not collective
525a82e8c82SStefano Zampini 
526a82e8c82SStefano Zampini   Input Parameter:
527a82e8c82SStefano Zampini . tao - the Tao context
528a82e8c82SStefano Zampini 
529a82e8c82SStefano Zampini   Output Parameters:
530a82e8c82SStefano Zampini + g - the vector to internally hold the gradient computation
531a82e8c82SStefano Zampini . func - the gradient function
532a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
533a82e8c82SStefano Zampini 
534a82e8c82SStefano Zampini   Calling sequence of func:
535a82e8c82SStefano Zampini $      func (Tao tao, Vec x, Vec g, void *ctx);
536a82e8c82SStefano Zampini 
537a82e8c82SStefano Zampini + x - input vector
538a82e8c82SStefano Zampini . g - gradient value (output)
539a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
540a82e8c82SStefano Zampini 
541a82e8c82SStefano Zampini   Level: beginner
542a82e8c82SStefano Zampini 
543a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoSetGradient()
544a82e8c82SStefano Zampini @*/
545a82e8c82SStefano Zampini PetscErrorCode TaoGetGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, Vec, void*),void **ctx)
546a82e8c82SStefano Zampini {
547a82e8c82SStefano Zampini   PetscFunctionBegin;
548a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
549a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
550a82e8c82SStefano Zampini   if (func) *func = tao->ops->computegradient;
551a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_gradP;
552a82e8c82SStefano Zampini   PetscFunctionReturn(0);
553a82e8c82SStefano Zampini }
554a82e8c82SStefano Zampini 
555a82e8c82SStefano Zampini /*@C
556a82e8c82SStefano Zampini   TaoSetObjectiveAndGradient - Sets a combined objective function and gradient evaluation routine for minimization
557a7e14dcfSSatish Balay 
558441846f8SBarry Smith   Logically collective on Tao
559a7e14dcfSSatish Balay 
560d8d19677SJose E. Roman   Input Parameters:
561441846f8SBarry Smith + tao - the Tao context
562a82e8c82SStefano Zampini . g - [optional] the vector to internally hold the gradient computation
563a7e14dcfSSatish Balay . func - the gradient function
564a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
5656c23d075SBarry Smith         routine (may be NULL)
566a7e14dcfSSatish Balay 
567a7e14dcfSSatish Balay   Calling sequence of func:
56817477c02SJason Sarich $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
569a7e14dcfSSatish Balay 
570a7e14dcfSSatish Balay + x - input vector
57117477c02SJason Sarich . f - objective value (output)
572a7e14dcfSSatish Balay . g - gradient value (output)
573a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
574a7e14dcfSSatish Balay 
575a7e14dcfSSatish Balay   Level: beginner
576a7e14dcfSSatish Balay 
577a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetGradient(), TaoGetObjectiveAndGradient()
578a7e14dcfSSatish Balay @*/
579a82e8c82SStefano Zampini PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec g, PetscErrorCode (*func)(Tao, Vec, PetscReal*, Vec, void*), void *ctx)
580a82e8c82SStefano Zampini {
581a82e8c82SStefano Zampini   PetscErrorCode ierr;
582a82e8c82SStefano Zampini 
583a82e8c82SStefano Zampini   PetscFunctionBegin;
584a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
585a82e8c82SStefano Zampini   if (g) {
586a82e8c82SStefano Zampini     PetscValidHeaderSpecific(g,VEC_CLASSID,2);
587a82e8c82SStefano Zampini     PetscCheckSameComm(tao,1,g,2);
588a82e8c82SStefano Zampini     ierr = PetscObjectReference((PetscObject)g);CHKERRQ(ierr);
589a82e8c82SStefano Zampini     ierr = VecDestroy(&tao->gradient);CHKERRQ(ierr);
590a82e8c82SStefano Zampini     tao->gradient = g;
591a82e8c82SStefano Zampini   }
592a82e8c82SStefano Zampini   if (ctx) tao->user_objgradP = ctx;
593a82e8c82SStefano Zampini   if (func) tao->ops->computeobjectiveandgradient = func;
594a82e8c82SStefano Zampini   PetscFunctionReturn(0);
595a82e8c82SStefano Zampini }
596a82e8c82SStefano Zampini 
597a82e8c82SStefano Zampini /*@C
598a82e8c82SStefano Zampini   TaoGetObjectiveAndGradient - Gets a combined objective function and gradient evaluation routine for minimization
599a82e8c82SStefano Zampini 
600a82e8c82SStefano Zampini   Not collective
601a82e8c82SStefano Zampini 
602a82e8c82SStefano Zampini   Input Parameter:
603a82e8c82SStefano Zampini . tao - the Tao context
604a82e8c82SStefano Zampini 
605a82e8c82SStefano Zampini   Output Parameters:
606*817da375SSatish Balay + g - the vector to internally hold the gradient computation
607a82e8c82SStefano Zampini . func - the gradient function
608a82e8c82SStefano Zampini - ctx - user-defined context for private data for the gradient evaluation routine
609a82e8c82SStefano Zampini 
610a82e8c82SStefano Zampini   Calling sequence of func:
611a82e8c82SStefano Zampini $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
612a82e8c82SStefano Zampini 
613a82e8c82SStefano Zampini + x - input vector
614a82e8c82SStefano Zampini . f - objective value (output)
615a82e8c82SStefano Zampini . g - gradient value (output)
616a82e8c82SStefano Zampini - ctx - [optional] user-defined function context
617a82e8c82SStefano Zampini 
618a82e8c82SStefano Zampini   Level: beginner
619a82e8c82SStefano Zampini 
620a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetGradient(), TaoSetHessian(), TaoSetObjectiveAndGradient()
621a82e8c82SStefano Zampini @*/
622a82e8c82SStefano Zampini PetscErrorCode TaoGetObjectiveAndGradient(Tao tao, Vec *g, PetscErrorCode (**func)(Tao, Vec, PetscReal*, Vec, void*), void **ctx)
623a7e14dcfSSatish Balay {
624a7e14dcfSSatish Balay   PetscFunctionBegin;
625441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
626a82e8c82SStefano Zampini   if (g) *g = tao->gradient;
627a82e8c82SStefano Zampini   if (func) *func = tao->ops->computeobjectiveandgradient;
628a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_objgradP;
629a7e14dcfSSatish Balay   PetscFunctionReturn(0);
630a7e14dcfSSatish Balay }
631a7e14dcfSSatish Balay 
632a7e14dcfSSatish Balay /*@
633a82e8c82SStefano Zampini   TaoIsObjectiveDefined - Checks to see if the user has
634a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
635a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
636a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
637a7e14dcfSSatish Balay 
638a82e8c82SStefano Zampini   Not collective
639a7e14dcfSSatish Balay 
640a82e8c82SStefano Zampini   Input Parameter:
641a82e8c82SStefano Zampini . tao - the Tao context
642a82e8c82SStefano Zampini 
643a82e8c82SStefano Zampini   Output Parameter:
644f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
645a82e8c82SStefano Zampini 
646a7e14dcfSSatish Balay   Level: developer
647a7e14dcfSSatish Balay 
648a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoIsGradientDefined(), TaoIsObjectiveAndGradientDefined()
649a7e14dcfSSatish Balay @*/
650441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg)
651a7e14dcfSSatish Balay {
652a7e14dcfSSatish Balay   PetscFunctionBegin;
653441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
65483c8fe1dSLisandro Dalcin   if (tao->ops->computeobjective == NULL) *flg = PETSC_FALSE;
65545cf516eSBarry Smith   else *flg = PETSC_TRUE;
656a7e14dcfSSatish Balay   PetscFunctionReturn(0);
657a7e14dcfSSatish Balay }
658a7e14dcfSSatish Balay 
659a7e14dcfSSatish Balay /*@
660a82e8c82SStefano Zampini   TaoIsGradientDefined - Checks to see if the user has
661a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
662a7e14dcfSSatish Balay   it is appropriate to call TaoComputeGradient() or
663a7e14dcfSSatish Balay   TaoComputeGradientAndGradient()
664a7e14dcfSSatish Balay 
665a7e14dcfSSatish Balay   Not Collective
666a7e14dcfSSatish Balay 
667a82e8c82SStefano Zampini   Input Parameter:
668a82e8c82SStefano Zampini . tao - the Tao context
669a82e8c82SStefano Zampini 
670a82e8c82SStefano Zampini   Output Parameter:
671f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
672a82e8c82SStefano Zampini 
673a7e14dcfSSatish Balay   Level: developer
674a7e14dcfSSatish Balay 
675a82e8c82SStefano Zampini .seealso: TaoSetGradient(), TaoIsObjectiveDefined(), TaoIsObjectiveAndGradientDefined()
676a7e14dcfSSatish Balay @*/
677441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg)
678a7e14dcfSSatish Balay {
679a7e14dcfSSatish Balay   PetscFunctionBegin;
680441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
68183c8fe1dSLisandro Dalcin   if (tao->ops->computegradient == NULL) *flg = PETSC_FALSE;
68245cf516eSBarry Smith   else *flg = PETSC_TRUE;
683a7e14dcfSSatish Balay   PetscFunctionReturn(0);
684a7e14dcfSSatish Balay }
685a7e14dcfSSatish Balay 
686a7e14dcfSSatish Balay /*@
687a82e8c82SStefano Zampini   TaoIsObjectiveAndGradientDefined - Checks to see if the user has
688a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
689a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
690a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
691a7e14dcfSSatish Balay 
692a7e14dcfSSatish Balay   Not Collective
693a7e14dcfSSatish Balay 
694a82e8c82SStefano Zampini   Input Parameter:
695a82e8c82SStefano Zampini . tao - the Tao context
696a82e8c82SStefano Zampini 
697a82e8c82SStefano Zampini   Output Parameter:
698f1a722f8SMatthew G. Knepley . flg - PETSC_TRUE if function routine is set by user, PETSC_FALSE otherwise
699a82e8c82SStefano Zampini 
700a7e14dcfSSatish Balay   Level: developer
701a7e14dcfSSatish Balay 
702a82e8c82SStefano Zampini .seealso: TaoSetObjectiveAndGradient(), TaoIsObjectiveDefined(), TaoIsGradientDefined()
703a7e14dcfSSatish Balay @*/
704441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg)
705a7e14dcfSSatish Balay {
706a7e14dcfSSatish Balay   PetscFunctionBegin;
707441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
70883c8fe1dSLisandro Dalcin   if (tao->ops->computeobjectiveandgradient == NULL) *flg = PETSC_FALSE;
70945cf516eSBarry Smith   else *flg = PETSC_TRUE;
710a7e14dcfSSatish Balay   PetscFunctionReturn(0);
711a7e14dcfSSatish Balay }
712