summaryrefslogtreecommitdiffstats
path: root/polymatrix/expression/mixins/legendreseriesmixin.py
diff options
context:
space:
mode:
Diffstat (limited to 'polymatrix/expression/mixins/legendreseriesmixin.py')
-rw-r--r--polymatrix/expression/mixins/legendreseriesmixin.py62
1 files changed, 62 insertions, 0 deletions
diff --git a/polymatrix/expression/mixins/legendreseriesmixin.py b/polymatrix/expression/mixins/legendreseriesmixin.py
new file mode 100644
index 0000000..3232207
--- /dev/null
+++ b/polymatrix/expression/mixins/legendreseriesmixin.py
@@ -0,0 +1,62 @@
+import abc
+
+from polymatrix.utils.getstacklines import FrameSummary
+from polymatrix.polymatrix.polymatrix import PolyMatrix
+from polymatrix.polymatrix.init.initpolymatrix import init_poly_matrix
+from polymatrix.expressionstate.expressionstate import ExpressionState
+from polymatrix.expression.mixins.expressionbasemixin import ExpressionBaseMixin
+
+
+class LegendreSeriesMixin(ExpressionBaseMixin):
+ @property
+ @abc.abstractmethod
+ def underlying(self) -> tuple[ExpressionBaseMixin]:
+ ...
+
+ @property
+ @abc.abstractmethod
+ def degrees(self) -> tuple[int, ...] | None:
+ ...
+
+ @property
+ @abc.abstractmethod
+ def stack(self) -> tuple[FrameSummary]:
+ ...
+
+ # overwrites abstract method of `ExpressionBaseMixin`
+ def apply(
+ self,
+ state: ExpressionState,
+ ) -> tuple[ExpressionState, PolyMatrix]:
+
+ state, underlying = self.underlying.apply(state)
+
+ if self.degrees is None:
+ degrees = range(underlying.shape[0])
+ else:
+ degrees = self.degrees
+
+ terms = {}
+
+ for degree in degrees:
+ # for degree in self.degree:
+ poly = underlying.get_poly(degree, 0)
+
+ terms[degree, 0] = dict(poly)
+
+ if 2 <= degree:
+ poly = underlying.get_poly(degree - 2, 0)
+ factor = - (degree - 1) / (degree + 1)
+
+ for m, v in poly.items():
+ if m in terms[degree, 0]:
+ terms[degree, 0][m] += v*factor
+ else:
+ terms[degree, 0][m] = v*factor
+
+ poly_matrix = init_poly_matrix(
+ terms=terms,
+ shape=(len(terms), 1),
+ )
+
+ return state, poly_matrix