Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
More bugfixes and expanding the Dirichlet __call__ input.
Browse files Browse the repository at this point in the history
  • Loading branch information
Travis Scrimshaw committed Sep 28, 2021
1 parent 38ac82f commit 8578585
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 17 deletions.
46 changes: 44 additions & 2 deletions src/sage/rings/lazy_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -2562,13 +2562,55 @@ def __call__(self, p):
sage: Z(s)*Z(s-1)/Z(2*s-2) - (1/Psi).map_coefficients(abs)
O(1/(8^s))
sage: Z(5)
zeta(5)
sage: Z(1+I)
zeta(I + 1)
sage: f = D([1,2,-3,-4], valuation=2); f
1/(2^s) + 2/3^s - 3/4^s - 4/5^s
sage: f(2)
449/3600
sage: 1/2^2 + 2/3^2 + -3/4^2 + -4/5^2
449/3600
sage: f(0)
0
sage: f(-2)
-126
sage: f = D([4,2,-3,2])
sage: f(0)
4
sage: f = D([1,2,-3,-4], constant=2)
sage: bool(f(2) == -1 + -5/3^2 + -6/4^2 + 2*zeta(2))
True
"""
P = self.parent()
coeff_stream = self._coeff_stream
if not p:
return self[1]

# Special behavior for finite series
if isinstance(coeff_stream, Stream_exact):
from sage.rings.all import CC
if not coeff_stream._constant:
try:
return sum(self[k] * ~(ZZ(k)**p)
for k in range(1, coeff_stream._degree))
except (ValueError, TypeError, ArithmeticError):
pass
elif p in CC:
from sage.functions.transcendental import zeta
C = coeff_stream._constant
ret = sum((self[k] - C) * ~(ZZ(k)**p)
for k in range(1, coeff_stream._degree))
return ret + C * zeta(p)

R = PolynomialRing(ZZ, P.variable_name())
p = R(p)
if p.degree() != 1:
raise ValueError("the argument must be a linear polynomial of degree 1 with integer coefficients")
coeff_stream = self._coeff_stream
b, a = p
if a < 0:
raise ValueError("the leading coefficient must be positive")
Expand All @@ -2578,7 +2620,7 @@ def coefficient(m):
n = m.nth_root(a)
return coeff_stream[n] * n ** (-b)
except ValueError:
return 0
return ZZ.zero()
return P.element_class(P, Stream_function(coefficient, P._coeff_ring, P._sparse, 1))

def _format_series(self, formatter, format_strings=False):
Expand Down
44 changes: 29 additions & 15 deletions src/sage/rings/lazy_series_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,15 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No
sage: D(1+2*q)
3 + 5/2^t + 7/3^t + 9/4^t + 11/5^t + 13/6^t + 15/7^t + O(1/(8^t))
In some cases, this may yield surprising results::
In this example, the Dirichlet series ``m`` is considered as an
element in the base ring::
sage: m = D(moebius)
sage: s = L(m, valuation=0); s[1]
Traceback (most recent call last):
...
ValueError: the argument must be a linear polynomial of degree 1 with integer coefficients
sage: s = L(m, valuation=0)
sage: s[0]
1 - 1/(2^s) - 1/(3^s) - 1/(5^s) + 1/(6^s) - 1/(7^s) + O(1/(8^s))
sage: s[1]
0
TESTS:
Expand Down Expand Up @@ -344,7 +346,7 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No
return self.element_class(self, coeff_stream)

# Handle when it is a lazy series
if isinstance(x, self.element_class):
if isinstance(x, self.Element):
if x._coeff_stream._is_sparse is not self._sparse:
# TODO: Implement a way to make a self._sparse copy
raise NotImplementedError("cannot convert between sparse and dense")
Expand Down Expand Up @@ -1150,6 +1152,13 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No
sage: D(s, valuation=2)
1/(2^t) + 2/3^t + 3/4^t + 4/5^t + 5/6^t + 6/7^t + 7/8^t + O(1/(9^t))
sage: Ds = LazyDirichletSeriesRing(ZZ, 's')
sage: m = Ds(moebius, valuation=2); m
-1/(2^s) - 1/(3^s) - 1/(5^s) + 1/(6^s) - 1/(7^s) + O(1/(9^s))
sage: D = LazyDirichletSeriesRing(QQ, 't')
sage: D(m)
-1/(2^t) - 1/(3^t) - 1/(5^t) + 1/(6^t) - 1/(7^t) + O(1/(9^t))
.. TODO::
Add a method to make a copy of ``self._sparse``.
Expand All @@ -1163,21 +1172,26 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No
else:
x = p.shift(1)
else:
if valuation is None:
valuation = 1

if coefficients is not None:
if valuation is None:
valuation = 1
return super()._element_constructor_(x, valuation, degree, constant, coefficients)

BR = self.base_ring()
if x in BR:
if valuation is None:
valuation = 1
x = BR(x)
if not isinstance(x, LazyDirichletSeries) and (isinstance(x, LazyModuleElement)
or callable(x)):
if coefficients is not None:
raise ValueError("coefficients must be None if x is provided")
coefficients = x
x = None

if not isinstance(x, LazyDirichletSeries):
if valuation is None:
valuation = 1

if isinstance(x, LazyModuleElement) or callable(x):
if coefficients is not None:
raise ValueError("coefficients must be None if x is provided")
coefficients = x
x = None

if valuation is not None and (valuation not in ZZ or valuation <= 0):
raise ValueError("the valuation must be a positive integer")
Expand Down

0 comments on commit 8578585

Please sign in to comment.