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: + tao - the `Tao` solver
 45: . xl  - vector of lower bounds
 46: . xu  - vector of upper bounds
 47: - ctx - the (optional) user-defined function context

 49:   Level: beginner

 51:   Note:
 52:   The func passed to `TaoSetVariableBoundsRoutine()` takes precedence over any values set in `TaoSetVariableBounds()`.

 54: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
 55: @*/
 56: PetscErrorCode TaoSetVariableBoundsRoutine(Tao tao, PetscErrorCode (*func)(Tao tao, Vec xl, Vec xu, void *ctx), void *ctx)
 57: {
 58:   PetscFunctionBegin;
 60:   tao->user_boundsP       = ctx;
 61:   tao->ops->computebounds = func;
 62:   tao->bounded            = func ? PETSC_TRUE : PETSC_FALSE;
 63:   PetscFunctionReturn(PETSC_SUCCESS);
 64: }

 66: /*@
 67:   TaoGetVariableBounds - Gets the upper and lower bounds vectors set with `TaoSetVariableBounds()`

 69:   Not Collective

 71:   Input Parameter:
 72: . tao - the `Tao` context

 74:   Output Parameters:
 75: + XL - vector of lower bounds
 76: - XU - vector of upper bounds

 78:   Level: beginner

 80: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
 81: @*/
 82: PetscErrorCode TaoGetVariableBounds(Tao tao, Vec *XL, Vec *XU)
 83: {
 84:   PetscFunctionBegin;
 86:   if (XL) *XL = tao->XL;
 87:   if (XU) *XU = tao->XU;
 88:   PetscFunctionReturn(PETSC_SUCCESS);
 89: }

 91: /*@
 92:   TaoComputeVariableBounds - Compute the variable bounds using the
 93:   routine set by `TaoSetVariableBoundsRoutine()`.

 95:   Collective

 97:   Input Parameter:
 98: . tao - the `Tao` context

100:   Level: developer

102: .seealso: [](ch_tao), `Tao`, `TaoSetVariableBoundsRoutine()`, `TaoSetVariableBounds()`
103: @*/
104: PetscErrorCode TaoComputeVariableBounds(Tao tao)
105: {
106:   PetscFunctionBegin;
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(PETSC_SUCCESS);
120: }

122: /*@
123:   TaoSetInequalityBounds - Sets the upper and lower bounds

125:   Logically Collective

127:   Input Parameters:
128: + tao - the `Tao` context
129: . IL  - vector of lower bounds
130: - IU  - vector of upper bounds

132:   Level: beginner

134: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetInequalityBounds()`
135: @*/
136: PetscErrorCode TaoSetInequalityBounds(Tao tao, Vec IL, Vec IU)
137: {
138:   PetscFunctionBegin;
142:   PetscCall(PetscObjectReference((PetscObject)IL));
143:   PetscCall(PetscObjectReference((PetscObject)IU));
144:   PetscCall(VecDestroy(&tao->IL));
145:   PetscCall(VecDestroy(&tao->IU));
146:   tao->IL               = IL;
147:   tao->IU               = IU;
148:   tao->ineq_doublesided = (PetscBool)(IL || IU);
149:   PetscFunctionReturn(PETSC_SUCCESS);
150: }

152: /*@
153:   TaoGetInequalityBounds - Gets the upper and lower bounds set via `TaoSetInequalityBounds()`

155:   Logically Collective

157:   Input Parameter:
158: . tao - the `Tao` context

160:   Output Parameters:
161: + IL - vector of lower bounds
162: - IU - vector of upper bounds

164:   Level: beginner

166: .seealso: [](ch_tao), `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetInequalityBounds()`
167: @*/
168: PetscErrorCode TaoGetInequalityBounds(Tao tao, Vec *IL, Vec *IU)
169: {
170:   PetscFunctionBegin;
172:   if (IL) *IL = tao->IL;
173:   if (IU) *IU = tao->IU;
174:   PetscFunctionReturn(PETSC_SUCCESS);
175: }

177: /*@
178:   TaoComputeConstraints - Compute the variable bounds using the
179:   routine set by `TaoSetConstraintsRoutine()`.

181:   Collective

183:   Input Parameters:
184: + tao - the `Tao` context
185: - X   - location to evaluate the constraints

187:   Output Parameter:
188: . C - the constraints

190:   Level: developer

192: .seealso: [](ch_tao), `Tao`, `TaoSetConstraintsRoutine()`, `TaoComputeJacobian()`
193: @*/
194: PetscErrorCode TaoComputeConstraints(Tao tao, Vec X, Vec C)
195: {
196:   PetscFunctionBegin;
200:   PetscCheckSameComm(tao, 1, X, 2);
201:   PetscCheckSameComm(tao, 1, C, 3);
202:   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval, tao, X, C, NULL));
203:   PetscCallBack("Tao callback constraints", (*tao->ops->computeconstraints)(tao, X, C, tao->user_conP));
204:   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval, tao, X, C, NULL));
205:   tao->nconstraints++;
206:   PetscFunctionReturn(PETSC_SUCCESS);
207: }

