Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/abvar/abvar_ambient_jacobian.py
4100 views
1
"""
2
Ambient Jacobian Abelian Variety
3
4
TESTS::
5
6
sage: loads(dumps(J0(37))) == J0(37)
7
True
8
sage: loads(dumps(J1(13))) == J1(13)
9
True
10
"""
11
12
import weakref
13
from sage.structure.sequence import Sequence
14
15
from abvar import (ModularAbelianVariety_modsym_abstract, ModularAbelianVariety,
16
simple_factorization_of_modsym_space, modsym_lattices,
17
ModularAbelianVariety_modsym)
18
from sage.rings.all import QQ
19
20
from sage.modular.modsym.modsym import ModularSymbols
21
import morphism
22
23
24
_cache = {}
25
26
def ModAbVar_ambient_jacobian(group):
27
"""
28
Return the ambient Jacobian attached to a given congruence
29
subgroup.
30
31
The result is cached using a weakref. This function is called
32
internally by modular abelian variety constructors.
33
34
INPUT:
35
36
37
- ``group`` - a congruence subgroup.
38
39
40
OUTPUT: a modular abelian variety attached
41
42
EXAMPLES::
43
44
sage: import sage.modular.abvar.abvar_ambient_jacobian as abvar_ambient_jacobian
45
sage: A = abvar_ambient_jacobian.ModAbVar_ambient_jacobian(Gamma0(11))
46
sage: A
47
Abelian variety J0(11) of dimension 1
48
sage: B = abvar_ambient_jacobian.ModAbVar_ambient_jacobian(Gamma0(11))
49
sage: A is B
50
True
51
52
You can get access to and/or clear the cache as follows::
53
54
sage: abvar_ambient_jacobian._cache = {}
55
sage: B = abvar_ambient_jacobian.ModAbVar_ambient_jacobian(Gamma0(11))
56
sage: A is B
57
False
58
"""
59
try:
60
X = _cache[group]()
61
if not X is None:
62
return X
63
except KeyError:
64
pass
65
X = ModAbVar_ambient_jacobian_class(group)
66
_cache[group] = weakref.ref(X)
67
return X
68
69
class ModAbVar_ambient_jacobian_class(ModularAbelianVariety_modsym_abstract):
70
"""
71
An ambient Jacobian modular abelian variety attached to a
72
congruence subgroup.
73
"""
74
def __init__(self, group):
75
"""
76
Create an ambient Jacobian modular abelian variety.
77
78
EXAMPLES::
79
80
sage: A = J0(37); A
81
Abelian variety J0(37) of dimension 2
82
sage: type(A)
83
<class 'sage.modular.abvar.abvar_ambient_jacobian.ModAbVar_ambient_jacobian_class_with_category'>
84
sage: A.group()
85
Congruence Subgroup Gamma0(37)
86
"""
87
ModularAbelianVariety_modsym_abstract.__init__(self, (group,), QQ)
88
self.__group = group
89
self._is_hecke_stable = True
90
91
def _modular_symbols(self):
92
"""
93
Return the modular symbols space associated to this ambient
94
Jacobian.
95
96
OUTPUT: modular symbols space
97
98
EXAMPLES::
99
100
sage: M = J0(33)._modular_symbols(); M
101
Modular Symbols subspace of dimension 6 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field
102
sage: J0(33)._modular_symbols() is M
103
True
104
"""
105
try:
106
return self.__modsym
107
except AttributeError:
108
self.__modsym = ModularSymbols(self.__group, weight=2).cuspidal_submodule()
109
return self.__modsym
110
111
def _repr_(self):
112
"""
113
Return string representation of this Jacobian modular abelian
114
variety.
115
116
EXAMPLES::
117
118
sage: A = J0(11); A
119
Abelian variety J0(11) of dimension 1
120
sage: A._repr_()
121
'Abelian variety J0(11) of dimension 1'
122
sage: A.rename("J_0(11)")
123
sage: A
124
J_0(11)
125
126
We now clear the cache to get rid of our renamed
127
`J_0(11)`.
128
129
::
130
131
sage: import sage.modular.abvar.abvar_ambient_jacobian as abvar_ambient_jacobian
132
sage: abvar_ambient_jacobian._cache = {}
133
"""
134
return 'Abelian variety %s of dimension %s%s'%(self._ambient_repr(), self.dimension(),
135
'' if self.base_field() == QQ else ' over %s'%self.base_field())
136
137
def _latex_(self):
138
"""
139
Return Latex representation of self.
140
141
EXAMPLES::
142
143
sage: latex(J0(37))
144
J_0(37)
145
sage: J1(13)._latex_()
146
'J_1(13)'
147
sage: latex(JH(389,[16]))
148
J_H(389,[16])
149
"""
150
return self._ambient_latex_repr()
151
152
def ambient_variety(self):
153
"""
154
Return the ambient modular abelian variety that contains self.
155
Since self is a Jacobian modular abelian variety, this is just
156
self.
157
158
OUTPUT: abelian variety
159
160
EXAMPLES::
161
162
sage: A = J0(17)
163
sage: A.ambient_variety()
164
Abelian variety J0(17) of dimension 1
165
sage: A is A.ambient_variety()
166
True
167
"""
168
return self
169
170
def group(self):
171
"""
172
Return the group that this Jacobian modular abelian variety is
173
attached to.
174
175
EXAMPLES::
176
177
sage: J1(37).group()
178
Congruence Subgroup Gamma1(37)
179
sage: J0(5077).group()
180
Congruence Subgroup Gamma0(5077)
181
sage: J = GammaH(11,[3]).modular_abelian_variety(); J
182
Abelian variety JH(11,[3]) of dimension 1
183
sage: J.group()
184
Congruence Subgroup Gamma_H(11) with H generated by [3]
185
"""
186
return self.__group
187
188
def groups(self):
189
"""
190
Return the tuple of congruence subgroups attached to this ambient
191
Jacobian. This is always a tuple of length 1.
192
193
OUTPUT: tuple
194
195
EXAMPLES::
196
197
sage: J0(37).groups()
198
(Congruence Subgroup Gamma0(37),)
199
"""
200
return (self.__group,)
201
202
def _calculate_endomorphism_generators(self):
203
"""
204
Calculate generators for the endomorphism ring of self.
205
206
EXAMPLES::
207
208
sage: J0(11)._calculate_endomorphism_generators()
209
[Abelian variety endomorphism of Abelian variety J0(11) of dimension 1]
210
sage: ls = J0(46)._calculate_endomorphism_generators() ; ls
211
[Abelian variety endomorphism of Abelian variety J0(46) of dimension 5,
212
Abelian variety endomorphism of Abelian variety J0(46) of dimension 5,
213
Abelian variety endomorphism of Abelian variety J0(46) of dimension 5,
214
Abelian variety endomorphism of Abelian variety J0(46) of dimension 5,
215
Abelian variety endomorphism of Abelian variety J0(46) of dimension 5]
216
sage: len(ls) == J0(46).dimension()
217
True
218
"""
219
D = self.decomposition()
220
phi = self._isogeny_to_product_of_simples()
221
psi = phi.complementary_isogeny()
222
223
m1 = phi.matrix()
224
m2 = psi.matrix()
225
226
H = self.Hom(self)
227
M = H.matrix_space()
228
229
ls = []
230
ind = 0
231
for d in D:
232
to_newform = d._isogeny_to_newform_abelian_variety()
233
n1 = to_newform.matrix()
234
n2 = to_newform.complementary_isogeny().matrix()
235
f_gens = to_newform.codomain()._calculate_endomorphism_generators()
236
small_space = to_newform.parent().matrix_space()
237
f_gens = [ small_space(x.list()) for x in f_gens ]
238
for m in f_gens:
239
mat = H.matrix_space()(0)
240
mat.set_block(ind, ind, n1 * m * n2 )
241
ls.append((m1 * mat * m2).list())
242
ind += 2*d.dimension()
243
244
return [ H( morphism.Morphism(H, M(x)) ) for x in ls ]
245
246
def degeneracy_map(self, level, t=1, check=True):
247
"""
248
Return the t-th degeneracy map from self to J(level). Here t must
249
be a divisor of either level/self.level() or self.level()/level.
250
251
INPUT:
252
253
254
- ``level`` - integer (multiple or divisor of level of
255
self)
256
257
- ``t`` - divisor of quotient of level of self and
258
level
259
260
- ``check`` - bool (default: True); if True do some
261
checks on the input
262
263
264
OUTPUT: a morphism
265
266
EXAMPLES::
267
268
sage: J0(11).degeneracy_map(33)
269
Degeneracy map from Abelian variety J0(11) of dimension 1 to Abelian variety J0(33) of dimension 3 defined by [1]
270
sage: J0(11).degeneracy_map(33).matrix()
271
[ 0 -3 2 1 -2 0]
272
[ 1 -2 0 1 0 -1]
273
sage: J0(11).degeneracy_map(33,3).matrix()
274
[-1 0 0 0 1 -2]
275
[-1 -1 1 -1 1 0]
276
sage: J0(33).degeneracy_map(11,1).matrix()
277
[ 0 1]
278
[ 0 -1]
279
[ 1 -1]
280
[ 0 1]
281
[-1 1]
282
[ 0 0]
283
sage: J0(11).degeneracy_map(33,1).matrix() * J0(33).degeneracy_map(11,1).matrix()
284
[4 0]
285
[0 4]
286
"""
287
if check:
288
if (level % self.level()) and (self.level() % level):
289
raise ValueError, "level must be divisible by level of self"
290
if (max(level,self.level()) // min(self.level(),level)) % t:
291
raise ValueError, "t must divide the quotient of the two levels"
292
293
Mself = self.modular_symbols()
294
#Jdest = Mself.ambient_module().modular_symbols_of_level(level).cuspidal_subspace().abelian_variety()
295
Jdest = (type(Mself.group()))(level).modular_abelian_variety()
296
Mdest = Jdest.modular_symbols()
297
298
symbol_map = Mself.degeneracy_map(level, t).restrict_codomain(Mdest)
299
H = self.Hom(Jdest)
300
301
return H(morphism.DegeneracyMap(H, symbol_map.matrix(), [t]))
302
303
def dimension(self):
304
"""
305
Return the dimension of this modular abelian variety.
306
307
EXAMPLES::
308
309
sage: J0(2007).dimension()
310
221
311
sage: J1(13).dimension()
312
2
313
sage: J1(997).dimension()
314
40920
315
sage: J0(389).dimension()
316
32
317
sage: JH(389,[4]).dimension()
318
64
319
sage: J1(389).dimension()
320
6112
321
"""
322
try:
323
return self._dimension
324
except AttributeError:
325
d = self.group().genus()
326
self._dimension = d
327
return d
328
329
def decomposition(self, simple=True, bound=None):
330
"""
331
Decompose this ambient Jacobian as a product of abelian
332
subvarieties, up to isogeny.
333
334
EXAMPLES::
335
336
sage: J0(33).decomposition(simple=False)
337
[
338
Abelian subvariety of dimension 2 of J0(33),
339
Abelian subvariety of dimension 1 of J0(33)
340
]
341
sage: J0(33).decomposition(simple=False)[1].is_simple()
342
True
343
sage: J0(33).decomposition(simple=False)[0].is_simple()
344
False
345
sage: J0(33).decomposition(simple=False)
346
[
347
Abelian subvariety of dimension 2 of J0(33),
348
Simple abelian subvariety 33a(None,33) of dimension 1 of J0(33)
349
]
350
sage: J0(33).decomposition(simple=True)
351
[
352
Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33),
353
Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33),
354
Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)
355
]
356
"""
357
try:
358
return self.__decomposition[simple]
359
except KeyError:
360
pass
361
except AttributeError:
362
self.__decomposition = {}
363
364
M = self.modular_symbols().ambient_module()
365
level = M.level()
366
group = M.group()
367
factors = simple_factorization_of_modsym_space(M, simple=simple)
368
factors = modsym_lattices(M, factors)
369
370
D = []
371
for newform_level, isogeny_number, number, modsym, lattice in factors:
372
if simple:
373
is_simple = True
374
else:
375
is_simple = None
376
A = ModularAbelianVariety_modsym(modsym, lattice=lattice,
377
newform_level = (newform_level, group), is_simple=is_simple,
378
isogeny_number=isogeny_number, number=(number, level), check=False)
379
D.append(A)
380
381
# This line below could be safely deleted. It basically creates a circular
382
# reference so that say J0(389)[0] + J0(389)[1] doesn't do two separate
383
# decompositions. Memory will be freed though, at least if you do
384
# import gc; gc.collect().
385
A._ambient = self
386
387
388
D.sort()
389
D = Sequence(D, immutable=True, cr=True, universe=self.category())
390
self.__decomposition[simple] = D
391
return D
392
393
394
395
396
397