Require expression to be linear in specified variables.
(self, *vars, allow_affine=False, self_name=None, vars_name=None, error=AssertionError, recurse=True)
| 329 | return self |
| 330 | |
| 331 | def require_linearity(self, *vars, allow_affine=False, self_name=None, vars_name=None, error=AssertionError, recurse=True): |
| 332 | """Require expression to be linear in specified variables.""" |
| 333 | arg0, arg1 = self.args |
| 334 | op_arg0 = (isinstance(arg0, Operand) and arg0.has(*vars)) |
| 335 | op_arg1 = (isinstance(arg1, Operand) and arg1.has(*vars)) |
| 336 | if op_arg0 and op_arg1: |
| 337 | if self_name is None: |
| 338 | self_name = str(self) |
| 339 | if vars_name is None: |
| 340 | vars_name = [str(var) for var in vars] |
| 341 | raise error(f"{self_name} is nonlinear in {vars_name}.") |
| 342 | elif op_arg0 or op_arg1: |
| 343 | op_index = int(op_arg1) |
| 344 | if recurse: |
| 345 | self.args[op_index].require_linearity(*vars, allow_affine=allow_affine, self_name=self_name, vars_name=vars_name, error=error) |
| 346 | return op_index |
| 347 | elif not allow_affine: |
| 348 | if self_name is None: |
| 349 | self_name = str(self) |
| 350 | if vars_name is None: |
| 351 | vars_name = [str(var) for var in vars] |
| 352 | raise error(f"{self_name} must be strictly linear in {vars_name}.") |
| 353 | |
| 354 | def require_first_order(self, *args, **kw): |
| 355 | """Require expression to be maximally first order in specified operators.""" |
no test coverage detected