xref: /petsc/src/tao/interface/taosolver_fg.c (revision e356b196b2ca973047f7df0b6b8679f2b9eca46d)
1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2a7e14dcfSSatish Balay 
3a7e14dcfSSatish Balay /*@
4a7e14dcfSSatish Balay   TaoSetInitialVector - Sets 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
13a7e14dcfSSatish Balay .seealso: TaoCreate(), TaoSolve()
14a7e14dcfSSatish Balay @*/
15a7e14dcfSSatish Balay 
16441846f8SBarry Smith PetscErrorCode TaoSetInitialVector(Tao tao, Vec x0)
1745cf516eSBarry Smith {
18a7e14dcfSSatish Balay   PetscErrorCode ierr;
19a7e14dcfSSatish Balay 
20a7e14dcfSSatish Balay   PetscFunctionBegin;
21441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
22a7e14dcfSSatish Balay   if (x0) {
23a7e14dcfSSatish Balay     PetscValidHeaderSpecific(x0,VEC_CLASSID,2);
24a7e14dcfSSatish Balay     PetscObjectReference((PetscObject)x0);
25a7e14dcfSSatish Balay   }
26a7e14dcfSSatish Balay   ierr = VecDestroy(&tao->solution);CHKERRQ(ierr);
27a7e14dcfSSatish Balay   tao->solution = x0;
28a7e14dcfSSatish Balay   PetscFunctionReturn(0);
29a7e14dcfSSatish Balay }
30a7e14dcfSSatish Balay 
31a7e14dcfSSatish Balay /*@
32a7e14dcfSSatish Balay   TaoComputeGradient - Computes the gradient of the objective function
33a7e14dcfSSatish Balay 
34441846f8SBarry Smith   Collective on Tao
35a7e14dcfSSatish Balay 
36a7e14dcfSSatish Balay   Input Parameters:
37441846f8SBarry Smith + tao - the Tao context
38a7e14dcfSSatish Balay - X - input vector
39a7e14dcfSSatish Balay 
40a7e14dcfSSatish Balay   Output Parameter:
41a7e14dcfSSatish Balay . G - gradient vector
42a7e14dcfSSatish Balay 
43a7e14dcfSSatish Balay   Notes: TaoComputeGradient() is typically used within minimization implementations,
44a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
45a7e14dcfSSatish Balay 
46a7e14dcfSSatish Balay   Level: advanced
47a7e14dcfSSatish Balay 
48a7e14dcfSSatish Balay .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetGradientRoutine()
49a7e14dcfSSatish Balay @*/
50441846f8SBarry Smith PetscErrorCode TaoComputeGradient(Tao tao, Vec X, Vec G)
51a7e14dcfSSatish Balay {
52a7e14dcfSSatish Balay   PetscErrorCode ierr;
53a7e14dcfSSatish Balay   PetscReal      dummy;
5487f595a5SBarry Smith 
55a7e14dcfSSatish Balay   PetscFunctionBegin;
56441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
57a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
58a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G,VEC_CLASSID,2);
59a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
60a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,3);
61f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
62a7e14dcfSSatish Balay   if (tao->ops->computegradient) {
63441846f8SBarry Smith     ierr = PetscLogEventBegin(Tao_GradientEval,tao,X,G,NULL);CHKERRQ(ierr);
64441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
65a7e14dcfSSatish Balay     ierr = (*tao->ops->computegradient)(tao,X,G,tao->user_gradP);CHKERRQ(ierr);
66a7e14dcfSSatish Balay     PetscStackPop;
67441846f8SBarry Smith     ierr = PetscLogEventEnd(Tao_GradientEval,tao,X,G,NULL);CHKERRQ(ierr);
68a7e14dcfSSatish Balay     tao->ngrads++;
69a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
70441846f8SBarry Smith     ierr = PetscLogEventBegin(Tao_ObjGradientEval,tao,X,G,NULL);CHKERRQ(ierr);
71a7e14dcfSSatish Balay     PetscStackPush("Tao user objective/gradient evaluation routine");
72a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,&dummy,G,tao->user_objgradP);CHKERRQ(ierr);
73a7e14dcfSSatish Balay     PetscStackPop;
74441846f8SBarry Smith     ierr = PetscLogEventEnd(Tao_ObjGradientEval,tao,X,G,NULL);CHKERRQ(ierr);
75a7e14dcfSSatish Balay     tao->nfuncgrads++;
7687f595a5SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetGradientRoutine() has not been called");
77f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
78a7e14dcfSSatish Balay   PetscFunctionReturn(0);
79a7e14dcfSSatish Balay }
80a7e14dcfSSatish Balay 
81a7e14dcfSSatish Balay /*@
82a7e14dcfSSatish Balay   TaoComputeObjective - Computes the objective function value at a given point
83a7e14dcfSSatish Balay 
84441846f8SBarry Smith   Collective on Tao
85a7e14dcfSSatish Balay 
86a7e14dcfSSatish Balay   Input Parameters:
87441846f8SBarry Smith + tao - the Tao context
88a7e14dcfSSatish Balay - X - input vector
89a7e14dcfSSatish Balay 
90a7e14dcfSSatish Balay   Output Parameter:
91a7e14dcfSSatish Balay . f - Objective value at X
92a7e14dcfSSatish Balay 
93a7e14dcfSSatish Balay   Notes: TaoComputeObjective() is typically used within minimization implementations,
94a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
95a7e14dcfSSatish Balay 
96a7e14dcfSSatish Balay   Level: advanced
97a7e14dcfSSatish Balay 
98a7e14dcfSSatish Balay .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjectiveRoutine()
99a7e14dcfSSatish Balay @*/
100441846f8SBarry Smith PetscErrorCode TaoComputeObjective(Tao tao, Vec X, PetscReal *f)
101a7e14dcfSSatish Balay {
102a7e14dcfSSatish Balay   PetscErrorCode ierr;
103a7e14dcfSSatish Balay   Vec            temp;
10487f595a5SBarry Smith 
105a7e14dcfSSatish Balay   PetscFunctionBegin;
106441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
107a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
108a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
109f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
110a7e14dcfSSatish Balay   if (tao->ops->computeobjective) {
111441846f8SBarry Smith     ierr = PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
112441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
113a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjective)(tao,X,f,tao->user_objP);CHKERRQ(ierr);
114a7e14dcfSSatish Balay     PetscStackPop;
115441846f8SBarry Smith     ierr = PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
116a7e14dcfSSatish Balay     tao->nfuncs++;
117a7e14dcfSSatish Balay   } else if (tao->ops->computeobjectiveandgradient) {
118955c1f14SBarry Smith     ierr = PetscInfo(tao,"Duplicating variable vector in order to call func/grad routine\n");CHKERRQ(ierr);
119a7e14dcfSSatish Balay     ierr = VecDuplicate(X,&temp);CHKERRQ(ierr);
120441846f8SBarry Smith     ierr = PetscLogEventBegin(Tao_ObjGradientEval,tao,X,NULL,NULL);CHKERRQ(ierr);
121441846f8SBarry Smith     PetscStackPush("Tao user objective/gradient evaluation routine");
122a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,f,temp,tao->user_objgradP);CHKERRQ(ierr);
123a7e14dcfSSatish Balay     PetscStackPop;
124441846f8SBarry Smith     ierr = PetscLogEventEnd(Tao_ObjGradientEval,tao,X,NULL,NULL);CHKERRQ(ierr);
125a7e14dcfSSatish Balay     ierr = VecDestroy(&temp);CHKERRQ(ierr);
126a7e14dcfSSatish Balay     tao->nfuncgrads++;
12787f595a5SBarry Smith   }  else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjectiveRoutine() has not been called");
128*e356b196STodd Munson   ierr = PetscInfo1(tao,"TAO Function evaluation: %20.19e\n",(double)(*f));CHKERRQ(ierr);
129f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
130a7e14dcfSSatish Balay   PetscFunctionReturn(0);
131a7e14dcfSSatish Balay }
132a7e14dcfSSatish Balay 
133a7e14dcfSSatish Balay /*@
134a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient - Computes the objective function value at a given point
135a7e14dcfSSatish Balay 
136441846f8SBarry Smith   Collective on Tao
137a7e14dcfSSatish Balay 
138a7e14dcfSSatish Balay   Input Parameters:
139441846f8SBarry Smith + tao - the Tao context
140a7e14dcfSSatish Balay - X - input vector
141a7e14dcfSSatish Balay 
142a7e14dcfSSatish Balay   Output Parameter:
143a7e14dcfSSatish Balay + f - Objective value at X
144a7e14dcfSSatish Balay - g - Gradient vector at X
145a7e14dcfSSatish Balay 
146a7e14dcfSSatish Balay   Notes: TaoComputeObjectiveAndGradient() is typically used within minimization implementations,
147a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
148a7e14dcfSSatish Balay 
149a7e14dcfSSatish Balay   Level: advanced
150a7e14dcfSSatish Balay 
151a7e14dcfSSatish Balay .seealso: TaoComputeGradient(), TaoComputeObjectiveAndGradient(), TaoSetObjectiveRoutine()
152a7e14dcfSSatish Balay @*/
153441846f8SBarry Smith PetscErrorCode TaoComputeObjectiveAndGradient(Tao tao, Vec X, PetscReal *f, Vec G)
154a7e14dcfSSatish Balay {
155a7e14dcfSSatish Balay   PetscErrorCode ierr;
15687f595a5SBarry Smith 
157a7e14dcfSSatish Balay   PetscFunctionBegin;
158441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
159a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
160a7e14dcfSSatish Balay   PetscValidHeaderSpecific(G,VEC_CLASSID,4);
161a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
162a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,G,4);
163f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
164a7e14dcfSSatish Balay   if (tao->ops->computeobjectiveandgradient) {
165441846f8SBarry Smith     ierr = PetscLogEventBegin(Tao_ObjGradientEval,tao,X,G,NULL);CHKERRQ(ierr);
166f4c1ad5cSStefano Zampini     if (tao->ops->computegradient == TaoDefaultComputeGradient) {
167f4c1ad5cSStefano Zampini       ierr = TaoComputeObjective(tao,X,f);CHKERRQ(ierr);
168f4c1ad5cSStefano Zampini       ierr = TaoDefaultComputeGradient(tao,X,G,NULL);CHKERRQ(ierr);
169f4c1ad5cSStefano Zampini     } else {
170441846f8SBarry Smith       PetscStackPush("Tao user objective/gradient evaluation routine");
171a7e14dcfSSatish Balay       ierr = (*tao->ops->computeobjectiveandgradient)(tao,X,f,G,tao->user_objgradP);CHKERRQ(ierr);
1720cbffdbaSBarry Smith       PetscStackPop;
173a7e14dcfSSatish Balay     }
174441846f8SBarry Smith     ierr = PetscLogEventEnd(Tao_ObjGradientEval,tao,X,G,NULL);CHKERRQ(ierr);
175a7e14dcfSSatish Balay     tao->nfuncgrads++;
176a7e14dcfSSatish Balay   } else if (tao->ops->computeobjective && tao->ops->computegradient) {
177441846f8SBarry Smith     ierr = PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
178441846f8SBarry Smith     PetscStackPush("Tao user objective evaluation routine");
179a7e14dcfSSatish Balay     ierr = (*tao->ops->computeobjective)(tao,X,f,tao->user_objP);CHKERRQ(ierr);
180a7e14dcfSSatish Balay     PetscStackPop;
181441846f8SBarry Smith     ierr = PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
182a7e14dcfSSatish Balay     tao->nfuncs++;
183441846f8SBarry Smith     ierr = PetscLogEventBegin(Tao_GradientEval,tao,X,G,NULL);CHKERRQ(ierr);
184441846f8SBarry Smith     PetscStackPush("Tao user gradient evaluation routine");
185a7e14dcfSSatish Balay     ierr = (*tao->ops->computegradient)(tao,X,G,tao->user_gradP);CHKERRQ(ierr);
186a7e14dcfSSatish Balay     PetscStackPop;
187441846f8SBarry Smith     ierr = PetscLogEventEnd(Tao_GradientEval,tao,X,G,NULL);CHKERRQ(ierr);
188a7e14dcfSSatish Balay     tao->ngrads++;
18987f595a5SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetObjectiveRoutine() or TaoSetGradientRoutine() not set");
190*e356b196STodd Munson   ierr = PetscInfo1(tao,"TAO Function evaluation: %20.19e\n",(double)(*f));CHKERRQ(ierr);
191f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
192a7e14dcfSSatish Balay   PetscFunctionReturn(0);
193a7e14dcfSSatish Balay }
194a7e14dcfSSatish Balay 
195a7e14dcfSSatish Balay /*@C
196a7e14dcfSSatish Balay   TaoSetObjectiveRoutine - Sets the function evaluation routine for minimization
197a7e14dcfSSatish Balay 
198441846f8SBarry Smith   Logically collective on Tao
199a7e14dcfSSatish Balay 
200a7e14dcfSSatish Balay   Input Parameter:
201441846f8SBarry Smith + tao - the Tao context
202a7e14dcfSSatish Balay . func - the objective function
203a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2046c23d075SBarry Smith         routine (may be NULL)
205a7e14dcfSSatish Balay 
206a7e14dcfSSatish Balay   Calling sequence of func:
207441846f8SBarry Smith $      func (Tao tao, Vec x, PetscReal *f, void *ctx);
208a7e14dcfSSatish Balay 
209a7e14dcfSSatish Balay + x - input vector
210a7e14dcfSSatish Balay . f - function value
211a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
212a7e14dcfSSatish Balay 
213a7e14dcfSSatish Balay   Level: beginner
214a7e14dcfSSatish Balay 
215a7e14dcfSSatish Balay .seealso: TaoSetGradientRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
216a7e14dcfSSatish Balay @*/
217441846f8SBarry Smith PetscErrorCode TaoSetObjectiveRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal*,void*),void *ctx)
218a7e14dcfSSatish Balay {
219a7e14dcfSSatish Balay   PetscFunctionBegin;
220441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
221a7e14dcfSSatish Balay   tao->user_objP = ctx;
222a7e14dcfSSatish Balay   tao->ops->computeobjective = func;
223a7e14dcfSSatish Balay   PetscFunctionReturn(0);
224a7e14dcfSSatish Balay }
225a7e14dcfSSatish Balay 
226a7e14dcfSSatish Balay /*@C
227a7e14dcfSSatish Balay   TaoSetSeparableObjectiveRoutine - Sets the function evaluation routine for least-square applications
228a7e14dcfSSatish Balay 
229441846f8SBarry Smith   Logically collective on Tao
230a7e14dcfSSatish Balay 
231a7e14dcfSSatish Balay   Input Parameter:
232441846f8SBarry Smith + tao - the Tao context
233a7e14dcfSSatish Balay . func - the objective function evaluation routine
234a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the function evaluation
2356c23d075SBarry Smith         routine (may be NULL)
236a7e14dcfSSatish Balay 
237a7e14dcfSSatish Balay   Calling sequence of func:
238441846f8SBarry Smith $      func (Tao tao, Vec x, Vec f, void *ctx);
239a7e14dcfSSatish Balay 
240a7e14dcfSSatish Balay + x - input vector
241a7e14dcfSSatish Balay . f - function value vector
242a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
243a7e14dcfSSatish Balay 
244a7e14dcfSSatish Balay   Level: beginner
245a7e14dcfSSatish Balay 
246a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetJacobianRoutine()
247a7e14dcfSSatish Balay @*/
248441846f8SBarry Smith PetscErrorCode TaoSetSeparableObjectiveRoutine(Tao tao, Vec sepobj, PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
249a7e14dcfSSatish Balay {
250a7e14dcfSSatish Balay   PetscFunctionBegin;
251441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
252a7e14dcfSSatish Balay   PetscValidHeaderSpecific(sepobj, VEC_CLASSID,2);
253a7e14dcfSSatish Balay   tao->user_sepobjP = ctx;
254a7e14dcfSSatish Balay   tao->sep_objective = sepobj;
255a7e14dcfSSatish Balay   tao->ops->computeseparableobjective = func;
256a7e14dcfSSatish Balay   PetscFunctionReturn(0);
257a7e14dcfSSatish Balay }
258a7e14dcfSSatish Balay 
2598b7a9b22SJason Sarich /*@
2608b7a9b22SJason Sarich   TaoSetSeparableObjectiveWeights - Give weights for the separable objective 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.
2618b7a9b22SJason Sarich 
2628b7a9b22SJason Sarich   Collective on Tao
2638b7a9b22SJason Sarich 
2648b7a9b22SJason Sarich   Input Parameters:
2658b7a9b22SJason Sarich + tao - the Tao context
2668b7a9b22SJason Sarich . sigma_v - vector of weights (diagonal terms only)
2678b7a9b22SJason Sarich . n       - the number of weights (if using off-diagonal)
2688b7a9b22SJason Sarich . rows    - index list of rows for sigma_w
2698b7a9b22SJason Sarich . cols    - index list of columns for sigma_w
2708b7a9b22SJason Sarich - vals - array of weights
2718b7a9b22SJason Sarich 
2728b7a9b22SJason Sarich 
2738b7a9b22SJason Sarich 
2748b7a9b22SJason Sarich   Note: Either sigma_v or sigma_w (or both) should be NULL
2758b7a9b22SJason Sarich 
2768b7a9b22SJason Sarich   Level: intermediate
2778b7a9b22SJason Sarich 
2788b7a9b22SJason Sarich .seealso: TaoSetSeparableObjectiveRoutine()
2798b7a9b22SJason Sarich @*/
2808b7a9b22SJason Sarich PetscErrorCode TaoSetSeparableObjectiveWeights(Tao tao, Vec sigma_v, PetscInt n, PetscInt *rows, PetscInt *cols, PetscReal *vals)
2818b7a9b22SJason Sarich {
2828b7a9b22SJason Sarich   PetscErrorCode ierr;
2838b7a9b22SJason Sarich   PetscInt       i;
2848b7a9b22SJason Sarich   PetscFunctionBegin;
2858b7a9b22SJason Sarich   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
2868b7a9b22SJason Sarich   ierr = VecDestroy(&tao->sep_weights_v);CHKERRQ(ierr);
2878b7a9b22SJason Sarich   tao->sep_weights_v=sigma_v;
2888b7a9b22SJason Sarich   if (sigma_v) {
2898b7a9b22SJason Sarich     ierr = PetscObjectReference((PetscObject)sigma_v);CHKERRQ(ierr);
2908b7a9b22SJason Sarich   }
2918b7a9b22SJason Sarich   if (vals) {
2928b7a9b22SJason Sarich     if (tao->sep_weights_n) {
2938b7a9b22SJason Sarich       ierr = PetscFree(tao->sep_weights_rows);CHKERRQ(ierr);
2948b7a9b22SJason Sarich       ierr = PetscFree(tao->sep_weights_cols);CHKERRQ(ierr);
2958b7a9b22SJason Sarich       ierr = PetscFree(tao->sep_weights_w);CHKERRQ(ierr);
2968b7a9b22SJason Sarich     }
2978b7a9b22SJason Sarich     ierr = PetscMalloc1(n,&tao->sep_weights_rows);CHKERRQ(ierr);
2988b7a9b22SJason Sarich     ierr = PetscMalloc1(n,&tao->sep_weights_cols);CHKERRQ(ierr);
2998b7a9b22SJason Sarich     ierr = PetscMalloc1(n,&tao->sep_weights_w);CHKERRQ(ierr);
3008b7a9b22SJason Sarich     tao->sep_weights_n=n;
3018b7a9b22SJason Sarich     for (i=0;i<n;i++) {
3028b7a9b22SJason Sarich       tao->sep_weights_rows[i]=rows[i];
3038b7a9b22SJason Sarich       tao->sep_weights_cols[i]=cols[i];
3048b7a9b22SJason Sarich       tao->sep_weights_w[i]=vals[i];
3058b7a9b22SJason Sarich     }
3068b7a9b22SJason Sarich   } else {
3078b7a9b22SJason Sarich     tao->sep_weights_n=0;
3088b7a9b22SJason Sarich     tao->sep_weights_rows=0;
3098b7a9b22SJason Sarich     tao->sep_weights_cols=0;
3108b7a9b22SJason Sarich   }
3118b7a9b22SJason Sarich   PetscFunctionReturn(0);
3128b7a9b22SJason Sarich }
313a7e14dcfSSatish Balay /*@
314a7e14dcfSSatish Balay   TaoComputeSeparableObjective - Computes a separable objective function vector at a given point (for least-square applications)
315a7e14dcfSSatish Balay 
316441846f8SBarry Smith   Collective on Tao
317a7e14dcfSSatish Balay 
318a7e14dcfSSatish Balay   Input Parameters:
319441846f8SBarry Smith + tao - the Tao context
320a7e14dcfSSatish Balay - X - input vector
321a7e14dcfSSatish Balay 
322a7e14dcfSSatish Balay   Output Parameter:
323a7e14dcfSSatish Balay . f - Objective vector at X
324a7e14dcfSSatish Balay 
325a7e14dcfSSatish Balay   Notes: TaoComputeSeparableObjective() is typically used within minimization implementations,
326a7e14dcfSSatish Balay   so most users would not generally call this routine themselves.
327a7e14dcfSSatish Balay 
328a7e14dcfSSatish Balay   Level: advanced
329a7e14dcfSSatish Balay 
330a7e14dcfSSatish Balay .seealso: TaoSetSeparableObjectiveRoutine()
331a7e14dcfSSatish Balay @*/
332441846f8SBarry Smith PetscErrorCode TaoComputeSeparableObjective(Tao tao, Vec X, Vec F)
333a7e14dcfSSatish Balay {
334a7e14dcfSSatish Balay   PetscErrorCode ierr;
33587f595a5SBarry Smith 
336a7e14dcfSSatish Balay   PetscFunctionBegin;
337441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
338a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
339a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
340a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
341a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,F,3);
342a7e14dcfSSatish Balay   if (tao->ops->computeseparableobjective) {
343441846f8SBarry Smith     ierr = PetscLogEventBegin(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
344441846f8SBarry Smith     PetscStackPush("Tao user separable objective evaluation routine");
345a7e14dcfSSatish Balay     ierr = (*tao->ops->computeseparableobjective)(tao,X,F,tao->user_sepobjP);CHKERRQ(ierr);
346a7e14dcfSSatish Balay     PetscStackPop;
347441846f8SBarry Smith     ierr = PetscLogEventEnd(Tao_ObjectiveEval,tao,X,NULL,NULL);CHKERRQ(ierr);
348a7e14dcfSSatish Balay     tao->nfuncs++;
34987f595a5SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetSeparableObjectiveRoutine() has not been called");
350a7e14dcfSSatish Balay   ierr = PetscInfo(tao,"TAO separable function evaluation.\n");CHKERRQ(ierr);
351a7e14dcfSSatish Balay   PetscFunctionReturn(0);
352a7e14dcfSSatish Balay }
353a7e14dcfSSatish Balay 
354a7e14dcfSSatish Balay /*@C
355a7e14dcfSSatish Balay   TaoSetGradientRoutine - Sets the gradient evaluation routine for minimization
356a7e14dcfSSatish Balay 
357441846f8SBarry Smith   Logically collective on Tao
358a7e14dcfSSatish Balay 
359a7e14dcfSSatish Balay   Input Parameter:
360441846f8SBarry Smith + tao - the Tao context
361a7e14dcfSSatish Balay . func - the gradient function
362a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
3636c23d075SBarry Smith         routine (may be NULL)
364a7e14dcfSSatish Balay 
365a7e14dcfSSatish Balay   Calling sequence of func:
366441846f8SBarry Smith $      func (Tao tao, Vec x, Vec g, void *ctx);
367a7e14dcfSSatish Balay 
368a7e14dcfSSatish Balay + x - input vector
369a7e14dcfSSatish Balay . g - gradient value (output)
370a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
371a7e14dcfSSatish Balay 
372a7e14dcfSSatish Balay   Level: beginner
373a7e14dcfSSatish Balay 
374a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
375a7e14dcfSSatish Balay @*/
376441846f8SBarry Smith PetscErrorCode TaoSetGradientRoutine(Tao tao,  PetscErrorCode (*func)(Tao, Vec, Vec, void*),void *ctx)
377a7e14dcfSSatish Balay {
378a7e14dcfSSatish Balay   PetscFunctionBegin;
379441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
380a7e14dcfSSatish Balay   tao->user_gradP = ctx;
381a7e14dcfSSatish Balay   tao->ops->computegradient = func;
382a7e14dcfSSatish Balay   PetscFunctionReturn(0);
383a7e14dcfSSatish Balay }
384a7e14dcfSSatish Balay 
385a7e14dcfSSatish Balay /*@C
386a7e14dcfSSatish Balay   TaoSetObjectiveAndGradientRoutine - Sets a combined objective function and gradient evaluation routine for minimization
387a7e14dcfSSatish Balay 
388441846f8SBarry Smith   Logically collective on Tao
389a7e14dcfSSatish Balay 
390a7e14dcfSSatish Balay   Input Parameter:
391441846f8SBarry Smith + tao - the Tao context
392a7e14dcfSSatish Balay . func - the gradient function
393a7e14dcfSSatish Balay - ctx - [optional] user-defined context for private data for the gradient evaluation
3946c23d075SBarry Smith         routine (may be NULL)
395a7e14dcfSSatish Balay 
396a7e14dcfSSatish Balay   Calling sequence of func:
39717477c02SJason Sarich $      func (Tao tao, Vec x, PetscReal *f, Vec g, void *ctx);
398a7e14dcfSSatish Balay 
399a7e14dcfSSatish Balay + x - input vector
40017477c02SJason Sarich . f - objective value (output)
401a7e14dcfSSatish Balay . g - gradient value (output)
402a7e14dcfSSatish Balay - ctx - [optional] user-defined function context
403a7e14dcfSSatish Balay 
404a7e14dcfSSatish Balay   Level: beginner
405a7e14dcfSSatish Balay 
406a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine()
407a7e14dcfSSatish Balay @*/
408441846f8SBarry Smith PetscErrorCode TaoSetObjectiveAndGradientRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, PetscReal *, Vec, void*), void *ctx)
409a7e14dcfSSatish Balay {
410a7e14dcfSSatish Balay   PetscFunctionBegin;
411441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
412a7e14dcfSSatish Balay   tao->user_objgradP = ctx;
413a7e14dcfSSatish Balay   tao->ops->computeobjectiveandgradient = func;
414a7e14dcfSSatish Balay   PetscFunctionReturn(0);
415a7e14dcfSSatish Balay }
416a7e14dcfSSatish Balay 
417a7e14dcfSSatish Balay /*@
418a7e14dcfSSatish Balay   TaoIsObjectiveDefined -- Checks to see if the user has
419a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
420a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
421a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
422a7e14dcfSSatish Balay 
423441846f8SBarry Smith   Collective on Tao
424a7e14dcfSSatish Balay 
425a7e14dcfSSatish Balay   Input Parameter:
426441846f8SBarry Smith + tao - the Tao context
427a7e14dcfSSatish Balay - ctx - PETSC_TRUE if objective function routine is set by user,
428a7e14dcfSSatish Balay         PETSC_FALSE otherwise
429a7e14dcfSSatish Balay   Level: developer
430a7e14dcfSSatish Balay 
431a7e14dcfSSatish Balay .seealso: TaoSetObjectiveRoutine(), TaoIsGradientDefined(), TaoIsObjectiveAndGradientDefined()
432a7e14dcfSSatish Balay @*/
433441846f8SBarry Smith PetscErrorCode TaoIsObjectiveDefined(Tao tao, PetscBool *flg)
434a7e14dcfSSatish Balay {
435a7e14dcfSSatish Balay   PetscFunctionBegin;
436441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
43745cf516eSBarry Smith   if (tao->ops->computeobjective == 0) *flg = PETSC_FALSE;
43845cf516eSBarry Smith   else *flg = PETSC_TRUE;
439a7e14dcfSSatish Balay   PetscFunctionReturn(0);
440a7e14dcfSSatish Balay }
441a7e14dcfSSatish Balay 
442a7e14dcfSSatish Balay /*@
443a7e14dcfSSatish Balay   TaoIsGradientDefined -- Checks to see if the user has
444a7e14dcfSSatish Balay   declared an objective-only routine.  Useful for determining when
445a7e14dcfSSatish Balay   it is appropriate to call TaoComputeGradient() or
446a7e14dcfSSatish Balay   TaoComputeGradientAndGradient()
447a7e14dcfSSatish Balay 
448a7e14dcfSSatish Balay   Not Collective
449a7e14dcfSSatish Balay 
450a7e14dcfSSatish Balay   Input Parameter:
451441846f8SBarry Smith + tao - the Tao context
452a7e14dcfSSatish Balay - ctx - PETSC_TRUE if gradient routine is set by user, PETSC_FALSE otherwise
453a7e14dcfSSatish Balay   Level: developer
454a7e14dcfSSatish Balay 
455a7e14dcfSSatish Balay .seealso: TaoSetGradientRoutine(), TaoIsObjectiveDefined(), TaoIsObjectiveAndGradientDefined()
456a7e14dcfSSatish Balay @*/
457441846f8SBarry Smith PetscErrorCode TaoIsGradientDefined(Tao tao, PetscBool *flg)
458a7e14dcfSSatish Balay {
459a7e14dcfSSatish Balay   PetscFunctionBegin;
460441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
46145cf516eSBarry Smith   if (tao->ops->computegradient == 0) *flg = PETSC_FALSE;
46245cf516eSBarry Smith   else *flg = PETSC_TRUE;
463a7e14dcfSSatish Balay   PetscFunctionReturn(0);
464a7e14dcfSSatish Balay }
465a7e14dcfSSatish Balay 
466a7e14dcfSSatish Balay /*@
467a7e14dcfSSatish Balay   TaoIsObjectiveAndGradientDefined -- Checks to see if the user has
468a7e14dcfSSatish Balay   declared a joint objective/gradient routine.  Useful for determining when
469a7e14dcfSSatish Balay   it is appropriate to call TaoComputeObjective() or
470a7e14dcfSSatish Balay   TaoComputeObjectiveAndGradient()
471a7e14dcfSSatish Balay 
472a7e14dcfSSatish Balay   Not Collective
473a7e14dcfSSatish Balay 
474a7e14dcfSSatish Balay   Input Parameter:
475441846f8SBarry Smith + tao - the Tao context
476a7e14dcfSSatish Balay - ctx - PETSC_TRUE if objective/gradient routine is set by user, PETSC_FALSE otherwise
477a7e14dcfSSatish Balay   Level: developer
478a7e14dcfSSatish Balay 
479a7e14dcfSSatish Balay .seealso: TaoSetObjectiveAndGradientRoutine(), TaoIsObjectiveDefined(), TaoIsGradientDefined()
480a7e14dcfSSatish Balay @*/
481441846f8SBarry Smith PetscErrorCode TaoIsObjectiveAndGradientDefined(Tao tao, PetscBool *flg)
482a7e14dcfSSatish Balay {
483a7e14dcfSSatish Balay   PetscFunctionBegin;
484441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
48545cf516eSBarry Smith   if (tao->ops->computeobjectiveandgradient == 0) *flg = PETSC_FALSE;
48645cf516eSBarry Smith   else *flg = PETSC_TRUE;
487a7e14dcfSSatish Balay   PetscFunctionReturn(0);
488a7e14dcfSSatish Balay }
489