From 7501204e1bd216361a395824d2bff70acc8962da Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 11 Aug 2021 09:30:40 +1000 Subject: [PATCH] Adding documentation to the user-facing class level documentation. --- src/sage/rings/lazy_laurent_series.py | 68 ++++++++++++++++++---- src/sage/rings/lazy_laurent_series_ring.py | 59 +++++++++++++++++-- 2 files changed, 109 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/lazy_laurent_series.py b/src/sage/rings/lazy_laurent_series.py index 073ab4a48b0..24946d6edcd 100644 --- a/src/sage/rings/lazy_laurent_series.py +++ b/src/sage/rings/lazy_laurent_series.py @@ -1158,25 +1158,69 @@ class LazyLaurentSeries(LazySequencesModuleElement, LazyCauchyProductSeries): EXAMPLES:: sage: L. = LazyLaurentSeriesRing(ZZ) - sage: L(lambda i: i, valuation=-3, constant=(-1,3)) - -3*z^-3 - 2*z^-2 - z^-1 + z + 2*z^2 - z^3 - z^4 - z^5 + O(z^6) - sage: L(lambda i: i, valuation=-3, constant=-1, degree=3) - -3*z^-3 - 2*z^-2 - z^-1 + z + 2*z^2 - z^3 - z^4 - z^5 + O(z^6) - :: + We can build a series from a function and specify if the series + eventually takes a constant value:: - sage: f = 1 / (1 - z - z^2); f + sage: f = L(lambda i: i, valuation=-3, constant=-1, degree=3) + sage: f + -3*z^-3 - 2*z^-2 - z^-1 + z + 2*z^2 - z^3 - z^4 - z^5 + O(z^6) + sage: f[-2] + -2 + sage: f[10] + -1 + sage: f[-5] + 0 + + sage: f = L(lambda i: i, valuation=-3) + sage: f + -3*z^-3 - 2*z^-2 - z^-1 + z + 2*z^2 + 3*z^3 + O(z^4) + sage: f[20] + 20 + + Anything that converts into a polynomial can be input, where + we can also specify the valuation or if the series eventually + takes a constant value:: + + sage: L([-5,2,0,5]) + -5 + 2*z + 5*z^3 + sage: L([-5,2,0,5], constant=6) + -5 + 2*z + 5*z^3 + 6*z^4 + 6*z^5 + 6*z^6 + O(z^7) + sage: L([-5,2,0,5], degree=6, constant=6) + -5 + 2*z + 5*z^3 + 6*z^6 + 6*z^7 + 6*z^8 + O(z^9) + sage: L([-5,2,0,5], valuation=-2, degree=3, constant=6) + -5*z^-2 + 2*z^-1 + 5*z + 6*z^3 + 6*z^4 + 6*z^5 + O(z^6) + sage: L([-5,2,0,5], valuation=5) + -5*z^5 + 2*z^6 + 5*z^8 + sage: L({-2:9, 3:4}, constant=2, degree=5) + 9*z^-2 + 4*z^3 + 2*z^5 + 2*z^6 + 2*z^7 + O(z^8) + + We can also perform arithmetic:: + + sage: f = 1 / (1 - z - z^2) + sage: f 1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7) sage: f.coefficient(100) 573147844013817084101 + sage: f = (z^-2 - 1 + 2*z) / (z^-1 - z + 3*z^2) + sage: f + z^-1 - z^2 - z^4 + 3*z^5 + O(z^6) - Lazy Laurent series is picklable:: + However, we may not always be able to know when a result is + exactly a polynomial:: - sage: g = loads(dumps(f)) - sage: g - 1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7) - sage: g == f - True + sage: f * (z^-1 - z + 3*z^2) + z^-2 - 1 + 2*z + O(z^5) + + TESTS:: + + sage: L. = LazyLaurentSeriesRing(ZZ, sparse=True) + sage: f = 1 / (1 - z - z^2) + sage: TestSuite(f).run() + + sage: L. = LazyLaurentSeriesRing(ZZ, sparse=False) + sage: f = 1 / (1 - z - z^2) + sage: TestSuite(f).run() """ def change_ring(self, ring): diff --git a/src/sage/rings/lazy_laurent_series_ring.py b/src/sage/rings/lazy_laurent_series_ring.py index 50eb3f9d397..6d7ee048d23 100644 --- a/src/sage/rings/lazy_laurent_series_ring.py +++ b/src/sage/rings/lazy_laurent_series_ring.py @@ -58,9 +58,9 @@ class LazyLaurentSeriesRing(UniqueRepresentation, Parent): EXAMPLES:: sage: L. = LazyLaurentSeriesRing(QQ) - sage: 1/(1 - z) + sage: 1 / (1 - z) 1 + z + z^2 + z^3 + z^4 + z^5 + z^6 + O(z^7) - sage: 1/(1 - z) == 1/(1 - z) + sage: 1 / (1 - z) == 1 / (1 - z) True sage: L in Fields True @@ -75,17 +75,57 @@ class LazyLaurentSeriesRing(UniqueRepresentation, Parent): sage: e.coefficient(100).parent() Finite Field of size 3 - Generating functions of integer sequences are Laurent series over the - integer ring:: + Series can be defined by specifying a coefficient function + along with a valuation or a degree where after the series + is evenutally constant:: + + sage: R. = QQ[] + sage: L. = LazyLaurentSeriesRing(R) + sage: def coeff(n): + ....: if n < 0: + ....: return -2 + n + ....: if n == 0: + ....: return 6 + ....: return x + y^n + sage: f = L(coeff, valuation=-5) + sage: f + -7*z^-5 - 6*z^-4 - 5*z^-3 - 4*z^-2 - 3*z^-1 + 6 + (x + y)*z + O(z^2) + sage: 1 / (1 - f) + 1/7*z^5 - 6/49*z^6 + 1/343*z^7 + 8/2401*z^8 + 64/16807*z^9 + + 17319/117649*z^10 + (1/49*x + 1/49*y - 180781/823543)*z^11 + O(z^12) + sage: L(coeff, valuation=-3, degree=3, constant=x) + -5*z^-3 - 4*z^-2 - 3*z^-1 + 6 + (x + y)*z + (y^2 + x)*z^2 + + x*z^3 + x*z^4 + x*z^5 + O(z^6) + + Similarly, we can specify a polynomial or the initial + coefficients with anything that converts into the + corresponding Laurent polynomial ring:: + + sage: L([1, x, y, 0, x+y]) + 1 + x*z + y*z^2 + (x + y)*z^4 + sage: L([1, x, y, 0, x+y], constant=2) + 1 + x*z + y*z^2 + (x + y)*z^4 + 2*z^5 + 2*z^6 + 2*z^7 + O(z^8) + sage: L([1, x, y, 0, x+y], degree=7, constant=2) + 1 + x*z + y*z^2 + (x + y)*z^4 + 2*z^7 + 2*z^8 + 2*z^9 + O(z^10) + sage: L([1, x, y, 0, x+y], valuation=-2) + z^-2 + x*z^-1 + y + (x + y)*z^2 + sage: L([1, x, y, 0, x+y], valuation=-2, constant=3) + z^-2 + x*z^-1 + y + (x + y)*z^2 + 3*z^3 + 3*z^4 + 3*z^5 + O(z^6) + sage: L([1, x, y, 0, x+y], valuation=-2, degree=4, constant=3) + z^-2 + x*z^-1 + y + (x + y)*z^2 + 3*z^4 + 3*z^5 + 3*z^6 + O(z^7) + + Generating functions of integer sequences are Laurent series + over the integer ring:: sage: L. = LazyLaurentSeriesRing(ZZ); L Lazy Laurent Series Ring in z over Integer Ring sage: L in Fields False - sage: 1/(1 - 2*z)^3 + sage: 1 / (1 - 2*z)^3 1 + 6*z + 24*z^2 + 80*z^3 + 240*z^4 + 672*z^5 + 1792*z^6 + O(z^7) - Power series can be defined recursively:: + Power series can be defined recursively (see :meth:`define()` for + more examples):: sage: L. = LazyLaurentSeriesRing(ZZ) sage: s = L(None) @@ -370,6 +410,13 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No ... ValueError: constant may only be specified if the degree is specified + We support the old input format for ``constant``:: + + sage: f = L(lambda i: i, valuation=-3, constant=-1, degree=3) + sage: g = L(lambda i: i, valuation=-3, constant=(-1,3)) + sage: f == g + True + .. TODO:: Add a method to change the sparse/dense implementation.