From de0f75c08b6d18b52dd5e595d82eecff15e02895 Mon Sep 17 00:00:00 2001 From: Michael Schneeberger Date: Thu, 4 Aug 2022 15:23:02 +0200 Subject: clean up and restructurings --- README.md | 51 ++- polymatrix/__init__.py | 86 ++--- polymatrix/expression/derivativekey.py | 4 - polymatrix/expression/expressionstate.py | 4 - polymatrix/expression/fromarrayexpr.py | 4 - polymatrix/expression/fromsympyexpr.py | 4 + polymatrix/expression/impl/derivativekeyimpl.py | 8 - polymatrix/expression/impl/expressionstateimpl.py | 12 - polymatrix/expression/impl/fromarrayexprimpl.py | 8 - polymatrix/expression/impl/fromsympyexprimpl.py | 7 + polymatrix/expression/impl/polymatriximpl.py | 8 - .../expression/impl/quadraticmonomialsexprimpl.py | 9 + polymatrix/expression/impl/sosmonomialsexprimpl.py | 9 - polymatrix/expression/init/initderivativekey.py | 11 - polymatrix/expression/init/initexpressionstate.py | 19 - polymatrix/expression/init/initfromarrayexpr.py | 31 -- polymatrix/expression/init/initfromsympyexpr.py | 35 ++ polymatrix/expression/init/initfromtermsexpr.py | 2 +- polymatrix/expression/init/initpolymatrix.py | 12 - .../expression/init/initquadraticmonomialsexpr.py | 12 + polymatrix/expression/init/initsosmonomialsexpr.py | 12 - polymatrix/expression/init/initvstackexpr.py | 4 +- polymatrix/expression/mixins/additionexprmixin.py | 8 +- .../expression/mixins/assertdegreeexprmixin.py | 6 +- polymatrix/expression/mixins/blockdiagexprmixin.py | 6 +- polymatrix/expression/mixins/cacheexprmixin.py | 6 +- .../expression/mixins/combinationsexprmixin.py | 6 +- .../expression/mixins/derivativeexprmixin.py | 116 +----- polymatrix/expression/mixins/derivativekeymixin.py | 13 - .../expression/mixins/determinantexprmixin.py | 6 +- .../expression/mixins/divergenceexprmixin.py | 9 +- polymatrix/expression/mixins/divisionexprmixin.py | 6 +- polymatrix/expression/mixins/elemmultexprmixin.py | 8 +- polymatrix/expression/mixins/evalexprmixin.py | 6 +- .../expression/mixins/expressionbasemixin.py | 9 +- polymatrix/expression/mixins/expressionmixin.py | 22 +- .../expression/mixins/expressionstatemixin.py | 58 --- polymatrix/expression/mixins/eyeexprmixin.py | 6 +- polymatrix/expression/mixins/filterexprmixin.py | 6 +- .../expression/mixins/filterlinearpartexprmixin.py | 6 +- polymatrix/expression/mixins/fromarrayexprmixin.py | 68 ---- polymatrix/expression/mixins/fromsympyexprmixin.py | 67 ++++ polymatrix/expression/mixins/fromtermsexprmixin.py | 6 +- polymatrix/expression/mixins/getitemexprmixin.py | 8 +- polymatrix/expression/mixins/linearinexprmixin.py | 6 +- .../expression/mixins/linearinmutipleexprmixin.py | 77 +--- .../expression/mixins/linearmatrixinexprmixin.py | 6 +- .../expression/mixins/linearmonomialsexprmixin.py | 6 +- .../expression/mixins/matrixmultexprmixin.py | 6 +- polymatrix/expression/mixins/maxdegreeexprmixin.py | 6 +- polymatrix/expression/mixins/maxexprmixin.py | 6 +- .../expression/mixins/parametrizeexprmixin.py | 6 +- .../expression/mixins/polymatrixasdictmixin.py | 2 +- polymatrix/expression/mixins/polymatrixmixin.py | 26 -- .../expression/mixins/quadraticinexprmixin.py | 6 +- .../mixins/quadraticmonomialsexprmixin.py | 6 +- polymatrix/expression/mixins/repmatexprmixin.py | 4 +- polymatrix/expression/mixins/reshapeexprmixin.py | 4 +- .../expression/mixins/setelementatexprmixin.py | 8 +- polymatrix/expression/mixins/squeezeexprmixin.py | 6 +- .../expression/mixins/substituteexprmixin.py | 6 +- .../mixins/subtractmonomialsexprmixin.py | 6 +- polymatrix/expression/mixins/sumexprmixin.py | 6 +- polymatrix/expression/mixins/symmetricexprmixin.py | 6 +- .../expression/mixins/toconstantexprmixin.py | 6 +- .../expression/mixins/toquadraticexprmixin.py | 6 +- polymatrix/expression/mixins/transposeexprmixin.py | 8 +- polymatrix/expression/mixins/truncateexprmixin.py | 6 +- polymatrix/expression/mixins/vstackexprmixin.py | 6 +- polymatrix/expression/polymatrix.py | 4 - .../expression/utils/getderivativemonomials.py | 10 +- polymatrix/expression/utils/monomialtoindex.py | 7 + polymatrix/expressionstate/__init__.py | 0 polymatrix/expressionstate/expressionstate.py | 4 + polymatrix/expressionstate/impl/__init__.py | 0 .../expressionstate/impl/expressionstateimpl.py | 12 + polymatrix/expressionstate/init/__init__.py | 0 .../expressionstate/init/initexpressionstate.py | 19 + polymatrix/expressionstate/mixins/__init__.py | 0 .../expressionstate/mixins/expressionstatemixin.py | 58 +++ polymatrix/polymatrix/__init__.py | 0 polymatrix/polymatrix/impl/__init__.py | 0 polymatrix/polymatrix/impl/polymatriximpl.py | 8 + polymatrix/polymatrix/init/__init__.py | 0 polymatrix/polymatrix/init/initpolymatrix.py | 12 + polymatrix/polymatrix/mixins/__init__.py | 0 polymatrix/polymatrix/mixins/polymatrixmixin.py | 26 ++ polymatrix/polymatrix/polymatrix.py | 4 + polymatrix/polysolver.py | 401 --------------------- polymatrix/sympyutils.py | 87 ----- polymatrix/utils.py | 43 --- setup.py | 27 +- test_polymatrix/test_expression/test_addition.py | 2 +- test_polymatrix/test_expression/test_blockdiag.py | 2 +- test_polymatrix/test_expression/test_derivative.py | 2 +- test_polymatrix/test_expression/test_divergence.py | 2 +- test_polymatrix/test_expression/test_eval.py | 2 +- test_polymatrix/test_expression/test_linearin.py | 2 +- test_polymatrix/test_expression/test_matrixmult.py | 2 +- .../test_expression/test_quadraticin.py | 2 +- test_polymatrix/test_expression/test_substitude.py | 2 +- .../test_expression/test_subtractmonomials.py | 2 +- test_polymatrix/test_expression/test_sum.py | 2 +- test_polymatrix/test_expression/test_symmetric.py | 2 +- test_polymatrix/test_expression/test_toconstant.py | 2 +- test_polymatrix/test_expression/test_truncate.py | 2 +- test_polymatrix/test_expression/test_vstack.py | 2 +- test_polymatrix/test_tomatrixrepr.py | 2 +- 108 files changed, 555 insertions(+), 1240 deletions(-) delete mode 100644 polymatrix/expression/derivativekey.py delete mode 100644 polymatrix/expression/expressionstate.py delete mode 100644 polymatrix/expression/fromarrayexpr.py create mode 100644 polymatrix/expression/fromsympyexpr.py delete mode 100644 polymatrix/expression/impl/derivativekeyimpl.py delete mode 100644 polymatrix/expression/impl/expressionstateimpl.py delete mode 100644 polymatrix/expression/impl/fromarrayexprimpl.py create mode 100644 polymatrix/expression/impl/fromsympyexprimpl.py delete mode 100644 polymatrix/expression/impl/polymatriximpl.py create mode 100644 polymatrix/expression/impl/quadraticmonomialsexprimpl.py delete mode 100644 polymatrix/expression/impl/sosmonomialsexprimpl.py delete mode 100644 polymatrix/expression/init/initderivativekey.py delete mode 100644 polymatrix/expression/init/initexpressionstate.py delete mode 100644 polymatrix/expression/init/initfromarrayexpr.py create mode 100644 polymatrix/expression/init/initfromsympyexpr.py delete mode 100644 polymatrix/expression/init/initpolymatrix.py create mode 100644 polymatrix/expression/init/initquadraticmonomialsexpr.py delete mode 100644 polymatrix/expression/init/initsosmonomialsexpr.py delete mode 100644 polymatrix/expression/mixins/derivativekeymixin.py delete mode 100644 polymatrix/expression/mixins/expressionstatemixin.py delete mode 100644 polymatrix/expression/mixins/fromarrayexprmixin.py create mode 100644 polymatrix/expression/mixins/fromsympyexprmixin.py delete mode 100644 polymatrix/expression/mixins/polymatrixmixin.py delete mode 100644 polymatrix/expression/polymatrix.py create mode 100644 polymatrix/expression/utils/monomialtoindex.py create mode 100644 polymatrix/expressionstate/__init__.py create mode 100644 polymatrix/expressionstate/expressionstate.py create mode 100644 polymatrix/expressionstate/impl/__init__.py create mode 100644 polymatrix/expressionstate/impl/expressionstateimpl.py create mode 100644 polymatrix/expressionstate/init/__init__.py create mode 100644 polymatrix/expressionstate/init/initexpressionstate.py create mode 100644 polymatrix/expressionstate/mixins/__init__.py create mode 100644 polymatrix/expressionstate/mixins/expressionstatemixin.py create mode 100644 polymatrix/polymatrix/__init__.py create mode 100644 polymatrix/polymatrix/impl/__init__.py create mode 100644 polymatrix/polymatrix/impl/polymatriximpl.py create mode 100644 polymatrix/polymatrix/init/__init__.py create mode 100644 polymatrix/polymatrix/init/initpolymatrix.py create mode 100644 polymatrix/polymatrix/mixins/__init__.py create mode 100644 polymatrix/polymatrix/mixins/polymatrixmixin.py create mode 100644 polymatrix/polymatrix/polymatrix.py delete mode 100644 polymatrix/polysolver.py delete mode 100644 polymatrix/sympyutils.py delete mode 100644 polymatrix/utils.py diff --git a/README.md b/README.md index 3ba3ae5..98ba196 100644 --- a/README.md +++ b/README.md @@ -1 +1,50 @@ -# Polynomial matrix library +# Multivariate polynomial library + +`polymatrix` is a library to represent and operate on multivariate polynomials. + +It is currently mainly used to define Sum Of Squares optimization problems. + +Some aspects of the library + +* it has a lazy behavior: + * the library implements operators to build polynomial expression + * the actual polynomial representation is created by calling the `apply(state)` method on the polynomial expression +* a `sympy` expression can be converted to a polynomial expression using the `polymatrix.from_sympy` function +* multiple polynomial expressions are combined using functions like `polymatrix.v_stack` or `polymatrix.block_diag`. +* polynomial expressions are manipulated using bounded functions like `diff`, `reshape`, `substitute`, `sum` or `to_constant` (see `polymatrix/expression/mixins/expressionmixin.py`) +* an expression can be converted to matrix representation using `polymatrix.to_matrix_repr`. Again, to get the actual representation the `apply(state)` method needs to be called. + +## Example + +``` python +import sympy +import polymatrix + +state = polymatrix.init_expression_state() + +x1, x2 = sympy.symbols('x1, x2') +x = polymatrix.from_((x1, x2)) + +f1 = polymatrix.from_(x1 + x2) +f2 = polymatrix.from_(x1 + x1*x2) + +expr = f1 + f2 + +# prints the data structure of the expression +# ExpressionImpl(underlying=AdditionExprImpl(left=FromSympyExprImpl(data=((x1 + x2,),)), right=FromSympyExprImpl(data=((x1*x2 + x1,),)))) +print(expr) + +state, poly_matrix = expr.apply(state) + +# prints the data structure of the polynomial matrix +# PolyMatrixImpl(terms={(0, 0): {((0, 1), (1, 1)): 1, ((0, 1),): 2, ((1, 1),): 1}}, shape=(1, 1)) +print(poly_matrix) + +state, matrix_repr = polymatrix.to_matrix_repr((expr,), x).apply(state) + +# prints the numpy matrix representations of the polynomial matrix +# array([[2., 1.]]) +# array([[0. , 0.5, 0.5, 0. ]]) +print(matrix_repr.data[0][1]) +print(matrix_repr.data[0][2].toarray()) +``` diff --git a/polymatrix/__init__.py b/polymatrix/__init__.py index 58729d2..4df9a81 100644 --- a/polymatrix/__init__.py +++ b/polymatrix/__init__.py @@ -4,31 +4,41 @@ import itertools import typing import numpy as np import scipy.sparse -# import polymatrix.statemonad from polymatrix.expression.expression import Expression -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.init.initblockdiagexpr import init_block_diag_expr from polymatrix.expression.init.initexpression import init_expression from polymatrix.expression.init.initeyeexpr import init_eye_expr -from polymatrix.expression.init.initfromarrayexpr import init_from_array_expr +from polymatrix.expression.init.initfromsympyexpr import init_from_sympy_expr from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initvstackexpr import init_v_stack_expr -from polymatrix.expression.polymatrix import PolyMatrix +from polymatrix.polymatrix.polymatrix import PolyMatrix from polymatrix.expression.utils.getvariableindices import get_variable_indices from polymatrix.statemonad.init.initstatemonad import init_state_monad from polymatrix.statemonad.mixins.statemonadmixin import StateMonadMixin -from polymatrix.utils import monomial_to_index +from polymatrix.expression.utils.monomialtoindex import monomial_to_index +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state as original_init_expression_state -def from_( +def init_expression_state(): + return original_init_expression_state() + + +def from_sympy( data: tuple[tuple[float]], ): return init_expression( - init_from_array_expr(data) + init_from_sympy_expr(data) ) +def from_( + data: tuple[tuple[float]], +): + return from_sympy(data) + + def from_polymatrix( polymatrix: PolyMatrix, ): @@ -37,32 +47,6 @@ def from_polymatrix( ) -# def accumulate( -# expr, -# func, -# initial = None, -# ): -# def lifted_func(acc, polymat: PolyMatrix): - -# # # print(f'{terms=}') -# # print(f'{terms=}') - -# lifeted_val = init_expression( -# underlying=init_from_terms_expr( -# terms=polymat.terms, -# shape=polymat.shape, -# ), -# ) -# return func(acc, lifeted_val) - -# return init_expression( -# underlying=init_accumulate_expr( -# underlying=expr.underlying, -# acc_func=lifted_func, -# initial=initial, -# ), -# ) - def v_stack( expressions: tuple[Expression], ): @@ -326,22 +310,22 @@ class MatrixBuffer: @dataclasses.dataclass -class MatrixEquations: - matrix_equations: tuple[MatrixBuffer, ...] - auxillary_matrix_equations: typing.Optional[MatrixBuffer] - variable_index: tuple[int, ...] +class MatrixRepresentations: + data: tuple[MatrixBuffer, ...] + aux_data: typing.Optional[MatrixBuffer] + variable_mapping: tuple[int, ...] state: ExpressionState def merge_matrix_equations(self): def gen_matrices(index: int): - for equations in self.matrix_equations: + for equations in self.data: if index < len(equations): yield equations[index] - if index < len(self.auxillary_matrix_equations): - yield self.auxillary_matrix_equations[index] + if index < len(self.aux_data): + yield self.aux_data[index] - indices = set(key for equations in self.matrix_equations + (self.auxillary_matrix_equations,) for key in equations.keys()) + indices = set(key for equations in self.data + (self.aux_data,) for key in equations.keys()) def gen_matrices(): for index in indices: @@ -358,9 +342,9 @@ class MatrixEquations: def gen_value_index(): for variable_index in variable_indices: try: - yield self.variable_index.index(variable_index) + yield self.variable_mapping.index(variable_index) except ValueError: - raise ValueError(f'{variable_index} not found in {self.variable_index}') + raise ValueError(f'{variable_index} not found in {self.variable_mapping}') value_index = list(gen_value_index()) @@ -368,13 +352,13 @@ class MatrixEquations: def set_value(self, variable, value): variable_indices = get_variable_indices(self.state, variable)[1] - value_index = list(self.variable_index.index(variable_index) for variable_index in variable_indices) - vec = np.zeros(len(self.variable_index)) + value_index = list(self.variable_mapping.index(variable_index) for variable_index in variable_indices) + vec = np.zeros(len(self.variable_mapping)) vec[value_index] = value return vec def get_func(self, eq_idx: int): - equations = self.matrix_equations[eq_idx].data + equations = self.data[eq_idx].data max_idx = max(equations.keys()) if 2 <= max_idx: @@ -416,7 +400,7 @@ class MatrixEquations: return func -def to_matrix_equations( +def to_matrix_repr( expressions: tuple[Expression], variables: Expression, ) -> StateMonadMixin[ExpressionState, tuple[tuple[tuple[np.ndarray, ...], ...], tuple[int, ...]]]: @@ -547,10 +531,10 @@ def to_matrix_equations( auxillary_matrix_equations = buffer - result = MatrixEquations( - matrix_equations=underlying_matrices, - auxillary_matrix_equations=auxillary_matrix_equations, - variable_index=ordered_variable_index, + result = MatrixRepresentations( + data=underlying_matrices, + aux_data=auxillary_matrix_equations, + variable_mapping=ordered_variable_index, state=state, ) diff --git a/polymatrix/expression/derivativekey.py b/polymatrix/expression/derivativekey.py deleted file mode 100644 index 6d1fff8..0000000 --- a/polymatrix/expression/derivativekey.py +++ /dev/null @@ -1,4 +0,0 @@ -from polymatrix.expression.mixins.derivativekeymixin import DerivativeKeyMixin - -class DerivativeKey(DerivativeKeyMixin): - pass diff --git a/polymatrix/expression/expressionstate.py b/polymatrix/expression/expressionstate.py deleted file mode 100644 index e4b97aa..0000000 --- a/polymatrix/expression/expressionstate.py +++ /dev/null @@ -1,4 +0,0 @@ -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin - -class ExpressionState(ExpressionStateMixin): - pass diff --git a/polymatrix/expression/fromarrayexpr.py b/polymatrix/expression/fromarrayexpr.py deleted file mode 100644 index b22792b..0000000 --- a/polymatrix/expression/fromarrayexpr.py +++ /dev/null @@ -1,4 +0,0 @@ -from polymatrix.expression.mixins.fromarrayexprmixin import FromArrayExprMixin - -class FromArrayExpr(FromArrayExprMixin): - pass diff --git a/polymatrix/expression/fromsympyexpr.py b/polymatrix/expression/fromsympyexpr.py new file mode 100644 index 0000000..b1e723a --- /dev/null +++ b/polymatrix/expression/fromsympyexpr.py @@ -0,0 +1,4 @@ +from polymatrix.expression.mixins.fromsympyexprmixin import FromSympyExprMixin + +class FromSympyExpr(FromSympyExprMixin): + pass diff --git a/polymatrix/expression/impl/derivativekeyimpl.py b/polymatrix/expression/impl/derivativekeyimpl.py deleted file mode 100644 index 675503a..0000000 --- a/polymatrix/expression/impl/derivativekeyimpl.py +++ /dev/null @@ -1,8 +0,0 @@ -import dataclass_abc -from polymatrix.expression.derivativekey import DerivativeKey - - -@dataclass_abc.dataclass_abc(frozen=True) -class DerivativeKeyImpl(DerivativeKey): - variable: int - with_respect_to: int diff --git a/polymatrix/expression/impl/expressionstateimpl.py b/polymatrix/expression/impl/expressionstateimpl.py deleted file mode 100644 index 5459eb7..0000000 --- a/polymatrix/expression/impl/expressionstateimpl.py +++ /dev/null @@ -1,12 +0,0 @@ -from functools import cached_property -import dataclass_abc -from polymatrix.expression.expressionstate import ExpressionState - -from typing import Optional - -@dataclass_abc.dataclass_abc(frozen=True) -class ExpressionStateImpl(ExpressionState): - n_param: int - offset_dict: dict - auxillary_equations: dict[int, dict[tuple[int], float]] - cache: dict diff --git a/polymatrix/expression/impl/fromarrayexprimpl.py b/polymatrix/expression/impl/fromarrayexprimpl.py deleted file mode 100644 index 7d7c45e..0000000 --- a/polymatrix/expression/impl/fromarrayexprimpl.py +++ /dev/null @@ -1,8 +0,0 @@ -import dataclass_abc -from polymatrix.expression.fromarrayexpr import FromArrayExpr - -from numpy import array - -@dataclass_abc.dataclass_abc(frozen=True) -class FromArrayExprImpl(FromArrayExpr): - data: tuple[tuple[float]] diff --git a/polymatrix/expression/impl/fromsympyexprimpl.py b/polymatrix/expression/impl/fromsympyexprimpl.py new file mode 100644 index 0000000..986612b --- /dev/null +++ b/polymatrix/expression/impl/fromsympyexprimpl.py @@ -0,0 +1,7 @@ +import dataclass_abc +from polymatrix.expression.fromsympyexpr import FromSympyExpr + + +@dataclass_abc.dataclass_abc(frozen=True) +class FromSympyExprImpl(FromSympyExpr): + data: tuple[tuple[float]] diff --git a/polymatrix/expression/impl/polymatriximpl.py b/polymatrix/expression/impl/polymatriximpl.py deleted file mode 100644 index 63f577a..0000000 --- a/polymatrix/expression/impl/polymatriximpl.py +++ /dev/null @@ -1,8 +0,0 @@ -import dataclass_abc -from polymatrix.expression.polymatrix import PolyMatrix - - -@dataclass_abc.dataclass_abc(frozen=True) -class PolyMatrixImpl(PolyMatrix): - terms: dict - shape: tuple[int, ...] diff --git a/polymatrix/expression/impl/quadraticmonomialsexprimpl.py b/polymatrix/expression/impl/quadraticmonomialsexprimpl.py new file mode 100644 index 0000000..5930764 --- /dev/null +++ b/polymatrix/expression/impl/quadraticmonomialsexprimpl.py @@ -0,0 +1,9 @@ +import dataclass_abc +from polymatrix.expression.quadraticmonomialsexpr import QuadraticMonomialsExpr + +from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin + +@dataclass_abc.dataclass_abc(frozen=True) +class QuadraticMonomialsExprImpl(QuadraticMonomialsExpr): + underlying: ExpressionBaseMixin + variables: tuple diff --git a/polymatrix/expression/impl/sosmonomialsexprimpl.py b/polymatrix/expression/impl/sosmonomialsexprimpl.py deleted file mode 100644 index 400c2ae..0000000 --- a/polymatrix/expression/impl/sosmonomialsexprimpl.py +++ /dev/null @@ -1,9 +0,0 @@ -import dataclass_abc -from polymatrix.expression.quadraticmonomialsexpr import QuadraticMonomialsExpr - -from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin - -@dataclass_abc.dataclass_abc(frozen=True) -class SOSMonomialsExprImpl(QuadraticMonomialsExpr): - underlying: ExpressionBaseMixin - variables: tuple diff --git a/polymatrix/expression/init/initderivativekey.py b/polymatrix/expression/init/initderivativekey.py deleted file mode 100644 index db249ec..0000000 --- a/polymatrix/expression/init/initderivativekey.py +++ /dev/null @@ -1,11 +0,0 @@ -from polymatrix.expression.impl.derivativekeyimpl import DerivativeKeyImpl - - -def init_derivative_key( - variable: int, - with_respect_to: int -): - return DerivativeKeyImpl( - variable=variable, - with_respect_to=with_respect_to, -) diff --git a/polymatrix/expression/init/initexpressionstate.py b/polymatrix/expression/init/initexpressionstate.py deleted file mode 100644 index be2e4f1..0000000 --- a/polymatrix/expression/init/initexpressionstate.py +++ /dev/null @@ -1,19 +0,0 @@ -from polymatrix.expression.impl.expressionstateimpl import ExpressionStateImpl - - -def init_expression_state( - n_param: int = None, - offset_dict: dict = None, -): - if n_param is None: - n_param = 0 - - if offset_dict is None: - offset_dict = {} - - return ExpressionStateImpl( - n_param=n_param, - offset_dict=offset_dict, - auxillary_equations={}, - cache={}, -) diff --git a/polymatrix/expression/init/initfromarrayexpr.py b/polymatrix/expression/init/initfromarrayexpr.py deleted file mode 100644 index e6f57c8..0000000 --- a/polymatrix/expression/init/initfromarrayexpr.py +++ /dev/null @@ -1,31 +0,0 @@ -import typing -import numpy as np - -from polymatrix.expression.impl.fromarrayexprimpl import FromArrayExprImpl - - -def init_from_array_expr( - data: typing.Union[np.ndarray, tuple[tuple[float]]], -): - - match data: - case np.ndarray(): - data = tuple(tuple(i for i in row) for row in data) - - case tuple(): - - match data[0]: - - case tuple(): - n_col = len(data[0]) - assert all(len(col) == n_col for col in data) - - case _: - data = tuple((e,) for e in data) - - case _: - data = ((data,),) - - return FromArrayExprImpl( - data=data, - ) diff --git a/polymatrix/expression/init/initfromsympyexpr.py b/polymatrix/expression/init/initfromsympyexpr.py new file mode 100644 index 0000000..08a6a04 --- /dev/null +++ b/polymatrix/expression/init/initfromsympyexpr.py @@ -0,0 +1,35 @@ +import typing +import numpy as np +import sympy + +from polymatrix.expression.impl.fromsympyexprimpl import FromSympyExprImpl + + +def init_from_sympy_expr( + data: typing.Union[np.ndarray, tuple[tuple[float]]], +): + + match data: + case np.ndarray(): + data = tuple(tuple(i for i in row) for row in data) + + case sympy.Matrix(): + data = tuple(tuple(i for i in data.row(row)) for row in range(data.rows)) + + case tuple(): + + match data[0]: + + case tuple(): + n_col = len(data[0]) + assert all(len(col) == n_col for col in data) + + case _: + data = tuple((e,) for e in data) + + case _: + data = ((data,),) + + return FromSympyExprImpl( + data=data, + ) diff --git a/polymatrix/expression/init/initfromtermsexpr.py b/polymatrix/expression/init/initfromtermsexpr.py index 1abac12..f338c92 100644 --- a/polymatrix/expression/init/initfromtermsexpr.py +++ b/polymatrix/expression/init/initfromtermsexpr.py @@ -1,6 +1,6 @@ import typing from polymatrix.expression.impl.fromtermsexprimpl import FromTermsExprImpl -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin def init_from_terms_expr( diff --git a/polymatrix/expression/init/initpolymatrix.py b/polymatrix/expression/init/initpolymatrix.py deleted file mode 100644 index d0c9577..0000000 --- a/polymatrix/expression/init/initpolymatrix.py +++ /dev/null @@ -1,12 +0,0 @@ -from polymatrix.expression.impl.polymatriximpl import PolyMatrixImpl - - -def init_poly_matrix( - terms: dict, - shape: tuple, -): - - return PolyMatrixImpl( - terms=terms, - shape=shape, -) diff --git a/polymatrix/expression/init/initquadraticmonomialsexpr.py b/polymatrix/expression/init/initquadraticmonomialsexpr.py new file mode 100644 index 0000000..8e46c62 --- /dev/null +++ b/polymatrix/expression/init/initquadraticmonomialsexpr.py @@ -0,0 +1,12 @@ +from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin +from polymatrix.expression.impl.quadraticmonomialsexprimpl import QuadraticMonomialsExprImpl + + +def init_quadratic_monomials_expr( + underlying: ExpressionBaseMixin, + variables: tuple, +): + return QuadraticMonomialsExprImpl( + underlying=underlying, + variables=variables, +) diff --git a/polymatrix/expression/init/initsosmonomialsexpr.py b/polymatrix/expression/init/initsosmonomialsexpr.py deleted file mode 100644 index 0f5d034..0000000 --- a/polymatrix/expression/init/initsosmonomialsexpr.py +++ /dev/null @@ -1,12 +0,0 @@ -from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.impl.sosmonomialsexprimpl import SOSMonomialsExprImpl - - -def init_sos_monomials_expr( - underlying: ExpressionBaseMixin, - variables: tuple, -): - return SOSMonomialsExprImpl( - underlying=underlying, - variables=variables, -) diff --git a/polymatrix/expression/init/initvstackexpr.py b/polymatrix/expression/init/initvstackexpr.py index 70764ef..1edc716 100644 --- a/polymatrix/expression/init/initvstackexpr.py +++ b/polymatrix/expression/init/initvstackexpr.py @@ -1,5 +1,5 @@ from polymatrix.expression.impl.vstackexprimpl import VStackExprImpl -from polymatrix.expression.init.initfromarrayexpr import init_from_array_expr +from polymatrix.expression.init.initfromsympyexpr import init_from_sympy_expr from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin @@ -13,7 +13,7 @@ def init_v_stack_expr( if isinstance(e, ExpressionBaseMixin): yield e else: - yield init_from_array_expr(e) + yield init_from_sympy_expr(e) return VStackExprImpl( underlying=tuple(gen_underlying()), diff --git a/polymatrix/expression/mixins/additionexprmixin.py b/polymatrix/expression/mixins/additionexprmixin.py index 2c7a652..3d2d15b 100644 --- a/polymatrix/expression/mixins/additionexprmixin.py +++ b/polymatrix/expression/mixins/additionexprmixin.py @@ -3,11 +3,11 @@ import abc import typing import dataclass_abc -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class AdditionExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/assertdegreeexprmixin.py b/polymatrix/expression/mixins/assertdegreeexprmixin.py index af0a3e6..a41e6ba 100644 --- a/polymatrix/expression/mixins/assertdegreeexprmixin.py +++ b/polymatrix/expression/mixins/assertdegreeexprmixin.py @@ -2,11 +2,11 @@ import abc import itertools import dataclass_abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class AssertDegreeExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/blockdiagexprmixin.py b/polymatrix/expression/mixins/blockdiagexprmixin.py index b0006e3..8775fde 100644 --- a/polymatrix/expression/mixins/blockdiagexprmixin.py +++ b/polymatrix/expression/mixins/blockdiagexprmixin.py @@ -2,11 +2,11 @@ import abc import itertools import dataclass_abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class BlockDiagExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/cacheexprmixin.py b/polymatrix/expression/mixins/cacheexprmixin.py index ba9a612..ef99644 100644 --- a/polymatrix/expression/mixins/cacheexprmixin.py +++ b/polymatrix/expression/mixins/cacheexprmixin.py @@ -2,10 +2,10 @@ import abc import dataclasses -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class CacheExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/combinationsexprmixin.py b/polymatrix/expression/mixins/combinationsexprmixin.py index 824ebf1..4841e8e 100644 --- a/polymatrix/expression/mixins/combinationsexprmixin.py +++ b/polymatrix/expression/mixins/combinationsexprmixin.py @@ -3,10 +3,10 @@ import abc import itertools import math -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getmonomialindices import get_monomial_indices from polymatrix.expression.utils.mergemonomialindices import merge_monomial_indices from polymatrix.expression.utils.sortmonomials import sort_monomials diff --git a/polymatrix/expression/mixins/derivativeexprmixin.py b/polymatrix/expression/mixins/derivativeexprmixin.py index 4fc48a5..32823e5 100644 --- a/polymatrix/expression/mixins/derivativeexprmixin.py +++ b/polymatrix/expression/mixins/derivativeexprmixin.py @@ -4,12 +4,11 @@ import collections import dataclasses import itertools import typing -from polymatrix.expression.init.initderivativekey import init_derivative_key -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getderivativemonomials import get_derivative_monomials from polymatrix.expression.utils.getvariableindices import get_variable_indices @@ -42,115 +41,6 @@ class DerivativeExprMixin(ExpressionBaseMixin): state, diff_wrt_variables = get_variable_indices(state, self.variables) - # def get_derivative_terms( - # monomial_terms, - # diff_wrt_variable: int, - # state: ExpressionState, - # considered_variables: set, - # ): - - # if self.introduce_derivatives: - - # raise Exception('not implemented') - - # def gen_new_variables(): - # for monomial in monomial_terms.keys(): - # for var in monomial: - # if var not in diff_wrt_variables and var not in considered_variables: - # yield var - - # new_variables = set(gen_new_variables()) - - # new_considered_variables = considered_variables | new_variables - - # def acc_state_candidates(acc, new_variable): - # state, candidates = acc - - # key = init_derivative_key( - # variable=new_variable, - # with_respect_to=diff_wrt_variable, - # ) - # state = state.register(key=key, n_param=1) - - # state, auxillary_derivation_terms = get_derivative_terms( - # monomial_terms=state.auxillary_equations[new_variable], - # diff_wrt_variable=diff_wrt_variable, - # state=state, - # considered_variables=new_considered_variables, - # ) - - # if 1 < len(auxillary_derivation_terms): - # derivation_variable = state.offset_dict[key][0] - - # state = dataclasses.replace( - # state, - # auxillary_equations=state.auxillary_equations | {derivation_variable: auxillary_derivation_terms}, - # ) - - # return state, candidates + (new_variable,) - - # else: - # return state, candidates - - # *_, (state, confirmed_variables) = itertools.accumulate( - # new_variables, - # acc_state_candidates, - # initial=(state, tuple()), - # ) - - # else: - # confirmed_variables = tuple() - - # derivation_terms = collections.defaultdict(float) - - # for monomial, value in monomial_terms.items(): - - # # # count powers for each variable - # # monomial_cnt = dict(collections.Counter(monomial)) - # monomial_cnt = dict(monomial) - - # def differentiate_monomial(dependent_variable, derivation_variable=None): - # def gen_diff_monomial(): - # for current_variable, current_count in monomial: - - # if current_variable is dependent_variable: - # sel_counter = current_count - 1 - - # else: - # sel_counter = current_count - - # # for _ in range(sel_counter): - # # yield current_variable - # yield current_variable, sel_counter - - # if derivation_variable is not None: - # yield derivation_variable - - # diff_monomial = tuple(sorted(gen_diff_monomial())) - - # return diff_monomial, value * monomial_cnt[dependent_variable] - - # if diff_wrt_variable in monomial_cnt: - # diff_monomial, value = differentiate_monomial(diff_wrt_variable) - # derivation_terms[diff_monomial] += value - - # # only used if introduce_derivatives == True - # for candidate_variable in monomial_cnt.keys(): - # if candidate_variable in considered_variables or candidate_variable in confirmed_variables: - # key = init_derivative_key( - # variable=candidate_variable, - # with_respect_to=diff_wrt_variable, - # ) - # derivation_variable = state.offset_dict[key][0] - - # diff_monomial, value = differentiate_monomial( - # dependent_variable=candidate_variable, - # derivation_variable=derivation_variable, - # ) - # derivation_terms[diff_monomial] += value - - # return state, dict(derivation_terms) - terms = {} for row in range(underlying.shape[0]): diff --git a/polymatrix/expression/mixins/derivativekeymixin.py b/polymatrix/expression/mixins/derivativekeymixin.py deleted file mode 100644 index db4951a..0000000 --- a/polymatrix/expression/mixins/derivativekeymixin.py +++ /dev/null @@ -1,13 +0,0 @@ -import abc - -# move this class -class DerivativeKeyMixin(abc.ABC): - @property - @abc.abstractmethod - def variable(self) -> int: - ... - - @property - @abc.abstractmethod - def with_respect_to(self) -> int: - ... diff --git a/polymatrix/expression/mixins/determinantexprmixin.py b/polymatrix/expression/mixins/determinantexprmixin.py index 8d41e3d..79defa9 100644 --- a/polymatrix/expression/mixins/determinantexprmixin.py +++ b/polymatrix/expression/mixins/determinantexprmixin.py @@ -4,10 +4,10 @@ import collections import dataclasses from numpy import var -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class DeterminantExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/divergenceexprmixin.py b/polymatrix/expression/mixins/divergenceexprmixin.py index b523b2d..391a221 100644 --- a/polymatrix/expression/mixins/divergenceexprmixin.py +++ b/polymatrix/expression/mixins/divergenceexprmixin.py @@ -1,15 +1,12 @@ import abc import collections -import dataclasses -import itertools import typing -from polymatrix.expression.init.initderivativekey import init_derivative_key -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getderivativemonomials import get_derivative_monomials from polymatrix.expression.utils.getvariableindices import get_variable_indices diff --git a/polymatrix/expression/mixins/divisionexprmixin.py b/polymatrix/expression/mixins/divisionexprmixin.py index 7551cda..ee9b2ff 100644 --- a/polymatrix/expression/mixins/divisionexprmixin.py +++ b/polymatrix/expression/mixins/divisionexprmixin.py @@ -2,10 +2,10 @@ import abc import dataclasses -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class DivisionExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/elemmultexprmixin.py b/polymatrix/expression/mixins/elemmultexprmixin.py index 7e0bc8c..24e91fc 100644 --- a/polymatrix/expression/mixins/elemmultexprmixin.py +++ b/polymatrix/expression/mixins/elemmultexprmixin.py @@ -4,11 +4,11 @@ import itertools import typing import dataclass_abc -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.mergemonomialindices import merge_monomial_indices diff --git a/polymatrix/expression/mixins/evalexprmixin.py b/polymatrix/expression/mixins/evalexprmixin.py index 0541e3d..ca1cf7d 100644 --- a/polymatrix/expression/mixins/evalexprmixin.py +++ b/polymatrix/expression/mixins/evalexprmixin.py @@ -3,10 +3,10 @@ import abc import itertools import math -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getvariableindices import get_variable_indices diff --git a/polymatrix/expression/mixins/expressionbasemixin.py b/polymatrix/expression/mixins/expressionbasemixin.py index a4d7dc2..f2f8507 100644 --- a/polymatrix/expression/mixins/expressionbasemixin.py +++ b/polymatrix/expression/mixins/expressionbasemixin.py @@ -1,6 +1,6 @@ import abc -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class ExpressionBaseMixin( @@ -10,8 +10,3 @@ class ExpressionBaseMixin( @abc.abstractmethod def apply(self, state: ExpressionStateMixin) -> tuple[ExpressionStateMixin, PolyMatrixMixin]: ... - - # def apply(self, state: ExpressionStateMixin) -> tuple[ExpressionStateMixin, PolyMatrixMixin]: - # assert isinstance(state, ExpressionStateMixin), f'{state} is not of type {ExpressionStateMixin.__name__}' - - # return self._apply(state) diff --git a/polymatrix/expression/mixins/expressionmixin.py b/polymatrix/expression/mixins/expressionmixin.py index ff2a146..a5acff1 100644 --- a/polymatrix/expression/mixins/expressionmixin.py +++ b/polymatrix/expression/mixins/expressionmixin.py @@ -16,7 +16,7 @@ from polymatrix.expression.init.initevalexpr import init_eval_expr from polymatrix.expression.init.initfilterexpr import init_filter_expr from polymatrix.expression.init.initlinearinexpr import init_linear_in_expr from polymatrix.expression.init.initlinearinmonomialsinexpr import init_linear_in_monomials_in -from polymatrix.expression.init.initfromarrayexpr import init_from_array_expr +from polymatrix.expression.init.initfromsympyexpr import init_from_sympy_expr from polymatrix.expression.init.initgetitemexpr import init_get_item_expr from polymatrix.expression.init.initlinearmatrixinexpr import init_linear_matrix_in_expr from polymatrix.expression.init.initlinearmonomialsexpr import init_linear_monomials_expr @@ -28,7 +28,7 @@ from polymatrix.expression.init.initquadraticinexpr import init_quadratic_in_exp from polymatrix.expression.init.initrepmatexpr import init_rep_mat_expr from polymatrix.expression.init.initreshapeexpr import init_reshape_expr from polymatrix.expression.init.initsetelementatexpr import init_set_element_at_expr -from polymatrix.expression.init.initsosmonomialsexpr import init_sos_monomials_expr +from polymatrix.expression.init.initquadraticmonomialsexpr import init_quadratic_monomials_expr from polymatrix.expression.init.initsubtractmonomialsexpr import init_subtract_monomials_expr from polymatrix.expression.init.initsumexpr import init_sum_expr from polymatrix.expression.init.initsymmetricexpr import init_symmetric_expr @@ -38,8 +38,8 @@ from polymatrix.expression.init.inittransposeexpr import init_transpose_expr from polymatrix.expression.init.inittruncateexpr import init_truncate_expr from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class ExpressionMixin( @@ -64,7 +64,7 @@ class ExpressionMixin( case ExpressionBaseMixin(): right = other.underlying case _: - right = init_from_array_expr(other) + right = init_from_sympy_expr(other) return dataclasses.replace( self, @@ -99,7 +99,7 @@ class ExpressionMixin( case ExpressionBaseMixin(): right = other.underlying case _: - right = init_from_array_expr(other) + right = init_from_sympy_expr(other) return dataclasses.replace( self, @@ -120,7 +120,7 @@ class ExpressionMixin( case ExpressionBaseMixin(): right = other.underlying case _: - right = init_from_array_expr(other) + right = init_from_sympy_expr(other) return dataclasses.replace( self, @@ -131,7 +131,7 @@ class ExpressionMixin( ) def __rmatmul__(self, other): - other = init_from_array_expr(other) + other = init_from_sympy_expr(other) return other @ self @@ -140,7 +140,7 @@ class ExpressionMixin( case ExpressionBaseMixin(): right = other.underlying case _: - right = init_from_array_expr(other) + right = init_from_sympy_expr(other) return dataclasses.replace( self, @@ -337,7 +337,7 @@ class ExpressionMixin( ) -> 'ExpressionMixin': return dataclasses.replace( self, - underlying=init_sos_monomials_expr( + underlying=init_quadratic_monomials_expr( underlying=self.underlying, variables=variables, ), @@ -378,7 +378,7 @@ class ExpressionMixin( if isinstance(value, ExpressionMixin): value = value.underlying else: - value = init_from_array_expr(value) + value = init_from_sympy_expr(value) return dataclasses.replace( self, diff --git a/polymatrix/expression/mixins/expressionstatemixin.py b/polymatrix/expression/mixins/expressionstatemixin.py deleted file mode 100644 index 523d2b7..0000000 --- a/polymatrix/expression/mixins/expressionstatemixin.py +++ /dev/null @@ -1,58 +0,0 @@ -import abc -import itertools -import dataclasses -import typing - -import sympy - -from polymatrix.statemonad.mixins.statemixin import StateCacheMixin - - -class ExpressionStateMixin( - StateCacheMixin, -): - - @property - @abc.abstractmethod - def n_param(self) -> int: - """ - current number of parameters used in polynomial matrix expressions - """ - - ... - - @property - @abc.abstractmethod - def offset_dict(self) -> dict[tuple[typing.Any], tuple[int, int]]: - ... - - @property - @abc.abstractmethod - def auxillary_equations(self) -> dict[int, dict[tuple[int], float]]: - ... - - # @property - # @abc.abstractmethod - # def cache(self) -> dict: - # ... - - def register( - self, - n_param: int, - key: typing.Any = None, - ) -> 'ExpressionStateMixin': - - if key is None: - updated_state = dataclasses.replace(self, n_param=self.n_param + n_param) - - elif key not in self.offset_dict: - updated_state = dataclasses.replace( - self, - offset_dict=self.offset_dict | {key: (self.n_param, self.n_param + n_param)}, - n_param=self.n_param + n_param, - ) - - else: - updated_state = self - - return updated_state diff --git a/polymatrix/expression/mixins/eyeexprmixin.py b/polymatrix/expression/mixins/eyeexprmixin.py index fde2017..f904feb 100644 --- a/polymatrix/expression/mixins/eyeexprmixin.py +++ b/polymatrix/expression/mixins/eyeexprmixin.py @@ -2,11 +2,11 @@ import abc import itertools import dataclass_abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class EyeExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/filterexprmixin.py b/polymatrix/expression/mixins/filterexprmixin.py index ad1253a..ad13814 100644 --- a/polymatrix/expression/mixins/filterexprmixin.py +++ b/polymatrix/expression/mixins/filterexprmixin.py @@ -5,10 +5,10 @@ import math import typing import dataclass_abc -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class FilterExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/filterlinearpartexprmixin.py b/polymatrix/expression/mixins/filterlinearpartexprmixin.py index c8e66ef..5670b79 100644 --- a/polymatrix/expression/mixins/filterlinearpartexprmixin.py +++ b/polymatrix/expression/mixins/filterlinearpartexprmixin.py @@ -3,10 +3,10 @@ import abc import collections from numpy import var -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getvariableindices import get_variable_indices diff --git a/polymatrix/expression/mixins/fromarrayexprmixin.py b/polymatrix/expression/mixins/fromarrayexprmixin.py deleted file mode 100644 index 2b066d4..0000000 --- a/polymatrix/expression/mixins/fromarrayexprmixin.py +++ /dev/null @@ -1,68 +0,0 @@ - -import abc -import math -from numpy import poly -import sympy - -from polymatrix.expression.init.initpolymatrix import init_poly_matrix -from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin - - -class FromArrayExprMixin(ExpressionBaseMixin): - @property - @abc.abstractmethod - def data(self) -> tuple[tuple[float]]: - pass - - # overwrites abstract method of `ExpressionBaseMixin` - def apply( - self, - state: ExpressionStateMixin, - ) -> tuple[ExpressionStateMixin, PolyMatrixMixin]: - - terms = {} - - for poly_row, col_data in enumerate(self.data): - for poly_col, poly_data in enumerate(col_data): - - try: - poly = sympy.poly(poly_data) - except sympy.polys.polyerrors.GeneratorsNeeded: - - if not math.isclose(poly_data, 0): - terms[poly_row, poly_col] = {tuple(): poly_data} - continue - - for symbol in poly.gens: - state = state.register(key=symbol, n_param=1) - # print(f'{symbol}: {state.n_param}') - - terms_row_col = {} - - # a5 x1 x3**2 -> c=a5, m_cnt=(1, 0, 2) - for value, monomial_count in zip(poly.coeffs(), poly.monoms()): - - if math.isclose(value, 0): - continue - - # m_cnt=(1, 0, 2) -> m=(0, 2, 2) - def gen_monomial(): - for rel_idx, p in enumerate(monomial_count): - if 0 < p: - idx, _ = state.offset_dict[poly.gens[rel_idx]] - yield idx, p - - monomial = tuple(gen_monomial()) - - terms_row_col[monomial] = value - - terms[poly_row, poly_col] = terms_row_col - - poly_matrix = init_poly_matrix( - terms=terms, - shape=(len(self.data), len(self.data[0])), - ) - - return state, poly_matrix diff --git a/polymatrix/expression/mixins/fromsympyexprmixin.py b/polymatrix/expression/mixins/fromsympyexprmixin.py new file mode 100644 index 0000000..f6953e1 --- /dev/null +++ b/polymatrix/expression/mixins/fromsympyexprmixin.py @@ -0,0 +1,67 @@ + +import abc +import math +import sympy + +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix +from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin + + +class FromSympyExprMixin(ExpressionBaseMixin): + @property + @abc.abstractmethod + def data(self) -> tuple[tuple[float]]: + pass + + # overwrites abstract method of `ExpressionBaseMixin` + def apply( + self, + state: ExpressionStateMixin, + ) -> tuple[ExpressionStateMixin, PolyMatrixMixin]: + + terms = {} + + for poly_row, col_data in enumerate(self.data): + for poly_col, poly_data in enumerate(col_data): + + try: + poly = sympy.poly(poly_data) + except sympy.polys.polyerrors.GeneratorsNeeded: + + if not math.isclose(poly_data, 0): + terms[poly_row, poly_col] = {tuple(): poly_data} + continue + + for symbol in poly.gens: + state = state.register(key=symbol, n_param=1) + # print(f'{symbol}: {state.n_param}') + + terms_row_col = {} + + # a5 x1 x3**2 -> c=a5, m_cnt=(1, 0, 2) + for value, monomial_count in zip(poly.coeffs(), poly.monoms()): + + if math.isclose(value, 0): + continue + + # m_cnt=(1, 0, 2) -> m=(0, 2, 2) + def gen_monomial(): + for rel_idx, p in enumerate(monomial_count): + if 0 < p: + idx, _ = state.offset_dict[poly.gens[rel_idx]] + yield idx, p + + monomial = tuple(gen_monomial()) + + terms_row_col[monomial] = value + + terms[poly_row, poly_col] = terms_row_col + + poly_matrix = init_poly_matrix( + terms=terms, + shape=(len(self.data), len(self.data[0])), + ) + + return state, poly_matrix diff --git a/polymatrix/expression/mixins/fromtermsexprmixin.py b/polymatrix/expression/mixins/fromtermsexprmixin.py index 4ada8ec..8fd9be6 100644 --- a/polymatrix/expression/mixins/fromtermsexprmixin.py +++ b/polymatrix/expression/mixins/fromtermsexprmixin.py @@ -3,10 +3,10 @@ import abc from numpy import poly import sympy -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class FromTermsExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/getitemexprmixin.py b/polymatrix/expression/mixins/getitemexprmixin.py index fa7edb1..1d0586f 100644 --- a/polymatrix/expression/mixins/getitemexprmixin.py +++ b/polymatrix/expression/mixins/getitemexprmixin.py @@ -3,12 +3,12 @@ import abc import dataclasses import typing import dataclass_abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class GetItemExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/linearinexprmixin.py b/polymatrix/expression/mixins/linearinexprmixin.py index 369467a..7f10b1c 100644 --- a/polymatrix/expression/mixins/linearinexprmixin.py +++ b/polymatrix/expression/mixins/linearinexprmixin.py @@ -3,10 +3,10 @@ import abc import collections from numpy import var -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getmonomialindices import get_monomial_indices from polymatrix.expression.utils.getvariableindices import get_variable_indices diff --git a/polymatrix/expression/mixins/linearinmutipleexprmixin.py b/polymatrix/expression/mixins/linearinmutipleexprmixin.py index 7d4f00e..b80f562 100644 --- a/polymatrix/expression/mixins/linearinmutipleexprmixin.py +++ b/polymatrix/expression/mixins/linearinmutipleexprmixin.py @@ -2,10 +2,10 @@ import abc import collections -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getvariableindices import get_variable_indices @@ -71,74 +71,3 @@ class LinearInMultipleExprMixin(ExpressionBaseMixin): ) return state, poly_matrix - - # state, variable_indices = get_variable_indices(state, self.variables) - - # underlying_terms = underlying.get_terms() - - # def gen_variable_terms(): - # for _, monomial_term in underlying_terms: - # for monomial in monomial_term.keys(): - - # x_monomial = tuple(var_idx for var_idx in monomial if var_idx in variable_indices) - # yield x_monomial - - # variable_terms = tuple(set(gen_variable_terms())) - - # terms = {} - - # for (row, _), monomial_term in underlying.get_terms(): - - # x_monomial_terms = collections.defaultdict(lambda: collections.defaultdict(float)) - - # for monomial, value in monomial_term.items(): - - # x_monomial = tuple(var_idx for var_idx in monomial if var_idx in variable_indices) - # p_monomial = tuple(var_idx for var_idx in monomial if var_idx not in variable_indices) - - # assert tuple(sorted(x_monomial)) == x_monomial, f'{x_monomial} is not sorted' - - # x_monomial_terms[x_monomial][p_monomial] += value - - # for x_monomial, data in x_monomial_terms.items(): - # terms[row, variable_terms.index(x_monomial)] = dict(data) - - # poly_matrix = init_poly_matrix( - # terms=terms, - # shape=(underlying.shape[0], len(variable_terms)), - # ) - - # return state, poly_matrix - - # terms = {} - # idx_row = 0 - - # for row in range(underlying.shape[0]): - # for col in range(underlying.shape[1]): - - # try: - # underlying_terms = underlying.get_poly(row, col) - # except KeyError: - # continue - - # x_monomial_terms = collections.defaultdict(lambda: collections.defaultdict(float)) - - # for monomial, value in underlying_terms.items(): - - # x_monomial = tuple(var_idx for var_idx in monomial if var_idx in variable_indices) - # p_monomial = tuple(var_idx for var_idx in monomial if var_idx not in variable_indices) - - # assert tuple(sorted(x_monomial)) == x_monomial, f'{x_monomial} is not sorted' - - # x_monomial_terms[x_monomial][p_monomial] += value - - # for data in x_monomial_terms.values(): - # terms[idx_row, 0] = dict(data) - # idx_row += 1 - - # poly_matrix = init_poly_matrix( - # terms=terms, - # shape=(idx_row, 1), - # ) - - # return state, poly_matrix diff --git a/polymatrix/expression/mixins/linearmatrixinexprmixin.py b/polymatrix/expression/mixins/linearmatrixinexprmixin.py index 956b01a..1358e1e 100644 --- a/polymatrix/expression/mixins/linearmatrixinexprmixin.py +++ b/polymatrix/expression/mixins/linearmatrixinexprmixin.py @@ -3,10 +3,10 @@ import abc import collections from numpy import var -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getvariableindices import get_variable_indices diff --git a/polymatrix/expression/mixins/linearmonomialsexprmixin.py b/polymatrix/expression/mixins/linearmonomialsexprmixin.py index 42a5b95..64ba66d 100644 --- a/polymatrix/expression/mixins/linearmonomialsexprmixin.py +++ b/polymatrix/expression/mixins/linearmonomialsexprmixin.py @@ -2,10 +2,10 @@ import abc import dataclasses -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin from polymatrix.expression.mixins.quadraticinexprmixin import QuadraticInExprMixin from polymatrix.expression.utils.getvariableindices import get_variable_indices from polymatrix.expression.utils.sortmonomials import sort_monomials diff --git a/polymatrix/expression/mixins/matrixmultexprmixin.py b/polymatrix/expression/mixins/matrixmultexprmixin.py index 029f700..d023f1e 100644 --- a/polymatrix/expression/mixins/matrixmultexprmixin.py +++ b/polymatrix/expression/mixins/matrixmultexprmixin.py @@ -3,10 +3,10 @@ import abc import itertools import math -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.mergemonomialindices import merge_monomial_indices from polymatrix.expression.utils.multiplypolynomial import multiply_polynomial diff --git a/polymatrix/expression/mixins/maxdegreeexprmixin.py b/polymatrix/expression/mixins/maxdegreeexprmixin.py index a1c9b1e..7502cbb 100644 --- a/polymatrix/expression/mixins/maxdegreeexprmixin.py +++ b/polymatrix/expression/mixins/maxdegreeexprmixin.py @@ -1,10 +1,10 @@ import abc -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class MaxDegreeExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/maxexprmixin.py b/polymatrix/expression/mixins/maxexprmixin.py index 6070f73..21fd6da 100644 --- a/polymatrix/expression/mixins/maxexprmixin.py +++ b/polymatrix/expression/mixins/maxexprmixin.py @@ -1,10 +1,10 @@ import abc -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class MaxExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/parametrizeexprmixin.py b/polymatrix/expression/mixins/parametrizeexprmixin.py index 11a767f..b9673e4 100644 --- a/polymatrix/expression/mixins/parametrizeexprmixin.py +++ b/polymatrix/expression/mixins/parametrizeexprmixin.py @@ -2,10 +2,10 @@ import abc import dataclasses -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class ParametrizeExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/polymatrixasdictmixin.py b/polymatrix/expression/mixins/polymatrixasdictmixin.py index 4a366de..69c59ac 100644 --- a/polymatrix/expression/mixins/polymatrixasdictmixin.py +++ b/polymatrix/expression/mixins/polymatrixasdictmixin.py @@ -1,6 +1,6 @@ import abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class PolyMatrixAsDictMixin( diff --git a/polymatrix/expression/mixins/polymatrixmixin.py b/polymatrix/expression/mixins/polymatrixmixin.py deleted file mode 100644 index bea80de..0000000 --- a/polymatrix/expression/mixins/polymatrixmixin.py +++ /dev/null @@ -1,26 +0,0 @@ -import abc -import typing - - -class PolyMatrixMixin(abc.ABC): - @property - @abc.abstractclassmethod - def shape(self) -> tuple[int, int]: - ... - - def get_terms(self) -> tuple[tuple[int, int], dict[tuple[int, ...], float]]: - def gen_terms(): - for row in range(self.shape[0]): - for col in range(self.shape[1]): - try: - monomial_terms = self.get_poly(row, col) - except KeyError: - continue - - yield (row, col), monomial_terms - - return tuple(gen_terms()) - - @abc.abstractclassmethod - def get_poly(self, row: int, col: int) -> typing.Optional[dict[tuple[int, ...], float]]: - ... diff --git a/polymatrix/expression/mixins/quadraticinexprmixin.py b/polymatrix/expression/mixins/quadraticinexprmixin.py index 7e08d7c..8c1a531 100644 --- a/polymatrix/expression/mixins/quadraticinexprmixin.py +++ b/polymatrix/expression/mixins/quadraticinexprmixin.py @@ -2,10 +2,10 @@ import abc import collections -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getmonomialindices import get_monomial_indices from polymatrix.expression.utils.getvariableindices import get_variable_indices from polymatrix.expression.utils.splitmonomialindices import split_monomial_indices diff --git a/polymatrix/expression/mixins/quadraticmonomialsexprmixin.py b/polymatrix/expression/mixins/quadraticmonomialsexprmixin.py index b953d17..dbc401b 100644 --- a/polymatrix/expression/mixins/quadraticmonomialsexprmixin.py +++ b/polymatrix/expression/mixins/quadraticmonomialsexprmixin.py @@ -2,10 +2,10 @@ import abc import dataclasses -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin from polymatrix.expression.mixins.quadraticinexprmixin import QuadraticInExprMixin from polymatrix.expression.utils.getvariableindices import get_variable_indices from polymatrix.expression.utils.splitmonomialindices import split_monomial_indices diff --git a/polymatrix/expression/mixins/repmatexprmixin.py b/polymatrix/expression/mixins/repmatexprmixin.py index 90c6a66..d45cca2 100644 --- a/polymatrix/expression/mixins/repmatexprmixin.py +++ b/polymatrix/expression/mixins/repmatexprmixin.py @@ -2,8 +2,8 @@ import abc import dataclass_abc from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class RepMatExprMixin(ExpressionBaseMixin): @property diff --git a/polymatrix/expression/mixins/reshapeexprmixin.py b/polymatrix/expression/mixins/reshapeexprmixin.py index ad2a5a6..a73c00e 100644 --- a/polymatrix/expression/mixins/reshapeexprmixin.py +++ b/polymatrix/expression/mixins/reshapeexprmixin.py @@ -5,8 +5,8 @@ import dataclass_abc import numpy as np from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class ReshapeExprMixin(ExpressionBaseMixin): @property diff --git a/polymatrix/expression/mixins/setelementatexprmixin.py b/polymatrix/expression/mixins/setelementatexprmixin.py index 5714631..9d552bc 100644 --- a/polymatrix/expression/mixins/setelementatexprmixin.py +++ b/polymatrix/expression/mixins/setelementatexprmixin.py @@ -3,12 +3,12 @@ import abc import dataclasses import typing import dataclass_abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class SetElementAtExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/squeezeexprmixin.py b/polymatrix/expression/mixins/squeezeexprmixin.py index 62fe7de..2f46e23 100644 --- a/polymatrix/expression/mixins/squeezeexprmixin.py +++ b/polymatrix/expression/mixins/squeezeexprmixin.py @@ -4,10 +4,10 @@ import collections import typing import dataclass_abc -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState # remove? diff --git a/polymatrix/expression/mixins/substituteexprmixin.py b/polymatrix/expression/mixins/substituteexprmixin.py index fc71f73..1ba8a1a 100644 --- a/polymatrix/expression/mixins/substituteexprmixin.py +++ b/polymatrix/expression/mixins/substituteexprmixin.py @@ -4,10 +4,10 @@ import collections import itertools import math -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getvariableindices import get_variable_indices from polymatrix.expression.utils.multiplypolynomial import multiply_polynomial diff --git a/polymatrix/expression/mixins/subtractmonomialsexprmixin.py b/polymatrix/expression/mixins/subtractmonomialsexprmixin.py index 45ef444..33dfc97 100644 --- a/polymatrix/expression/mixins/subtractmonomialsexprmixin.py +++ b/polymatrix/expression/mixins/subtractmonomialsexprmixin.py @@ -2,10 +2,10 @@ import abc import dataclasses -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin from polymatrix.expression.mixins.quadraticinexprmixin import QuadraticInExprMixin from polymatrix.expression.utils.getmonomialindices import get_monomial_indices from polymatrix.expression.utils.getvariableindices import get_variable_indices diff --git a/polymatrix/expression/mixins/sumexprmixin.py b/polymatrix/expression/mixins/sumexprmixin.py index b3afd51..75124d9 100644 --- a/polymatrix/expression/mixins/sumexprmixin.py +++ b/polymatrix/expression/mixins/sumexprmixin.py @@ -3,10 +3,10 @@ import abc import collections import dataclasses -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.mixins.expressionstatemixin import ExpressionStateMixin -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin class SumExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/symmetricexprmixin.py b/polymatrix/expression/mixins/symmetricexprmixin.py index da07715..989cb0e 100644 --- a/polymatrix/expression/mixins/symmetricexprmixin.py +++ b/polymatrix/expression/mixins/symmetricexprmixin.py @@ -3,11 +3,11 @@ import abc import collections import itertools import dataclass_abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class SymmetricExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/toconstantexprmixin.py b/polymatrix/expression/mixins/toconstantexprmixin.py index 1276251..e585d3c 100644 --- a/polymatrix/expression/mixins/toconstantexprmixin.py +++ b/polymatrix/expression/mixins/toconstantexprmixin.py @@ -3,10 +3,10 @@ import abc import collections from numpy import var -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getvariableindices import get_variable_indices diff --git a/polymatrix/expression/mixins/toquadraticexprmixin.py b/polymatrix/expression/mixins/toquadraticexprmixin.py index 02e366d..bbb0cbf 100644 --- a/polymatrix/expression/mixins/toquadraticexprmixin.py +++ b/polymatrix/expression/mixins/toquadraticexprmixin.py @@ -3,10 +3,10 @@ import abc import collections import dataclasses -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState # to be deleted? diff --git a/polymatrix/expression/mixins/transposeexprmixin.py b/polymatrix/expression/mixins/transposeexprmixin.py index da1c288..4153518 100644 --- a/polymatrix/expression/mixins/transposeexprmixin.py +++ b/polymatrix/expression/mixins/transposeexprmixin.py @@ -3,12 +3,12 @@ import abc import dataclasses import typing import dataclass_abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class TransposeExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/truncateexprmixin.py b/polymatrix/expression/mixins/truncateexprmixin.py index badc01e..3f23652 100644 --- a/polymatrix/expression/mixins/truncateexprmixin.py +++ b/polymatrix/expression/mixins/truncateexprmixin.py @@ -3,10 +3,10 @@ import abc import collections from numpy import var -from polymatrix.expression.init.initpolymatrix import init_poly_matrix +from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState from polymatrix.expression.utils.getvariableindices import get_variable_indices diff --git a/polymatrix/expression/mixins/vstackexprmixin.py b/polymatrix/expression/mixins/vstackexprmixin.py index 2929f7a..8d6c25d 100644 --- a/polymatrix/expression/mixins/vstackexprmixin.py +++ b/polymatrix/expression/mixins/vstackexprmixin.py @@ -2,11 +2,11 @@ import abc import itertools import dataclass_abc -from polymatrix.expression.mixins.polymatrixmixin import PolyMatrixMixin +from polymatrix.polymatrix.mixins.polymatrixmixin import PolyMatrixMixin from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin -from polymatrix.expression.polymatrix import PolyMatrix -from polymatrix.expression.expressionstate import ExpressionState +from polymatrix.polymatrix.polymatrix import PolyMatrix +from polymatrix.expressionstate.expressionstate import ExpressionState class VStackExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/polymatrix.py b/polymatrix/expression/polymatrix.py deleted file mode 100644 index c044081..0000000 --- a/polymatrix/expression/polymatrix.py +++ /dev/null @@ -1,4 +0,0 @@ -from polymatrix.expression.mixins.polymatrixasdictmixin import PolyMatrixAsDictMixin - -class PolyMatrix(PolyMatrixAsDictMixin): - pass diff --git a/polymatrix/expression/utils/getderivativemonomials.py b/polymatrix/expression/utils/getderivativemonomials.py index 9c5ac98..cec2d81 100644 --- a/polymatrix/expression/utils/getderivativemonomials.py +++ b/polymatrix/expression/utils/getderivativemonomials.py @@ -1,5 +1,6 @@ import collections -from polymatrix.expression.expressionstate import ExpressionState + +from polymatrix.expressionstate.expressionstate import ExpressionState def get_derivative_monomials( @@ -27,7 +28,12 @@ def get_derivative_monomials( # def acc_state_candidates(acc, new_variable): # state, candidates = acc - # key = init_derivative_key( + # @dataclasses.dataclass + # class DerivativeKey: + # variable: int + # with_respect_to: int + + # key = DerivativeKey( # variable=new_variable, # with_respect_to=diff_wrt_variable, # ) diff --git a/polymatrix/expression/utils/monomialtoindex.py b/polymatrix/expression/utils/monomialtoindex.py new file mode 100644 index 0000000..bb1e570 --- /dev/null +++ b/polymatrix/expression/utils/monomialtoindex.py @@ -0,0 +1,7 @@ +import itertools + + +def monomial_to_index(n_var, monomial): + monomial_perm = itertools.permutations(monomial) + + return set(sum(idx*(n_var**level) for level, idx in enumerate(monomial)) for monomial in monomial_perm) diff --git a/polymatrix/expressionstate/__init__.py b/polymatrix/expressionstate/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polymatrix/expressionstate/expressionstate.py b/polymatrix/expressionstate/expressionstate.py new file mode 100644 index 0000000..342432a --- /dev/null +++ b/polymatrix/expressionstate/expressionstate.py @@ -0,0 +1,4 @@ +from polymatrix.expressionstate.mixins.expressionstatemixin import ExpressionStateMixin + +class ExpressionState(ExpressionStateMixin): + pass diff --git a/polymatrix/expressionstate/impl/__init__.py b/polymatrix/expressionstate/impl/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polymatrix/expressionstate/impl/expressionstateimpl.py b/polymatrix/expressionstate/impl/expressionstateimpl.py new file mode 100644 index 0000000..31710fb --- /dev/null +++ b/polymatrix/expressionstate/impl/expressionstateimpl.py @@ -0,0 +1,12 @@ +from functools import cached_property +import dataclass_abc +from polymatrix.expressionstate.expressionstate import ExpressionState + +from typing import Optional + +@dataclass_abc.dataclass_abc(frozen=True) +class ExpressionStateImpl(ExpressionState): + n_param: int + offset_dict: dict + auxillary_equations: dict[int, dict[tuple[int], float]] + cache: dict diff --git a/polymatrix/expressionstate/init/__init__.py b/polymatrix/expressionstate/init/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polymatrix/expressionstate/init/initexpressionstate.py b/polymatrix/expressionstate/init/initexpressionstate.py new file mode 100644 index 0000000..7e868da --- /dev/null +++ b/polymatrix/expressionstate/init/initexpressionstate.py @@ -0,0 +1,19 @@ +from polymatrix.expressionstate.impl.expressionstateimpl import ExpressionStateImpl + + +def init_expression_state( + n_param: int = None, + offset_dict: dict = None, +): + if n_param is None: + n_param = 0 + + if offset_dict is None: + offset_dict = {} + + return ExpressionStateImpl( + n_param=n_param, + offset_dict=offset_dict, + auxillary_equations={}, + cache={}, +) diff --git a/polymatrix/expressionstate/mixins/__init__.py b/polymatrix/expressionstate/mixins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polymatrix/expressionstate/mixins/expressionstatemixin.py b/polymatrix/expressionstate/mixins/expressionstatemixin.py new file mode 100644 index 0000000..523d2b7 --- /dev/null +++ b/polymatrix/expressionstate/mixins/expressionstatemixin.py @@ -0,0 +1,58 @@ +import abc +import itertools +import dataclasses +import typing + +import sympy + +from polymatrix.statemonad.mixins.statemixin import StateCacheMixin + + +class ExpressionStateMixin( + StateCacheMixin, +): + + @property + @abc.abstractmethod + def n_param(self) -> int: + """ + current number of parameters used in polynomial matrix expressions + """ + + ... + + @property + @abc.abstractmethod + def offset_dict(self) -> dict[tuple[typing.Any], tuple[int, int]]: + ... + + @property + @abc.abstractmethod + def auxillary_equations(self) -> dict[int, dict[tuple[int], float]]: + ... + + # @property + # @abc.abstractmethod + # def cache(self) -> dict: + # ... + + def register( + self, + n_param: int, + key: typing.Any = None, + ) -> 'ExpressionStateMixin': + + if key is None: + updated_state = dataclasses.replace(self, n_param=self.n_param + n_param) + + elif key not in self.offset_dict: + updated_state = dataclasses.replace( + self, + offset_dict=self.offset_dict | {key: (self.n_param, self.n_param + n_param)}, + n_param=self.n_param + n_param, + ) + + else: + updated_state = self + + return updated_state diff --git a/polymatrix/polymatrix/__init__.py b/polymatrix/polymatrix/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polymatrix/polymatrix/impl/__init__.py b/polymatrix/polymatrix/impl/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polymatrix/polymatrix/impl/polymatriximpl.py b/polymatrix/polymatrix/impl/polymatriximpl.py new file mode 100644 index 0000000..0c269ca --- /dev/null +++ b/polymatrix/polymatrix/impl/polymatriximpl.py @@ -0,0 +1,8 @@ +import dataclass_abc +from polymatrix.polymatrix.polymatrix import PolyMatrix + + +@dataclass_abc.dataclass_abc(frozen=True) +class PolyMatrixImpl(PolyMatrix): + terms: dict + shape: tuple[int, ...] diff --git a/polymatrix/polymatrix/init/__init__.py b/polymatrix/polymatrix/init/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polymatrix/polymatrix/init/initpolymatrix.py b/polymatrix/polymatrix/init/initpolymatrix.py new file mode 100644 index 0000000..412adfb --- /dev/null +++ b/polymatrix/polymatrix/init/initpolymatrix.py @@ -0,0 +1,12 @@ +from polymatrix.polymatrix.impl.polymatriximpl import PolyMatrixImpl + + +def init_poly_matrix( + terms: dict, + shape: tuple, +): + + return PolyMatrixImpl( + terms=terms, + shape=shape, +) diff --git a/polymatrix/polymatrix/mixins/__init__.py b/polymatrix/polymatrix/mixins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polymatrix/polymatrix/mixins/polymatrixmixin.py b/polymatrix/polymatrix/mixins/polymatrixmixin.py new file mode 100644 index 0000000..bea80de --- /dev/null +++ b/polymatrix/polymatrix/mixins/polymatrixmixin.py @@ -0,0 +1,26 @@ +import abc +import typing + + +class PolyMatrixMixin(abc.ABC): + @property + @abc.abstractclassmethod + def shape(self) -> tuple[int, int]: + ... + + def get_terms(self) -> tuple[tuple[int, int], dict[tuple[int, ...], float]]: + def gen_terms(): + for row in range(self.shape[0]): + for col in range(self.shape[1]): + try: + monomial_terms = self.get_poly(row, col) + except KeyError: + continue + + yield (row, col), monomial_terms + + return tuple(gen_terms()) + + @abc.abstractclassmethod + def get_poly(self, row: int, col: int) -> typing.Optional[dict[tuple[int, ...], float]]: + ... diff --git a/polymatrix/polymatrix/polymatrix.py b/polymatrix/polymatrix/polymatrix.py new file mode 100644 index 0000000..c044081 --- /dev/null +++ b/polymatrix/polymatrix/polymatrix.py @@ -0,0 +1,4 @@ +from polymatrix.expression.mixins.polymatrixasdictmixin import PolyMatrixAsDictMixin + +class PolyMatrix(PolyMatrixAsDictMixin): + pass diff --git a/polymatrix/polysolver.py b/polymatrix/polysolver.py deleted file mode 100644 index 8c055f8..0000000 --- a/polymatrix/polysolver.py +++ /dev/null @@ -1,401 +0,0 @@ -import numpy as np -import sympy -import itertools -import scipy.linalg -import scipy.sparse.linalg -import collections -from scipy.special import binom -import more_itertools -import time - - -def convert_to_complex_equations(raw_data): - n = raw_data[0].shape[0] - - data = {} - data[0] = np.vstack((raw_data[0], np.zeros((n, 1)))) - data[1] = np.kron(np.eye(2), raw_data[1]) - - def get_tuple(n, idx): - row = idx % n - col = int((idx-row) / n) - return (row, col) - - def get_index(n, tple): - return sum(idx*(n**level) for level, idx in enumerate(tple)) - - csr_data = raw_data[2].tocsr() - - def gen_complex_data(): - for row in range(csr_data.shape[0]): - - pt = slice(csr_data.indptr[row], csr_data.indptr[row+1]) - - for col, value in zip(csr_data.indices[pt], csr_data.data[pt]): - - left, right = get_tuple(n, col) - - yield row, get_index(2*n, (left, right)), value - yield row, get_index(2*n, (left+n, right+n)), -value - - yield row+n, get_index(2*n, (left, right+n)), value - yield row+n, get_index(2*n, (left+n, right)), value - - row, col, idata = list(zip(*gen_complex_data())) - - data[2] = scipy.sparse.coo_array( - (idata, (row, col)), - shape=(2*n, (2*n)**2), - ) - - return data - - -def substitude_x_add_a(data, a): - - def kron_eye_and_a(n, data, a, indices): - # permutations = more_itertools.distinct_permutations(indices) - permutations = set(itertools.permutations(indices)) - - if not scipy.sparse.issparse(data): - ops = (np.eye(n), np.reshape(a, (-1, 1))) - - def acc_kron(perm): - *_, last = itertools.accumulate((ops[idx] for idx in perm), lambda acc, v: np.kron(acc, v)) - return last - - return sum(data @ acc_kron(perm) for perm in permutations) - - else: - # csr_data = data - csr_data = data.tocsr() - - n_eye = sum(1 for idx in indices if idx == 0) - n_col = n**n_eye - n_index = n_col * n**(len(indices) - n_eye) - - def gen_array_per_permuatation(): - - def gen_coord(perm): - n_row = csr_data.shape[0] - - def acc_col_idx_and_value(acc, v): - relindex, relrow, col, val = acc - - n_relrow = relrow / n - grp_index = int(relindex / n_relrow) - n_relindex = int(relindex - grp_index * n_relrow) - - if v == 1: - n_col = col - n_val = val * a[grp_index] - - else: - n_col = n * col + grp_index - n_val = val - - return n_relindex, n_relrow, n_col, n_val - - for row in range(n_row): - - pt = slice(csr_data.indptr[row], csr_data.indptr[row+1]) - - for inner_idx, array_val in zip(csr_data.indices[pt], csr_data.data[pt]): - - *_, last = itertools.accumulate( - perm, - acc_col_idx_and_value, - initial=(inner_idx, n_index, 0, array_val), - ) - _, _, col, val = last - - yield col, val - - for perm in permutations: - - col, data = list(zip(*gen_coord(perm))) - - yield scipy.sparse.csr_array((data, col, csr_data.indptr), shape=(csr_data.shape[0], n_col)) - - return sum(gen_array_per_permuatation()) - - n = data[1].shape[0] - - subs_data = {key: val.copy() for key, val in data.items()} - - for degree, d_data in data.items(): - for i_degree in range(degree): - indices = i_degree*(0,) + (degree - i_degree)*(1,) - update = kron_eye_and_a(n, d_data, a, indices) - subs_data[i_degree] += update - - first = -1/np.squeeze(subs_data[0]) - def gen_subs_data(): - for key, d_data in subs_data.items(): - if scipy.sparse.issparse(d_data): - - csr_data = d_data.tocsr() - for row, scale in enumerate(first): - csr_data.data[csr_data.indptr[row] : csr_data.indptr[row + 1]] *= scale - yield key, csr_data - - else: - d_data *= first[:, None] - yield key, d_data - return dict(gen_subs_data()) - - # return subs_data - - -def solve_poly_system(data, m): - if isinstance(data[1], np.ndarray): - b_num_inv = np.linalg.inv(data[1]) - else: - b_num_inv = scipy.sparse.linalg.inv(data[1]) - - n_var = b_num_inv.shape[0] - p0 = b_num_inv @ np.ones((n_var, 1)) - - assert (data[0] + np.ones((n_var, 1)) < 0.01).all(), f'{data[0]=}, {data[0] + np.ones((n_var, 1))=}' - assert (data[0] + np.ones((n_var, 1)) < 0.01).all(), f'data[0] is not one' - - def func(acc, _): - """ - acc: a nxk matrix whose ith column represent the ith parameter of the power series for each of the n variables - """ - - p = acc - k = p.shape[1] - - def gen_indices(n, d): - """ - n=2,d=1 = [(0,2), (1,1)] - n=3,d=1 = [(0,3), (1,2)] - n=2,d=2 = [(0,0,2), (0,1,1)] - """ - - if d==0: - yield (n,) - - else: - for idx in range(int(n/(d+1))+1): - yield from ((idx,)+tuple(i+idx*(d-1) for i in indices) for indices in gen_indices( - n - (2*d-1)*idx, - d-1, - )) - - def gen_p(): - for degree, d_data in data.items(): - if 1 < degree and degree-1 <= k: - indices_list = list(gen_indices(k-degree+1, degree-1)) - permutations = lambda: (perm for indices in indices_list for perm in more_itertools.distinct_permutations(indices)) - - if not scipy.sparse.issparse(d_data): - - def acc_kron(perm): - *_, last = itertools.accumulate(((p[:,idx:idx+1] for idx in perm)), lambda acc, v: np.kron(acc, v)) - return last - - yield from (d_data @ acc_kron(perm) for perm in permutations()) - - else: - - csr_data = d_data.tocsr() - - n_row = csr_data.shape[0] - n_col = csr_data.shape[1] - - def gen_row_values(): - - def acc_kron_operation(acc, v): - relindex, relrow, val = acc - - n_relrow = relrow / n_var - grp_index = int(relindex / n_relrow) - n_relindex = int(relindex - grp_index * n_relrow) - n_val = val * float(p[grp_index, v:v+1]) - - return n_relindex, n_relrow, n_val - - for row in range(n_row): - - pt = slice(csr_data.indptr[row], csr_data.indptr[row+1]) - - def gen_row_multiplication(): - for col_idx, col_val in zip(csr_data.indices[pt], csr_data.data[pt]): - for perm in permutations(): - - *_, (_, _, val) = itertools.accumulate( - perm, - acc_kron_operation, - initial=(col_idx, n_col, col_val), - ) - - yield val - - yield sum(gen_row_multiplication()) - - # for perm in permutations: - - row_values = tuple(gen_row_values()) - - assert len(row_values) == n_row - - yield scipy.sparse.coo_array( - (row_values, (range(n_row), np.zeros(n_row))), - shape=(n_row, 1), - ) - - return np.concatenate((p, -b_num_inv @ sum(gen_p())), axis=1) - - *_, sol_subs = itertools.accumulate(range(m-1), func, initial=p0) - - return sum(np.asarray(sol_subs).T) - - -def inner_smart_solve(data, irange=None, idegree=None, a_init=None): - - if irange is None: - irange = np.geomspace(20, 1.1, 8) - - if idegree is None: - idegree = 4 - - if a_init is None: - a_init = np.zeros(data[0].shape[0]) - - def acc_func(acc, v): - a, prev_err = acc - scale = v - - # print(f'iter: {index}') - - # print('substitude...') - subs_data = substitude_x_add_a(data, a) - - # print('modify scaling...') - def gen_data(): - for degree, d_data in subs_data.items(): - if 1 == degree: - yield degree, d_data * scale - else: - yield degree, d_data - scaled_data = dict(gen_data()) - - # print('solve...') - try: - sol = solve_poly_system(scaled_data, idegree) - except: - # return a, prev_err - raise - - err = np.max(np.abs(eval_solution(scaled_data, sol))) - - a = sol + a - - return a, err - - a, err = tuple(zip(*itertools.accumulate( - irange, - acc_func, - initial=(a_init, 0), - ))) - - return a, err - - -def outer_smart_solve(data, a_init=None, n_iter=10, a_max=1.0, irange=None, idegree=None): - n = data[1].shape[0] - - if a_init is None: - a_init = np.zeros(n) - - def gen_a_err(): - for _ in range(n_iter): - a_subs = a_init + a_max * (2 * np.random.rand(n) - 1) - - try: - a, err = inner_smart_solve(data, irange=irange, idegree=idegree, a_init=a_subs) - - # subs_data = substitude_x_add_a(data, a[-1]) - # sol = solve_poly_system(subs_data, 6) - - # error_index = np.max(np.abs(eval_solution(data, a[-1] + sol))) + max(a[-1]) - # error_index = np.max(np.abs(eval_solution(data, a[-1] + sol))) - # error_index = np.max(np.abs(eval_solution(subs_data, sol))) + max(a[-1]) - # error_index = np.max(np.abs(eval_solution(subs_data, sol))) - - except: - print(f'nan error, continue') - continue - - # print(f'{error_index=}') - - yield a, err - - a, err = tuple(zip(*gen_a_err())) - - return a, err - - -def eval_solution(data, x=None): - # if x is None: - # x = sum(sol.T) - - x = np.reshape(x, (-1, 1)) - - def gen_sum(): - n = data[1].shape[0] - - for degree, d_data in data.items(): - if 0 < degree: - # *_, last = itertools.accumulate(degree*(x,), lambda acc, v: np.kron(acc, v)) - # yield d_data @ last - - if not scipy.sparse.issparse(d_data): - - *_, last = itertools.accumulate(degree*(x,), lambda acc, v: np.kron(acc, v)) - yield d_data @ last - - else: - csr_data = d_data.tocsr() - - def gen_coord(): - n_row = csr_data.shape[0] - n_index = n**degree - - def acc_col_idx_and_value(acc, v): - relindex, relrow, val = acc - - n_relrow = relrow / n - grp_index = int(relindex / n_relrow) - n_relindex = int(relindex - grp_index * n_relrow) - - n_val = val * x[grp_index, 0] - - return n_relindex, n_relrow, n_val - - for row in range(n_row): - - pt = slice(csr_data.indptr[row], csr_data.indptr[row+1]) - - for inner_idx, array_val in zip(csr_data.indices[pt], csr_data.data[pt]): - - *_, last = itertools.accumulate( - range(degree), - acc_col_idx_and_value, - initial=(inner_idx, n_index, array_val), - ) - _, _, val = last - - yield val - - array_values = list(gen_coord()) - - yield scipy.sparse.csr_array((array_values, np.zeros(len(array_values)), csr_data.indptr), shape=(csr_data.shape[0], 1)) - - else: - yield d_data - - val = np.ravel(sum(gen_sum()).T) - return val diff --git a/polymatrix/sympyutils.py b/polymatrix/sympyutils.py deleted file mode 100644 index 8fd74b2..0000000 --- a/polymatrix/sympyutils.py +++ /dev/null @@ -1,87 +0,0 @@ -import collections -import itertools -import numpy as np -import scipy.sparse -import sympy - - -def poly_to_data_coord(poly_list, x, degree = None): - """ - poly_list = [ - poly(x1*x3**2, x) - ] - power: up to which power - """ - - sympy_poly_list = tuple(tuple(sympy.poly(p, x) for p in inner_poly_list) for inner_poly_list in poly_list) - - if degree is None: - degree = max(sum(monom) for inner_poly_list in sympy_poly_list for poly in inner_poly_list for monom in poly.monoms()) - - n = len(x) - - def gen_power_mat(): - - # for all powers generate a matrix - for i_degree in range(degree + 1): - - def gen_value_index(): - - # each polynomial defines a row in the matrix - for poly_row, inner_poly_list in enumerate(sympy_poly_list): - - for poly_col, p in enumerate(inner_poly_list): - - # a5 x1 x3**2 -> c=a5, m=(1, 0, 2) - for c, m in zip(p.coeffs(), p.monoms()): - - if sum(m) == i_degree: - - indices = (idx for idx, p in enumerate(m) for _ in range(p)) - index = sum(idx*(n**level) for level, idx in enumerate(indices)) - - yield (poly_row, poly_col, index), c - - data = dict(gen_value_index()) | collections.defaultdict(float) - - if len(data) > 0: - yield i_degree, data - - return dict(gen_power_mat()) - - -def poly_to_matrix(poly_list, x, power = None): - data_coord_dict = poly_to_data_coord(poly_list, x, power) - - n_var = len(x) - n_poly = len(poly_list) - n_eq = sum((1 for row_eq in poly_list for e in row_eq)) - - def gen_power_mat(): - if 0 not in data_coord_dict: - yield 0, np.zeros((n_var, 1)) - - # for all powers generate a matrix - for degree, data_coord in data_coord_dict.items(): - - # empty matrix - shape = (n_eq, n_var**degree) - - # fill matrix - if len(data_coord) == 0: - yield np.zeros((len(poly_list), n_var**degree)) - - else: - def gen_row_col_coord(): - for (p_row, p_col, index), value in data_coord.items(): - yield p_row + p_col * n_poly, index, value - - rows, cols, data = list(zip(*gen_row_col_coord())) - sparse_array = scipy.sparse.coo_matrix((data, (rows, cols)), dtype=np.double, shape=shape) - - if degree <= 1: - yield degree, sparse_array.toarray() - else: - yield degree, sparse_array.tocsr() - - return dict(gen_power_mat()) diff --git a/polymatrix/utils.py b/polymatrix/utils.py deleted file mode 100644 index 2234e4a..0000000 --- a/polymatrix/utils.py +++ /dev/null @@ -1,43 +0,0 @@ -import itertools -import scipy.special - - -def monomial_to_index(n_var, monomial): - # return sum(idx*(n_var**level) for level, idx in enumerate(monomial)) - - monomial_perm = itertools.permutations(monomial) - - return set(sum(idx*(n_var**level) for level, idx in enumerate(monomial)) for monomial in monomial_perm) - - -# def variable_to_index(n_var, combination): -# """ -# example: -# expr = x1 * x3**2 -# n_var = 3 -# combination = (2, 2, 0) - -# returns 5 -# """ - -# def gen_index_sum(): -# for k, x in enumerate(combination): -# yield scipy.special.binom(n_var+k-1, k+1) - scipy.special.binom(n_var+k-1-x, k+1) - -# return int(sum(gen_index_sum())) - - -# def variable_powers_to_index(powers): -# """ -# example: -# expr = x1 * x3**2 -# powers = (1, 0, 2) - -# returns 5 -# """ - -# n_var = len(powers) - -# indices = sorted((idx for idx, p in enumerate(powers) for _ in range(p)), reverse=True) - -# return variable_to_index(n_var, indices) \ No newline at end of file diff --git a/setup.py b/setup.py index e2da6c2..3188bd3 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,28 @@ -from setuptools import setup +from setuptools import setup, find_packages +from os import path + + +here = path.abspath(path.dirname(__file__)) + +# Get the long description from the README file +with open(path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() setup( - name='polymatrix' + name='polymatrix', + version='0.0.1a1', + install_requires=['dataclass-abc'], + description='A library to represent and manipulate multivariate polynomials', + long_description=long_description, + long_description_content_type='text/markdown', + url='https://gitlab.nccr-automation.ch/michael.schneeberger/polysolver', + author='Michael Schneeberger', + author_email='michael.schneeberger@fhnw.com', + classifiers=[ + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 3.10', + ], + keywords=['multivariate polynomial'], + packages=find_packages(include=['polymatrix', 'polymatrix.*']), + python_requires='>=3.10', ) \ No newline at end of file diff --git a/test_polymatrix/test_expression/test_addition.py b/test_polymatrix/test_expression/test_addition.py index 623b13f..6c8a9a2 100644 --- a/test_polymatrix/test_expression/test_addition.py +++ b/test_polymatrix/test_expression/test_addition.py @@ -1,7 +1,7 @@ import unittest from polymatrix.expression.init.initadditionexpr import init_addition_expr -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr diff --git a/test_polymatrix/test_expression/test_blockdiag.py b/test_polymatrix/test_expression/test_blockdiag.py index 69141a4..a66935e 100644 --- a/test_polymatrix/test_expression/test_blockdiag.py +++ b/test_polymatrix/test_expression/test_blockdiag.py @@ -1,7 +1,7 @@ import unittest from polymatrix.expression.init.initblockdiagexpr import init_block_diag_expr -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr diff --git a/test_polymatrix/test_expression/test_derivative.py b/test_polymatrix/test_expression/test_derivative.py index a4fc6f6..93c98f4 100644 --- a/test_polymatrix/test_expression/test_derivative.py +++ b/test_polymatrix/test_expression/test_derivative.py @@ -2,7 +2,7 @@ import unittest from polymatrix.expression.init.initderivativeexpr import init_derivative_expr from polymatrix.expression.init.initdivergenceexpr import init_divergence_expr -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initlinearinexpr import init_linear_in_expr diff --git a/test_polymatrix/test_expression/test_divergence.py b/test_polymatrix/test_expression/test_divergence.py index 412dcca..ad25577 100644 --- a/test_polymatrix/test_expression/test_divergence.py +++ b/test_polymatrix/test_expression/test_divergence.py @@ -1,7 +1,7 @@ import unittest from polymatrix.expression.init.initdivergenceexpr import init_divergence_expr -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initlinearinexpr import init_linear_in_expr diff --git a/test_polymatrix/test_expression/test_eval.py b/test_polymatrix/test_expression/test_eval.py index 662322a..9b9454f 100644 --- a/test_polymatrix/test_expression/test_eval.py +++ b/test_polymatrix/test_expression/test_eval.py @@ -1,7 +1,7 @@ import unittest from polymatrix.expression.init.initevalexpr import init_eval_expr -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr diff --git a/test_polymatrix/test_expression/test_linearin.py b/test_polymatrix/test_expression/test_linearin.py index 67f2c3d..53d324a 100644 --- a/test_polymatrix/test_expression/test_linearin.py +++ b/test_polymatrix/test_expression/test_linearin.py @@ -1,6 +1,6 @@ import unittest -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initlinearinexpr import init_linear_in_expr diff --git a/test_polymatrix/test_expression/test_matrixmult.py b/test_polymatrix/test_expression/test_matrixmult.py index 6facb48..12d0584 100644 --- a/test_polymatrix/test_expression/test_matrixmult.py +++ b/test_polymatrix/test_expression/test_matrixmult.py @@ -1,6 +1,6 @@ import unittest from polymatrix.expression.init.initadditionexpr import init_addition_expr -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initmatrixmultexpr import init_matrix_mult_expr diff --git a/test_polymatrix/test_expression/test_quadraticin.py b/test_polymatrix/test_expression/test_quadraticin.py index c340d7f..f25d8be 100644 --- a/test_polymatrix/test_expression/test_quadraticin.py +++ b/test_polymatrix/test_expression/test_quadraticin.py @@ -1,6 +1,6 @@ import unittest -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initquadraticinexpr import init_quadratic_in_expr diff --git a/test_polymatrix/test_expression/test_substitude.py b/test_polymatrix/test_expression/test_substitude.py index 9a6e875..21a8ab5 100644 --- a/test_polymatrix/test_expression/test_substitude.py +++ b/test_polymatrix/test_expression/test_substitude.py @@ -1,6 +1,6 @@ import unittest -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initsubstituteexpr import init_substitute_expr diff --git a/test_polymatrix/test_expression/test_subtractmonomials.py b/test_polymatrix/test_expression/test_subtractmonomials.py index f80f76a..8cd8585 100644 --- a/test_polymatrix/test_expression/test_subtractmonomials.py +++ b/test_polymatrix/test_expression/test_subtractmonomials.py @@ -2,7 +2,7 @@ import unittest from polymatrix.expression.init.initderivativeexpr import init_derivative_expr from polymatrix.expression.init.initdivergenceexpr import init_divergence_expr -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initlinearinexpr import init_linear_in_expr from polymatrix.expression.init.initsubtractmonomialsexpr import init_subtract_monomials_expr diff --git a/test_polymatrix/test_expression/test_sum.py b/test_polymatrix/test_expression/test_sum.py index 48ae073..053e428 100644 --- a/test_polymatrix/test_expression/test_sum.py +++ b/test_polymatrix/test_expression/test_sum.py @@ -1,7 +1,7 @@ import unittest from polymatrix.expression.init.initevalexpr import init_eval_expr -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initsumexpr import init_sum_expr diff --git a/test_polymatrix/test_expression/test_symmetric.py b/test_polymatrix/test_expression/test_symmetric.py index ac5eba6..a93d975 100644 --- a/test_polymatrix/test_expression/test_symmetric.py +++ b/test_polymatrix/test_expression/test_symmetric.py @@ -1,6 +1,6 @@ import unittest -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initquadraticinexpr import init_quadratic_in_expr from polymatrix.expression.init.initsymmetricexpr import init_symmetric_expr diff --git a/test_polymatrix/test_expression/test_toconstant.py b/test_polymatrix/test_expression/test_toconstant.py index 784aeec..f3a0643 100644 --- a/test_polymatrix/test_expression/test_toconstant.py +++ b/test_polymatrix/test_expression/test_toconstant.py @@ -1,6 +1,6 @@ import unittest -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initquadraticinexpr import init_quadratic_in_expr from polymatrix.expression.init.initsymmetricexpr import init_symmetric_expr diff --git a/test_polymatrix/test_expression/test_truncate.py b/test_polymatrix/test_expression/test_truncate.py index e944229..910bd37 100644 --- a/test_polymatrix/test_expression/test_truncate.py +++ b/test_polymatrix/test_expression/test_truncate.py @@ -1,6 +1,6 @@ import unittest -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initquadraticinexpr import init_quadratic_in_expr from polymatrix.expression.init.initsymmetricexpr import init_symmetric_expr diff --git a/test_polymatrix/test_expression/test_vstack.py b/test_polymatrix/test_expression/test_vstack.py index a50267f..8778f8a 100644 --- a/test_polymatrix/test_expression/test_vstack.py +++ b/test_polymatrix/test_expression/test_vstack.py @@ -1,6 +1,6 @@ import unittest -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initvstackexpr import init_v_stack_expr diff --git a/test_polymatrix/test_tomatrixrepr.py b/test_polymatrix/test_tomatrixrepr.py index 7486c8e..181f6fa 100644 --- a/test_polymatrix/test_tomatrixrepr.py +++ b/test_polymatrix/test_tomatrixrepr.py @@ -1,7 +1,7 @@ import unittest import polymatrix -from polymatrix.expression.init.initexpressionstate import init_expression_state +from polymatrix.expressionstate.init.initexpressionstate import init_expression_state from polymatrix.expression.init.initfromtermsexpr import init_from_terms_expr from polymatrix.expression.init.initlinearinexpr import init_linear_in_expr -- cgit v1.2.1