Skip to content

Commit 2e0d6d2

Browse files
author
Release Manager
committed
gh-39214: Add keyword prec for exponential and logarithm of Drinfeld modules Currently, the methods `exponential` and `logarithm` for Drinfeld modules return a `LazyPowerSeriesRing` for which not all methods are available. We add a keyword `prec`. When it is `Infinity` (which is the default), the behavior is unchanged. However, when we pass in a finite number, a classical power series (up to the given precision) is returned. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation and checked the documentation preview. URL: #39214 Reported by: Xavier Caruso Reviewer(s): Antoine Leudière, Martin Rubey, Xavier Caruso
2 parents b5c2615 + 1fa959b commit 2e0d6d2

File tree

1 file changed

+47
-18
lines changed

1 file changed

+47
-18
lines changed

src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py

+47-18
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525
from .drinfeld_module import DrinfeldModule
2626

2727
from sage.rings.integer_ring import ZZ
28+
from sage.rings.infinity import Infinity
2829

2930
from sage.misc.cachefunc import cached_method
3031
from sage.misc.lazy_import import lazy_import
3132

3233
lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing')
34+
lazy_import('sage.rings.power_series_ring', 'PowerSeriesRing')
3335

3436

3537
class DrinfeldModule_charzero(DrinfeldModule):
@@ -149,7 +151,7 @@ def _compute_coefficient_exp(self, k):
149151
c += self._compute_coefficient_exp(i)*self._compute_coefficient_log(j)**(q**i)
150152
return -c
151153

152-
def exponential(self, name='z'):
154+
def exponential(self, prec=Infinity, name='z'):
153155
r"""
154156
Return the exponential of this Drinfeld module.
155157
@@ -158,28 +160,38 @@ def exponential(self, name='z'):
158160
159161
INPUT:
160162
163+
- ``prec`` -- an integer or ``Infinity`` (default: ``Infinity``);
164+
the precision at which the series is returned; if ``Infinity``,
165+
a lazy power series in returned, else, a classical power series
166+
is returned.
167+
161168
- ``name`` -- string (default: ``'z'``); the name of the
162169
generator of the lazy power series ring
163170
164-
OUTPUT: a lazy power series over the base field
165-
166171
EXAMPLES::
167172
168173
sage: A = GF(2)['T']
169174
sage: K.<T> = Frac(A)
170175
sage: phi = DrinfeldModule(A, [T, 1])
171176
sage: q = A.base_ring().cardinality()
172-
sage: exp = phi.exponential(); exp
173-
z + ((1/(T^2+T))*z^2) + ((1/(T^8+T^6+T^5+T^3))*z^4) + O(z^8)
174177
175-
The exponential is returned as a lazy power series, meaning that
176-
any of its coefficients can be computed on demands::
178+
When ``prec`` is ``Infinity`` (which is the default),
179+
the exponential is returned as a lazy power series, meaning
180+
that any of its coefficients can be computed on demands::
177181
182+
sage: exp = phi.exponential(); exp
183+
z + ((1/(T^2+T))*z^2) + ((1/(T^8+T^6+T^5+T^3))*z^4) + O(z^8)
178184
sage: exp[2^4]
179185
1/(T^64 + T^56 + T^52 + ... + T^27 + T^23 + T^15)
180186
sage: exp[2^5]
181187
1/(T^160 + T^144 + T^136 + ... + T^55 + T^47 + T^31)
182188
189+
On the contrary, when ``prec`` is a finite number, all the
190+
required coefficients are computed at once::
191+
192+
sage: phi.exponential(prec=10)
193+
z + (1/(T^2 + T))*z^2 + (1/(T^8 + T^6 + T^5 + T^3))*z^4 + (1/(T^24 + T^20 + T^18 + T^17 + T^14 + T^13 + T^11 + T^7))*z^8 + O(z^10)
194+
183195
Example in higher rank::
184196
185197
sage: A = GF(5)['T']
@@ -216,7 +228,6 @@ def exponential(self, name='z'):
216228
See section 4.6 of [Gos1998]_ for the definition of the
217229
exponential.
218230
"""
219-
L = LazyPowerSeriesRing(self._base, name)
220231
zero = self._base.zero()
221232
q = self._Fq.cardinality()
222233

