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, PetscCtx ctx), PetscCtx 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, PetscCtx ctx), PetscCtx 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) PetscUseTypeMethod(tao, computedual, DL, DU);
275:   else {
276:     PetscCall(VecSet(DL, 0.0));
277:     PetscCall(VecSet(DU, 0.0));
278:   }
279:   PetscFunctionReturn(PETSC_SUCCESS);
280: }

282: /*@
283:   TaoGetDualVariables - Gets the dual vectors

285:   Collective

287:   Input Parameter:
288: . tao - the `Tao` context

290:   Output Parameters:
291: + DE - dual variable vector for the lower bounds
292: - DI - dual variable vector for the upper bounds

294:   Level: advanced

296: .seealso: [](ch_tao), `Tao`, `TaoComputeDualVariables()`
297: @*/
298: PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI)
299: {
300:   PetscFunctionBegin;
302:   if (DE) *DE = tao->DE;
303:   if (DI) *DI = tao->DI;
304:   PetscFunctionReturn(PETSC_SUCCESS);
305: }

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

310:   Logically Collective

312:   Input Parameters:
313: + tao  - the `Tao` context
314: . ce   - A vector that will be used to store equality constraint evaluation
315: . func - the bounds computation routine
316: - ctx  - [optional] user-defined context for private data for the equality constraints computation (may be `NULL`)

318:   Calling sequence of `func`:
319: + tao - the `Tao` solver
320: . x   - point to evaluate equality constraints
321: . ce  - vector of equality constraints evaluated at x
322: - ctx - the (optional) user-defined function context

324:   Level: intermediate

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

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

345:   Not Collective

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

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

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

361:   Level: intermediate

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

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

378:   Logically Collective

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

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

392:   Level: intermediate

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

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

413:   Not Collective

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

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

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

429:   Level: intermediate

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

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

447:   Collective

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

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

456:   Level: developer

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

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

479:   Collective

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

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

488:   Level: developer

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