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: }