@@ -228,7 +239,12 @@ def coeff_exp(k):
228239
return self._compute_coefficient_exp(v)
229240
else:
230241
return zero
231-
return L(coeff_exp, valuation=1)
242+
243+
if prec is Infinity:
244+
L = LazyPowerSeriesRing(self._base, name)
245+
return L(coeff_exp, valuation=1)
246+
L = PowerSeriesRing(self._base, name, default_prec=prec)
247+
return L([0] + [coeff_exp(i) for i in range(1,prec)], prec=prec)
232248

233249
@cached_method
234250
def _compute_coefficient_log(self, k):
@@ -264,7 +280,7 @@ def _compute_coefficient_log(self, k):
264280
c += self._compute_coefficient_log(i)*self._gen[j]**(q**i)
265281
return c/(T - T**(q**k))
266282

267-
def logarithm(self, name='z'):
283+
def logarithm(self, prec=Infinity, name='z'):
268284
r"""
269285
Return the logarithm of the given Drinfeld module.
270286
@@ -275,27 +291,36 @@ def logarithm(self, name='z'):
275291
276292
INPUT:
277293
294+
- ``prec`` -- an integer or ``Infinity`` (default: ``Infinity``);
295+
the precision at which the series is returned; if ``Infinity``,
296+
a lazy power series in returned
297+
278298
- ``name`` -- string (default: ``'z'``); the name of the
279299
generator of the lazy power series ring
280300
281-
OUTPUT: a lazy power series over the base field
282-
283301
EXAMPLES::
284302
285303
sage: A = GF(2)['T']
286304
sage: K.<T> = Frac(A)
287305
sage: phi = DrinfeldModule(A, [T, 1])
288-
sage: log = phi.logarithm(); log
289-
z + ((1/(T^2+T))*z^2) + ((1/(T^6+T^5+T^3+T^2))*z^4) + O(z^8)
290306
291-
The logarithm is returned as a lazy power series, meaning that
292-
any of its coefficients can be computed on demands::
307+
When ``prec`` is ``Infinity`` (which is the default),
308+
the logarithm is returned as a lazy power series, meaning
309+
that any of its coefficients can be computed on demands::
293310
311+
sage: log = phi.logarithm(); log
312+
z + ((1/(T^2+T))*z^2) + ((1/(T^6+T^5+T^3+T^2))*z^4) + O(z^8)
294313
sage: log[2^4]
295314
1/(T^30 + T^29 + T^27 + ... + T^7 + T^5 + T^4)
296315
sage: log[2^5]
297316
1/(T^62 + T^61 + T^59 + ... + T^8 + T^6 + T^5)
298317
318+
If ``prec`` is a finite number, all the
319+
required coefficients are computed at once::
320+
321+
sage: phi.logarithm(prec=10)
322+
z + (1/(T^2 + T))*z^2 + (1/(T^6 + T^5 + T^3 + T^2))*z^4 + (1/(T^14 + T^13 + T^11 + T^10 + T^7 + T^6 + T^4 + T^3))*z^8 + O(z^10)
323+
299324
Example in higher rank::
300325
301326
sage: A = GF(5)['T']
@@ -317,7 +342,6 @@ def logarithm(self, name='z'):
317342
sage: log[2**3] == -1/((T**q - T)*(T**(q**2) - T)*(T**(q**3) - T)) # expected value
318343
True
319344
"""
320-
L = LazyPowerSeriesRing(self._base, name)
321345
q = self._Fq.cardinality()
322346

323347
def coeff_log(k):
@@ -328,7 +352,12 @@ def coeff_log(k):
328352
return self._compute_coefficient_log(v)
329353
else:
330354
return self._base.zero()
331-
return L(coeff_log, valuation=1)
355+
356+
if prec is Infinity:
357+
L = LazyPowerSeriesRing(self._base, name)
358+
return L(coeff_log, valuation=1)
359+
L = PowerSeriesRing(self._base, name, default_prec=prec)
360+
return L([0] + [coeff_log(i) for i in range(1, prec)], prec=prec)
332361

333362
@cached_method
334363
def _compute_goss_polynomial(self, n, q, poly_ring, X):

0 commit comments

Comments
 (0)