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