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