diff options
15 files changed, 164 insertions, 179 deletions
diff --git a/polymatrix/expression/mixins/combinationsexprmixin.py b/polymatrix/expression/mixins/combinationsexprmixin.py index abbb53d..fdac6f5 100644 --- a/polymatrix/expression/mixins/combinationsexprmixin.py +++ b/polymatrix/expression/mixins/combinationsexprmixin.py @@ -2,7 +2,7 @@ import abc import itertools from typing import Iterable -from polymatrix.polymatrix.utils.multiplypolynomial import multiply_polynomial +from polymatrix.polymatrix.utils import multiply_polynomial from polymatrix.polymatrix.init import init_poly_matrix from polymatrix.polymatrix.abc import PolyMatrix from polymatrix.expressionstate import ExpressionState diff --git a/polymatrix/expression/mixins/elemmultexprmixin.py b/polymatrix/expression/mixins/elemmultexprmixin.py index 6ef97a3..c7fbb7f 100644 --- a/polymatrix/expression/mixins/elemmultexprmixin.py +++ b/polymatrix/expression/mixins/elemmultexprmixin.py @@ -9,7 +9,7 @@ from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin from polymatrix.polymatrix.mixins import PolyMatrixMixin from polymatrix.polymatrix.abc import PolyMatrix from polymatrix.expressionstate import ExpressionState -from polymatrix.polymatrix.utils.mergemonomialindices import merge_monomial_indices +from polymatrix.polymatrix.utils import merge_monomial_indices class ElemMultExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/linearmonomialsexprmixin.py b/polymatrix/expression/mixins/linearmonomialsexprmixin.py index 076cbb1..1d1982e 100644 --- a/polymatrix/expression/mixins/linearmonomialsexprmixin.py +++ b/polymatrix/expression/mixins/linearmonomialsexprmixin.py @@ -5,10 +5,8 @@ from polymatrix.polymatrix.init import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin from polymatrix.expressionstate import ExpressionState from polymatrix.polymatrix.mixins import PolyMatrixMixin -from polymatrix.expression.utils.getvariableindices import ( - get_variable_indices_from_variable, -) -from polymatrix.polymatrix.utils.sortmonomials import sort_monomials +from polymatrix.expression.utils.getvariableindices import get_variable_indices_from_variable +from polymatrix.polymatrix.utils import sort_monomials class LinearMonomialsExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/matrixmultexprmixin.py b/polymatrix/expression/mixins/matrixmultexprmixin.py index 10f5737..9d5b687 100644 --- a/polymatrix/expression/mixins/matrixmultexprmixin.py +++ b/polymatrix/expression/mixins/matrixmultexprmixin.py @@ -5,7 +5,7 @@ from polymatrix.polymatrix.init import init_poly_matrix from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin from polymatrix.polymatrix.abc import PolyMatrix from polymatrix.expressionstate import ExpressionState -from polymatrix.polymatrix.utils.multiplypolynomial import multiply_polynomial +from polymatrix.polymatrix.utils import multiply_polynomial from polymatrix.utils.tooperatorexception import to_operator_exception diff --git a/polymatrix/expression/mixins/productexprmixin.py b/polymatrix/expression/mixins/productexprmixin.py index 9db1b9c..08e35ed 100644 --- a/polymatrix/expression/mixins/productexprmixin.py +++ b/polymatrix/expression/mixins/productexprmixin.py @@ -1,9 +1,8 @@ import abc import itertools -import typing from polymatrix.polymatrix.index import PolynomialData -from polymatrix.polymatrix.utils.multiplypolynomial import multiply_polynomial +from polymatrix.polymatrix.utils import multiply_polynomial from polymatrix.utils.getstacklines import FrameSummary from polymatrix.polymatrix.init import init_poly_matrix diff --git a/polymatrix/expression/mixins/quadraticinexprmixin.py b/polymatrix/expression/mixins/quadraticinexprmixin.py index cba2844..a74f58e 100644 --- a/polymatrix/expression/mixins/quadraticinexprmixin.py +++ b/polymatrix/expression/mixins/quadraticinexprmixin.py @@ -9,7 +9,7 @@ from polymatrix.expression.utils.getmonomialindices import get_monomial_indices from polymatrix.expression.utils.getvariableindices import ( get_variable_indices_from_variable, ) -from polymatrix.polymatrix.utils.splitmonomialindices import split_monomial_indices +from polymatrix.polymatrix.utils import split_monomial_indices from polymatrix.utils.getstacklines import FrameSummary from polymatrix.utils.tooperatorexception import to_operator_exception diff --git a/polymatrix/expression/mixins/quadraticmonomialsexprmixin.py b/polymatrix/expression/mixins/quadraticmonomialsexprmixin.py index 3ce3b85..635bd23 100644 --- a/polymatrix/expression/mixins/quadraticmonomialsexprmixin.py +++ b/polymatrix/expression/mixins/quadraticmonomialsexprmixin.py @@ -8,7 +8,7 @@ from polymatrix.polymatrix.mixins import PolyMatrixMixin from polymatrix.expression.utils.getvariableindices import ( get_variable_indices_from_variable, ) -from polymatrix.polymatrix.utils.splitmonomialindices import split_monomial_indices +from polymatrix.polymatrix.utils import split_monomial_indices class QuadraticMonomialsExprMixin(ExpressionBaseMixin): diff --git a/polymatrix/expression/mixins/subtractmonomialsexprmixin.py b/polymatrix/expression/mixins/subtractmonomialsexprmixin.py index 3efb656..b5b4c55 100644 --- a/polymatrix/expression/mixins/subtractmonomialsexprmixin.py +++ b/polymatrix/expression/mixins/subtractmonomialsexprmixin.py @@ -6,8 +6,8 @@ from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin from polymatrix.expressionstate import ExpressionState from polymatrix.polymatrix.mixins import PolyMatrixMixin from polymatrix.expression.utils.getmonomialindices import get_monomial_indices -from polymatrix.polymatrix.utils.sortmonomials import sort_monomials -from polymatrix.polymatrix.utils.subtractmonomialindices import ( +from polymatrix.polymatrix.utils import ( + sort_monomials, SubtractError, subtract_monomial_indices, ) diff --git a/polymatrix/polymatrix/utils.py b/polymatrix/polymatrix/utils.py new file mode 100644 index 0000000..289302a --- /dev/null +++ b/polymatrix/polymatrix/utils.py @@ -0,0 +1,154 @@ +import itertools +import math + +from polymatrix.polymatrix.index import MonomialData, MonomialIndex, PolyDict +from polymatrix.utils.deprecation import deprecated + + + +# NP: this is a werid case of the product +# NP: merge is not intutive IMHO, find better name +@deprecated("Replaced by MonomialIndex.product") +def merge_monomial_indices( + monomials: tuple[MonomialIndex, ...], +) -> MonomialIndex: + """ + (x1**2 x2, x2**2) -> x1**2 x2**3 + + or in terms of indices {x1: 0, x2: 1}: + + ( + ((0, 2), (1, 1)), # x1**2 x2 + ((1, 2),) # x2**2 + ) -> ((0, 2), (1, 3)) # x1**1 x2**3 + """ + if len(monomials) == 0: + return MonomialIndex.empty() + + elif len(monomials) == 1: + return monomials[0] + + else: + m1_dict = dict(monomials[0]) + + for other in monomials[1:]: + for index, count in other: + if index in m1_dict: + m1_dict[index] += count + else: + m1_dict[index] = count + + # sort monomials according to their index + # ((1, 3), (0, 2)) -> ((0, 2), (1, 3)) + return sort_monomial_indices(m1_dict.items()) + + +# NP: compute index of product of polynomials +@deprecated("Replaced by PolyDict.product") +def multiply_polynomial( + left: PolyDict, + right: PolyDict, + result: PolyDict, +) -> None: + """ + Multiplies two polynomials `left` and `right` and adds the result to the mutable polynomial `result`. + """ + + for (left_monomial, left_value), (right_monomial, right_value) in itertools.product( + left.items(), right.items() + ): + value = left_value * right_value + + if math.isclose(value, 0, abs_tol=1e-12): + continue + + monomial = merge_monomial_indices((left_monomial, right_monomial)) + + if monomial not in result: + result[monomial] = 0 + + result[monomial] += value + + if math.isclose(result[monomial], 0, abs_tol=1e-12): + del result[monomial] + + +# NP: sort mononial indices with respect to variable index in state object + +@deprecated("With new index types you can use sorted() on MonomialIndex") +def sort_monomial_indices( + monomial: MonomialData, +) -> MonomialData: + return tuple( + sorted( + monomial, + key=lambda m: m[0], + ) + ) + +# NP: Sort list of monomials according to ... what? +def sort_monomials( + monomials: tuple[MonomialData], +) -> tuple[MonomialData]: + return tuple( + sorted( + monomials, + key=lambda m: (sum(count for _, count in m), len(m), m), + ) + ) + + +# NP: what does this function do? split according to what? +def split_monomial_indices( + monomial: MonomialData, +) -> tuple[MonomialData, MonomialData]: + left = [] + right = [] + + is_left = True + + for idx, count in monomial: + count_left = count // 2 + + if count % 2: + if is_left: + count_left = count_left + 1 + + is_left = not is_left + + count_right = count - count_left + + if 0 < count_left: + left.append((idx, count_left)) + + if 0 < count_right: + right.append((idx, count - count_left)) + + return tuple(left), tuple(right) + +# NP: consider making a module containing all exceptions +class SubtractError(Exception): + pass + + +# NP: set difference / division of polynomials? +# NP: name is very confusing, find better name once is clear what it does +def subtract_monomial_indices( + m1: MonomialData, + m2: MonomialData, +) -> MonomialData: + m1_dict = dict(m1) + + for index, count in m2: + if index not in m1_dict: + raise SubtractError() + + m1_dict[index] -= count + + if m1_dict[index] == 0: + del m1_dict[index] + + elif m1_dict[index] < 0: + raise SubtractError() + + return sort_monomial_indices(m1_dict.items()) diff --git a/polymatrix/polymatrix/utils/mergemonomialindices.py b/polymatrix/polymatrix/utils/mergemonomialindices.py deleted file mode 100644 index c84a59c..0000000 --- a/polymatrix/polymatrix/utils/mergemonomialindices.py +++ /dev/null @@ -1,40 +0,0 @@ -from polymatrix.polymatrix.index import MonomialIndex -from polymatrix.polymatrix.utils.sortmonomialindices import sort_monomial_indices -from polymatrix.utils.deprecation import deprecated - - -# NP: this is a werid case of the product -# NP: merge is not intutive IMHO, find better name -@deprecated("Replaced by MonomialIndex.product") -def merge_monomial_indices( - monomials: tuple[MonomialIndex, ...], -) -> MonomialIndex: - """ - (x1**2 x2, x2**2) -> x1**2 x2**3 - - or in terms of indices {x1: 0, x2: 1}: - - ( - ((0, 2), (1, 1)), # x1**2 x2 - ((1, 2),) # x2**2 - ) -> ((0, 2), (1, 3)) # x1**1 x2**3 - """ - if len(monomials) == 0: - return MonomialIndex.empty() - - elif len(monomials) == 1: - return monomials[0] - - else: - m1_dict = dict(monomials[0]) - - for other in monomials[1:]: - for index, count in other: - if index in m1_dict: - m1_dict[index] += count - else: - m1_dict[index] = count - - # sort monomials according to their index - # ((1, 3), (0, 2)) -> ((0, 2), (1, 3)) - return sort_monomial_indices(m1_dict.items()) diff --git a/polymatrix/polymatrix/utils/multiplypolynomial.py b/polymatrix/polymatrix/utils/multiplypolynomial.py deleted file mode 100644 index 0199b98..0000000 --- a/polymatrix/polymatrix/utils/multiplypolynomial.py +++ /dev/null @@ -1,36 +0,0 @@ -import itertools -import math - -from polymatrix.polymatrix.utils.mergemonomialindices import merge_monomial_indices -from polymatrix.polymatrix.index import PolyDict -from polymatrix.utils.deprecation import deprecated - - -# NP: compute index of product of polynomials -@deprecated("Replaced by PolyDict.product") -def multiply_polynomial( - left: PolyDict, - right: PolyDict, - result: PolyDict, -) -> None: - """ - Multiplies two polynomials `left` and `right` and adds the result to the mutable polynomial `result`. - """ - - for (left_monomial, left_value), (right_monomial, right_value) in itertools.product( - left.items(), right.items() - ): - value = left_value * right_value - - if math.isclose(value, 0, abs_tol=1e-12): - continue - - monomial = merge_monomial_indices((left_monomial, right_monomial)) - - if monomial not in result: - result[monomial] = 0 - - result[monomial] += value - - if math.isclose(result[monomial], 0, abs_tol=1e-12): - del result[monomial] diff --git a/polymatrix/polymatrix/utils/sortmonomialindices.py b/polymatrix/polymatrix/utils/sortmonomialindices.py deleted file mode 100644 index 5e5b6fe..0000000 --- a/polymatrix/polymatrix/utils/sortmonomialindices.py +++ /dev/null @@ -1,17 +0,0 @@ -from polymatrix.polymatrix.index import MonomialData - - -from polymatrix.utils.deprecation import deprecated - -# NP: sort mononial indices with respect to variable index in state object - -@deprecated("With new index types you can use sorted() on MonomialIndex") -def sort_monomial_indices( - monomial: MonomialData, -) -> MonomialData: - return tuple( - sorted( - monomial, - key=lambda m: m[0], - ) - ) diff --git a/polymatrix/polymatrix/utils/sortmonomials.py b/polymatrix/polymatrix/utils/sortmonomials.py deleted file mode 100644 index 31376d2..0000000 --- a/polymatrix/polymatrix/utils/sortmonomials.py +++ /dev/null @@ -1,12 +0,0 @@ -from polymatrix.polymatrix.index import MonomialData - -# NP: Sort list of monomials according to ... what? -def sort_monomials( - monomials: tuple[MonomialData], -) -> tuple[MonomialData]: - return tuple( - sorted( - monomials, - key=lambda m: (sum(count for _, count in m), len(m), m), - ) - ) diff --git a/polymatrix/polymatrix/utils/splitmonomialindices.py b/polymatrix/polymatrix/utils/splitmonomialindices.py deleted file mode 100644 index c905d15..0000000 --- a/polymatrix/polymatrix/utils/splitmonomialindices.py +++ /dev/null @@ -1,30 +0,0 @@ -from polymatrix.polymatrix.index import MonomialData - - -# NP: what does this function do? split according to what? -def split_monomial_indices( - monomial: MonomialData, -) -> tuple[MonomialData, MonomialData]: - left = [] - right = [] - - is_left = True - - for idx, count in monomial: - count_left = count // 2 - - if count % 2: - if is_left: - count_left = count_left + 1 - - is_left = not is_left - - count_right = count - count_left - - if 0 < count_left: - left.append((idx, count_left)) - - if 0 < count_right: - right.append((idx, count - count_left)) - - return tuple(left), tuple(right) diff --git a/polymatrix/polymatrix/utils/subtractmonomialindices.py b/polymatrix/polymatrix/utils/subtractmonomialindices.py deleted file mode 100644 index e8417ba..0000000 --- a/polymatrix/polymatrix/utils/subtractmonomialindices.py +++ /dev/null @@ -1,31 +0,0 @@ -from polymatrix.polymatrix.index import MonomialData - -from polymatrix.polymatrix.utils.sortmonomialindices import sort_monomial_indices - - -# NP: consider making a module containing all exceptions -class SubtractError(Exception): - pass - - -# NP: set difference / division of polynomials? -# NP: name is very confusing, find better name once is clear what it does -def subtract_monomial_indices( - m1: MonomialData, - m2: MonomialData, -) -> MonomialData: - m1_dict = dict(m1) - - for index, count in m2: - if index not in m1_dict: - raise SubtractError() - - m1_dict[index] -= count - - if m1_dict[index] == 0: - del m1_dict[index] - - elif m1_dict[index] < 0: - raise SubtractError() - - return sort_monomial_indices(m1_dict.items()) |