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

Commit

Permalink
Small reworkings and fixes. Adding another composition test.
Browse files Browse the repository at this point in the history
  • Loading branch information
Travis Scrimshaw committed Aug 10, 2021
1 parent 7c9a5dd commit 51357a0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 19 deletions.
33 changes: 25 additions & 8 deletions src/sage/rings/lazy_laurent_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -1272,12 +1272,24 @@ def __call__(self, g):
sage: g^-3 + g^-2 + 1 / (1 + g^2)
z^-9 + 3*z^-8 + 3*z^-7 - z^-6 - 4*z^-5 - 2*z^-4 + z^-3 + O(z^-2)
sage: f = z^-3; g = z^-2 + z^-1;
sage: f = z^-3
sage: g = z^-2 + z^-1
sage: g^(-3)
z^6 - 3*z^7 + 6*z^8 - 10*z^9 + 15*z^10 - 21*z^11 + 28*z^12 + O(z^13)
sage: f(g)
z^6 - 3*z^7 + 6*z^8 - 10*z^9 + 15*z^10 - 21*z^11 + 28*z^12 + O(z^13)
sage: f = z^2 + z^3
sage: g = z^-3 + z^-2
sage: f^-3 + f^-2
z^-6 - 3*z^-5 + 7*z^-4 - 12*z^-3 + 18*z^-2 - 25*z^-1 + 33 + O(z)
sage: g(f)
z^-6 - 3*z^-5 + 7*z^-4 - 12*z^-3 + 18*z^-2 - 25*z^-1 + 33 + O(z)
sage: g^2 + g^3
z^-9 + 3*z^-8 + 3*z^-7 + 2*z^-6 + 2*z^-5 + z^-4
sage: f(g)
z^-9 + 3*z^-8 + 3*z^-7 + 2*z^-6 + 2*z^-5 + z^-4
sage: f = L(lambda n: n); f
z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7)
sage: f(z^2)
Expand Down Expand Up @@ -1478,23 +1490,28 @@ def __call__(self, g):
# Return the sum since g is not known to be finite or we do not get a Laurent polynomial
# TODO: Optimize when f has positive valuation
ret = P.zero()
gp = P.one()
# We build this iteratively so each power can benefit from the caching
# Equivalent to P.sum(poly[i] * g**i for i in range(poly.valuation(), poly.degree()+1))
# We could just do "return poly(g)" if we don't care about speed
d = poly.degree()
v = poly.valuation()
if d >= 0:
for i in range(d):
ret += poly[i] * gp
ind = max(0, v)
gp = P.one() if ind == 0 else g ** ind
for i in range(ind, d):
if poly[i]:
ret += poly[i] * gp
gp *= g
ret += poly[d] * gp
v = poly.valuation()
if v < 0:
gi = ~g
gp = P.one()
for i in range(-1, v-1, -1):
ind = min(d, -1)
gp = gi if ind == -1 else gi ** -ind
for i in range(ind, v, -1):
if poly[i]:
ret += poly[i] * gp
gp *= gi
ret += poly[i] * gp
ret += poly[v] * gp
return ret

# g != 0 and val(g) > 0
Expand Down
25 changes: 14 additions & 11 deletions src/sage/rings/lazy_laurent_series_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No
sage: g
z^5 + 3*z^6 + 5*z^7 + 7*z^8 + 9*z^9 - z^10 - z^11 - z^12 + O(z^13)
TESTS::
TESTS:
This gives zero::
Expand Down Expand Up @@ -407,11 +407,13 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No
coeff_stream = CoefficientStream_exact(initial_coefficients, self._sparse,
valuation=x.valuation(), constant=constant, degree=degree)
return self.element_class(self, coeff_stream)

if isinstance(x, LazyLaurentSeries):
if x._coeff_stream._is_sparse is self._sparse:
return self.element_class(self, x._coeff_stream)
# TODO: Implement a way to make a self._sparse copy
raise NotImplementedError("cannot convert between sparse and dense")

if callable(x):
if valuation is None:
valuation = 0
Expand All @@ -420,16 +422,17 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No
raise ValueError("constant may only be specified if the degree is specified")
coeff_stream = CoefficientStream_coefficient_function(x, self.base_ring(), self._sparse, valuation)
return self.element_class(self, coeff_stream)
if degree is not None:
if constant is None:
constant = ZZ.zero()
p = [BR(x(i)) for i in range(valuation, degree)]
if not any(p) and not constant:
coeff_stream = CoefficientStream_zero(self._sparse)
else:
coeff_stream = CoefficientStream_exact(p, self._sparse, valuation=valuation,
constant=constant, degree=degree)
return self.element_class(self, coeff_stream)

# degree is not None
if constant is None:
constant = ZZ.zero()
p = [BR(x(i)) for i in range(valuation, degree)]
if not any(p) and not constant:
coeff_stream = CoefficientStream_zero(self._sparse)
else:
coeff_stream = CoefficientStream_exact(p, self._sparse, valuation=valuation,
constant=constant, degree=degree)
return self.element_class(self, coeff_stream)

raise ValueError(f"unable to convert {x} into a lazy Laurent series")

Expand Down

0 comments on commit 51357a0

Please sign in to comment.