1 #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/ 2 3 /*@ 4 TaoSetVariableBounds - Sets the upper and lower bounds for the optimization problem 5 6 Logically Collective 7 8 Input Parameters: 9 + tao - the `Tao` context 10 . XL - vector of lower bounds 11 - XU - vector of upper bounds 12 13 Level: beginner 14 15 .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetVariableBounds()` 16 @*/ 17 PetscErrorCode TaoSetVariableBounds(Tao tao, Vec XL, Vec XU) 18 { 19 PetscFunctionBegin; 20 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 21 if (XL) PetscValidHeaderSpecific(XL, VEC_CLASSID, 2); 22 if (XU) PetscValidHeaderSpecific(XU, VEC_CLASSID, 3); 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 } 32 33 /*@C 34 TaoSetVariableBoundsRoutine - Sets a function to be used to compute lower and upper variable bounds for the optimization 35 36 Logically Collective 37 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`) 42 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 49 50 Level: beginner 51 52 Note: 53 The func passed to `TaoSetVariableBoundsRoutine()` takes precedence over any values set in `TaoSetVariableBounds()`. 54 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; 60 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 61 tao->user_boundsP = ctx; 62 tao->ops->computebounds = func; 63 tao->bounded = func ? PETSC_TRUE : PETSC_FALSE; 64 PetscFunctionReturn(PETSC_SUCCESS); 65 } 66 67 /*@ 68 TaoGetVariableBounds - Gets the upper and lower bounds vectors set with `TaoSetVariableBounds()` 69 70 Not Collective 71 72 Input Parameter: 73 . tao - the `Tao` context 74 75 Output Parameters: 76 + XL - vector of lower bounds 77 - XU - vector of upper bounds 78 79 Level: beginner 80 81 .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()` 82 @*/ 83 PetscErrorCode TaoGetVariableBounds(Tao tao, Vec *XL, Vec *XU) 84 { 85 PetscFunctionBegin; 86 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 87 if (XL) *XL = tao->XL; 88 if (XU) *XU = tao->XU; 89 PetscFunctionReturn(PETSC_SUCCESS); 90 } 91 92 /*@C 93 TaoComputeVariableBounds - Compute the variable bounds using the 94 routine set by `TaoSetVariableBoundsRoutine()`. 95 96 Collective 97 98 Input Parameter: 99 . tao - the `Tao` context 100 101 Level: developer 102 103 .seealso: [](ch_tao), `Tao`, `TaoSetVariableBoundsRoutine()`, `TaoSetVariableBounds()` 104 @*/ 105 PetscErrorCode TaoComputeVariableBounds(Tao tao) 106 { 107 PetscFunctionBegin; 108 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 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 } 122 123 /*@ 124 TaoSetInequalityBounds - Sets the upper and lower bounds 125 126 Logically Collective 127 128 Input Parameters: 129 + tao - the `Tao` context 130 . IL - vector of lower bounds 131 - IU - vector of upper bounds 132 133 Level: beginner 134 135 .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetInequalityBounds()` 136 @*/ 137 PetscErrorCode TaoSetInequalityBounds(Tao tao, Vec IL, Vec IU) 138 { 139 PetscFunctionBegin; 140 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 141 if (IL) PetscValidHeaderSpecific(IL, VEC_CLASSID, 2); 142 if (IU) PetscValidHeaderSpecific(IU, VEC_CLASSID, 3); 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 } 152 153 /*@ 154 TaoGetInequalityBounds - Gets the upper and lower bounds set via `TaoSetInequalityBounds()` 155 156 Logically Collective 157 158 Input Parameter: 159 . tao - the `Tao` context 160 161 Output Parameters: 162 + IL - vector of lower bounds 163 - IU - vector of upper bounds 164 165 Level: beginner 166 167 .seealso: [](ch_tao), `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetInequalityBounds()` 168 @*/ 169 PetscErrorCode TaoGetInequalityBounds(Tao tao, Vec *IL, Vec *IU) 170 { 171 PetscFunctionBegin; 172 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 173 if (IL) *IL = tao->IL; 174 if (IU) *IU = tao->IU; 175 PetscFunctionReturn(PETSC_SUCCESS); 176 } 177 178 /*@C 179 TaoComputeConstraints - Compute the variable bounds using the 180 routine set by `TaoSetConstraintsRoutine()`. 181 182 Collective 183 184 Input Parameters: 185 + tao - the `Tao` context 186 - X - location to evaluate the constraints 187 188 Output Parameter: 189 . C - the constraints 190 191 Level: developer 192 193 .seealso: [](ch_tao), `Tao`, `TaoSetConstraintsRoutine()`, `TaoComputeJacobian()` 194 @*/ 195 PetscErrorCode TaoComputeConstraints(Tao tao, Vec X, Vec C) 196 { 197 PetscFunctionBegin; 198 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 199 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 200 PetscValidHeaderSpecific(C, VEC_CLASSID, 3); 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 } 209 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 212 213 Logically Collective 214 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`) 220 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 227 228 Level: intermediate 229 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; 235 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 236 if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 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 } 245 246 /*@ 247 TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds 248 of the variables 249 250 Collective 251 252 Input Parameter: 253 . tao - the `Tao` context 254 255 Output Parameters: 256 + DL - dual variable vector for the lower bounds 257 - DU - dual variable vector for the upper bounds 258 259 Level: advanced 260 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. 265 266 .seealso: [](ch_tao), `Tao`, `TaoComputeObjective()`, `TaoSetVariableBounds()` 267 @*/ 268 PetscErrorCode TaoComputeDualVariables(Tao tao, Vec DL, Vec DU) 269 { 270 PetscFunctionBegin; 271 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 272 PetscValidHeaderSpecific(DL, VEC_CLASSID, 2); 273 PetscValidHeaderSpecific(DU, VEC_CLASSID, 3); 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 } 284 285 /*@ 286 TaoGetDualVariables - Gets the dual vectors 287 288 Collective 289 290 Input Parameter: 291 . tao - the `Tao` context 292 293 Output Parameters: 294 + DE - dual variable vector for the lower bounds 295 - DI - dual variable vector for the upper bounds 296 297 Level: advanced 298 299 .seealso: [](ch_tao), `Tao`, `TaoComputeDualVariables()` 300 @*/ 301 PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI) 302 { 303 PetscFunctionBegin; 304 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 305 if (DE) *DE = tao->DE; 306 if (DI) *DI = tao->DI; 307 PetscFunctionReturn(PETSC_SUCCESS); 308 } 309 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 312 313 Logically Collective 314 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`) 320 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 327 328 Level: intermediate 329 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; 335 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 336 if (ce) PetscValidHeaderSpecific(ce, VEC_CLASSID, 2); 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 } 345 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 348 349 Logically Collective 350 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`) 356 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 363 364 Level: intermediate 365 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; 371 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 372 if (ci) PetscValidHeaderSpecific(ci, VEC_CLASSID, 2); 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 } 381 382 /*@C 383 TaoComputeEqualityConstraints - Compute the variable bounds using the 384 routine set by `TaoSetEqualityConstraintsRoutine()`. 385 386 Collective 387 388 Input Parameter: 389 . tao - the `Tao` context 390 391 Output Parameters: 392 + X - point the equality constraints were evaluated on 393 - CE - vector of equality constraints evaluated at X 394 395 Level: developer 396 397 .seealso: [](ch_tao), `Tao`, `TaoSetEqualityConstraintsRoutine()`, `TaoComputeJacobianEquality()`, `TaoComputeInequalityConstraints()` 398 @*/ 399 PetscErrorCode TaoComputeEqualityConstraints(Tao tao, Vec X, Vec CE) 400 { 401 PetscFunctionBegin; 402 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 403 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 404 PetscValidHeaderSpecific(CE, VEC_CLASSID, 3); 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 } 413 414 /*@C 415 TaoComputeInequalityConstraints - Compute the variable bounds using the 416 routine set by `TaoSetInequalityConstraintsRoutine()`. 417 418 Collective 419 420 Input Parameter: 421 . tao - the `Tao` context 422 423 Output Parameters: 424 + X - point the inequality constraints were evaluated on 425 - CE - vector of inequality constraints evaluated at X 426 427 Level: developer 428 429 .seealso: [](ch_tao), `Tao`, `TaoSetInequalityConstraintsRoutine()`, `TaoComputeJacobianInequality()`, `TaoComputeEqualityConstraints()` 430 @*/ 431 PetscErrorCode TaoComputeInequalityConstraints(Tao tao, Vec X, Vec CI) 432 { 433 PetscFunctionBegin; 434 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 435 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 436 PetscValidHeaderSpecific(CI, VEC_CLASSID, 3); 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 } 445