xref: /petsc/src/tao/interface/taosolver_bounds.c (revision d7547e516efde0cd36ffdeebcfafd4768debadcc)
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 Parameters:
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   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval, tao, X, C, NULL));
204   PetscCallBack("Tao callback constraints", (*tao->ops->computeconstraints)(tao, X, C, tao->user_conP));
205   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval, tao, X, C, NULL));
206   tao->nconstraints++;
207   PetscFunctionReturn(0);
208 }
209 
210 /*@C
211   TaoSetConstraintsRoutine - Sets a function to be used to compute constraints.  Tao only handles constraints under certain conditions, see manual for details
212 
213   Logically collective on tao
214 
215   Input Parameters:
216 + tao - the Tao context
217 . c   - A vector that will be used to store constraint evaluation
218 . func - the bounds computation routine
219 - ctx - [optional] user-defined context for private data for the constraints computation (may be NULL)
220 
221   Calling sequence of func:
222 $      func (Tao tao, Vec x, Vec c, void *ctx);
223 
224 + tao - the Tao
225 . x   - point to evaluate constraints
226 . c   - vector constraints evaluated at x
227 - ctx - the (optional) user-defined function context
228 
229   Level: intermediate
230 
231 .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariablevBounds()`
232 
233 @*/
234 PetscErrorCode TaoSetConstraintsRoutine(Tao tao, Vec c, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx)
235 {
236   PetscFunctionBegin;
237   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
238   if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2);
239   PetscCall(PetscObjectReference((PetscObject)c));
240   PetscCall(VecDestroy(&tao->constraints));
241   tao->constrained             = func ? PETSC_TRUE : PETSC_FALSE;
242   tao->constraints             = c;
243   tao->user_conP               = ctx;
244   tao->ops->computeconstraints = func;
245   PetscFunctionReturn(0);
246 }
247 
248 /*@
249   TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds
250   of the variables
251 
252   Collective on tao
253 
254   Input Parameter:
255 . tao - the Tao context
256 
257   Output Parameters:
258 + DL - dual variable vector for the lower bounds
259 - DU - dual variable vector for the upper bounds
260 
261   Level: advanced
262 
263   Note:
264   DL and DU should be created before calling this routine.  If calling
265   this routine after using an unconstrained solver, DL and DU are set to all
266   zeros.
267 
268   Level: advanced
269 
270  .seealso: `Tao`, `TaoComputeObjective()`, `TaoSetVariableBounds()`
271 @*/
272 PetscErrorCode TaoComputeDualVariables(Tao tao, Vec DL, Vec DU)
273 {
274   PetscFunctionBegin;
275   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
276   PetscValidHeaderSpecific(DL, VEC_CLASSID, 2);
277   PetscValidHeaderSpecific(DU, VEC_CLASSID, 3);
278   PetscCheckSameComm(tao, 1, DL, 2);
279   PetscCheckSameComm(tao, 1, DU, 3);
280   if (tao->ops->computedual) {
281     PetscUseTypeMethod(tao, computedual, DL, DU);
282   } else {
283     PetscCall(VecSet(DL, 0.0));
284     PetscCall(VecSet(DU, 0.0));
285   }
286   PetscFunctionReturn(0);
287 }
288 
289 /*@
290   TaoGetDualVariables - Gets the dual vectors
291 
292   Collective on tao
293 
294   Input Parameter:
295 . tao - the Tao context
296 
297   Output Parameters:
298 + DE - dual variable vector for the lower bounds
299 - DI - dual variable vector for the upper bounds
300 
301   Level: advanced
302 
303 .seealso: `Tao`, `TaoComputeDualVariables()`
304 @*/
305 PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI)
306 {
307   PetscFunctionBegin;
308   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
309   if (DE) *DE = tao->DE;
310   if (DI) *DI = tao->DI;
311   PetscFunctionReturn(0);
312 }
313 
314 /*@C
315   TaoSetEqualityConstraintsRoutine - Sets a function to be used to compute constraints.  Tao only handles constraints under certain conditions, see manual for details
316 
317   Logically collective on tao
318 
319   Input Parameters:
320 + tao - the Tao context
321 . ce   - A vector that will be used to store equality constraint evaluation
322 . func - the bounds computation routine
323 - ctx - [optional] user-defined context for private data for the equality constraints computation (may be NULL)
324 
325   Calling sequence of func:
326 $      func (Tao tao, Vec x, Vec ce, void *ctx);
327 
328 + tao - the Tao
329 . x   - point to evaluate equality constraints
330 . ce   - vector of equality constraints evaluated at x
331 - ctx - the (optional) user-defined function context
332 
333   Level: intermediate
334 
335 .seealso: `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
336 
337 @*/
338 PetscErrorCode TaoSetEqualityConstraintsRoutine(Tao tao, Vec ce, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx)
339 {
340   PetscFunctionBegin;
341   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
342   if (ce) PetscValidHeaderSpecific(ce, VEC_CLASSID, 2);
343   PetscCall(PetscObjectReference((PetscObject)ce));
344   PetscCall(VecDestroy(&tao->constraints_equality));
345   tao->eq_constrained                  = func ? PETSC_TRUE : PETSC_FALSE;
346   tao->constraints_equality            = ce;
347   tao->user_con_equalityP              = ctx;
348   tao->ops->computeequalityconstraints = func;
349   PetscFunctionReturn(0);
350 }
351 
352 /*@C
353   TaoSetInequalityConstraintsRoutine - Sets a function to be used to compute constraints.  Tao only handles constraints under certain conditions, see manual for details
354 
355   Logically collective on tao
356 
357   Input Parameters:
358 + tao - the Tao context
359 . ci   - A vector that will be used to store inequality constraint evaluation
360 . func - the bounds computation routine
361 - ctx - [optional] user-defined context for private data for the inequality constraints computation (may be NULL)
362 
363   Calling sequence of func:
364 $      func (Tao tao, Vec x, Vec ci, void *ctx);
365 
366 + tao - the Tao
367 . x   - point to evaluate inequality constraints
368 . ci   - vector of inequality constraints evaluated at x
369 - ctx - the (optional) user-defined function context
370 
371   Level: intermediate
372 
373  .seealso: `Tao, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
374 
375 @*/
376 PetscErrorCode TaoSetInequalityConstraintsRoutine(Tao tao, Vec ci, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx)
377 {
378   PetscFunctionBegin;
379   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
380   if (ci) PetscValidHeaderSpecific(ci, VEC_CLASSID, 2);
381   PetscCall(PetscObjectReference((PetscObject)ci));
382   PetscCall(VecDestroy(&tao->constraints_inequality));
383   tao->constraints_inequality            = ci;
384   tao->ineq_constrained                  = func ? PETSC_TRUE : PETSC_FALSE;
385   tao->user_con_inequalityP              = ctx;
386   tao->ops->computeinequalityconstraints = func;
387   PetscFunctionReturn(0);
388 }
389 
390 /*@C
391    TaoComputeEqualityConstraints - Compute the variable bounds using the
392    routine set by `TaoSetEqualityConstraintsRoutine()`.
393 
394    Collective on tao
395 
396    Input Parameter:
397 .  tao - the Tao context
398 
399    Output Parameters:
400 +  X - point the equality constraints were evaluted on
401 -  CE   - vector of equality constraints evaluated at X
402 
403    Level: developer
404 
405 .seealso: `Tao`, `TaoSetEqualityConstraintsRoutine()`, `TaoComputeJacobianEquality()`, `TaoComputeInequalityConstraints()`
406 @*/
407 
408 PetscErrorCode TaoComputeEqualityConstraints(Tao tao, Vec X, Vec CE)
409 {
410   PetscFunctionBegin;
411   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
412   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
413   PetscValidHeaderSpecific(CE, VEC_CLASSID, 3);
414   PetscCheckSameComm(tao, 1, X, 2);
415   PetscCheckSameComm(tao, 1, CE, 3);
416   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval, tao, X, CE, NULL));
417   PetscCallBack("Tao callback equality constraints", (*tao->ops->computeequalityconstraints)(tao, X, CE, tao->user_con_equalityP));
418   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval, tao, X, CE, NULL));
419   tao->nconstraints++;
420   PetscFunctionReturn(0);
421 }
422 
423 /*@C
424    TaoComputeInequalityConstraints - Compute the variable bounds using the
425    routine set by `TaoSetInequalityConstraintsRoutine()`.
426 
427    Collective on tao
428 
429    Input Parameter:
430 .  tao - the Tao context
431 
432    Output Parameters:
433 +  X - point the inequality constraints were evaluted on
434 -  CE   - vector of inequality constraints evaluated at X
435 
436    Level: developer
437 
438 .seealso: `Tao`, `TaoSetInequalityConstraintsRoutine()`, `TaoComputeJacobianInequality()`, `TaoComputeEqualityConstraints()`
439 @*/
440 
441 PetscErrorCode TaoComputeInequalityConstraints(Tao tao, Vec X, Vec CI)
442 {
443   PetscFunctionBegin;
444   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
445   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
446   PetscValidHeaderSpecific(CI, VEC_CLASSID, 3);
447   PetscCheckSameComm(tao, 1, X, 2);
448   PetscCheckSameComm(tao, 1, CI, 3);
449   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval, tao, X, CI, NULL));
450   PetscCallBack("Tao callback inequality constraints", (*tao->ops->computeinequalityconstraints)(tao, X, CI, tao->user_con_inequalityP));
451   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval, tao, X, CI, NULL));
452   tao->nconstraints++;
453   PetscFunctionReturn(0);
454 }
455