Skip to content

Relaxations

Relaxation

Bases: Module

Interval bounds and McCormick relaxations of an array over a box.

All four fields have the shape of the relaxed value. convex and concave are the values of the relaxations at the reference point, so they depend on that point, while lower and upper depend only on the box.

lower instance-attribute

lower: Array

Lower bound of the value over the box.

upper instance-attribute

upper: Array

Upper bound of the value over the box.

convex instance-attribute

convex: Array

Convex underestimator of the value, evaluated at the reference point.

concave instance-attribute

concave: Array

Concave overestimator of the value, evaluated at the reference point.

shape property

shape: tuple[int, ...]

The shape of the relaxed value.

dtype property

dtype: dtype

The dtype of the relaxed value.

constant classmethod

constant(value: ArrayLike) -> Self

Returns the exact relaxation of a value that does not depend on the variables.

variable classmethod

variable(
    reference: ArrayLike, lower: ArrayLike, upper: ArrayLike
) -> Self

Returns the relaxation of the variables themselves.

A variable is linear in itself, so both relaxations equal the reference point.

tightened

tightened() -> Self

Returns the relaxation with convex and concave clipped to the bounds.

The maximum of a convex function and a constant is still convex, so the clipped relaxations stay valid. Near a tie, the bound wins, even if the side is a few ulps tighter. Its gradient of zero gives a valid plane even where rounding has pushed the side past the bound.


intersect_relaxations

intersect_relaxations(
    *relaxations: PyTree[Relaxation],
) -> PyTree[Relaxation]

Returns the intersection of relaxations of the same function over the same box.

The relaxations may come from different forms of the function, such as x * (1 - x) and 0.25 - (x - 0.5) ** 2, or from different methods. Each field of the result is the tightest of its inputs. The maximum of convex functions is convex and the minimum of concave functions is concave, so the result is a valid relaxation and at least as tight as each input. Its derivatives follow the input that attains the maximum or minimum, which gives a valid subgradient.

The arguments have the same tree structure, with a Relaxation at every leaf.


UnsupportedPrimitiveError

Bases: NotImplementedError

Raised when a primitive acts on a relaxed operand and no rule covers that case.