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: [](ch_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: $ PetscErrorCode func(Tao tao, Vec xl, Vec xu, void *ctx);
45: + tao - the `Tao` solver
46: . xl - vector of lower bounds
47: . xu - vector of upper bounds
48: - ctx - the (optional) user-defined function context
50: Level: beginner
52: Note:
53: The func passed to `TaoSetVariableBoundsRoutine()` takes precedence over any values set in `TaoSetVariableBounds()`.
55: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
56: @*/
57: PetscErrorCode TaoSetVariableBoundsRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx)
58: {
59: PetscFunctionBegin;
61: tao->user_boundsP = ctx;
62: tao->ops->computebounds = func;
63: tao->bounded = func ? PETSC_TRUE : PETSC_FALSE;
64: PetscFunctionReturn(PETSC_SUCCESS);
65: }
67: /*@
68: TaoGetVariableBounds - Gets the upper and lower bounds vectors set with `TaoSetVariableBounds()`
70: Not Collective
72: Input Parameter:
73: . tao - the `Tao` context
75: Output Parameters:
76: + XL - vector of lower bounds
77: - XU - vector of upper bounds
79: Level: beginner
81: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
82: @*/
83: PetscErrorCode TaoGetVariableBounds(Tao tao, Vec *XL, Vec *XU)
84: {
85: PetscFunctionBegin;
87: if (XL) *XL = tao->XL;
88: if (XU) *XU = tao->XU;
89: PetscFunctionReturn(PETSC_SUCCESS);
90: }
92: /*@C
93: TaoComputeVariableBounds - Compute the variable bounds using the
94: routine set by `TaoSetVariableBoundsRoutine()`.
96: Collective
98: Input Parameter:
99: . tao - the `Tao` context
101: Level: developer
103: .seealso: [](ch_tao), `Tao`, `TaoSetVariableBoundsRoutine()`, `TaoSetVariableBounds()`
104: @*/
105: PetscErrorCode TaoComputeVariableBounds(Tao tao)
106: {
107: PetscFunctionBegin;
109: if (tao->ops->computebounds) {
110: if (!tao->XL) {
111: PetscCall(VecDuplicate(tao->solution, &tao->XL));
112: PetscCall(VecSet(tao->XL, PETSC_NINFINITY));
113: }
114: if (!tao->XU) {
115: PetscCall(VecDuplicate(tao->solution, &tao->XU));
116: PetscCall(VecSet(tao->XU, PETSC_INFINITY));
117: }
118: PetscCallBack("Tao callback variable bounds", (*tao->ops->computebounds)(tao, tao->XL, tao->XU, tao->user_boundsP));
119: }
120: PetscFunctionReturn(PETSC_SUCCESS);
121: }
123: /*@
124: TaoSetInequalityBounds - Sets the upper and lower bounds
126: Logically Collective
128: Input Parameters:
129: + tao - the `Tao` context
130: . IL - vector of lower bounds
131: - IU - vector of upper bounds
133: Level: beginner
135: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetInequalityBounds()`
136: @*/
137: PetscErrorCode TaoSetInequalityBounds(Tao tao, Vec IL, Vec IU)
138: {
139: PetscFunctionBegin;
143: PetscCall(PetscObjectReference((PetscObject)IL));
144: PetscCall(PetscObjectReference((PetscObject)IU));
145: PetscCall(VecDestroy(&tao->IL));
146: PetscCall(VecDestroy(&tao->IU));
147: tao->IL = IL;
148: tao->IU = IU;
149: tao->ineq_doublesided = (PetscBool)(IL || IU);
150: PetscFunctionReturn(PETSC_SUCCESS);
151: }
153: /*@
154: TaoGetInequalityBounds - Gets the upper and lower bounds set via `TaoSetInequalityBounds()`
156: Logically Collective
158: Input Parameter:
159: . tao - the `Tao` context
161: Output Parameters:
162: + IL - vector of lower bounds
163: - IU - vector of upper bounds
165: Level: beginner
167: .seealso: [](ch_tao), `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetInequalityBounds()`
168: @*/
169: PetscErrorCode TaoGetInequalityBounds(Tao tao, Vec *IL, Vec *IU)
170: {
171: PetscFunctionBegin;
173: if (IL) *IL = tao->IL;
174: if (IU) *IU = tao->IU;
175: PetscFunctionReturn(PETSC_SUCCESS);
176: }
178: /*@C
179: TaoComputeConstraints - Compute the variable bounds using the
180: routine set by `TaoSetConstraintsRoutine()`.
182: Collective
184: Input Parameters:
185: + tao - the `Tao` context
186: - X - location to evaluate the constraints
188: Output Parameter:
189: . C - the constraints
191: Level: developer
193: .seealso: [](ch_tao), `Tao`, `TaoSetConstraintsRoutine()`, `TaoComputeJacobian()`
194: @*/
195: PetscErrorCode TaoComputeConstraints(Tao tao, Vec X, Vec C)
196: {
197: PetscFunctionBegin;
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(PETSC_SUCCESS);
208: }
210: /*@C
211: TaoSetConstraintsRoutine - Sets a function to be used to compute constraints. Tao only handles constraints under certain conditions, see [](ch_tao) for details
213: Logically Collective
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`)
221: Calling sequence of `func`:
222: $ PetscErrorCode func(Tao tao, Vec x, Vec c, void *ctx);
223: + tao - the `Tao` solver
224: . x - point to evaluate constraints
225: . c - vector constraints evaluated at `x`
226: - ctx - the (optional) user-defined function context
228: Level: intermediate
230: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariablevBounds()`
231: @*/
232: PetscErrorCode TaoSetConstraintsRoutine(Tao tao, Vec c, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx)
233: {
234: PetscFunctionBegin;
237: PetscCall(PetscObjectReference((PetscObject)c));
238: PetscCall(VecDestroy(&tao->constraints));
239: tao->constrained = func ? PETSC_TRUE : PETSC_FALSE;
240: tao->constraints = c;
241: tao->user_conP = ctx;
242: tao->ops->computeconstraints = func;
243: PetscFunctionReturn(PETSC_SUCCESS);
244: }
246: /*@
247: TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds
248: of the variables
250: Collective
252: Input Parameter:
253: . tao - the `Tao` context
255: Output Parameters:
256: + DL - dual variable vector for the lower bounds
257: - DU - dual variable vector for the upper bounds
259: Level: advanced
261: Note:
262: DL and DU should be created before calling this routine. If calling
263: this routine after using an unconstrained solver, `DL` and `DU` are set to all
264: zeros.
266: .seealso: [](ch_tao), `Tao`, `TaoComputeObjective()`, `TaoSetVariableBounds()`
267: @*/
268: PetscErrorCode TaoComputeDualVariables(Tao tao, Vec DL, Vec DU)
269: {
270: PetscFunctionBegin;
274: PetscCheckSameComm(tao, 1, DL, 2);
275: PetscCheckSameComm(tao, 1, DU, 3);
276: if (tao->ops->computedual) {
277: PetscUseTypeMethod(tao, computedual, DL, DU);
278: } else {
279: PetscCall(VecSet(DL, 0.0));
280: PetscCall(VecSet(DU, 0.0));
281: }
282: PetscFunctionReturn(PETSC_SUCCESS);
283: }
285: /*@
286: TaoGetDualVariables - Gets the dual vectors
288: Collective
290: Input Parameter:
291: . tao - the `Tao` context
293: Output Parameters:
294: + DE - dual variable vector for the lower bounds
295: - DI - dual variable vector for the upper bounds
297: Level: advanced
299: .seealso: [](ch_tao), `Tao`, `TaoComputeDualVariables()`
300: @*/
301: PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI)
302: {
303: PetscFunctionBegin;
305: if (DE) *DE = tao->DE;
306: if (DI) *DI = tao->DI;
307: PetscFunctionReturn(PETSC_SUCCESS);
308: }
310: /*@C
311: TaoSetEqualityConstraintsRoutine - Sets a function to be used to compute constraints. Tao only handles constraints under certain conditions, see [](ch_tao) for details
313: Logically Collective
315: Input Parameters:
316: + tao - the `Tao` context
317: . ce - A vector that will be used to store equality constraint evaluation
318: . func - the bounds computation routine
319: - ctx - [optional] user-defined context for private data for the equality constraints computation (may be `NULL`)
321: Calling sequence of `func`:
322: $ PetscErrorCode func(Tao tao, Vec x, Vec ce, void *ctx);
323: + tao - the `Tao` solver
324: . x - point to evaluate equality constraints
325: . ce - vector of equality constraints evaluated at x
326: - ctx - the (optional) user-defined function context
328: Level: intermediate
330: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
331: @*/
332: PetscErrorCode TaoSetEqualityConstraintsRoutine(Tao tao, Vec ce, PetscErrorCode (*func)(Tao, Vec, Vec, void *), void *ctx)
333: {
334: PetscFunctionBegin;
337: PetscCall(PetscObjectReference((PetscObject)ce));
338: PetscCall(VecDestroy(&tao->constraints_equality));
339: tao->eq_constrained = func ? PETSC_TRUE : PETSC_FALSE;
340: tao->constraints_equality = ce;
341: tao->user_con_equalityP = ctx;
342: tao->ops->computeequalityconstraints = func;
343: PetscFunctionReturn(PETSC_SUCCESS);
344: }
346: /*@C
347: TaoSetInequalityConstraintsRoutine - Sets a function to be used to compute constraints. Tao only handles constraints under certain conditions, see [](ch_tao) for details
349: Logically Collective
351: Input Parameters:
352: + tao - the `Tao` context
353: . ci - A vector that will be used to store inequality constraint evaluation
354: . func - the bounds computation routine
355: - ctx - [optional] user-defined context for private data for the inequality constraints computation (may be `NULL`)
357: Calling sequence of `func`:
358: $ PetscErrorCode 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: [](ch_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: [](ch_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: [](ch_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: }