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 @*/
TaoSetVariableBounds(Tao tao,Vec XL,Vec XU)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 @*/
TaoSetVariableBoundsRoutine(Tao tao,PetscErrorCode (* func)(Tao tao,Vec xl,Vec xu,PetscCtx ctx),PetscCtx ctx)56 PetscErrorCode TaoSetVariableBoundsRoutine(Tao tao, PetscErrorCode (*func)(Tao tao, Vec xl, Vec xu, PetscCtx ctx), PetscCtx 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 @*/
TaoGetVariableBounds(Tao tao,Vec * XL,Vec * XU)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 @*/
TaoComputeVariableBounds(Tao tao)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 @*/
TaoSetInequalityBounds(Tao tao,Vec IL,Vec IU)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 @*/
TaoGetInequalityBounds(Tao tao,Vec * IL,Vec * IU)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 @*/
TaoComputeConstraints(Tao tao,Vec X,Vec C)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 @*/
TaoSetConstraintsRoutine(Tao tao,Vec c,PetscErrorCode (* func)(Tao tao,Vec x,Vec c,PetscCtx ctx),PetscCtx ctx)230 PetscErrorCode TaoSetConstraintsRoutine(Tao tao, Vec c, PetscErrorCode (*func)(Tao tao, Vec x, Vec c, PetscCtx ctx), PetscCtx 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 @*/
TaoComputeDualVariables(Tao tao,Vec DL,Vec DU)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 @*/
TaoGetDualVariables(Tao tao,Vec * DE,Vec * DI)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 @*/
TaoSetEqualityConstraintsRoutine(Tao tao,Vec ce,PetscErrorCode (* func)(Tao tao,Vec x,Vec ce,PetscCtx ctx),PetscCtx ctx)329 PetscErrorCode TaoSetEqualityConstraintsRoutine(Tao tao, Vec ce, PetscErrorCode (*func)(Tao tao, Vec x, Vec ce, PetscCtx ctx), PetscCtx 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 @*/
TaoGetEqualityConstraintsRoutine(Tao tao,Vec * ci,PetscErrorCode (** func)(Tao tao,Vec x,Vec ci,PetscCtx ctx),PetscCtxRt ctx)366 PetscErrorCode TaoGetEqualityConstraintsRoutine(Tao tao, Vec *ci, PetscErrorCode (**func)(Tao tao, Vec x, Vec ci, PetscCtx ctx), PetscCtxRt 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) *(void **)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 @*/
TaoSetInequalityConstraintsRoutine(Tao tao,Vec ci,PetscErrorCode (* func)(Tao tao,Vec x,Vec ci,PetscCtx ctx),PetscCtx ctx)397 PetscErrorCode TaoSetInequalityConstraintsRoutine(Tao tao, Vec ci, PetscErrorCode (*func)(Tao tao, Vec x, Vec ci, PetscCtx ctx), PetscCtx 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 @*/
TaoGetInequalityConstraintsRoutine(Tao tao,Vec * ci,PetscErrorCode (** func)(Tao tao,Vec x,Vec ci,PetscCtx ctx),PetscCtxRt ctx)434 PetscErrorCode TaoGetInequalityConstraintsRoutine(Tao tao, Vec *ci, PetscErrorCode (**func)(Tao tao, Vec x, Vec ci, PetscCtx ctx), PetscCtxRt 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) *(void **)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 @*/
TaoComputeEqualityConstraints(Tao tao,Vec X,Vec CE)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 @*/
TaoComputeInequalityConstraints(Tao tao,Vec X,Vec CI)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