119
119
from sage .functions .other import factorial
120
120
from sage .arith .power import generic_power
121
121
from sage .misc .misc_c import prod
122
+ from sage .misc .derivative import derivative_parse
122
123
from sage .rings .infinity import infinity
123
124
from sage .rings .integer_ring import ZZ
124
125
from sage .rings .polynomial .laurent_polynomial_ring import LaurentPolynomialRing
@@ -3083,14 +3084,12 @@ def revert(self):
3083
3084
3084
3085
compositional_inverse = revert
3085
3086
3086
- def derivative (self , order = 1 ):
3087
+ def derivative (self , * args ):
3087
3088
"""
3088
3089
Return the derivative of the Laurent series.
3089
3090
3090
3091
INPUT:
3091
3092
3092
- - ``order`` -- optional integer (default 1)
3093
-
3094
3093
EXAMPLES::
3095
3094
3096
3095
sage: L.<z> = LazyLaurentSeriesRing(ZZ)
@@ -3100,11 +3099,40 @@ def derivative(self, order=1):
3100
3099
0
3101
3100
sage: (1/z).derivative()
3102
3101
-z^-2
3103
- sage: (1/(1-z)).derivative()
3102
+ sage: (1/(1-z)).derivative(z )
3104
3103
1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)
3105
3104
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
+
3106
3124
"""
3107
3125
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
+
3108
3136
coeff_stream = self ._coeff_stream
3109
3137
if isinstance (coeff_stream , Stream_zero ):
3110
3138
return self
@@ -3113,16 +3141,25 @@ def derivative(self, order=1):
3113
3141
and not coeff_stream ._constant ):
3114
3142
if coeff_stream ._approximate_order >= 0 and coeff_stream ._degree <= order :
3115
3143
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 ,
3120
3153
self ._coeff_stream ._is_sparse ,
3121
3154
order = coeff_stream ._approximate_order - order ,
3122
3155
constant = coeff_stream ._constant )
3123
3156
return P .element_class (P , coeff_stream )
3124
3157
3125
3158
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 )
3126
3163
return P .element_class (P , coeff_stream )
3127
3164
3128
3165
def approximate_series (self , prec , name = None ):
@@ -3441,7 +3478,7 @@ def __call__(self, *g, check=True):
3441
3478
TypeError: no common canonical parent for objects with parents: ...
3442
3479
3443
3480
"""
3444
- if len (g ) != len ( self .parent ().variable_names ()) :
3481
+ if len (g ) != self .parent ()._arity :
3445
3482
raise ValueError ("arity of must be equal to the number of arguments provided" )
3446
3483
3447
3484
# Find a good parent for the result
0 commit comments