Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/modform/hecke_operator_on_qexp.py
4091 views
1
"""
2
Hecke Operators on `q`-expansions
3
"""
4
5
#########################################################################
6
# Copyright (C) 2004--2006 William Stein <[email protected]>
7
#
8
# Distributed under the terms of the GNU General Public License (GPL)
9
#
10
# http://www.gnu.org/licenses/
11
#########################################################################
12
13
from sage.modular.dirichlet import DirichletGroup, is_DirichletCharacter
14
from sage.rings.all import (divisors, gcd, ZZ, Integer, is_PowerSeries, Infinity, CyclotomicField)
15
from sage.matrix.all import matrix, MatrixSpace
16
from element import is_ModularFormElement
17
18
def hecke_operator_on_qexp(f, n, k, eps = None,
19
prec=None, check=True, _return_list=False):
20
r"""
21
Given the `q`-expansion `f` of a modular form with character
22
`\varepsilon`, this function computes the image of `f` under the
23
Hecke operator `T_{n,k}` of weight `k`.
24
25
EXAMPLES::
26
27
sage: M = ModularForms(1,12)
28
sage: hecke_operator_on_qexp(M.basis()[0], 3, 12)
29
252*q - 6048*q^2 + 63504*q^3 - 370944*q^4 + O(q^5)
30
sage: hecke_operator_on_qexp(M.basis()[0], 1, 12, prec=7)
31
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 + O(q^7)
32
sage: hecke_operator_on_qexp(M.basis()[0], 1, 12)
33
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + 84480*q^8 - 113643*q^9 - 115920*q^10 + 534612*q^11 - 370944*q^12 - 577738*q^13 + O(q^14)
34
35
sage: M.prec(20)
36
20
37
sage: hecke_operator_on_qexp(M.basis()[0], 3, 12)
38
252*q - 6048*q^2 + 63504*q^3 - 370944*q^4 + 1217160*q^5 - 1524096*q^6 + O(q^7)
39
sage: hecke_operator_on_qexp(M.basis()[0], 1, 12)
40
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + 84480*q^8 - 113643*q^9 - 115920*q^10 + 534612*q^11 - 370944*q^12 - 577738*q^13 + 401856*q^14 + 1217160*q^15 + 987136*q^16 - 6905934*q^17 + 2727432*q^18 + 10661420*q^19 - 7109760*q^20 + O(q^21)
41
42
sage: (hecke_operator_on_qexp(M.basis()[0], 1, 12)*252).add_bigoh(7)
43
252*q - 6048*q^2 + 63504*q^3 - 370944*q^4 + 1217160*q^5 - 1524096*q^6 + O(q^7)
44
45
sage: hecke_operator_on_qexp(M.basis()[0], 6, 12)
46
-6048*q + 145152*q^2 - 1524096*q^3 + O(q^4)
47
48
An example on a formal power series::
49
50
sage: R.<q> = QQ[[]]
51
sage: f = q + q^2 + q^3 + q^7 + O(q^8)
52
sage: hecke_operator_on_qexp(f, 3, 12)
53
q + O(q^3)
54
sage: hecke_operator_on_qexp(delta_qexp(24), 3, 12).prec()
55
8
56
sage: hecke_operator_on_qexp(delta_qexp(25), 3, 12).prec()
57
9
58
59
An example of computing `T_{p,k}` in characteristic `p`::
60
61
sage: p = 199
62
sage: fp = delta_qexp(prec=p^2+1, K=GF(p))
63
sage: tfp = hecke_operator_on_qexp(fp, p, 12)
64
sage: tfp == fp[p] * fp
65
True
66
sage: tf = hecke_operator_on_qexp(delta_qexp(prec=p^2+1), p, 12).change_ring(GF(p))
67
sage: tfp == tf
68
True
69
"""
70
if eps is None:
71
# Need to have base_ring=ZZ to work over finite fields, since
72
# ZZ can coerce to GF(p), but QQ can't.
73
eps = DirichletGroup(1, base_ring=ZZ).gen(0)
74
if check:
75
if not (is_PowerSeries(f) or is_ModularFormElement(f)):
76
raise TypeError, "f (=%s) must be a power series or modular form"%f
77
if not is_DirichletCharacter(eps):
78
raise TypeError, "eps (=%s) must be a Dirichlet character"%eps
79
k = Integer(k)
80
n = Integer(n)
81
v = []
82
83
if prec is None:
84
if is_ModularFormElement(f):
85
# always want at least three coefficients, but not too many, unless
86
# requested
87
pr = max(f.prec(), f.parent().prec(), (n+1)*3)
88
pr = min(pr, 100*(n+1))
89
prec = pr // n + 1
90
else:
91
prec = (f.prec() / ZZ(n)).ceil()
92
if prec == Infinity: prec = f.parent().default_prec() // n + 1
93
94
if f.prec() < prec:
95
f._compute_q_expansion(prec)
96
97
p = Integer(f.base_ring().characteristic())
98
if k != 1 and p.is_prime() and n.is_power_of(p):
99
# if computing T_{p^a} in characteristic p, use the simpler (and faster)
100
# formula
101
v = [f[m*n] for m in range(prec)]
102
else:
103
l = k-1
104
for m in range(prec):
105
am = sum([eps(d) * d**l * f[m*n//(d*d)] for \
106
d in divisors(gcd(n, m)) if (m*n) % (d*d) == 0])
107
v.append(am)
108
if _return_list:
109
return v
110
if is_ModularFormElement(f):
111
R = f.parent()._q_expansion_ring()
112
else:
113
R = f.parent()
114
return R(v, prec)
115
116
def _hecke_operator_on_basis(B, V, n, k, eps):
117
"""
118
Does the work for hecke_operator_on_basis once the input
119
is normalized.
120
121
EXAMPLES::
122
123
sage: hecke_operator_on_basis(ModularForms(1,16).q_expansion_basis(30), 3, 16) # indirect doctest
124
[ -3348 0]
125
[ 0 14348908]
126
127
The following used to cause a segfault due to accidentally
128
transposed second and third argument (#2107)::
129
130
sage: B = victor_miller_basis(100,30)
131
sage: t2 = hecke_operator_on_basis(B, 100, 2)
132
Traceback (most recent call last):
133
...
134
ValueError: The given basis vectors must be linearly independent.
135
"""
136
prec = V.degree()
137
TB = [hecke_operator_on_qexp(f, n, k, eps, prec, check=False, _return_list=True)
138
for f in B]
139
TB = [V.coordinate_vector(w) for w in TB]
140
return matrix(V.base_ring(), len(B), len(B), TB, sparse=False)
141
142
def hecke_operator_on_basis(B, n, k, eps=None,
143
already_echelonized = False):
144
r"""
145
Given a basis `B` of `q`-expansions for a space of modular forms
146
with character `\varepsilon` to precision at least `\#B\cdot n+1`,
147
this function computes the matrix of `T_n` relative to `B`.
148
149
.. note::
150
151
If the elements of B are not known to sufficient precision,
152
this function will report that the vectors are linearly
153
dependent (since they are to the specified precision).
154
155
INPUT:
156
157
- ``B`` - list of q-expansions
158
159
- ``n`` - an integer >= 1
160
161
- ``k`` - an integer
162
163
- ``eps`` - Dirichlet character
164
165
- ``already_echelonized`` -- bool (default: False); if True, use that the
166
basis is already in Echelon form, which saves a lot of time.
167
168
EXAMPLES::
169
170
sage: sage.modular.modform.constructor.ModularForms_clear_cache()
171
sage: ModularForms(1,12).q_expansion_basis()
172
[
173
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6),
174
1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + 3199218815520/691*q^5 + O(q^6)
175
]
176
sage: hecke_operator_on_basis(ModularForms(1,12).q_expansion_basis(), 3, 12)
177
Traceback (most recent call last):
178
...
179
ValueError: The given basis vectors must be linearly independent.
180
181
sage: hecke_operator_on_basis(ModularForms(1,12).q_expansion_basis(30), 3, 12)
182
[ 252 0]
183
[ 0 177148]
184
185
TESTS:
186
187
This shows that the problem with finite fields reported at trac #8281 is solved::
188
189
sage: bas_mod5 = [f.change_ring(GF(5)) for f in victor_miller_basis(12, 20)]
190
sage: hecke_operator_on_basis(bas_mod5, 2, 12)
191
[4 0]
192
[0 1]
193
194
This shows that empty input is handled sensibly (trac #12202)::
195
196
sage: x = hecke_operator_on_basis([], 3, 12); x
197
[]
198
sage: x.parent()
199
Full MatrixSpace of 0 by 0 dense matrices over Cyclotomic Field of order 1 and degree 1
200
sage: y = hecke_operator_on_basis([], 3, 12, eps=DirichletGroup(13).0^2); y
201
[]
202
sage: y.parent()
203
Full MatrixSpace of 0 by 0 dense matrices over Cyclotomic Field of order 12 and degree 4
204
"""
205
if not isinstance(B, (list, tuple)):
206
raise TypeError, "B (=%s) must be a list or tuple"%B
207
if len(B) == 0:
208
if eps is None:
209
R = CyclotomicField(1)
210
else:
211
R = eps.base_ring()
212
return MatrixSpace(R, 0)(0)
213
f = B[0]
214
R = f.base_ring()
215
if eps is None:
216
eps = DirichletGroup(1, R).gen(0)
217
all_powerseries = True
218
for x in B:
219
if not is_PowerSeries(x):
220
all_powerseries = False
221
if not all_powerseries:
222
raise TypeError, "each element of B must be a power series"
223
n = Integer(n)
224
k = Integer(k)
225
prec = (f.prec()-1)//n
226
A = R**prec
227
V = A.span_of_basis([g.padded_list(prec) for g in B],
228
already_echelonized = already_echelonized)
229
return _hecke_operator_on_basis(B, V, n, k, eps)
230
231
232
233