diff --git a/src/sage/rings/lazy_laurent_series.py b/src/sage/rings/lazy_laurent_series.py index 597d37f4bcb..1847f924fd8 100644 --- a/src/sage/rings/lazy_laurent_series.py +++ b/src/sage/rings/lazy_laurent_series.py @@ -148,6 +148,54 @@ def __init__(self, parent, coeff_stream): ModuleElement.__init__(self, parent) self._coeff_stream = coeff_stream + def finite_part(self, degree=None): + r""" + Return ``self`` truncated to ``degree`` as an element of an appropriate ring. + + INPUT: + + - ``degree`` -- ``None`` or an integer + + OUTPUT: + + If ``degree`` is not ``None``, the terms of the series of + degree greater than ``degree`` are removed first. If + ``degree`` is ``None`` and the series is not known to have + only finitely many nonzero coefficients, a ``ValueError`` is + raised. + + EXAMPLES:: + + sage: L. = LazyLaurentSeriesRing(ZZ) + sage: f = L([1,0,0,2,0,0,0,3], valuation=-3); f.finite_part() + z^-3 + 2 + 3*z^4 + sage: f.polynomial() + z^-3 + 2 + 3*z^4 + + sage: L = LazyDirichletSeriesRing(ZZ, "s") + sage: f = L([1,0,0,2,0,0,0,3], valuation=2); f.finite_part() + 3/9^s + 2/5^s + 1/2^s + + sage: L. = LazyTaylorSeriesRing(ZZ) + sage: f = 1/(1+x+y^2); f.finite_part(3) + -x^3 + 2*x*y^2 + x^2 - y^2 - x + 1 + """ + P = self.parent() + L = P._laurent_poly_ring + coeff_stream = self._coeff_stream + if degree is None: + if isinstance(coeff_stream, CoefficientStream_zero): + return L.zero() + elif isinstance(coeff_stream, CoefficientStream_exact) and not coeff_stream._constant: + m = coeff_stream._degree + else: + raise ValueError("not a polynomial") + else: + m = degree + 1 + + v = self.valuation() + return L.sum(self[i]*P.monomial(1, i) for i in range(v, m)) + def __getitem__(self, n): """ Return the coefficient of the term with exponent ``n`` of the series. @@ -618,6 +666,143 @@ def define(self, s): self._coeff_stream._target = s._coeff_stream + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: L. = LazyLaurentSeriesRing(ZZ) + sage: z^-3 + z - 5 + z^-3 - 5 + z + sage: -1/(1 + 2*z) + -1 + 2*z - 4*z^2 + 8*z^3 - 16*z^4 + 32*z^5 - 64*z^6 + O(z^7) + sage: -z^-7/(1 + 2*z) + -z^-7 + 2*z^-6 - 4*z^-5 + 8*z^-4 - 16*z^-3 + 32*z^-2 - 64*z^-1 + O(1) + sage: L([1,5,0,3], valuation=-1, degree=5, constant=2) + z^-1 + 5 + 3*z^2 + 2*z^5 + 2*z^6 + 2*z^7 + O(z^8) + sage: L(constant=5, valuation=2) + 5*z^2 + 5*z^3 + 5*z^4 + O(z^5) + sage: L(constant=5, degree=-2) + 5*z^-2 + 5*z^-1 + 5 + O(z) + sage: L(lambda x: x if x < 0 else 0, valuation=-2) + -2*z^-2 - z^-1 + O(z^5) + sage: L(lambda x: x if x < 0 else 0, valuation=2) + O(z^9) + sage: L(lambda x: x if x > 0 else 0, valuation=-2) + z + 2*z^2 + 3*z^3 + 4*z^4 + O(z^5) + sage: L(lambda x: x if x > 0 else 0, valuation=-10) + O(z^-3) + + sage: L(None) + Uninitialized Lazy Laurent Series + sage: L(0) + 0 + + sage: R. = QQ[] + sage: L. = LazyLaurentSeriesRing(R) + sage: z^-2 / (1 - (x-y)*z) + x^4*z^-3 + (1-y)*z^-4 + (-y + 1)*z^-4 + x^4*z^-3 + z^-2 + (x - y)*z^-1 + + (x^2 - 2*x*y + y^2) + (x^3 - 3*x^2*y + 3*x*y^2 - y^3)*z + + (x^4 - 4*x^3*y + 6*x^2*y^2 - 4*x*y^3 + y^4)*z^2 + O(z^3) + """ + if isinstance(self._coeff_stream, CoefficientStream_zero): + return '0' + if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: + return 'Uninitialized Lazy Laurent Series' + return self._format_series(repr) + + def _latex_(self): + r""" + Return a latex representation of ``self``. + + EXAMPLES:: + + sage: L. = LazyLaurentSeriesRing(ZZ) + sage: latex(z^-3 + z - 5) + \frac{1}{z^{3}} - 5 + z + sage: latex(-1/(1 + 2*z)) + -1 + 2z - 4z^{2} + 8z^{3} - 16z^{4} + 32z^{5} - 64z^{6} + O(z^{7}) + sage: latex(-z^-7/(1 + 2*z)) + \frac{-1}{z^{7}} + \frac{2}{z^{6}} + \frac{-4}{z^{5}} + \frac{8}{z^{4}} + + \frac{-16}{z^{3}} + \frac{32}{z^{2}} + \frac{-64}{z} + O(1) + sage: latex(L([1,5,0,3], valuation=-1, degree=5, constant=2)) + \frac{1}{z} + 5 + 3z^{2} + 2z^{5} + 2z^{6} + 2z^{7} + O(z^{8}) + sage: latex(L(constant=5, valuation=2)) + 5z^{2} + 5z^{3} + 5z^{4} + O(z^{5}) + sage: latex(L(constant=5, degree=-2)) + \frac{5}{z^{2}} + \frac{5}{z} + 5 + O(z) + sage: latex(L(lambda x: x if x < 0 else 0, valuation=-2)) + \frac{-2}{z^{2}} + \frac{-1}{z} + O(z^{5}) + sage: latex(L(lambda x: x if x < 0 else 0, valuation=2)) + O(z^{9}) + sage: latex(L(lambda x: x if x > 0 else 0, valuation=-2)) + z + 2z^{2} + 3z^{3} + 4z^{4} + O(z^{5}) + sage: latex(L(lambda x: x if x > 0 else 0, valuation=-10)) + O(\frac{1}{z^{3}}) + + sage: latex(L(None)) + \text{\texttt{Undef}} + sage: latex(L(0)) + 0 + + sage: R. = QQ[] + sage: L. = LazyLaurentSeriesRing(R) + sage: latex(z^-2 / (1 - (x-y)*z) + x^4*z^-3 + (1-y)*z^-4) + \frac{-y + 1}{z^{4}} + \frac{x^{4}}{z^{3}} + \frac{1}{z^{2}} + + \frac{x - y}{z} + x^{2} - 2 x y + y^{2} + + \left(x^{3} - 3 x^{2} y + 3 x y^{2} - y^{3}\right)z + + \left(x^{4} - 4 x^{3} y + 6 x^{2} y^{2} - 4 x y^{3} + y^{4}\right)z^{2} + + O(z^{3}) + """ + from sage.misc.latex import latex + if isinstance(self._coeff_stream, CoefficientStream_zero): + return latex('0') + if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: + return latex("Undef") + return self._format_series(latex) + + def _ascii_art_(self): + r""" + Return an ascii art representation of ``self``. + + EXAMPLES:: + + sage: e = SymmetricFunctions(QQ).e() + sage: L. = LazyLaurentSeriesRing(e) + sage: L.options.display_length = 3 + sage: ascii_art(1 / (1 - e[1]*z)) + e[] + e[1]*z + e[1, 1]*z^2 + O(e[]*z^3) + sage: L.options._reset() + """ + from sage.typeset.ascii_art import ascii_art, AsciiArt + if isinstance(self._coeff_stream, CoefficientStream_zero): + return AsciiArt('0') + if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: + return AsciiArt('Uninitialized Lazy Laurent Series') + return self._format_series(ascii_art, True) + + def _unicode_art_(self): + r""" + Return a unicode art representation of ``self``. + + EXAMPLES:: + + sage: e = SymmetricFunctions(QQ).e() + sage: L. = LazyLaurentSeriesRing(e) + sage: L.options.display_length = 3 + sage: unicode_art(1 / (1 - e[1]*z)) + e[] + e[1]*z + e[1, 1]*z^2 + O(e[]*z^3) + sage: L.options._reset() + """ + from sage.typeset.unicode_art import unicode_art, UnicodeArt + if isinstance(self._coeff_stream, CoefficientStream_zero): + return UnicodeArt('0') + if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: + return UnicodeArt('Uninitialized Lazy Laurent Series') + return self._format_series(unicode_art, True) + + class LazySequencesModuleElement(LazySequenceElement): r""" A lazy series where addition and scalar multiplication @@ -891,7 +1076,7 @@ def _lmul_(self, scalar): Similarly for Dirichlet series:: sage: L = LazyDirichletSeriesRing(ZZ, "z") - sage: g = L.gen(1) + sage: g = L.gen(2) sage: 2*g 2/2^z sage: -1*g @@ -1009,7 +1194,7 @@ class LazyCauchyProductSeries(RingElement): """ def __init__(self, parent): RingElement.__init__(self, parent) - + def _mul_(self, other): """ Return the product of this series with ``other``. @@ -1162,7 +1347,7 @@ def _div_(self, other): return P.zero() right = other._coeff_stream return P.element_class(P, CoefficientStream_cauchy_product(left, CoefficientStream_cauchy_inverse(right))) - + def __pow__(self, n): """ Return the ``n``-th power of the series. @@ -1839,142 +2024,6 @@ def _format_series(self, formatter, format_strings=False): return strformat("O({})".format(formatter(z**m))) return formatter(poly) + strformat(" + O({})".format(formatter(z**m))) - def _repr_(self): - r""" - Return a string representation of ``self``. - - EXAMPLES:: - - sage: L. = LazyLaurentSeriesRing(ZZ) - sage: z^-3 + z - 5 - z^-3 - 5 + z - sage: -1/(1 + 2*z) - -1 + 2*z - 4*z^2 + 8*z^3 - 16*z^4 + 32*z^5 - 64*z^6 + O(z^7) - sage: -z^-7/(1 + 2*z) - -z^-7 + 2*z^-6 - 4*z^-5 + 8*z^-4 - 16*z^-3 + 32*z^-2 - 64*z^-1 + O(1) - sage: L([1,5,0,3], valuation=-1, degree=5, constant=2) - z^-1 + 5 + 3*z^2 + 2*z^5 + 2*z^6 + 2*z^7 + O(z^8) - sage: L(constant=5, valuation=2) - 5*z^2 + 5*z^3 + 5*z^4 + O(z^5) - sage: L(constant=5, degree=-2) - 5*z^-2 + 5*z^-1 + 5 + O(z) - sage: L(lambda x: x if x < 0 else 0, valuation=-2) - -2*z^-2 - z^-1 + O(z^5) - sage: L(lambda x: x if x < 0 else 0, valuation=2) - O(z^9) - sage: L(lambda x: x if x > 0 else 0, valuation=-2) - z + 2*z^2 + 3*z^3 + 4*z^4 + O(z^5) - sage: L(lambda x: x if x > 0 else 0, valuation=-10) - O(z^-3) - - sage: L(None) - Uninitialized Lazy Laurent Series - sage: L(0) - 0 - - sage: R. = QQ[] - sage: L. = LazyLaurentSeriesRing(R) - sage: z^-2 / (1 - (x-y)*z) + x^4*z^-3 + (1-y)*z^-4 - (-y + 1)*z^-4 + x^4*z^-3 + z^-2 + (x - y)*z^-1 - + (x^2 - 2*x*y + y^2) + (x^3 - 3*x^2*y + 3*x*y^2 - y^3)*z - + (x^4 - 4*x^3*y + 6*x^2*y^2 - 4*x*y^3 + y^4)*z^2 + O(z^3) - """ - if isinstance(self._coeff_stream, CoefficientStream_zero): - return '0' - if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: - return 'Uninitialized Lazy Laurent Series' - return self._format_series(repr) - - def _latex_(self): - r""" - Return a latex representation of ``self``. - - EXAMPLES:: - - sage: L. = LazyLaurentSeriesRing(ZZ) - sage: latex(z^-3 + z - 5) - \frac{1}{z^{3}} - 5 + z - sage: latex(-1/(1 + 2*z)) - -1 + 2z - 4z^{2} + 8z^{3} - 16z^{4} + 32z^{5} - 64z^{6} + O(z^{7}) - sage: latex(-z^-7/(1 + 2*z)) - \frac{-1}{z^{7}} + \frac{2}{z^{6}} + \frac{-4}{z^{5}} + \frac{8}{z^{4}} - + \frac{-16}{z^{3}} + \frac{32}{z^{2}} + \frac{-64}{z} + O(1) - sage: latex(L([1,5,0,3], valuation=-1, degree=5, constant=2)) - \frac{1}{z} + 5 + 3z^{2} + 2z^{5} + 2z^{6} + 2z^{7} + O(z^{8}) - sage: latex(L(constant=5, valuation=2)) - 5z^{2} + 5z^{3} + 5z^{4} + O(z^{5}) - sage: latex(L(constant=5, degree=-2)) - \frac{5}{z^{2}} + \frac{5}{z} + 5 + O(z) - sage: latex(L(lambda x: x if x < 0 else 0, valuation=-2)) - \frac{-2}{z^{2}} + \frac{-1}{z} + O(z^{5}) - sage: latex(L(lambda x: x if x < 0 else 0, valuation=2)) - O(z^{9}) - sage: latex(L(lambda x: x if x > 0 else 0, valuation=-2)) - z + 2z^{2} + 3z^{3} + 4z^{4} + O(z^{5}) - sage: latex(L(lambda x: x if x > 0 else 0, valuation=-10)) - O(\frac{1}{z^{3}}) - - sage: latex(L(None)) - \text{\texttt{Undef}} - sage: latex(L(0)) - 0 - - sage: R. = QQ[] - sage: L. = LazyLaurentSeriesRing(R) - sage: latex(z^-2 / (1 - (x-y)*z) + x^4*z^-3 + (1-y)*z^-4) - \frac{-y + 1}{z^{4}} + \frac{x^{4}}{z^{3}} + \frac{1}{z^{2}} - + \frac{x - y}{z} + x^{2} - 2 x y + y^{2} - + \left(x^{3} - 3 x^{2} y + 3 x y^{2} - y^{3}\right)z - + \left(x^{4} - 4 x^{3} y + 6 x^{2} y^{2} - 4 x y^{3} + y^{4}\right)z^{2} - + O(z^{3}) - """ - from sage.misc.latex import latex - if isinstance(self._coeff_stream, CoefficientStream_zero): - return latex('0') - if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: - return latex("Undef") - return self._format_series(latex) - - def _ascii_art_(self): - r""" - Return an ascii art representation of ``self``. - - EXAMPLES:: - - sage: e = SymmetricFunctions(QQ).e() - sage: L. = LazyLaurentSeriesRing(e) - sage: L.options.display_length = 3 - sage: ascii_art(1 / (1 - e[1]*z)) - e[] + e[1]*z + e[1, 1]*z^2 + O(e[]*z^3) - sage: L.options._reset() - """ - from sage.typeset.ascii_art import ascii_art, AsciiArt - if isinstance(self._coeff_stream, CoefficientStream_zero): - return AsciiArt('0') - if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: - return AsciiArt('Uninitialized Lazy Laurent Series') - return self._format_series(ascii_art, True) - - def _unicode_art_(self): - r""" - Return a unicode art representation of ``self``. - - EXAMPLES:: - - sage: e = SymmetricFunctions(QQ).e() - sage: L. = LazyLaurentSeriesRing(e) - sage: L.options.display_length = 3 - sage: unicode_art(1 / (1 - e[1]*z)) - e[] + e[1]*z + e[1, 1]*z^2 + O(e[]*z^3) - sage: L.options._reset() - """ - from sage.typeset.unicode_art import unicode_art, UnicodeArt - if isinstance(self._coeff_stream, CoefficientStream_zero): - return UnicodeArt('0') - if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: - return UnicodeArt('Uninitialized Lazy Laurent Series') - return self._format_series(unicode_art, True) - class LazyTaylorSeries(LazySequencesModuleElement, LazyCauchyProductSeries): r""" @@ -2026,44 +2075,40 @@ def change_ring(self, ring): Q = LazyTaylorSeriesRing(ring, names=self.parent().variable_names()) return Q.element_class(Q, self._coeff_stream) - def _repr_(self): + def _format_series(self, formatter, format_strings=False): """ - Return the string representation of this Taylor series. + Return nonzero ``self`` formatted by ``formatter``. TESTS:: - sage: L. = LazyTaylorSeriesRing(ZZ) - sage: -1/(1 + 2*z) - -1 + 2*z + -4*z^2 + 8*z^3 + -16*z^4 + 32*z^5 + -64*z^6 + ... - """ - if isinstance(self._coeff_stream, CoefficientStream_zero): - return '0' - if isinstance(self._coeff_stream, CoefficientStream_uninitialized) and self._coeff_stream._target is None: - return 'Uninitialized Lazy Taylor Series' - - atomic_repr = self.base_ring()._repr_option('element_is_atomic') - X = self.parent().variable_name() - v = self._coeff_stream._approximate_valuation + sage: L. = LazyTaylorSeriesRing(QQ) + sage: f = 1 / (2 - x^2 - y) + sage: f._format_series(ascii_art, True) - if not isinstance(self._coeff_stream, CoefficientStream_exact): - m = v + 7 # long enough + """ + if format_strings: + strformat = formatter else: - m = self._coeff_stream._degree + 3 + strformat = lambda x: x - R = self.parent()._poly_ring - if len(self.parent().variable_names()) == 1: - z = R.gen() - ret = " + ".join([repr(self[i] * z**i) for i in range(v, m) - if self[i]]) + P = self.parent() + cs = self._coeff_stream + v = cs._approximate_valuation + if isinstance(cs, CoefficientStream_exact): + if not cs._constant: + m = cs._degree + else: + m = cs._degree + P.options.constant_length else: - ret = " + ".join([repr(self[i]) for i in range(v, m) - if self[i]]) - if not ret: - return "0" - # TODO: Better handling when ret == 0 but we have not checked up to the constant term - if isinstance(self._coeff_stream, CoefficientStream_exact) and not self._coeff_stream._constant: - return ret - return ret + ' + ...' + m = v + P.options.display_length + + # atomic_repr = P._coeff_ring._repr_option('element_is_atomic') + + poly = [formatter(P.monomial(self[i], i)) for i in range(v, m) if self[i]] + poly = " + ".join(poly) + if isinstance(cs, CoefficientStream_exact) and not cs._constant: + return poly + return poly + strformat(" + O({})".format(formatter(P.monomial(1, m)))) class LazyDirichletSeries(LazySequencesModuleElement): diff --git a/src/sage/rings/lazy_laurent_series_ring.py b/src/sage/rings/lazy_laurent_series_ring.py index d12bf5e2ae3..e7957cc70a5 100644 --- a/src/sage/rings/lazy_laurent_series_ring.py +++ b/src/sage/rings/lazy_laurent_series_ring.py @@ -84,6 +84,7 @@ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing, LaurentPolynomialRing_generic from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.structure.global_options import GlobalOptions +from sage.symbolic.ring import SR from .lazy_laurent_series import LazyLaurentSeries, LazyDirichletSeries, LazyTaylorSeries @@ -168,6 +169,22 @@ def is_sparse(self): """ return self._sparse + @cached_method + def monomial(self, c, n): + r""" + Return the interpretation of the coefficient ``c`` at index ``n``. + + EXAMPLES:: + + sage: L = LazyLaurentSeriesRing(ZZ, 'z') + sage: L.monomial(1, 3) + z^3 + sage: L.monomial(2, -4) + 2*z^-4 + """ + L = self._laurent_poly_ring + return L(c) * L.gen() ** n + @cached_method def gen(self, n=0): r""" @@ -556,11 +573,11 @@ def __init__(self, base_ring, names, sparse=False, category=None): sage: TestSuite(L).run(skip='_test_elements') """ self._sparse = sparse - self._poly_ring = PolynomialRing(base_ring, names) if len(names) == 1: self._coeff_ring = base_ring else: self._coeff_ring = PolynomialRing(base_ring, names) + self._laurent_poly_ring = PolynomialRing(base_ring, names) Parent.__init__(self, base=base_ring, names=names, category=MagmasAndAdditiveMagmas().or_subcategory(category)) @@ -592,6 +609,23 @@ def _latex_(self): generators_rep = ", ".join(self.variable_names()) return latex(self.base_ring()) + r"[\![{}]\!]".format(generators_rep) + @cached_method + def monomial(self, c, n): + r""" + Return the interpretation of the coefficient ``c`` at index ``n``. + + EXAMPLES:: + + sage: L = LazyLaurentSeriesRing(ZZ, 'z') + sage: L.monomial(2, 3) + 2*z^3 + """ + m = len(self.variable_names()) + L = self._laurent_poly_ring + if m == 1: + return L(c) * L.gen() ** n + return L(c) + @cached_method def gen(self, n=0): """ @@ -613,7 +647,7 @@ def gen(self, n=0): raise IndexError("there is only one generator") raise IndexError("there are only %s generators" % m) - R = self._poly_ring + R = self._laurent_poly_ring if len(self.variable_names()) == 1: coeff_stream = CoefficientStream_exact([1], self._sparse, constant=ZZ.zero(), valuation=1) else: @@ -666,7 +700,7 @@ def _coerce_map_from_(self, S): if self.base_ring().has_coerce_map_from(S): return True - R = self._poly_ring + R = self._laurent_poly_ring if R.has_coerce_map_from(S): def make_series_from(poly): p_dict = poly.homogeneous_components() @@ -744,7 +778,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No valuation = 0 assert valuation >= 0, "the valuation of a Taylor series must be positive" - R = self._poly_ring + R = self._laurent_poly_ring if x is None: assert degree is None coeff_stream = CoefficientStream_uninitialized(self._sparse, valuation) @@ -817,7 +851,7 @@ def _an_element_(self): z + z^2 + z^3 + z^4 + ... """ c = self.base_ring()(1) - R = self._poly_ring + R = self._laurent_poly_ring coeff_stream = CoefficientStream_exact([R.one()], self._sparse, valuation=1, constant=c) return self.element_class(self, coeff_stream) @@ -832,7 +866,7 @@ def one(self): sage: L.one() 1 """ - R = self._poly_ring + R = self._laurent_poly_ring coeff_stream = CoefficientStream_exact([R.one()], self._sparse, constant=ZZ.zero(), degree=1) return self.element_class(self, coeff_stream) @@ -849,6 +883,18 @@ def zero(self): """ return self.element_class(self, CoefficientStream_zero(self._sparse)) + # add options to class + class options(GlobalOptions): + NAME = 'LazyTaylorSeriesRing' + module = 'sage.rings.lazy_laurent_series_ring' + display_length = dict(default=7, + description='the number of coefficients to display from the valuation', + checker=lambda x: x in ZZ and x > 0) + constant_length = dict(default=3, + description='the number of coefficients to display for nonzero constant series', + checker=lambda x: x in ZZ and x > 0) + + ###################################################################### class LazyDirichletSeriesRing(UniqueRepresentation, Parent): @@ -882,6 +928,7 @@ def __init__(self, base_ring, names, sparse=False, category=None): self._sparse = sparse self._coeff_ring = base_ring + self._laurent_poly_ring = SR Parent.__init__(self, base=base_ring, names=names, category=MagmasAndAdditiveMagmas().or_subcategory(category)) @@ -897,7 +944,21 @@ def _repr_(self): return "Lazy Dirichlet Series Ring in {} over {}".format(self.variable_name(), self.base_ring()) @cached_method - def gen(self, n=0): + def monomial(self, c, n): + r""" + Return the interpretation of the coefficient ``c`` at index ``n``. + + EXAMPLES:: + + sage: L = LazyDirichletSeriesRing(ZZ, 'z') + sage: L.monomial(5, 3) + 5/3^z + """ + L = self._laurent_poly_ring + return L(c) * L(n) ** -L(self.variable_name()) + + @cached_method + def gen(self, n=1): """ Return the `n`-th generator of this Dirichlet series ring. @@ -906,12 +967,12 @@ def gen(self, n=0): sage: L = LazyDirichletSeriesRing(ZZ, 'z') sage: L.gen() 1 - sage: L.gen(3) + sage: L.gen(4) 1/(4^z) """ - assert n >= 0 - coeff_stream = CoefficientStream_exact([1], self._sparse, valuation=n+1, constant=ZZ.zero()) + assert n >= 1 + coeff_stream = CoefficientStream_exact([1], self._sparse, valuation=n, constant=ZZ.zero()) return self.element_class(self, coeff_stream) def ngens(self): @@ -938,7 +999,7 @@ def gens(self): sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: L.gens() Lazy family ((i))_{i in Positive integers} - sage: L.gens()[1] + sage: L.gens()[2] 1/(2^z) """ @@ -1105,3 +1166,14 @@ def zero(self): 0 """ return self.element_class(self, CoefficientStream_zero(self._sparse)) + + # add options to class + class options(GlobalOptions): + NAME = 'LazyDirichletSeriesRing' + module = 'sage.rings.lazy_laurent_series_ring' + display_length = dict(default=7, + description='the number of coefficients to display from the valuation', + checker=lambda x: x in ZZ and x > 0) + constant_length = dict(default=3, + description='the number of coefficients to display for nonzero constant series', + checker=lambda x: x in ZZ and x > 0)