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