diff options
-rw-r--r-- | polymatrix/denserepr/from_.py | 1 | ||||
-rw-r--r-- | polymatrix/expression/expression.py | 2 | ||||
-rw-r--r-- | polymatrix/expression/init.py | 576 | ||||
-rw-r--r-- | polymatrix/expression/mixins/quadraticinexprmixin.py | 3 | ||||
-rw-r--r-- | polymatrix/expression/mixins/substituteexprmixin.py | 3 |
5 files changed, 290 insertions, 295 deletions
diff --git a/polymatrix/denserepr/from_.py b/polymatrix/denserepr/from_.py index a8540e6..e44228f 100644 --- a/polymatrix/denserepr/from_.py +++ b/polymatrix/denserepr/from_.py @@ -91,6 +91,7 @@ def from_polymatrix( try: index = variable_index_map[var] except KeyError: + # todo: improve this error message! raise KeyError(f'{var=} ({state.get_key_from_offset(var)}) is incompatible with {variable_index_map=}') for _ in range(count): diff --git a/polymatrix/expression/expression.py b/polymatrix/expression/expression.py index 6231714..45ac41b 100644 --- a/polymatrix/expression/expression.py +++ b/polymatrix/expression/expression.py @@ -355,7 +355,7 @@ class Expression( ), ) - #todo: remove? + #remove? def squeeze( self, ) -> 'Expression': diff --git a/polymatrix/expression/init.py b/polymatrix/expression/init.py index 5e4eac1..06fe23c 100644 --- a/polymatrix/expression/init.py +++ b/polymatrix/expression/init.py @@ -14,508 +14,508 @@ from polymatrix.expression.impl import FromTupleExprImpl, AdditionExprImpl def init_addition_expr( - left: ExpressionBaseMixin, - right: ExpressionBaseMixin, - stack: tuple[FrameSummary], -): - return AdditionExprImpl( - left=left, - right=right, - stack=stack, + left: ExpressionBaseMixin, + right: ExpressionBaseMixin, + stack: tuple[FrameSummary], +): + return AdditionExprImpl( + left=left, + right=right, + stack=stack, ) def init_block_diag_expr( - underlying: tuple, + underlying: tuple, ): - return polymatrix.expression.impl.BlockDiagExprImpl( - underlying=underlying, - ) + return polymatrix.expression.impl.BlockDiagExprImpl( + underlying=underlying, + ) def init_cache_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.CacheExprImpl( - underlying=underlying, + return polymatrix.expression.impl.CacheExprImpl( + underlying=underlying, ) def init_combinations_expr( - expression: ExpressionBaseMixin, - degrees: tuple[int, ...] | int, + expression: ExpressionBaseMixin, + degrees: tuple[int, ...] | int, ): - if isinstance(degrees, int): - degrees = (degrees,) + if isinstance(degrees, int): + degrees = (degrees,) - return polymatrix.expression.impl.CombinationsExprImpl( - expression=expression, - degrees=degrees, + return polymatrix.expression.impl.CombinationsExprImpl( + expression=expression, + degrees=degrees, ) def init_determinant_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.DeterminantExprImpl( - underlying=underlying, + return polymatrix.expression.impl.DeterminantExprImpl( + underlying=underlying, ) def init_diag_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.DiagExprImpl( - underlying=underlying, + return polymatrix.expression.impl.DiagExprImpl( + underlying=underlying, ) def init_divergence_expr( - underlying: ExpressionBaseMixin, - variables: tuple, + underlying: ExpressionBaseMixin, + variables: tuple, ): - return polymatrix.expression.impl.DivergenceExprImpl( - underlying=underlying, - variables=variables, + return polymatrix.expression.impl.DivergenceExprImpl( + underlying=underlying, + variables=variables, ) def init_division_expr( - left: ExpressionBaseMixin, - right: ExpressionBaseMixin, - stack: tuple[FrameSummary], -): - return polymatrix.expression.impl.DivisionExprImpl( - left=left, - right=right, - stack=stack, + left: ExpressionBaseMixin, + right: ExpressionBaseMixin, + stack: tuple[FrameSummary], +): + return polymatrix.expression.impl.DivisionExprImpl( + left=left, + right=right, + stack=stack, ) def init_elem_mult_expr( - left: ExpressionBaseMixin, - right: ExpressionBaseMixin, - stack: tuple[FrameSummary], + left: ExpressionBaseMixin, + right: ExpressionBaseMixin, + stack: tuple[FrameSummary], ): - return polymatrix.expression.impl.ElemMultExprImpl( - left=left, - right=right, + return polymatrix.expression.impl.ElemMultExprImpl( + left=left, + right=right, ) def init_eval_expr( - underlying: ExpressionBaseMixin, - variables: typing.Union[typing.Any, tuple, dict], - values: typing.Union[float, tuple] = None, + underlying: ExpressionBaseMixin, + variables: typing.Union[typing.Any, tuple, dict], + values: typing.Union[float, tuple] = None, ): - substitutions = format_substitutions( - variables=variables, - values=values, - ) + substitutions = format_substitutions( + variables=variables, + values=values, + ) - def formatted_values(value): - if isinstance(value, np.ndarray): - return tuple(value.reshape(-1)) + def formatted_values(value): + if isinstance(value, np.ndarray): + return tuple(value.reshape(-1)) - elif isinstance(value, tuple): - return value + elif isinstance(value, tuple): + return value - elif isinstance(value, int) or isinstance(value, float): - return (value,) + elif isinstance(value, int) or isinstance(value, float): + return (value,) - else: - return (float(value),) + else: + return (float(value),) - substitutions = tuple((variable, formatted_values(value)) for variable, value in substitutions) + substitutions = tuple((variable, formatted_values(value)) for variable, value in substitutions) - return polymatrix.expression.impl.EvalExprImpl( - underlying=underlying, - substitutions=substitutions, - ) + return polymatrix.expression.impl.EvalExprImpl( + underlying=underlying, + substitutions=substitutions, + ) def init_eye_expr( - variable: ExpressionBaseMixin, + variable: ExpressionBaseMixin, ): - return polymatrix.expression.impl.EyeExprImpl( - variable=variable, + return polymatrix.expression.impl.EyeExprImpl( + variable=variable, ) def init_from_symmetric_matrix_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.FromSymmetricMatrixExprImpl( - underlying=underlying, + return polymatrix.expression.impl.FromSymmetricMatrixExprImpl( + underlying=underlying, ) DATA_TYPE = str | np.ndarray | sympy.Matrix | sympy.Expr | tuple | ExpressionBaseMixin def init_from_expr_or_none( - data: DATA_TYPE, + data: DATA_TYPE, ) -> ExpressionBaseMixin | None: - if isinstance(data, str): - return init_parametrize_expr( - underlying=init_from_expr_or_none(1), - name=data, - ) - - elif isinstance(data, StateMonad): - return data.flat_map(lambda inner_data: init_from_expr_or_none(inner_data)) + if isinstance(data, str): + return init_parametrize_expr( + underlying=init_from_expr_or_none(1), + name=data, + ) + + elif isinstance(data, StateMonad): + return data.flat_map(lambda inner_data: init_from_expr_or_none(inner_data)) - elif isinstance(data, np.ndarray): - assert len(data.shape) <= 2 + elif isinstance(data, np.ndarray): + assert len(data.shape) <= 2 - def gen_elements(): - for row in data: - if isinstance(row, np.ndarray): - yield tuple(row) - else: - yield (row,) + def gen_elements(): + for row in data: + if isinstance(row, np.ndarray): + yield tuple(row) + else: + yield (row,) - data = tuple(gen_elements()) + data = tuple(gen_elements()) - elif isinstance(data, sympy.Matrix): - data = tuple(tuple(i for i in data.row(row)) for row in range(data.rows)) + elif isinstance(data, sympy.Matrix): + data = tuple(tuple(i for i in data.row(row)) for row in range(data.rows)) - elif isinstance(data, sympy.Expr): - data = ((sympy.expand(data),),) + elif isinstance(data, sympy.Expr): + data = ((sympy.expand(data),),) - elif isinstance(data, tuple): + elif isinstance(data, tuple): - if isinstance(data[0], tuple): - n_col = len(data[0]) - assert all(len(col) == n_col for col in data) + if isinstance(data[0], tuple): + n_col = len(data[0]) + assert all(len(col) == n_col for col in data) - else: - data = tuple((e,) for e in data) + else: + data = tuple((e,) for e in data) - elif isinstance(data, ExpressionBaseMixin): - return data + elif isinstance(data, ExpressionBaseMixin): + return data - else: - if not isinstance(data, (float, int, np.number)): - return None + else: + if not isinstance(data, (float, int, np.number)): + return None - data = ((data,),) + data = ((data,),) - return FromTupleExprImpl( - data=data, - stack=get_stack_lines(), - ) + return FromTupleExprImpl( + data=data, + stack=get_stack_lines(), + ) def init_from_expr( - data: DATA_TYPE + data: DATA_TYPE ): - expr = init_from_expr_or_none(data) + expr = init_from_expr_or_none(data) - if expr is None: - raise Exception(f'{data=}') + if expr is None: + raise Exception(f'{data=}') - return expr + return expr def init_from_terms_expr( - terms: typing.Union[tuple, PolyMatrixMixin], - shape: tuple[int, int] = None, + terms: typing.Union[tuple, PolyMatrixMixin], + shape: tuple[int, int] = None, ): - if isinstance(terms, PolyMatrixMixin): - shape = terms.shape - gen_terms = terms.gen_terms() + if isinstance(terms, PolyMatrixMixin): + shape = terms.shape + gen_terms = terms.gen_terms() - else: - assert shape is not None + else: + assert shape is not None - if isinstance(terms, tuple): - gen_terms = terms + if isinstance(terms, tuple): + gen_terms = terms - elif isinstance(terms, dict): - gen_terms = terms.items() + elif isinstance(terms, dict): + gen_terms = terms.items() - else: - raise Exception(f'{terms=}') + else: + raise Exception(f'{terms=}') - # Expression needs to be hashable - terms_formatted = tuple((key, tuple(monomials.items())) for key, monomials in gen_terms) + # Expression needs to be hashable + terms_formatted = tuple((key, tuple(monomials.items())) for key, monomials in gen_terms) - return polymatrix.expression.impl.FromTermsExprImpl( - terms=terms_formatted, - shape=shape, - ) + return polymatrix.expression.impl.FromTermsExprImpl( + terms=terms_formatted, + shape=shape, + ) def init_get_item_expr( - underlying: ExpressionBaseMixin, - index: tuple[tuple[int, ...], tuple[int, ...]], + underlying: ExpressionBaseMixin, + index: tuple[tuple[int, ...], tuple[int, ...]], ): - def get_hashable_slice(index): - if isinstance(index, slice): - return polymatrix.expression.impl.GetItemExprImpl.Slice(start=index.start, stop=index.stop, step=index.step) - else: - return index + def get_hashable_slice(index): + if isinstance(index, slice): + return polymatrix.expression.impl.GetItemExprImpl.Slice(start=index.start, stop=index.stop, step=index.step) + else: + return index - proper_index = (get_hashable_slice(index[0]), get_hashable_slice(index[1])) + proper_index = (get_hashable_slice(index[0]), get_hashable_slice(index[1])) - return polymatrix.expression.impl.GetItemExprImpl( - underlying=underlying, - index=proper_index, + return polymatrix.expression.impl.GetItemExprImpl( + underlying=underlying, + index=proper_index, ) def init_half_newton_polytope_expr( - monomials: ExpressionBaseMixin, - variables: ExpressionBaseMixin, - filter: ExpressionBaseMixin | None = None, -): - return polymatrix.expression.impl.HalfNewtonPolytopeExprImpl( - monomials=monomials, - variables=variables, - filter=filter + monomials: ExpressionBaseMixin, + variables: ExpressionBaseMixin, + filter: ExpressionBaseMixin | None = None, +): + return polymatrix.expression.impl.HalfNewtonPolytopeExprImpl( + monomials=monomials, + variables=variables, + filter=filter ) def init_linear_matrix_in_expr( - underlying: ExpressionBaseMixin, - variable: int, + underlying: ExpressionBaseMixin, + variable: int, ): - return polymatrix.expression.impl.LinearMatrixInExprImpl( - underlying=underlying, - variable=variable, + return polymatrix.expression.impl.LinearMatrixInExprImpl( + underlying=underlying, + variable=variable, ) def init_matrix_mult_expr( - left: ExpressionBaseMixin, - right: ExpressionBaseMixin, - stack: tuple[FrameSummary], -): - return polymatrix.expression.impl.MatrixMultExprImpl( - left=left, - right=right, - stack=stack, + left: ExpressionBaseMixin, + right: ExpressionBaseMixin, + stack: tuple[FrameSummary], +): + return polymatrix.expression.impl.MatrixMultExprImpl( + left=left, + right=right, + stack=stack, ) def init_max_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.MaxExprImpl( - underlying=underlying, + return polymatrix.expression.impl.MaxExprImpl( + underlying=underlying, ) def init_parametrize_expr( - underlying: ExpressionBaseMixin, - name: str = None, + underlying: ExpressionBaseMixin, + name: str = None, ): - if name is None: - name = 'undefined' + if name is None: + name = 'undefined' - return polymatrix.expression.impl.ParametrizeExprImpl( - underlying=underlying, - name=name, + return polymatrix.expression.impl.ParametrizeExprImpl( + underlying=underlying, + name=name, ) def init_parametrize_matrix_expr( - underlying: ExpressionBaseMixin, - name: str, + underlying: ExpressionBaseMixin, + name: str, ): - return polymatrix.expression.impl.ParametrizeMatrixExprImpl( - underlying=underlying, - name=name, - ) + return polymatrix.expression.impl.ParametrizeMatrixExprImpl( + underlying=underlying, + name=name, + ) def init_quadratic_in_expr( - underlying: ExpressionBaseMixin, - monomials: ExpressionBaseMixin, - variables: ExpressionBaseMixin, - stack: tuple[FrameSummary], + underlying: ExpressionBaseMixin, + monomials: ExpressionBaseMixin, + variables: ExpressionBaseMixin, + stack: tuple[FrameSummary], ): - assert isinstance(variables, ExpressionBaseMixin), f'{variables=}' + assert isinstance(variables, ExpressionBaseMixin), f'{variables=}' - return polymatrix.expression.impl.QuadraticInExprImpl( - underlying=underlying, - monomials=monomials, - variables=variables, - stack=stack, - ) + return polymatrix.expression.impl.QuadraticInExprImpl( + underlying=underlying, + monomials=monomials, + variables=variables, + stack=stack, + ) def init_quadratic_monomials_expr( - underlying: ExpressionBaseMixin, - variables: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, + variables: ExpressionBaseMixin, ): - assert isinstance(variables, ExpressionBaseMixin), f'{variables=}' + assert isinstance(variables, ExpressionBaseMixin), f'{variables=}' - return polymatrix.expression.impl.QuadraticMonomialsExprImpl( - underlying=underlying, - variables=variables, - ) + return polymatrix.expression.impl.QuadraticMonomialsExprImpl( + underlying=underlying, + variables=variables, + ) def init_rep_mat_expr( - underlying: ExpressionBaseMixin, - repetition: tuple, + underlying: ExpressionBaseMixin, + repetition: tuple, ): - return polymatrix.expression.impl.RepMatExprImpl( - underlying=underlying, - repetition=repetition, + return polymatrix.expression.impl.RepMatExprImpl( + underlying=underlying, + repetition=repetition, ) def init_reshape_expr( - underlying: ExpressionBaseMixin, - new_shape: tuple, + underlying: ExpressionBaseMixin, + new_shape: tuple, ): - return polymatrix.expression.impl.ReshapeExprImpl( - underlying=underlying, - new_shape=new_shape, + return polymatrix.expression.impl.ReshapeExprImpl( + underlying=underlying, + new_shape=new_shape, ) def init_set_element_at_expr( - underlying: ExpressionBaseMixin, - index: tuple, - value: ExpressionBaseMixin, -): - return polymatrix.expression.impl.SetElementAtExprImpl( - underlying=underlying, - index=index, - value=value, + underlying: ExpressionBaseMixin, + index: tuple, + value: ExpressionBaseMixin, +): + return polymatrix.expression.impl.SetElementAtExprImpl( + underlying=underlying, + index=index, + value=value, ) def init_squeeze_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.SqueezeExprImpl( - underlying=underlying, + return polymatrix.expression.impl.SqueezeExprImpl( + underlying=underlying, ) def init_substitute_expr( - underlying: ExpressionBaseMixin, - variables: tuple, - values: tuple = None, + underlying: ExpressionBaseMixin, + variables: tuple, + values: tuple = None, ): - substitutions = format_substitutions( - variables=variables, - values=values, - ) + substitutions = format_substitutions( + variables=variables, + values=values, + ) - def formatted_values(value) -> ExpressionBaseMixin: - if isinstance(value, ExpressionBaseMixin): - expr = value - - else: - expr = init_from_expr(value) + def formatted_values(value) -> ExpressionBaseMixin: + if isinstance(value, ExpressionBaseMixin): + expr = value + + else: + expr = init_from_expr(value) - return polymatrix.expression.impl.ReshapeExprImpl( - underlying=expr, - new_shape=(-1, 1), - ) + return polymatrix.expression.impl.ReshapeExprImpl( + underlying=expr, + new_shape=(-1, 1), + ) - substitutions = tuple((variable, formatted_values(value)) for variable, value in substitutions) + substitutions = tuple((variable, formatted_values(value)) for variable, value in substitutions) - return polymatrix.expression.impl.SubstituteExprImpl( - underlying=underlying, - substitutions=substitutions, - ) + return polymatrix.expression.impl.SubstituteExprImpl( + underlying=underlying, + substitutions=substitutions, + ) def init_subtract_monomials_expr( - underlying: ExpressionBaseMixin, - monomials: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, + monomials: ExpressionBaseMixin, ): - return polymatrix.expression.impl.SubtractMonomialsExprImpl( - underlying=underlying, - monomials=monomials, + return polymatrix.expression.impl.SubtractMonomialsExprImpl( + underlying=underlying, + monomials=monomials, ) def init_sum_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.SumExprImpl( - underlying=underlying, + return polymatrix.expression.impl.SumExprImpl( + underlying=underlying, ) def init_symmetric_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.SymmetricExprImpl( - underlying=underlying, + return polymatrix.expression.impl.SymmetricExprImpl( + underlying=underlying, ) def init_to_constant_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.ToConstantExprImpl( - underlying=underlying, + return polymatrix.expression.impl.ToConstantExprImpl( + underlying=underlying, ) def init_to_quadratic_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.ToQuadraticExprImpl( - underlying=underlying, + return polymatrix.expression.impl.ToQuadraticExprImpl( + underlying=underlying, ) def init_to_sorted_variables( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.ToSortedVariablesImpl( - underlying=underlying, + return polymatrix.expression.impl.ToSortedVariablesImpl( + underlying=underlying, ) def init_to_symmetric_matrix_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.ToSymmetricMatrixExprImpl( - underlying=underlying, + return polymatrix.expression.impl.ToSymmetricMatrixExprImpl( + underlying=underlying, ) def init_transpose_expr( - underlying: ExpressionBaseMixin, + underlying: ExpressionBaseMixin, ): - return polymatrix.expression.impl.TransposeExprImpl( - underlying=underlying, + return polymatrix.expression.impl.TransposeExprImpl( + underlying=underlying, ) def init_truncate_expr( - underlying: ExpressionBaseMixin, - degrees: tuple[int], - variables: ExpressionBaseMixin | None = None, - inverse: bool | None = None, -): - if isinstance(degrees, int): - degrees = (degrees,) - - if inverse is None: - inverse = False - - return polymatrix.expression.impl.TruncateExprImpl( - underlying=underlying, - variables=variables, - degrees=degrees, - inverse=inverse, - ) + underlying: ExpressionBaseMixin, + degrees: tuple[int], + variables: ExpressionBaseMixin | None = None, + inverse: bool | None = None, +): + if isinstance(degrees, int): + degrees = (degrees,) + + if inverse is None: + inverse = False + + return polymatrix.expression.impl.TruncateExprImpl( + underlying=underlying, + variables=variables, + degrees=degrees, + inverse=inverse, + ) diff --git a/polymatrix/expression/mixins/quadraticinexprmixin.py b/polymatrix/expression/mixins/quadraticinexprmixin.py index 6fe1d4b..19c1610 100644 --- a/polymatrix/expression/mixins/quadraticinexprmixin.py +++ b/polymatrix/expression/mixins/quadraticinexprmixin.py @@ -44,7 +44,6 @@ class QuadraticInExprMixin(ExpressionBaseMixin): state, sos_monomials = get_monomial_indices(state, self.monomials) state, variable_indices = get_variable_indices_from_variable(state, self.variables) - # assert underlying.shape == (1, 1), f'underlying shape is {underlying.shape}' if not (underlying.shape == (1, 1)): raise AssertionError(to_operator_exception( message=f'underlying shape is {underlying.shape}', @@ -76,7 +75,6 @@ class QuadraticInExprMixin(ExpressionBaseMixin): message=f'{left=} not in {sos_monomials=}', stack=self.stack, )) - # raise ValueError(f'{left=} not in {sos_monomials=}') try: row = sos_monomials.index(right) @@ -85,7 +83,6 @@ class QuadraticInExprMixin(ExpressionBaseMixin): message=f'{right=} not in {sos_monomials=}', stack=self.stack, )) - # raise ValueError(f'{right=} not in {sos_monomials=}') terms[row, col][p_monomial] += value diff --git a/polymatrix/expression/mixins/substituteexprmixin.py b/polymatrix/expression/mixins/substituteexprmixin.py index 1b30dcb..e1c0c3d 100644 --- a/polymatrix/expression/mixins/substituteexprmixin.py +++ b/polymatrix/expression/mixins/substituteexprmixin.py @@ -47,9 +47,6 @@ class SubstituteExprMixin(ExpressionBaseMixin): # new_shape=(-1, 1), # ).apply(state) - # # todo: improve this? - # assert substitution.shape[1] == 1, f'The substitutions have to be a vector {substitution=}' - def gen_polynomials(): for row in range(substitution.shape[0]): yield substitution.get_poly(row, 0) |