Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/abvar/abvar_newform.py
4079 views
1
"""
2
Abelian varieties attached to newforms
3
4
TESTS::
5
6
sage: A = AbelianVariety('23a')
7
sage: loads(dumps(A)) == A
8
True
9
"""
10
11
12
###########################################################################
13
# Copyright (C) 2008 William Stein <[email protected]> #
14
# Distributed under the terms of the GNU General Public License (GPL) #
15
# http://www.gnu.org/licenses/ #
16
###########################################################################
17
18
from sage.databases.cremona import cremona_letter_code
19
20
from sage.rings.all import QQ, ZZ
21
22
from sage.modular.modform.element import Newform
23
from sage.modular.arithgroup.all import is_Gamma0, is_Gamma1, is_GammaH
24
25
26
from abvar import ModularAbelianVariety_modsym_abstract
27
import homspace
28
29
class ModularAbelianVariety_newform(ModularAbelianVariety_modsym_abstract):
30
"""
31
A modular abelian variety attached to a specific newform.
32
"""
33
def __init__(self, f, internal_name=False):
34
"""
35
Create the modular abelian variety `A_f` attached to the
36
newform `f`.
37
38
INPUT:
39
f -- a newform
40
41
EXAMPLES::
42
43
sage: f = CuspForms(37).newforms('a')[0]
44
sage: f.abelian_variety()
45
Newform abelian subvariety 37a of dimension 1 of J0(37)
46
"""
47
if not isinstance(f, Newform):
48
raise TypeError, "f must be a newform"
49
self.__f = f
50
self._is_hecke_stable = True
51
K = f.qexp().base_ring()
52
if K == QQ:
53
variable_name = None
54
else:
55
variable_name = K.variable_name()
56
self.__named_newforms = { variable_name: self.__f }
57
if not internal_name:
58
self.__named_newforms[None] = self.__f
59
ModularAbelianVariety_modsym_abstract.__init__(self, (f.group(),), QQ,
60
is_simple=True, newform_level = (f.level(), f.group()),
61
isogeny_number=f.number(), number=0)
62
63
def _modular_symbols(self,sign=0):
64
"""
65
EXAMPLES::
66
67
sage: f = CuspForms(52).newforms('a')[0]
68
sage: A = f.abelian_variety()
69
sage: A._modular_symbols()
70
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 15 for Gamma_0(52) of weight 2 with sign 0 over Rational Field
71
sage: A._modular_symbols(1)
72
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 10 for Gamma_0(52) of weight 2 with sign 1 over Rational Field
73
sage: A._modular_symbols(-1)
74
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5 for Gamma_0(52) of weight 2 with sign -1 over Rational Field
75
"""
76
return self.__f.modular_symbols(sign=sign)
77
78
def newform(self, names=None):
79
r"""
80
Return the newform that this modular abelian variety is attached to.
81
82
EXAMPLES::
83
84
sage: f = Newform('37a')
85
sage: A = f.abelian_variety()
86
sage: A.newform()
87
q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)
88
sage: A.newform() is f
89
True
90
91
If the a variable name has not been specified, we must specify one::
92
93
sage: A = AbelianVariety('67b')
94
sage: A.newform()
95
Traceback (most recent call last):
96
...
97
TypeError: You must specify the name of the generator.
98
sage: A.newform('alpha')
99
q + alpha*q^2 + (-alpha - 3)*q^3 + (-3*alpha - 3)*q^4 - 3*q^5 + O(q^6)
100
101
If the eigenform is actually over `\QQ` then we don't have to specify
102
the name::
103
104
sage: A = AbelianVariety('67a')
105
sage: A.newform()
106
q + 2*q^2 - 2*q^3 + 2*q^4 + 2*q^5 + O(q^6)
107
"""
108
try:
109
return self.__named_newforms[names]
110
except KeyError:
111
self.__named_newforms[names] = Newform(self.__f.parent().change_ring(QQ), self.__f.modular_symbols(1), names=names, check=False)
112
return self.__named_newforms[names]
113
114
def label(self):
115
"""
116
Return canonical label that defines this newform modular
117
abelian variety.
118
119
OUTPUT:
120
string
121
122
EXAMPLES::
123
124
sage: A = AbelianVariety('43b')
125
sage: A.label()
126
'43b'
127
"""
128
G = self.__f.group()
129
if is_Gamma0(G):
130
group = ''
131
elif is_Gamma1(G):
132
group = 'G1'
133
elif is_GammaH(G):
134
group = 'GH[' + ','.join([str(z) for z in G._generators_for_H()]) + ']'
135
return '%s%s%s'%(self.level(), cremona_letter_code(self.factor_number()), group)
136
137
def factor_number(self):
138
"""
139
Return factor number.
140
141
OUTPUT:
142
int
143
144
EXAMPLES::
145
146
sage: A = AbelianVariety('43b')
147
sage: A.factor_number()
148
1
149
"""
150
try:
151
return self.__factor_number
152
except AttributeError:
153
self.__factor_number = self.__f.number()
154
return self.__factor_number
155
156
def _repr_(self):
157
"""
158
String representation of this modular abelian variety.
159
160
EXAMPLES::
161
162
sage: AbelianVariety('37a')._repr_()
163
'Newform abelian subvariety 37a of dimension 1 of J0(37)'
164
"""
165
return "Newform abelian subvariety %s of dimension %s of %s" % (
166
self.newform_label(), self.dimension(), self._ambient_repr())
167
168
def endomorphism_ring(self):
169
"""
170
Return the endomorphism ring of this newform abelian variety.
171
172
EXAMPLES::
173
174
sage: A = AbelianVariety('23a')
175
sage: E = A.endomorphism_ring(); E
176
Endomorphism ring of Newform abelian subvariety 23a of dimension 2 of J0(23)
177
178
We display the matrices of these two basis matrices::
179
180
sage: E.0.matrix()
181
[1 0 0 0]
182
[0 1 0 0]
183
[0 0 1 0]
184
[0 0 0 1]
185
sage: E.1.matrix()
186
[ 0 1 -1 0]
187
[ 0 1 -1 1]
188
[-1 2 -2 1]
189
[-1 1 0 -1]
190
191
The result is cached::
192
193
sage: E is A.endomorphism_ring()
194
True
195
"""
196
try:
197
return self.__endomorphism_ring
198
except AttributeError:
199
pass
200
201
E = homspace.EndomorphismSubring(self)
202
self.__endomorphism_ring = E
203
return self.__endomorphism_ring
204
205
def _calculate_endomorphism_generators(self):
206
"""
207
EXAMPLES::
208
209
sage: A = AbelianVariety('43b')
210
sage: B = A.endomorphism_ring(); B # indirect doctest
211
Endomorphism ring of Newform abelian subvariety 43b of dimension 2 of J0(43)
212
sage: [b.matrix() for b in B.gens()]
213
[
214
[1 0 0 0] [ 0 1 0 0]
215
[0 1 0 0] [ 1 -2 0 0]
216
[0 0 1 0] [ 1 0 -2 -1]
217
[0 0 0 1], [ 0 1 -1 0]
218
]
219
"""
220
M = self.modular_symbols()
221
bound = M.sturm_bound()
222
223
d = self.dimension()
224
T1list = self.hecke_operator(1).matrix().list()
225
EndVecZ = ZZ**(len(T1list))
226
V = EndVecZ.submodule([T1list])
227
n = 2
228
229
while V.dimension() < d:
230
W = EndVecZ.submodule([((self.hecke_operator(n).matrix())**i).list()
231
for i in range(1,d+1)])
232
V = V+W
233
n += 1
234
235
return V.saturation().basis()
236
237
238