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