209: /*@C
210:   TaoSetConstraintsRoutine - Sets a function to be used to compute constraints.  Tao only handles constraints under certain conditions, see [](ch_tao) for details

212:   Logically Collective

214:   Input Parameters:
215: + tao  - the `Tao` context
216: . c    - A vector that will be used to store constraint evaluation
217: . func - the bounds computation routine
218: - ctx  - [optional] user-defined context for private data for the constraints computation (may be `NULL`)

220:   Calling sequence of `func`:
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: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariablevBounds()`
229: @*/
230: PetscErrorCode TaoSetConstraintsRoutine(Tao tao, Vec c, PetscErrorCode (*func)(Tao tao, Vec x, Vec c, void *ctx), 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: [](ch_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: [](ch_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 [](ch_tao) 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: + tao - the `Tao` solver
321: . x   - point to evaluate equality constraints
322: . ce  - vector of equality constraints evaluated at x
323: - ctx - the (optional) user-defined function context

325:   Level: intermediate

327: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
328: @*/
329: PetscErrorCode TaoSetEqualityConstraintsRoutine(Tao tao, Vec ce, PetscErrorCode (*func)(Tao tao, Vec x, Vec ce, void *ctx), void *ctx)
330: {
331:   PetscFunctionBegin;
334:   PetscCall(PetscObjectReference((PetscObject)ce));
335:   PetscCall(VecDestroy(&tao->constraints_equality));
336:   tao->eq_constrained                  = func ? PETSC_TRUE : PETSC_FALSE;
337:   tao->constraints_equality            = ce;
338:   tao->user_con_equalityP              = ctx;
339:   tao->ops->computeequalityconstraints = func;
340:   PetscFunctionReturn(PETSC_SUCCESS);
341: }

343: /*@C
344:   TaoGetEqualityConstraintsRoutine - Gets the function used to compute equality constraints.

346:   Not Collective

348:   Input Parameter:
349: . tao - the `Tao` context

351:   Output Parameters:
352: + ci   - the vector to internally hold the constraint computation
353: . func - the bounds computation routine
354: - ctx  - the (optional) user-defined context

356:   Calling sequence of `func`:
357: + tao - the `Tao` solver
358: . x   - point to evaluate equality constraints
359: . ci  - vector of equality constraints evaluated at x
360: - ctx - the (optional) user-defined function context

362:   Level: intermediate

364: .seealso: [](ch_tao), `Tao`, `TaoSolve()`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetHessian()`, `TaoGetObjectiveAndGradient()`, `TaoGetInequalityConstraintsRoutine()`
365: @*/
366: PetscErrorCode TaoGetEqualityConstraintsRoutine(Tao tao, Vec *ci, PetscErrorCode (**func)(Tao tao, Vec x, Vec ci, void *ctx), void **ctx)
367: {
368:   PetscFunctionBegin;
370:   if (ci) *ci = tao->constraints_equality;
371:   if (func) *func = tao->ops->computeequalityconstraints;
372:   if (ctx) *ctx = tao->user_con_equalityP;
373:   PetscFunctionReturn(PETSC_SUCCESS);
374: }

376: /*@C
377:   TaoSetInequalityConstraintsRoutine - Sets a function to be used to compute constraints.  Tao only handles constraints under certain conditions, see [](ch_tao) for details

379:   Logically Collective

381:   Input Parameters:
382: + tao  - the `Tao` context
383: . ci   - A vector that will be used to store inequality constraint evaluation
384: . func - the bounds computation routine
385: - ctx  - [optional] user-defined context for private data for the inequality constraints computation (may be `NULL`)

387:   Calling sequence of `func`:
388: + tao - the `Tao` solver
389: . x   - point to evaluate inequality constraints
390: . ci  - vector of inequality constraints evaluated at x
391: - ctx - the (optional) user-defined function context

393:   Level: intermediate

395: .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()`
396: @*/
397: PetscErrorCode TaoSetInequalityConstraintsRoutine(Tao tao, Vec ci, PetscErrorCode (*func)(Tao tao, Vec x, Vec ci, void *ctx), void *ctx)
398: {
399:   PetscFunctionBegin;
402:   PetscCall(PetscObjectReference((PetscObject)ci));
403:   PetscCall(VecDestroy(&tao->constraints_inequality));
404:   tao->constraints_inequality            = ci;
405:   tao->ineq_constrained                  = func ? PETSC_TRUE : PETSC_FALSE;
406:   tao->user_con_inequalityP              = ctx;
407:   tao->ops->computeinequalityconstraints = func;
408:   PetscFunctionReturn(PETSC_SUCCESS);
409: }

411: /*@C
412:   TaoGetInequalityConstraintsRoutine - Gets the function used to compute inequality constraints.

414:   Not Collective

416:   Input Parameter:
417: . tao - the `Tao` context

419:   Output Parameters:
420: + ci   - the vector to internally hold the constraint computation
421: . func - the bounds computation routine
422: - ctx  - the (optional) user-defined context

424:   Calling sequence of `func`:
425: + tao - the `Tao` solver
426: . x   - point to evaluate inequality constraints
427: . ci  - vector of inequality constraints evaluated at x
428: - ctx - the (optional) user-defined function context

430:   Level: intermediate

432: .seealso: [](ch_tao), `Tao`, `TaoSolve()`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetHessian()`, `TaoGetObjectiveAndGradient()`, `TaoGetEqualityConstraintsRoutine()`
433: @*/
434: PetscErrorCode TaoGetInequalityConstraintsRoutine(Tao tao, Vec *ci, PetscErrorCode (**func)(Tao tao, Vec x, Vec ci, void *ctx), void **ctx)
435: {
436:   PetscFunctionBegin;
438:   if (ci) *ci = tao->constraints_inequality;
439:   if (func) *func = tao->ops->computeinequalityconstraints;
440:   if (ctx) *ctx = tao->user_con_inequalityP;
441:   PetscFunctionReturn(PETSC_SUCCESS);
442: }

444: /*@
445:   TaoComputeEqualityConstraints - Compute the variable bounds using the
446:   routine set by `TaoSetEqualityConstraintsRoutine()`.

448:   Collective

450:   Input Parameter:
451: . tao - the `Tao` context

453:   Output Parameters:
454: + X  - point the equality constraints were evaluated on
455: - CE - vector of equality constraints evaluated at X

457:   Level: developer

459: .seealso: [](ch_tao), `Tao`, `TaoSetEqualityConstraintsRoutine()`, `TaoComputeJacobianEquality()`, `TaoComputeInequalityConstraints()`
460: @*/
461: PetscErrorCode TaoComputeEqualityConstraints(Tao tao, Vec X, Vec CE)
462: {
463:   PetscFunctionBegin;
467:   PetscCheckSameComm(tao, 1, X, 2);
468:   PetscCheckSameComm(tao, 1, CE, 3);
469:   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval, tao, X, CE, NULL));
470:   PetscCallBack("Tao callback equality constraints", (*tao->ops->computeequalityconstraints)(tao, X, CE, tao->user_con_equalityP));
471:   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval, tao, X, CE, NULL));
472:   tao->nconstraints++;
473:   PetscFunctionReturn(PETSC_SUCCESS);
474: }

476: /*@
477:   TaoComputeInequalityConstraints - Compute the variable bounds using the
478:   routine set by `TaoSetInequalityConstraintsRoutine()`.

480:   Collective

482:   Input Parameter:
483: . tao - the `Tao` context

485:   Output Parameters:
486: + X  - point the inequality constraints were evaluated on
487: - CI - vector of inequality constraints evaluated at X

489:   Level: developer

491: .seealso: [](ch_tao), `Tao`, `TaoSetInequalityConstraintsRoutine()`, `TaoComputeJacobianInequality()`, `TaoComputeEqualityConstraints()`
492: @*/
493: PetscErrorCode TaoComputeInequalityConstraints(Tao tao, Vec X, Vec CI)
494: {
495:   PetscFunctionBegin;
499:   PetscCheckSameComm(tao, 1, X, 2);
500:   PetscCheckSameComm(tao, 1, CI, 3);
501:   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval, tao, X, CI, NULL));
502:   PetscCallBack("Tao callback inequality constraints", (*tao->ops->computeinequalityconstraints)(tao, X, CI, tao->user_con_inequalityP));
503:   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval, tao, X, CI, NULL));
504:   tao->nconstraints++;
505:   PetscFunctionReturn(PETSC_SUCCESS);
506: }