14"""Data structures for linear and quadratic constraints.
16In contrast to BoundedLinearExpression and related structures, there is no
17offset inside the inequality.
19This is not part of the MathOpt public API, do not depend on it externally.
24from typing
import Mapping, Optional, Union
29_BoundedLinearExpressions = (
30 variables.LowerBoundedLinearExpression,
31 variables.UpperBoundedLinearExpression,
32 variables.BoundedLinearExpression,
35_BoundedQuadraticExpressions = (
36 variables.LowerBoundedLinearExpression,
37 variables.UpperBoundedLinearExpression,
38 variables.BoundedLinearExpression,
39 variables.LowerBoundedQuadraticExpression,
40 variables.UpperBoundedQuadraticExpression,
41 variables.BoundedQuadraticExpression,
44_BoundedExpressions = (
53 "Unsupported type for bounded_expr argument:"
54 " bool. This error can occur when trying to add != constraints "
55 "(which are not supported) or inequalities/equalities with constant "
56 "left-hand-side and right-hand-side (which are redundant or make a "
63 """Represents an inequality lb <= expr <= ub where expr's offset is zero."""
74 expr: Optional[variables.LinearTypes],
76 """Raises a ValueError if expr's offset is infinite."""
77 lb = -math.inf
if lb
is None else lb
78 ub = math.inf
if ub
is None else ub
79 expr = 0.0
if expr
is None else expr
82 f
"Unsupported type for expr argument: {type(expr).__name__!r}."
85 flat_expr = variables.as_flat_linear_expression(expr)
86 if math.isinf(flat_expr.offset):
88 "Trying to create a linear constraint whose expression has an"
91 self.
lb = lb - flat_expr.offset
92 self.
ub = ub - flat_expr.offset
97 bounded_expr: variables.BoundedLinearTypes,
98) -> NormalizedLinearInequality:
99 """Converts a bounded linear expression into a NormalizedLinearInequality."""
104 expr=bounded_expr.first_variable - bounded_expr.second_variable,
106 elif isinstance(bounded_expr, _BoundedExpressions):
109 lb=bounded_expr.lower_bound,
110 ub=bounded_expr.upper_bound,
111 expr=bounded_expr.expression,
115 "Bad type of expression in bounded_expr:"
116 f
" {type(bounded_expr.expression).__name__!r}."
119 raise TypeError(f
"bounded_expr has bad type: {type(bounded_expr).__name__!r}.")
126 bounded_expr: Optional[Union[bool, variables.BoundedLinearTypes]] =
None,
128 lb: Optional[float] =
None,
129 ub: Optional[float] =
None,
130 expr: Optional[variables.LinearTypes] =
None,
131) -> NormalizedLinearInequality:
132 """Builds a NormalizedLinearInequality.
134 If bounded_expr is not None, then all other arguments must be None.
136 If expr has a nonzero offset, it will be subtracted from both lb and ub.
138 When bounded_expr is unset and a named argument is unset, we use the defaults:
144 bounded_expr: a linear inequality describing the constraint.
145 lb: The lower bound when bounded_expr is None.
146 ub: The upper bound if bounded_expr is None.
147 expr: The expression when bounded_expr is None.
150 A NormalizedLinearInequality representing the linear constraint.
152 if isinstance(bounded_expr, bool):
154 if bounded_expr
is not None:
156 raise AssertionError(
157 "lb cannot be specified when bounded_expr is not None."
160 raise AssertionError(
161 "ub cannot be specified when bounded_expr is not None."
164 raise AssertionError(
165 "expr cannot be specified when bounded_expr is not None"
172@dataclasses.dataclass
174 """Represents an inequality lb <= expr <= ub where expr's offset is zero."""
184 lb: Optional[float] =
None,
185 ub: Optional[float] =
None,
186 expr: Optional[variables.QuadraticTypes] =
None,
188 """Raises a ValueError if expr's offset is infinite."""
189 lb = -math.inf
if lb
is None else lb
190 ub = math.inf
if ub
is None else ub
191 expr = 0.0
if expr
is None else expr
196 f
"Unsupported type for expr argument: {type(expr).__name__!r}."
198 flat_expr = variables.as_flat_quadratic_expression(expr)
199 if math.isinf(flat_expr.offset):
201 "Trying to create a quadratic constraint whose expression has an"
204 self.
lb = lb - flat_expr.offset
205 self.
ub = ub - flat_expr.offset
211 bounded_expr: Union[variables.BoundedQuadraticTypes, variables.BoundedLinearTypes],
212) -> NormalizedQuadraticInequality:
213 """Converts a bounded quadratic expression into a NormalizedQuadraticInequality."""
218 expr=bounded_expr.first_variable - bounded_expr.second_variable,
220 elif isinstance(bounded_expr, _BoundedExpressions):
222 bounded_expr.expression,
226 lb=bounded_expr.lower_bound,
227 ub=bounded_expr.upper_bound,
228 expr=bounded_expr.expression,
232 "bounded_expr.expression has bad type:"
233 f
" {type(bounded_expr.expression).__name__!r}."
236 raise TypeError(f
"bounded_expr has bad type: {type(bounded_expr).__name__!r}.")
243 bounded_expr: Optional[
244 Union[bool, variables.BoundedLinearTypes, variables.BoundedQuadraticTypes]
247 lb: Optional[float] =
None,
248 ub: Optional[float] =
None,
249 expr: Optional[variables.QuadraticTypes] =
None,
250) -> NormalizedQuadraticInequality:
251 """Builds a NormalizedLinearInequality.
253 If bounded_expr is not None, then all other arguments must be None.
255 If expr has a nonzero offset, it will be subtracted from both lb and ub.
257 When bounded_expr is unset and a named argument is unset, we use the defaults:
263 bounded_expr: a quadratic inequality describing the constraint.
264 lb: The lower bound when bounded_expr is None.
265 ub: The upper bound if bounded_expr is None.
266 expr: The expression when bounded_expr is None.
269 A NormalizedLinearInequality representing the linear constraint.
271 if isinstance(bounded_expr, bool):
273 if bounded_expr
is not None:
275 raise AssertionError(
276 "lb cannot be specified when bounded_expr is not None."
279 raise AssertionError(
280 "ub cannot be specified when bounded_expr is not None."
283 raise AssertionError(
284 "expr cannot be specified when bounded_expr is not None"