From 6fc66f1e4329877fa48965c1f0e52d234ee3af15 Mon Sep 17 00:00:00 2001 From: Michael Schneeberger Date: Wed, 29 Mar 2023 13:46:51 +0200 Subject: add operator to convert vector to symmetric matrix and back --- polymatrix/expression/fromsymmetricmatrixexpr.py | 4 ++ .../expression/impl/fromsymmetricmatrixexprimpl.py | 8 +++ .../expression/impl/tosymmetricmatrixexprimpl.py | 8 +++ .../expression/init/initfromsymmetricmatrixexpr.py | 10 ++++ .../expression/init/inittosymmetricmatrixexpr.py | 10 ++++ .../mixins/fromsymmetricmatrixexprmixin.py | 44 +++++++++++++++ .../mixins/tosymmetricmatrixexprmixin.py | 62 ++++++++++++++++++++++ polymatrix/expression/tosymmetricmatrixexpr.py | 4 ++ 8 files changed, 150 insertions(+) create mode 100644 polymatrix/expression/fromsymmetricmatrixexpr.py create mode 100644 polymatrix/expression/impl/fromsymmetricmatrixexprimpl.py create mode 100644 polymatrix/expression/impl/tosymmetricmatrixexprimpl.py create mode 100644 polymatrix/expression/init/initfromsymmetricmatrixexpr.py create mode 100644 polymatrix/expression/init/inittosymmetricmatrixexpr.py create mode 100644 polymatrix/expression/mixins/fromsymmetricmatrixexprmixin.py create mode 100644 polymatrix/expression/mixins/tosymmetricmatrixexprmixin.py create mode 100644 polymatrix/expression/tosymmetricmatrixexpr.py diff --git a/polymatrix/expression/fromsymmetricmatrixexpr.py b/polymatrix/expression/fromsymmetricmatrixexpr.py new file mode 100644 index 0000000..8ddf2ef --- /dev/null +++ b/polymatrix/expression/fromsymmetricmatrixexpr.py @@ -0,0 +1,4 @@ +from polymatrix.expression.mixins.fromsymmetricmatrixexprmixin import FromSymmetricMatrixExprMixin + +class FromSymmetricMatrixExpr(FromSymmetricMatrixExprMixin): + pass diff --git a/polymatrix/expression/impl/fromsymmetricmatrixexprimpl.py b/polymatrix/expression/impl/fromsymmetricmatrixexprimpl.py new file mode 100644 index 0000000..1c54162 --- /dev/null +++ b/polymatrix/expression/impl/fromsymmetricmatrixexprimpl.py @@ -0,0 +1,8 @@ +import dataclass_abc +from polymatrix.expression.fromsymmetricmatrixexpr import FromSymmetricMatrixExpr + +from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin + +@dataclass_abc.dataclass_abc(frozen=True) +class FromSymmetricMatrixExprImpl(FromSymmetricMatrixExpr): + underlying: ExpressionBaseMixin diff --git a/polymatrix/expression/impl/tosymmetricmatrixexprimpl.py b/polymatrix/expression/impl/tosymmetricmatrixexprimpl.py new file mode 100644 index 0000000..da43157 --- /dev/null +++ b/polymatrix/expression/impl/tosymmetricmatrixexprimpl.py @@ -0,0 +1,8 @@ +import dataclass_abc +from polymatrix.expression.tosymmetricmatrixexpr import ToSymmetricMatrixExpr + +from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin + +@dataclass_abc.dataclass_abc(frozen=True) +class ToSymmetricMatrixExprImpl(ToSymmetricMatrixExpr): + underlying: ExpressionBaseMixin diff --git a/polymatrix/expression/init/initfromsymmetricmatrixexpr.py b/polymatrix/expression/init/initfromsymmetricmatrixexpr.py new file mode 100644 index 0000000..3af7dc3 --- /dev/null +++ b/polymatrix/expression/init/initfromsymmetricmatrixexpr.py @@ -0,0 +1,10 @@ +from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin +from polymatrix.expression.impl.fromsymmetricmatrixexprimpl import FromSymmetricMatrixExprImpl + + +def init_from_symmetric_matrix_expr( + underlying: ExpressionBaseMixin, +): + return FromSymmetricMatrixExprImpl( + underlying=underlying, +) diff --git a/polymatrix/expression/init/inittosymmetricmatrixexpr.py b/polymatrix/expression/init/inittosymmetricmatrixexpr.py new file mode 100644 index 0000000..89fc46c --- /dev/null +++ b/polymatrix/expression/init/inittosymmetricmatrixexpr.py @@ -0,0 +1,10 @@ +from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin +from polymatrix.expression.impl.tosymmetricmatrixexprimpl import ToSymmetricMatrixExprImpl + + +def init_to_symmetric_matrix_expr( + underlying: ExpressionBaseMixin, +): + return ToSymmetricMatrixExprImpl( + underlying=underlying, +) diff --git a/polymatrix/expression/mixins/fromsymmetricmatrixexprmixin.py b/polymatrix/expression/mixins/fromsymmetricmatrixexprmixin.py new file mode 100644 index 0000000..906adf8 --- /dev/null +++ b/polymatrix/expression/mixins/fromsymmetricmatrixexprmixin.py @@ -0,0 +1,44 @@ + +import abc +import dataclasses +import math +from polymatrix.expression.utils.getvariableindices import get_variable_indices_from_variable + +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 FromSymmetricMatrixExprMixin(ExpressionBaseMixin): + @property + @abc.abstractclassmethod + def underlying(self) -> ExpressionBaseMixin: + ... + + # overwrites abstract method of `ExpressionBaseMixin` + def apply( + self, + state: ExpressionStateMixin, + ) -> tuple[ExpressionStateMixin, PolyMatrixMixin]: + + state, underlying = self.underlying.apply(state) + + assert underlying.shape[0] == underlying.shape[1] + + terms = {} + var_index = 0 + + for row in range(underlying.shape[0]): + for col in range(row, underlying.shape[1]): + + terms[var_index, 0] = underlying.get_poly(row, col) + + var_index += 1 + + poly_matrix = init_poly_matrix( + terms=terms, + shape=(var_index, 1), + ) + + return state, poly_matrix \ No newline at end of file diff --git a/polymatrix/expression/mixins/tosymmetricmatrixexprmixin.py b/polymatrix/expression/mixins/tosymmetricmatrixexprmixin.py new file mode 100644 index 0000000..0d8c6ed --- /dev/null +++ b/polymatrix/expression/mixins/tosymmetricmatrixexprmixin.py @@ -0,0 +1,62 @@ + +import abc + +from polymatrix.expression.utils.getvariableindices import get_variable_indices_from_variable +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 ToSymmetricMatrixExprMixin(ExpressionBaseMixin): + @property + @abc.abstractclassmethod + def underlying(self) -> ExpressionBaseMixin: + ... + + # overwrites abstract method of `ExpressionBaseMixin` + def apply( + self, + state: ExpressionStateMixin, + ) -> tuple[ExpressionStateMixin, PolyMatrixMixin]: + + state, underlying = self.underlying.apply(state) + + assert underlying.shape[1] == 1 + + # state, variable_indices = get_variable_indices_from_variable(state, self.underlying) + + def invert_binomial_coefficient(val): + idx = 1 + sum_val = 1 + + while sum_val < val: + idx += 1 + sum_val += idx + + assert sum_val == val, f'{sum_val=}, {val=}' + + return idx + + # n_row = invert_binomial_coefficient(len(variable_indices)) + n_row = invert_binomial_coefficient(underlying.shape[0]) + + terms = {} + var_index = 0 + + for row in range(n_row): + for col in range(row, n_row): + # terms[row, col] = {((variable_indices[var_index], 1),): 1.0} + terms[row, col] = underlying.get_poly(var_index, 0) + + if row != col: + terms[col, row] = terms[row, col] + + var_index += 1 + + poly_matrix = init_poly_matrix( + terms=terms, + shape=(n_row, n_row), + ) + + return state, poly_matrix diff --git a/polymatrix/expression/tosymmetricmatrixexpr.py b/polymatrix/expression/tosymmetricmatrixexpr.py new file mode 100644 index 0000000..119e13b --- /dev/null +++ b/polymatrix/expression/tosymmetricmatrixexpr.py @@ -0,0 +1,4 @@ +from polymatrix.expression.mixins.tosymmetricmatrixexprmixin import ToSymmetricMatrixExprMixin + +class ToSymmetricMatrixExpr(ToSymmetricMatrixExprMixin): + pass -- cgit v1.2.1