15"""Data structures for linear and quadratic constraints.
17In contrast to BoundedLinearExpression and related structures, there is no
18offset inside the inequality.
20This is not part of the MathOpt public API, do not depend on it externally.
25from typing
import Mapping, Optional, Union
30_BoundedLinearExpressions = (
31 variables.LowerBoundedLinearExpression,
32 variables.UpperBoundedLinearExpression,
33 variables.BoundedLinearExpression,
36_BoundedQuadraticExpressions = (
37 variables.LowerBoundedLinearExpression,
38 variables.UpperBoundedLinearExpression,
39 variables.BoundedLinearExpression,
40 variables.LowerBoundedQuadraticExpression,
41 variables.UpperBoundedQuadraticExpression,
42 variables.BoundedQuadraticExpression,
45_BoundedExpressions = (
54 "Unsupported type for bounded_expr argument:"
55 " bool. This error can occur when trying to add != constraints "
56 "(which are not supported) or inequalities/equalities with constant "
57 "left-hand-side and right-hand-side (which are redundant or make a "
64 """Represents an inequality lb <= expr <= ub where expr's offset is zero."""
75 expr: Optional[variables.LinearTypes],
77 """Raises a ValueError if expr's offset is infinite."""
78 lb = -math.inf
if lb
is None else lb
79 ub = math.inf
if ub
is None else ub
80 expr = 0.0
if expr
is None else expr
83 f
"Unsupported type for expr argument: {type(expr).__name__!r}."
86 flat_expr = variables.as_flat_linear_expression(expr)
87 if math.isinf(flat_expr.offset):
89 "Trying to create a linear constraint whose expression has an"
92 self.
lb = lb - flat_expr.offset
93 self.
ub = ub - flat_expr.offset
98 bounded_expr: variables.BoundedLinearTypes,
99) -> NormalizedLinearInequality:
100 """Converts a bounded linear expression into a NormalizedLinearInequality."""
105 expr=bounded_expr.first_variable - bounded_expr.second_variable,
107 elif isinstance(bounded_expr, _BoundedExpressions):
110 lb=bounded_expr.lower_bound,
111 ub=bounded_expr.upper_bound,
112 expr=bounded_expr.expression,
116 "Bad type of expression in bounded_expr:"
117 f
" {type(bounded_expr.expression).__name__!r}."
120 raise TypeError(f
"bounded_expr has bad type: {type(bounded_expr).__name__!r}.")
127 bounded_expr: Optional[Union[bool, variables.BoundedLinearTypes]] =
None,
129 lb: Optional[float] =
None,
130 ub: Optional[float] =
None,
131 expr: Optional[variables.LinearTypes] =
None,
132) -> NormalizedLinearInequality:
133 """Builds a NormalizedLinearInequality.
135 If bounded_expr is not None, then all other arguments must be None.
137 If expr has a nonzero offset, it will be subtracted from both lb and ub.
139 When bounded_expr is unset and a named argument is unset, we use the defaults:
145 bounded_expr: a linear inequality describing the constraint.
146 lb: The lower bound when bounded_expr is None.
147 ub: The upper bound if bounded_expr is None.
148 expr: The expression when bounded_expr is None.
151 A NormalizedLinearInequality representing the linear constraint.
153 if isinstance(bounded_expr, bool):
155 if bounded_expr
is not None:
157 raise AssertionError(
158 "lb cannot be specified when bounded_expr is not None."
161 raise AssertionError(
162 "ub cannot be specified when bounded_expr is not None."
165 raise AssertionError(
166 "expr cannot be specified when bounded_expr is not None"
173@dataclasses.dataclass
175 """Represents an inequality lb <= expr <= ub where expr's offset is zero."""
185 lb: Optional[float] =
None,
186 ub: Optional[float] =
None,
187 expr: Optional[variables.QuadraticTypes] =
None,
189 """Raises a ValueError if expr's offset is infinite."""
190 lb = -math.inf
if lb
is None else lb
191 ub = math.inf
if ub
is None else ub
192 expr = 0.0
if expr
is None else expr
197 f
"Unsupported type for expr argument: {type(expr).__name__!r}."
199 flat_expr = variables.as_flat_quadratic_expression(expr)
200 if math.isinf(flat_expr.offset):
202 "Trying to create a quadratic constraint whose expression has an"
205 self.
lb = lb - flat_expr.offset
206 self.
ub = ub - flat_expr.offset
212 bounded_expr: Union[variables.BoundedQuadraticTypes, variables.BoundedLinearTypes],
213) -> NormalizedQuadraticInequality:
214 """Converts a bounded quadratic expression into a NormalizedQuadraticInequality."""
219 expr=bounded_expr.first_variable - bounded_expr.second_variable,
221 elif isinstance(bounded_expr, _BoundedExpressions):
223 bounded_expr.expression,
227 lb=bounded_expr.lower_bound,
228 ub=bounded_expr.upper_bound,
229 expr=bounded_expr.expression,
233 "bounded_expr.expression has bad type:"
234 f
" {type(bounded_expr.expression).__name__!r}."
237 raise TypeError(f
"bounded_expr has bad type: {type(bounded_expr).__name__!r}.")
244 bounded_expr: Optional[
245 Union[bool, variables.BoundedLinearTypes, variables.BoundedQuadraticTypes]
248 lb: Optional[float] =
None,
249 ub: Optional[float] =
None,
250 expr: Optional[variables.QuadraticTypes] =
None,
251) -> NormalizedQuadraticInequality:
252 """Builds a NormalizedLinearInequality.
254 If bounded_expr is not None, then all other arguments must be None.
256 If expr has a nonzero offset, it will be subtracted from both lb and ub.
258 When bounded_expr is unset and a named argument is unset, we use the defaults:
264 bounded_expr: a quadratic inequality describing the constraint.
265 lb: The lower bound when bounded_expr is None.
266 ub: The upper bound if bounded_expr is None.
267 expr: The expression when bounded_expr is None.
270 A NormalizedLinearInequality representing the linear constraint.
272 if isinstance(bounded_expr, bool):
274 if bounded_expr
is not None:
276 raise AssertionError(
277 "lb cannot be specified when bounded_expr is not None."
280 raise AssertionError(
281 "ub cannot be specified when bounded_expr is not None."
284 raise AssertionError(
285 "expr cannot be specified when bounded_expr is not None"