Skip to content

Commit 55761b8

Browse files
committed
better derivative for LazyLaurentSeries
1 parent 4098dbf commit 55761b8

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

src/sage/rings/lazy_series.py

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
from sage.functions.other import factorial
120120
from sage.arith.power import generic_power
121121
from sage.misc.misc_c import prod
122+
from sage.misc.derivative import derivative_parse
122123
from sage.rings.infinity import infinity
123124
from sage.rings.integer_ring import ZZ
124125
from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
@@ -3083,14 +3084,12 @@ def revert(self):
30833084

30843085
compositional_inverse = revert
30853086

3086-
def derivative(self, order=1):
3087+
def derivative(self, *args):
30873088
"""
30883089
Return the derivative of the Laurent series.
30893090
30903091
INPUT:
30913092
3092-
- ``order`` -- optional integer (default 1)
3093-
30943093
EXAMPLES::
30953094
30963095
sage: L.<z> = LazyLaurentSeriesRing(ZZ)
@@ -3100,11 +3099,40 @@ def derivative(self, order=1):
31003099
0
31013100
sage: (1/z).derivative()
31023101
-z^-2
3103-
sage: (1/(1-z)).derivative()
3102+
sage: (1/(1-z)).derivative(z)
31043103
1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)
31053104
3105+
TESTS::
3106+
3107+
sage: R.<q> = QQ[]
3108+
sage: L.<z> = LazyLaurentSeriesRing(R)
3109+
sage: (z*q).derivative()
3110+
q
3111+
3112+
sage: (z*q).derivative(q)
3113+
z
3114+
3115+
sage: (z*q).derivative(q, z)
3116+
1
3117+
3118+
sage: f = 1/(1-q*z+z^2)
3119+
sage: f
3120+
1 + q*z + (q^2 - 1)*z^2 + (q^3 - 2*q)*z^3 + (q^4 - 3*q^2 + 1)*z^4 + (q^5 - 4*q^3 + 3*q)*z^5 + (q^6 - 5*q^4 + 6*q^2 - 1)*z^6 + O(z^7)
3121+
sage: f.derivative(q)[3]
3122+
3*q^2 - 2
3123+
31063124
"""
31073125
P = self.parent()
3126+
R = P._laurent_poly_ring
3127+
v = R.gen()
3128+
order = 0
3129+
vars = []
3130+
for x in derivative_parse(args):
3131+
if x is None or x == v:
3132+
order += 1
3133+
else:
3134+
vars.append(x)
3135+
31083136
coeff_stream = self._coeff_stream
31093137
if isinstance(coeff_stream, Stream_zero):
31103138
return self
@@ -3113,16 +3141,25 @@ def derivative(self, order=1):
31133141
and not coeff_stream._constant):
31143142
if coeff_stream._approximate_order >= 0 and coeff_stream._degree <= order:
31153143
return P.zero()
3116-
initial_coefficients = [prod(i-k for k in range(order)) * c
3117-
for i, c in enumerate(coeff_stream._initial_coefficients,
3118-
coeff_stream._approximate_order)]
3119-
coeff_stream = Stream_exact(initial_coefficients,
3144+
if vars:
3145+
coeffs = [prod(i-k for k in range(order)) * c.derivative(vars)
3146+
for i, c in enumerate(coeff_stream._initial_coefficients,
3147+
coeff_stream._approximate_order)]
3148+
else:
3149+
coeffs = [prod(i-k for k in range(order)) * c
3150+
for i, c in enumerate(coeff_stream._initial_coefficients,
3151+
coeff_stream._approximate_order)]
3152+
coeff_stream = Stream_exact(coeffs,
31203153
self._coeff_stream._is_sparse,
31213154
order=coeff_stream._approximate_order - order,
31223155
constant=coeff_stream._constant)
31233156
return P.element_class(P, coeff_stream)
31243157

31253158
coeff_stream = Stream_derivative(self._coeff_stream, order)
3159+
if vars:
3160+
coeff_stream = Stream_map_coefficients(coeff_stream,
3161+
lambda c: c.derivative(vars),
3162+
R)
31263163
return P.element_class(P, coeff_stream)
31273164

31283165
def approximate_series(self, prec, name=None):
@@ -3441,7 +3478,7 @@ def __call__(self, *g, check=True):
34413478
TypeError: no common canonical parent for objects with parents: ...
34423479
34433480
"""
3444-
if len(g) != len(self.parent().variable_names()):
3481+
if len(g) != self.parent()._arity:
34453482
raise ValueError("arity of must be equal to the number of arguments provided")
34463483

34473484
# Find a good parent for the result

src/sage/rings/lazy_series_ring.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,8 @@ def __init__(self, base_ring, names, sparse=True, category=None):
11471147
names = normalize_names(-1, names)
11481148
self._sparse = sparse
11491149
self._laurent_poly_ring = PolynomialRing(base_ring, names)
1150-
if len(names) == 1:
1150+
self._arity = len(names)
1151+
if self._arity == 1:
11511152
self._internal_poly_ring = self._laurent_poly_ring
11521153
else:
11531154
coeff_ring = PolynomialRing(base_ring, names)

0 commit comments

Comments
 (0)