xref: /petsc/src/tao/interface/taosolver_bounds.c (revision ebead697dbf761eb322f829370bbe90b3bd93fa3)
1 #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2 
3 /*@
4   TaoSetVariableBounds - Sets the upper and lower bounds for the optimization problem
5 
6   Logically collective on tao
7 
8   Input Parameters:
9 + tao - the Tao context
10 . XL  - vector of lower bounds
11 - XU  - vector of upper bounds
12 
13   Level: beginner
14 
15 .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetVariableBounds()`
16 @*/
17 PetscErrorCode TaoSetVariableBounds(Tao tao, Vec XL, Vec XU)
18 {
19   PetscFunctionBegin;
20   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
21   if (XL) PetscValidHeaderSpecific(XL,VEC_CLASSID,2);
22   if (XU) PetscValidHeaderSpecific(XU,VEC_CLASSID,3);
23   PetscCall(PetscObjectReference((PetscObject)XL));
24   PetscCall(PetscObjectReference((PetscObject)XU));
25   PetscCall(VecDestroy(&tao->XL));
26   PetscCall(VecDestroy(&tao->XU));
27   tao->XL = XL;
28   tao->XU = XU;
29   tao->bounded = (PetscBool)(XL || XU);
30   PetscFunctionReturn(0);
31 }
32 
33 /*@C
34   TaoSetVariableBoundsRoutine - Sets a function to be used to compute lower and upper variable bounds for the optimization
35 
36   Logically collective on tao
37 
38   Input Parameters:
39 + tao - the Tao context
40 . func - the bounds computation routine
41 - ctx - [optional] user-defined context for private data for the bounds computation (may be NULL)
42 
43   Calling sequence of func:
44 $      func (Tao tao, Vec xl, Vec xu);
45 
46 + tao - the Tao
47 . xl  - vector of lower bounds
48 . xu  - vector of upper bounds
49 - ctx - the (optional) user-defined function context
50 
51   Level: beginner
52 
53   Note:
54   The func passed to `TaoSetVariableBoundsRoutine()` takes precedence over any values set in `TaoSetVariableBounds()`.
55 
56 .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
57 
58 @*/
59 PetscErrorCode TaoSetVariableBoundsRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx)
60 {
61   PetscFunctionBegin;
62   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
63   tao->user_boundsP = ctx;
64   tao->ops->computebounds = func;
65   tao->bounded = func ? PETSC_TRUE : PETSC_FALSE;
66   PetscFunctionReturn(0);
67 }
68 
69 /*@
70   TaoGetVariableBounds - Gets the upper and lower bounds vectors set with `TaoSetVariableBounds()`
71 
72   Not collective
73 
74   Input Parameter:
75 . tao - the Tao context
76 
77   Output Parametrs:
78 + XL  - vector of lower bounds
79 - XU  - vector of upper bounds
80 
81   Level: beginner
82 
83 .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
84 @*/
85 PetscErrorCode TaoGetVariableBounds(Tao tao, Vec *XL, Vec *XU)
86 {
87   PetscFunctionBegin;
88   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
89   if (XL) *XL = tao->XL;
90   if (XU) *XU = tao->XU;
91   PetscFunctionReturn(0);
92 }
93 
94 /*@C
95    TaoComputeVariableBounds - Compute the variable bounds using the
96    routine set by `TaoSetVariableBoundsRoutine()`.
97 
98    Collective on tao
99 
100    Input Parameter:
101 .  tao - the Tao context
102 
103    Level: developer
104 
105 .seealso: `Tao`, `TaoSetVariableBoundsRoutine()`, `TaoSetVariableBounds()`
106 @*/
107 
108 PetscErrorCode TaoComputeVariableBounds(Tao tao)
109 {
110   PetscFunctionBegin;
111   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
112   if (tao->ops->computebounds) {
113     if (!tao->XL) {
114       PetscCall(VecDuplicate(tao->solution, &tao->XL));
115       PetscCall(VecSet(tao->XL, PETSC_NINFINITY));
116     }
117     if (!tao->XU) {
118       PetscCall(VecDuplicate(tao->solution, &tao->XU));
119       PetscCall(VecSet(tao->XU, PETSC_INFINITY));
120     }
121     PetscCallBack("Tao callback variable bounds",(*tao->ops->computebounds)(tao,tao->XL,tao->XU,tao->user_boundsP));
122   }
123   PetscFunctionReturn(0);
124 }
125 
126 /*@
127   TaoSetInequalityBounds - Sets the upper and lower bounds
128 
129   Logically collective on tao
130 
131   Input Parameters:
132 + tao - the Tao context
133 . IL  - vector of lower bounds
134 - IU  - vector of upper bounds
135 
136   Level: beginner
137 
138 .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetInequalityBounds()`
139 @*/
140 PetscErrorCode TaoSetInequalityBounds(Tao tao, Vec IL, Vec IU)
141 {
142   PetscFunctionBegin;
143   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
144   if (IL) PetscValidHeaderSpecific(IL,VEC_CLASSID,2);
145   if (IU) PetscValidHeaderSpecific(IU,VEC_CLASSID,3);
146   PetscCall(PetscObjectReference((PetscObject)IL));
147   PetscCall(PetscObjectReference((PetscObject)IU));
148   PetscCall(VecDestroy(&tao->IL));
149   PetscCall(VecDestroy(&tao->IU));
150   tao->IL = IL;
151   tao->IU = IU;
152   tao->ineq_doublesided = (PetscBool)(IL || IU);
153   PetscFunctionReturn(0);
154 }
155 
156 /*@
157   TaoGetInequalityBounds - Gets the upper and lower bounds set via `TaoSetInequalityBounds()`
158 
159   Logically collective on tao
160 
161   Input Parameter:
162 . tao - the Tao context
163 
164   Output Parameters:
165 + IL  - vector of lower bounds
166 - IU  - vector of upper bounds
167 
168   Level: beginner
169 
170 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetInequalityBounds()`
171 @*/
172 PetscErrorCode TaoGetInequalityBounds(Tao tao, Vec *IL, Vec *IU)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
176   if (IL) *IL = tao->IL;
177   if (IU) *IU = tao->IU;
178   PetscFunctionReturn(0);
179 }
180 
181 /*@C
182    TaoComputeConstraints - Compute the variable bounds using the
183    routine set by `TaoSetConstraintsRoutine()`.
184 
185    Collective on tao
186 
187    Input Parameters:
188 .  tao - the Tao context
189 
190    Level: developer
191 
192 .seealso: `Tao`, `TaoSetConstraintsRoutine()`, `TaoComputeJacobian()`
193 @*/
194 
195 PetscErrorCode TaoComputeConstraints(Tao tao, Vec X, Vec C)
196 {
197   PetscFunctionBegin;
198   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
199   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
200   PetscValidHeaderSpecific(C,VEC_CLASSID,3);
201   PetscCheckSameComm(tao,1,X,2);
202   PetscCheckSameComm(tao,1,C,3);
203   PetscCheck(tao->ops->computeconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetConstraintsRoutine() has not been called");
204   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,C,NULL));
205   PetscCallBack("Tao callback constraints",(*tao->ops->computeconstraints)(tao,X,C,tao->user_conP));
206   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,C,NULL));
207   tao->nconstraints++;
208   PetscFunctionReturn(0);
209 }
210 
211 /*@C
212   TaoSetConstraintsRoutine - Sets a function to be used to compute constraints.  Tao only handles constraints under certain conditions, see manual for details
213 
214   Logically collective on tao
215 
216   Input Parameters:
217 + tao - the Tao context
218 . c   - A vector that will be used to store constraint evaluation
219 . func - the bounds computation routine
220 - ctx - [optional] user-defined context for private data for the constraints computation (may be NULL)
221 
222   Calling sequence of func:
223 $      func (Tao tao, Vec x, Vec c, void *ctx);
224 
225 + tao - the Tao
226 . x   - point to evaluate constraints
227 . c   - vector constraints evaluated at x
228 - ctx - the (optional) user-defined function context
229 
230   Level: intermediate
231 
232 .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariablevBounds()`
233 
234 @*/
235 PetscErrorCode TaoSetConstraintsRoutine(Tao tao, Vec c, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx)
236 {
237   PetscFunctionBegin;
238   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
239   if (c) PetscValidHeaderSpecific(c,VEC_CLASSID,2);
240   PetscCall(PetscObjectReference((PetscObject)c));
241   PetscCall(VecDestroy(&tao->constraints));
242   tao->constrained = func ? PETSC_TRUE : PETSC_FALSE;
243   tao->constraints = c;
244   tao->user_conP = ctx;
245   tao->ops->computeconstraints = func;
246   PetscFunctionReturn(0);
247 }
248 
249 /*@
250   TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds
251   of the variables
252 
253   Collective on tao
254 
255   Input Parameter:
256 . tao - the Tao context
257 
258   Output Parameters:
259 + DL - dual variable vector for the lower bounds
260 - DU - dual variable vector for the upper bounds
261 
262   Level: advanced
263 
264   Note:
265   DL and DU should be created before calling this routine.  If calling
266   this routine after using an unconstrained solver, DL and DU are set to all
267   zeros.
268 
269   Level: advanced
270 
271  .seealso: `Tao`, `TaoComputeObjective()`, `TaoSetVariableBounds()`
272 @*/
273 PetscErrorCode TaoComputeDualVariables(Tao tao, Vec DL, Vec DU)
274 {
275   PetscFunctionBegin;
276   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
277   PetscValidHeaderSpecific(DL,VEC_CLASSID,2);
278   PetscValidHeaderSpecific(DU,VEC_CLASSID,3);
279   PetscCheckSameComm(tao,1,DL,2);
280   PetscCheckSameComm(tao,1,DU,3);
281   if (tao->ops->computedual) {
282     PetscCall((*tao->ops->computedual)(tao,DL,DU));
283   } else {
284     PetscCall(VecSet(DL,0.0));
285     PetscCall(VecSet(DU,0.0));
286   }
287   PetscFunctionReturn(0);
288 }
289 
290 /*@
291   TaoGetDualVariables - Gets the dual vectors
292 
293   Collective on tao
294 
295   Input Parameter:
296 . tao - the Tao context
297 
298   Output Parameters:
299 + DE - dual variable vector for the lower bounds
300 - DI - dual variable vector for the upper bounds
301 
302   Level: advanced
303 
304 .seealso: `Tao`, `TaoComputeDualVariables()`
305 @*/
306 PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI)
307 {
308   PetscFunctionBegin;
309   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
310   if (DE) *DE = tao->DE;
311   if (DI) *DI = tao->DI;
312   PetscFunctionReturn(0);
313 }
314 
315 /*@C
316   TaoSetEqualityConstraintsRoutine - Sets a function to be used to compute constraints.  Tao only handles constraints under certain conditions, see manual for details
317 
318   Logically collective on tao
319 
320   Input Parameters:
321 + tao - the Tao context
322 . ce   - A vector that will be used to store equality constraint evaluation
323 . func - the bounds computation routine
324 - ctx - [optional] user-defined context for private data for the equality constraints computation (may be NULL)
325 
326   Calling sequence of func:
327 $      func (Tao tao, Vec x, Vec ce, void *ctx);
328 
329 + tao - the Tao
330 . x   - point to evaluate equality constraints
331 . ce   - vector of equality constraints evaluated at x
332 - ctx - the (optional) user-defined function context
333 
334   Level: intermediate
335 
336 .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
337 
338 @*/
339 PetscErrorCode TaoSetEqualityConstraintsRoutine(Tao tao, Vec ce, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx)
340 {
341   PetscFunctionBegin;
342   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
343   if (ce) PetscValidHeaderSpecific(ce,VEC_CLASSID,2);
344   PetscCall(PetscObjectReference((PetscObject)ce));
345   PetscCall(VecDestroy(&tao->constraints_equality));
346   tao->eq_constrained = func ? PETSC_TRUE : PETSC_FALSE;
347   tao->constraints_equality = ce;
348   tao->user_con_equalityP = ctx;
349   tao->ops->computeequalityconstraints = func;
350   PetscFunctionReturn(0);
351 }
352 
353 /*@C
354   TaoSetInequalityConstraintsRoutine - Sets a function to be used to compute constraints.  Tao only handles constraints under certain conditions, see manual for details
355 
356   Logically collective on tao
357 
358   Input Parameters:
359 + tao - the Tao context
360 . ci   - A vector that will be used to store inequality constraint evaluation
361 . func - the bounds computation routine
362 - ctx - [optional] user-defined context for private data for the inequality constraints computation (may be NULL)
363 
364   Calling sequence of func:
365 $      func (Tao tao, Vec x, Vec ci, void *ctx);
366 
367 + tao - the Tao
368 . x   - point to evaluate inequality constraints
369 . ci   - vector of inequality constraints evaluated at x
370 - ctx - the (optional) user-defined function context
371 
372   Level: intermediate
373 
374  .seealso: `Tao, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
375 
376 @*/
377 PetscErrorCode TaoSetInequalityConstraintsRoutine(Tao tao, Vec ci, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx)
378 {
379   PetscFunctionBegin;
380   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
381   if (ci) PetscValidHeaderSpecific(ci,VEC_CLASSID,2);
382   PetscCall(PetscObjectReference((PetscObject)ci));
383   PetscCall(VecDestroy(&tao->constraints_inequality));
384   tao->constraints_inequality = ci;
385   tao->ineq_constrained = func ? PETSC_TRUE : PETSC_FALSE;
386   tao->user_con_inequalityP = ctx;
387   tao->ops->computeinequalityconstraints = func;
388   PetscFunctionReturn(0);
389 }
390 
391 /*@C
392    TaoComputeEqualityConstraints - Compute the variable bounds using the
393    routine set by `TaoSetEqualityConstraintsRoutine()`.
394 
395    Collective on tao
396 
397    Input Parameter:
398 .  tao - the Tao context
399 
400    Output Parameters:
401 +  X - point the equality constraints were evaluted on
402 -  CE   - vector of equality constraints evaluated at X
403 
404    Level: developer
405 
406 .seealso: `Tao`, `TaoSetEqualityConstraintsRoutine()`, `TaoComputeJacobianEquality()`, `TaoComputeInequalityConstraints()`
407 @*/
408 
409 PetscErrorCode TaoComputeEqualityConstraints(Tao tao, Vec X, Vec CE)
410 {
411   PetscFunctionBegin;
412   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
413   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
414   PetscValidHeaderSpecific(CE,VEC_CLASSID,3);
415   PetscCheckSameComm(tao,1,X,2);
416   PetscCheckSameComm(tao,1,CE,3);
417   PetscCheck(tao->ops->computeequalityconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetEqualityConstraintsRoutine() has not been called");
418   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,CE,NULL));
419   PetscCallBack("Tao callback equality constraints",(*tao->ops->computeequalityconstraints)(tao,X,CE,tao->user_con_equalityP));
420   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,CE,NULL));
421   tao->nconstraints++;
422   PetscFunctionReturn(0);
423 }
424 
425 /*@C
426    TaoComputeInequalityConstraints - Compute the variable bounds using the
427    routine set by `TaoSetInequalityConstraintsRoutine()`.
428 
429    Collective on tao
430 
431    Input Parameter:
432 .  tao - the Tao context
433 
434    Output Parameters:
435 +  X - point the inequality constraints were evaluted on
436 -  CE   - vector of inequality constraints evaluated at X
437 
438    Level: developer
439 
440 .seealso: `Tao`, `TaoSetInequalityConstraintsRoutine()`, `TaoComputeJacobianInequality()`, `TaoComputeEqualityConstraints()`
441 @*/
442 
443 PetscErrorCode TaoComputeInequalityConstraints(Tao tao, Vec X, Vec CI)
444 {
445   PetscFunctionBegin;
446   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
447   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
448   PetscValidHeaderSpecific(CI,VEC_CLASSID,3);
449   PetscCheckSameComm(tao,1,X,2);
450   PetscCheckSameComm(tao,1,CI,3);
451   PetscCheck(tao->ops->computeinequalityconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetInequalityConstraintsRoutine() has not been called");
452   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,CI,NULL));
453   PetscCallBack("Tao callback inequality constraints",(*tao->ops->computeinequalityconstraints)(tao,X,CI,tao->user_con_inequalityP));
454   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,CI,NULL));
455   tao->nconstraints++;
456   PetscFunctionReturn(0);
457 }
458