diff options
-rw-r--r-- | polymatrix/polymatrix/impl.py | 1 | ||||
-rw-r--r-- | polymatrix/polymatrix/init.py | 7 | ||||
-rw-r--r-- | polymatrix/polymatrix/mixins.py | 18 |
3 files changed, 13 insertions, 13 deletions
diff --git a/polymatrix/polymatrix/impl.py b/polymatrix/polymatrix/impl.py index ef92412..85f56bf 100644 --- a/polymatrix/polymatrix/impl.py +++ b/polymatrix/polymatrix/impl.py @@ -22,3 +22,4 @@ class PolyMatrixAsAffineExpressionImpl(PolyMatrixAsAffineExpressionMixin): data: PolyMatrixAsAffineExpressionMixin.MatrixType shape: tuple[int, int] slices: dict[MonomialIndex, PolyMatrixAsAffineExpressionMixin.MatrixType] + degree: int diff --git a/polymatrix/polymatrix/init.py b/polymatrix/polymatrix/init.py index 5c1ff58..af09111 100644 --- a/polymatrix/polymatrix/init.py +++ b/polymatrix/polymatrix/init.py @@ -54,7 +54,7 @@ def init_broadcast_poly_matrix( def to_affine_expression(p: PolyMatrixMixin) -> PolyMatrixAsAffineExpressionMixin: - + """ Convert a polymatrix into a PolyMatrixAsAffineExpressionMixin. """ if isinstance(p, PolyMatrixAsAffineExpressionMixin): return p @@ -76,4 +76,7 @@ def to_affine_expression(p: PolyMatrixMixin) -> PolyMatrixAsAffineExpressionMixi slice = slices[monomial] data[row, slice[col]] += coeff - return PolyMatrixAsAffineExpressionImpl(data, p.shape, slices) + max_degree = max(m.degree for m in slices.keys()) + + return PolyMatrixAsAffineExpressionImpl( + data=data, shape=p.shape, slices=slices, degree=max_degree) diff --git a/polymatrix/polymatrix/mixins.py b/polymatrix/polymatrix/mixins.py index eaaba04..3ca4f66 100644 --- a/polymatrix/polymatrix/mixins.py +++ b/polymatrix/polymatrix/mixins.py @@ -208,7 +208,11 @@ class PolyMatrixAsAffineExpressionMixin( Map from monomial indices to column slices of the big matrix that stores all :math:`A_\alpha`. """ - ... + + @property + @abc.abstractmethod + def degree(self) -> int: + """ Maximal degree of the affine expressions """ @override def at(self, row: int, col: int) -> PolyDict: @@ -317,17 +321,13 @@ class PolyMatrixAsAffineExpressionMixin( return terms - # Get the highest degree we need to compute from the monomial indices - # TODO: this value should be cached - d = max(m.degree for m in self.slices.keys()) - # Add the constant term monomial_values = { MonomialIndex.constant(): 1. } # Compute all monomials and convert key to MonomialIndex - for key, val in compute_with_triangles(d, x).items(): + for key, val in compute_with_triangles(self.degree, x).items(): # See comment above for structure of key # Count occurrences to convert to MonomialIndex new_key: dict[int, int] = {} @@ -385,13 +385,9 @@ class PolyMatrixAsAffineExpressionMixin( raise ValueError(f"The value must be a {q} dimensional, however " f"{x} is {len(x)} dimensional.") - # Get the highest degree we need to compute from the monomial indices - # TODO: this value should be cached - d = max(m.degree for m in self.slices.keys()) - # Compute number of monomials that are generated by that # TODO: this value should be cached - n = sum(math.comb(k + q - 1, k) for k in range(0, d+1)) + n = sum(math.comb(k + q - 1, k) for k in range(0, self.degree+1)) # Heuristic on efficiency, computing all monomials exploits the # structure to reduce the number of computations necessary. But the |