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 + tao - the `Tao` solver 45 . xl - vector of lower bounds 46 . xu - vector of upper bounds 47 - ctx - the (optional) user-defined function context 48 49 Level: beginner 50 51 Note: 52 The func passed to `TaoSetVariableBoundsRoutine()` takes precedence over any values set in `TaoSetVariableBounds()`. 53 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; 59 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 60 tao->user_boundsP = ctx; 61 tao->ops->computebounds = func; 62 tao->bounded = func ? PETSC_TRUE : PETSC_FALSE; 63 PetscFunctionReturn(PETSC_SUCCESS); 64 } 65 66 /*@ 67 TaoGetVariableBounds - Gets the upper and lower bounds vectors set with `TaoSetVariableBounds()` 68 69 Not Collective 70 71 Input Parameter: 72 . tao - the `Tao` context 73 74 Output Parameters: 75 + XL - vector of lower bounds 76 - XU - vector of upper bounds 77 78 Level: beginner 79 80 .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()` 81 @*/ 82 PetscErrorCode TaoGetVariableBounds(Tao tao, Vec *XL, Vec *XU) 83 { 84 PetscFunctionBegin; 85 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 86 if (XL) *XL = tao->XL; 87 if (XU) *XU = tao->XU; 88 PetscFunctionReturn(PETSC_SUCCESS); 89 } 90 91 /*@ 92 TaoComputeVariableBounds - Compute the variable bounds using the 93 routine set by `TaoSetVariableBoundsRoutine()`. 94 95 Collective 96 97 Input Parameter: 98 . tao - the `Tao` context 99 100 Level: developer 101 102 .seealso: [](ch_tao), `Tao`, `TaoSetVariableBoundsRoutine()`, `TaoSetVariableBounds()` 103 @*/ 104 PetscErrorCode TaoComputeVariableBounds(Tao tao) 105 { 106 PetscFunctionBegin; 107 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 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 } 121 122 /*@ 123 TaoSetInequalityBounds - Sets the upper and lower bounds 124 125 Logically Collective 126 127 Input Parameters: 128 + tao - the `Tao` context 129 . IL - vector of lower bounds 130 - IU - vector of upper bounds 131 132 Level: beginner 133 134 .seealso: [](ch_tao), `Tao`, `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetInequalityBounds()` 135 @*/ 136 PetscErrorCode TaoSetInequalityBounds(Tao tao, Vec IL, Vec IU) 137 { 138 PetscFunctionBegin; 139 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 140 if (IL) PetscValidHeaderSpecific(IL, VEC_CLASSID, 2); 141 if (IU) PetscValidHeaderSpecific(IU, VEC_CLASSID, 3); 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 } 151 152 /*@ 153 TaoGetInequalityBounds - Gets the upper and lower bounds set via `TaoSetInequalityBounds()` 154 155 Logically Collective 156 157 Input Parameter: 158 . tao - the `Tao` context 159 160 Output Parameters: 161 + IL - vector of lower bounds 162 - IU - vector of upper bounds 163 164 Level: beginner 165 166 .seealso: [](ch_tao), `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetInequalityBounds()` 167 @*/ 168 PetscErrorCode TaoGetInequalityBounds(Tao tao, Vec *IL, Vec *IU) 169 { 170 PetscFunctionBegin; 171 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 172 if (IL) *IL = tao->IL; 173 if (IU) *IU = tao->IU; 174 PetscFunctionReturn(PETSC_SUCCESS); 175 } 176 177 /*@ 178 TaoComputeConstraints - Compute the variable bounds using the 179 routine set by `TaoSetConstraintsRoutine()`. 180 181 Collective 182 183 Input Parameters: 184 + tao - the `Tao` context 185 - X - location to evaluate the constraints 186 187 Output Parameter: 188 . C - the constraints 189 190 Level: developer 191 192 .seealso: [](ch_tao), `Tao`, `TaoSetConstraintsRoutine()`, `TaoComputeJacobian()` 193 @*/ 194 PetscErrorCode TaoComputeConstraints(Tao tao, Vec X, Vec C) 195 { 196 PetscFunctionBegin; 197 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 198 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 199 PetscValidHeaderSpecific(C, VEC_CLASSID, 3); 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 } 208 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 211 212 Logically Collective 213 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`) 219 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 225 226 Level: intermediate 227 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; 233 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 234 if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 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 } 243 244 /*@ 245 TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds 246 of the variables 247 248 Collective 249 250 Input Parameter: 251 . tao - the `Tao` context 252 253 Output Parameters: 254 + DL - dual variable vector for the lower bounds 255 - DU - dual variable vector for the upper bounds 256 257 Level: advanced 258 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. 263 264 .seealso: [](ch_tao), `Tao`, `TaoComputeObjective()`, `TaoSetVariableBounds()` 265 @*/ 266 PetscErrorCode TaoComputeDualVariables(Tao tao, Vec DL, Vec DU) 267 { 268 PetscFunctionBegin; 269 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 270 PetscValidHeaderSpecific(DL, VEC_CLASSID, 2); 271 PetscValidHeaderSpecific(DU, VEC_CLASSID, 3); 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 } 282 283 /*@ 284 TaoGetDualVariables - Gets the dual vectors 285 286 Collective 287 288 Input Parameter: 289 . tao - the `Tao` context 290 291 Output Parameters: 292 + DE - dual variable vector for the lower bounds 293 - DI - dual variable vector for the upper bounds 294 295 Level: advanced 296 297 .seealso: [](ch_tao), `Tao`, `TaoComputeDualVariables()` 298 @*/ 299 PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI) 300 { 301 PetscFunctionBegin; 302 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 303 if (DE) *DE = tao->DE; 304 if (DI) *DI = tao->DI; 305 PetscFunctionReturn(PETSC_SUCCESS); 306 } 307 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 310 311 Logically Collective 312 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`) 318 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 324 325 Level: intermediate 326 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; 332 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 333 if (ce) PetscValidHeaderSpecific(ce, VEC_CLASSID, 2); 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 } 342 343 /*@C 344 TaoGetEqualityConstraintsRoutine - Gets the function used to compute equality constraints. 345 346 Not Collective 347 348 Input Parameter: 349 . tao - the `Tao` context 350 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 355 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 361 362 Level: intermediate 363 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; 369 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 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 } 375 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 378 379 Logically Collective 380 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`) 386 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 392 393 Level: intermediate 394 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; 400 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 401 if (ci) PetscValidHeaderSpecific(ci, VEC_CLASSID, 2); 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 } 410 411 /*@C 412 TaoGetInequalityConstraintsRoutine - Gets the function used to compute inequality constraints. 413 414 Not Collective 415 416 Input Parameter: 417 . tao - the `Tao` context 418 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 423 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 429 430 Level: intermediate 431 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; 437 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 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 } 443 444 /*@ 445 TaoComputeEqualityConstraints - Compute the variable bounds using the 446 routine set by `TaoSetEqualityConstraintsRoutine()`. 447 448 Collective 449 450 Input Parameter: 451 . tao - the `Tao` context 452 453 Output Parameters: 454 + X - point the equality constraints were evaluated on 455 - CE - vector of equality constraints evaluated at X 456 457 Level: developer 458 459 .seealso: [](ch_tao), `Tao`, `TaoSetEqualityConstraintsRoutine()`, `TaoComputeJacobianEquality()`, `TaoComputeInequalityConstraints()` 460 @*/ 461 PetscErrorCode TaoComputeEqualityConstraints(Tao tao, Vec X, Vec CE) 462 { 463 PetscFunctionBegin; 464 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 465 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 466 PetscValidHeaderSpecific(CE, VEC_CLASSID, 3); 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 } 475 476 /*@ 477 TaoComputeInequalityConstraints - Compute the variable bounds using the 478 routine set by `TaoSetInequalityConstraintsRoutine()`. 479 480 Collective 481 482 Input Parameter: 483 . tao - the `Tao` context 484 485 Output Parameters: 486 + X - point the inequality constraints were evaluated on 487 - CI - vector of inequality constraints evaluated at X 488 489 Level: developer 490 491 .seealso: [](ch_tao), `Tao`, `TaoSetInequalityConstraintsRoutine()`, `TaoComputeJacobianInequality()`, `TaoComputeEqualityConstraints()` 492 @*/ 493 PetscErrorCode TaoComputeInequalityConstraints(Tao tao, Vec X, Vec CI) 494 { 495 PetscFunctionBegin; 496 PetscValidHeaderSpecific(tao, TAO_CLASSID, 1); 497 PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 498 PetscValidHeaderSpecific(CI, VEC_CLASSID, 3); 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 } 507