Actual source code: taosolver_bounds.c
1: #include <petsc/private/taoimpl.h>
3: /*@
4: TaoSetVariableBounds - Sets the upper and lower bounds for the optimization problem
6: Logically collective
8: Input Parameters:
9: + tao - the `Tao` context
10: . XL - vector of lower bounds
11: - XU - vector of upper bounds
13: Level: beginner
15: .seealso: [](chapter_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetVariableBounds()`
16: @*/
17: PetscErrorCode TaoSetVariableBounds(Tao tao, Vec XL, Vec XU)
18: {
19: PetscFunctionBegin;
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: }
33: /*@C
34: TaoSetVariableBoundsRoutine - Sets a function to be used to compute lower and upper variable bounds for the optimization
36: Logically collective
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`)
43: Calling sequence of func:
44: $ func (Tao tao, Vec xl, Vec xu);
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
51: Level: beginner
53: Note:
54: The func passed to `TaoSetVariableBoundsRoutine()` takes precedence over any values set in `TaoSetVariableBounds()`.
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;
62: tao->user_boundsP = ctx;
63: tao->ops->computebounds = func;
64: tao->bounded = func ? PETSC_TRUE : PETSC_FALSE;
65: PetscFunctionReturn(PETSC_SUCCESS);
66: }
68: /*@
69: TaoGetVariableBounds - Gets the upper and lower bounds vectors set with `TaoSetVariableBounds()`
71: Not collective
73: Input Parameter:
74: . tao - the `Tao` context
76: Output Parameters:
77: + XL - vector of lower bounds
78: - XU - vector of upper bounds
80: Level: beginner
82: .seealso: [](chapter_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
83: @*/
84: PetscErrorCode TaoGetVariableBounds(Tao tao, Vec *XL, Vec *XU)
85: {
86: PetscFunctionBegin;
88: if (XL) *XL = tao->XL;
89: if (XU) *XU = tao->XU;
90: PetscFunctionReturn(PETSC_SUCCESS);
91: }
93: /*@C
94: TaoComputeVariableBounds - Compute the variable bounds using the
95: routine set by `TaoSetVariableBoundsRoutine()`.
97: Collective
99: Input Parameter:
100: . tao - the `Tao` context
102: Level: developer
104: .seealso: [](chapter_tao), `Tao`, `TaoSetVariableBoundsRoutine()`, `TaoSetVariableBounds()`
105: @*/
106: PetscErrorCode TaoComputeVariableBounds(Tao tao)
107: {
108: PetscFunctionBegin;
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: }
124: /*@
125: TaoSetInequalityBounds - Sets the upper and lower bounds
127: Logically collective
129: Input Parameters:
130: + tao - the `Tao` context
131: . IL - vector of lower bounds
132: - IU - vector of upper bounds
134: Level: beginner
136: .seealso: [](chapter_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetInequalityBounds()`
137: @*/
138: PetscErrorCode TaoSetInequalityBounds(Tao tao, Vec IL, Vec IU)
139: {
140: PetscFunctionBegin;
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: }
154: /*@
155: TaoGetInequalityBounds - Gets the upper and lower bounds set via `TaoSetInequalityBounds()`
157: Logically collective
159: Input Parameter:
160: . tao - the `Tao` context
162: Output Parameters:
163: + IL - vector of lower bounds
164: - IU - vector of upper bounds
166: Level: beginner
168: .seealso: [](chapter_tao), `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetInequalityBounds()`
169: @*/
170: PetscErrorCode TaoGetInequalityBounds(Tao tao, Vec *IL, Vec *IU)
171: {
172: PetscFunctionBegin;
174: if (IL) *IL = tao->IL;
175: if (IU) *IU = tao->IU;
176: PetscFunctionReturn(PETSC_SUCCESS);
177: }
179: /*@C
180: TaoComputeConstraints - Compute the variable bounds using the
181: routine set by `TaoSetConstraintsRoutine()`.
183: Collective
185: Input Parameters:
186: . tao - the `Tao` context
188: Level: developer
190: .seealso: [](chapter_tao), `Tao`, `TaoSetConstraintsRoutine()`, `TaoComputeJacobian()`
191: @*/
192: PetscErrorCode TaoComputeConstraints(Tao tao, Vec X, Vec C)
193: {
194: PetscFunctionBegin;
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: }
207: /*@C
208: TaoSetConstraintsRoutine - Sets a function to be used to compute constraints. Tao only handles constraints under certain conditions, see manual for details
210: Logically collective
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)
218: Calling sequence of func:
219: $ func (Tao tao, Vec x, Vec c, void *ctx);
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
226: Level: intermediate
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;
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: }
244: /*@
245: TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds
246: of the variables
248: Collective
250: Input Parameter:
251: . tao - the `Tao` context
253: Output Parameters:
254: + DL - dual variable vector for the lower bounds
255: - DU - dual variable vector for the upper bounds
257: Level: advanced
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.
264: .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoSetVariableBounds()`
265: @*/
266: PetscErrorCode TaoComputeDualVariables(Tao tao, Vec DL, Vec DU)
267: {
268: PetscFunctionBegin;
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: }
283: /*@
284: TaoGetDualVariables - Gets the dual vectors
286: Collective
288: Input Parameter:
289: . tao - the `Tao` context
291: Output Parameters:
292: + DE - dual variable vector for the lower bounds
293: - DI - dual variable vector for the upper bounds
295: Level: advanced
297: .seealso: [](chapter_tao), `Tao`, `TaoComputeDualVariables()`
298: @*/
299: PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI)
300: {
301: PetscFunctionBegin;
303: if (DE) *DE = tao->DE;
304: if (DI) *DI = tao->DI;
305: PetscFunctionReturn(PETSC_SUCCESS);
306: }
308: /*@C
309: TaoSetEqualityConstraintsRoutine - Sets a function to be used to compute constraints. Tao only handles constraints under certain conditions, see manual for details
311: Logically collective
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)
319: Calling sequence of func:
320: $ func (Tao tao, Vec x, Vec ce, void *ctx);
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
327: Level: intermediate
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;
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: }
345: /*@C
346: TaoSetInequalityConstraintsRoutine - Sets a function to be used to compute constraints. Tao only handles constraints under certain conditions, see manual for details
348: Logically collective
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)
356: Calling sequence of func:
357: $ func (Tao tao, Vec x, Vec ci, void *ctx);
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
364: Level: intermediate
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;
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: }
382: /*@C
383: TaoComputeEqualityConstraints - Compute the variable bounds using the
384: routine set by `TaoSetEqualityConstraintsRoutine()`.
386: Collective
388: Input Parameter:
389: . tao - the `Tao` context
391: Output Parameters:
392: + X - point the equality constraints were evaluated on
393: - CE - vector of equality constraints evaluated at X
395: Level: developer
397: .seealso: [](chapter_tao), `Tao`, `TaoSetEqualityConstraintsRoutine()`, `TaoComputeJacobianEquality()`, `TaoComputeInequalityConstraints()`
398: @*/
399: PetscErrorCode TaoComputeEqualityConstraints(Tao tao, Vec X, Vec CE)
400: {
401: PetscFunctionBegin;
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: }
414: /*@C
415: TaoComputeInequalityConstraints - Compute the variable bounds using the
416: routine set by `TaoSetInequalityConstraintsRoutine()`.
418: Collective
420: Input Parameter:
421: . tao - the `Tao` context
423: Output Parameters:
424: + X - point the inequality constraints were evaluated on
425: - CE - vector of inequality constraints evaluated at X
427: Level: developer
429: .seealso: [](chapter_tao), `Tao`, `TaoSetInequalityConstraintsRoutine()`, `TaoComputeJacobianInequality()`, `TaoComputeEqualityConstraints()`
430: @*/
431: PetscErrorCode TaoComputeInequalityConstraints(Tao tao, Vec X, Vec CI)
432: {
433: PetscFunctionBegin;
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: }