Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/modular/abvar/finite_subgroup.py
8820 views
1
r"""
2
Finite subgroups of modular abelian varieties
3
4
Sage can compute with fairly general finite subgroups of modular
5
abelian varieties. Elements of finite order are represented by
6
equivalence classes of elements in `H_1(A,\QQ)`
7
modulo `H_1(A,\ZZ)`. A finite subgroup can be
8
defined by giving generators and via various other constructions.
9
Given a finite subgroup, one can compute generators, as well as the
10
structure as an abstract group. Arithmetic on subgroups is also
11
supported, including adding two subgroups together, checking
12
inclusion, etc.
13
14
TODO: Intersection, action of Hecke operators.
15
16
AUTHORS:
17
18
- William Stein (2007-03)
19
20
EXAMPLES::
21
22
sage: J = J0(33)
23
sage: C = J.cuspidal_subgroup()
24
sage: C
25
Finite subgroup with invariants [10, 10] over QQ of Abelian variety J0(33) of dimension 3
26
sage: C.order()
27
100
28
sage: C.gens()
29
[[(1/10, 0, 1/10, 1/10, 1/10, 3/10)], [(0, 1/5, 1/10, 0, 1/10, 9/10)], [(0, 0, 1/2, 0, 1/2, 1/2)]]
30
sage: C.0 + C.1
31
[(1/10, 1/5, 1/5, 1/10, 1/5, 6/5)]
32
sage: 10*(C.0 + C.1)
33
[(0, 0, 0, 0, 0, 0)]
34
sage: G = C.subgroup([C.0 + C.1]); G
35
Finite subgroup with invariants [10] over QQbar of Abelian variety J0(33) of dimension 3
36
sage: G.gens()
37
[[(1/10, 1/5, 1/5, 1/10, 1/5, 1/5)]]
38
sage: G.order()
39
10
40
sage: G <= C
41
True
42
sage: G >= C
43
False
44
45
We make a table of the order of the cuspidal subgroup for the first
46
few levels::
47
48
sage: for N in range(11,40): print N, J0(N).cuspidal_subgroup().order()
49
...
50
11 5
51
12 1
52
13 1
53
14 6
54
15 8
55
16 1
56
17 4
57
18 1
58
19 3
59
20 6
60
21 8
61
22 25
62
23 11
63
24 8
64
25 1
65
26 21
66
27 9
67
28 36
68
29 7
69
30 192
70
31 5
71
32 8
72
33 100
73
34 48
74
35 48
75
36 12
76
37 3
77
38 135
78
39 56
79
80
TESTS::
81
82
sage: G = J0(11).finite_subgroup([[1/3,0], [0,1/5]]); G
83
Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1
84
sage: loads(dumps(G)) == G
85
True
86
sage: loads(dumps(G.0)) == G.0
87
True
88
"""
89
90
###########################################################################
91
# Copyright (C) 2007 William Stein <[email protected]> #
92
# Distributed under the terms of the GNU General Public License (GPL) #
93
# http://www.gnu.org/licenses/ #
94
###########################################################################
95
96
from sage.modules.module import Module_old
97
from sage.modules.free_module import is_FreeModule
98
from sage.structure.element import ModuleElement
99
from sage.structure.sequence import Sequence
100
from sage.rings.all import gcd, lcm, QQ, ZZ, QQbar, Integer, composite_field
101
from sage.misc.misc import prod
102
103
import abvar as abelian_variety
104
from sage.categories.fields import Fields
105
_Fields = Fields()
106
107
class FiniteSubgroup(Module_old):
108
def __init__(self, abvar, field_of_definition=QQ):
109
"""
110
A finite subgroup of a modular abelian variety.
111
112
INPUT:
113
114
115
- ``abvar`` - a modular abelian variety
116
117
- ``field_of_definition`` - a field over which this
118
group is defined.
119
120
121
EXAMPLES: This is an abstract base class, so there are no instances
122
of this class itself.
123
124
::
125
126
sage: A = J0(37)
127
sage: G = A.torsion_subgroup(3); G
128
Finite subgroup with invariants [3, 3, 3, 3] over QQ of Abelian variety J0(37) of dimension 2
129
sage: type(G)
130
<class 'sage.modular.abvar.finite_subgroup.FiniteSubgroup_lattice'>
131
sage: from sage.modular.abvar.finite_subgroup import FiniteSubgroup
132
sage: isinstance(G, FiniteSubgroup)
133
True
134
"""
135
if field_of_definition not in _Fields:
136
raise TypeError, "field_of_definition must be a field"
137
if not abelian_variety.is_ModularAbelianVariety(abvar):
138
raise TypeError, "abvar must be a modular abelian variety"
139
Module_old.__init__(self, ZZ)
140
self.__abvar = abvar
141
self.__field_of_definition = field_of_definition
142
143
################################################################
144
# DERIVED CLASS MUST OVERRIDE THE lattice METHOD
145
################################################################
146
def lattice(self):
147
"""
148
Return the lattice corresponding to this subgroup in the rational
149
homology of the modular Jacobian product. The elements of the
150
subgroup are represented by vectors in the ambient vector space
151
(the rational homology), and this returns the lattice they span.
152
EXAMPLES::
153
154
sage: J = J0(33); C = J[0].cuspidal_subgroup(); C
155
Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
156
sage: C.lattice()
157
Free module of degree 6 and rank 2 over Integer Ring
158
Echelon basis matrix:
159
[ 1/5 13/5 -2 -4/5 2 -1/5]
160
[ 0 3 -2 -1 2 0]
161
"""
162
raise NotImplementedError
163
164
def _relative_basis_matrix(self):
165
"""
166
Return matrix of this finite subgroup, but relative to the homology
167
of the parent abelian variety.
168
169
EXAMPLES::
170
171
sage: A = J0(43)[1]; A
172
Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)
173
sage: C = A.cuspidal_subgroup(); C
174
Finite subgroup with invariants [7] over QQ of Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)
175
sage: C._relative_basis_matrix()
176
[ 1 0 0 0]
177
[ 0 1/7 6/7 5/7]
178
[ 0 0 1 0]
179
[ 0 0 0 1]
180
"""
181
try:
182
return self.__relative_basis_matrix
183
except AttributeError:
184
M = self.__abvar.lattice().coordinate_module(self.lattice()).basis_matrix()
185
self.__relative_basis_matrix = M
186
return M
187
188
# General functionality
189
def __cmp__(self, other):
190
"""
191
Compare this finite subgroup to other.
192
193
If other is not a modular abelian variety finite subgroup, then the
194
types of self and other are compared. If other is a finite
195
subgroup, and the ambient abelian varieties are equal, then the
196
subgroups themselves are compared, by comparing their full modules.
197
If the containing abelian varieties are not equal and their ambient
198
varieties are different they are compared; if they are the same,
199
then a NotImplemnetedError is raised (this is temporary).
200
201
EXAMPLES: We first compare to subgroups of `J_0(37)`::
202
203
sage: A = J0(37)
204
sage: G = A.torsion_subgroup(3); G.order()
205
81
206
sage: H = A.cuspidal_subgroup(); H.order()
207
3
208
sage: H < G
209
True
210
sage: H.is_subgroup(G)
211
True
212
sage: H < 5 #random (meaningless since it depends on memory layout)
213
False
214
sage: 5 < H #random (meaningless since it depends on memory layout)
215
True
216
217
The ambient varieties are compared::
218
219
sage: cmp(A[0].cuspidal_subgroup(), J0(11).cuspidal_subgroup())
220
1
221
222
Comparing subgroups sitting in different abelian varieties::
223
224
sage: cmp(A[0].cuspidal_subgroup(), A[1].cuspidal_subgroup())
225
-1
226
"""
227
if not isinstance(other, FiniteSubgroup):
228
return cmp(type(self), type(other))
229
A = self.abelian_variety()
230
B = other.abelian_variety()
231
if not A.in_same_ambient_variety(B):
232
return cmp(A.ambient_variety(), B.ambient_variety())
233
L = A.lattice() + B.lattice()
234
# Minus sign because order gets reversed in passing to lattices.
235
return -cmp(self.lattice() + L, other.lattice() + L)
236
237
def is_subgroup(self, other):
238
"""
239
Return True exactly if self is a subgroup of other, and both are
240
defined as subgroups of the same ambient abelian variety.
241
242
EXAMPLES::
243
244
sage: C = J0(22).cuspidal_subgroup()
245
sage: H = C.subgroup([C.0])
246
sage: K = C.subgroup([C.1])
247
sage: H.is_subgroup(K)
248
False
249
sage: K.is_subgroup(H)
250
False
251
sage: K.is_subgroup(C)
252
True
253
sage: H.is_subgroup(C)
254
True
255
"""
256
# We use that self is contained in other, whether other is
257
# either a finite group or an abelian variety, if and only
258
# if self doesn't shrink when intersected with other.
259
try:
260
return self.intersection(other).order() == self.order()
261
except TypeError:
262
return False
263
264
def __add__(self, other):
265
"""
266
Return the sum of two subgroups.
267
268
EXAMPLES::
269
270
sage: C = J0(22).cuspidal_subgroup()
271
sage: C.gens()
272
[[(1/5, 1/5, 4/5, 0)], [(0, 0, 0, 1/5)]]
273
sage: A = C.subgroup([C.0]); B = C.subgroup([C.1])
274
sage: A + B == C
275
True
276
"""
277
if not isinstance(other, FiniteSubgroup):
278
raise TypeError, "only addition of two finite subgroups is defined"
279
A = self.abelian_variety()
280
B = other.abelian_variety()
281
if not A.in_same_ambient_variety(B):
282
raise ValueError("self and other must be in the same ambient Jacobian")
283
K = composite_field(self.field_of_definition(), other.field_of_definition())
284
lattice = self.lattice() + other.lattice()
285
if A != B:
286
lattice += C.lattice()
287
288
return FiniteSubgroup_lattice(self.abelian_variety(), lattice, field_of_definition=K)
289
290
def exponent(self):
291
"""
292
Return the exponent of this finite abelian group.
293
294
OUTPUT: Integer
295
296
EXAMPLES::
297
298
sage: t = J0(33).hecke_operator(7)
299
sage: G = t.kernel()[0]; G
300
Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3
301
sage: G.exponent()
302
4
303
"""
304
try:
305
return self.__exponent
306
except AttributeError:
307
e = lcm(self.invariants())
308
self.__exponent = e
309
return e
310
311
def intersection(self, other):
312
"""
313
Return the intersection of the finite subgroups self and other.
314
315
INPUT:
316
317
318
- ``other`` - a finite group
319
320
321
OUTPUT: a finite group
322
323
EXAMPLES::
324
325
sage: E11a0, E11a1, B = J0(33)
326
sage: G = E11a0.torsion_subgroup(6); H = E11a0.torsion_subgroup(9)
327
sage: G.intersection(H)
328
Finite subgroup with invariants [3, 3] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
329
sage: W = E11a1.torsion_subgroup(15)
330
sage: G.intersection(W)
331
Finite subgroup with invariants [] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
332
sage: E11a0.intersection(E11a1)[0]
333
Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
334
335
We intersect subgroups of different abelian varieties.
336
337
::
338
339
sage: E11a0, E11a1, B = J0(33)
340
sage: G = E11a0.torsion_subgroup(5); H = E11a1.torsion_subgroup(5)
341
sage: G.intersection(H)
342
Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
343
sage: E11a0.intersection(E11a1)[0]
344
Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
345
346
We intersect abelian varieties with subgroups::
347
348
sage: t = J0(33).hecke_operator(7)
349
sage: G = t.kernel()[0]; G
350
Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3
351
sage: A = J0(33).old_subvariety()
352
sage: A.intersection(G)
353
Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)
354
sage: A.hecke_operator(7).kernel()[0]
355
Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)
356
sage: B = J0(33).new_subvariety()
357
sage: B.intersection(G)
358
Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)
359
sage: B.hecke_operator(7).kernel()[0]
360
Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)
361
sage: A.intersection(B)[0]
362
Finite subgroup with invariants [3, 3] over QQ of Abelian subvariety of dimension 2 of J0(33)
363
"""
364
A = self.abelian_variety()
365
if abelian_variety.is_ModularAbelianVariety(other):
366
amb = other
367
B = other
368
M = B.lattice().scale(Integer(1)/self.exponent())
369
K = composite_field(self.field_of_definition(), other.base_field())
370
else:
371
amb = A
372
if not isinstance(other, FiniteSubgroup):
373
raise TypeError, "only addition of two finite subgroups is defined"
374
B = other.abelian_variety()
375
if A.ambient_variety() != B.ambient_variety():
376
raise TypeError, "finite subgroups must be in the same ambient product Jacobian"
377
M = other.lattice()
378
K = composite_field(self.field_of_definition(), other.field_of_definition())
379
380
L = self.lattice()
381
if A != B:
382
# TODO: This might be way slower than what we could do if
383
# we think more carefully.
384
C = A + B
385
L = L + C.lattice()
386
M = M + C.lattice()
387
W = L.intersection(M).intersection(amb.vector_space())
388
return FiniteSubgroup_lattice(amb, W, field_of_definition=K)
389
390
def __mul__(self, right):
391
"""
392
Multiply this subgroup by the rational number right.
393
394
If right is an integer the result is a subgroup of self. If right
395
is a rational number `n/m`, then this group is first
396
divided by `m` then multiplied by `n`.
397
398
INPUT:
399
400
401
- ``right`` - a rational number
402
403
404
OUTPUT: a subgroup
405
406
EXAMPLES::
407
408
sage: J = J0(37)
409
sage: H = J.cuspidal_subgroup(); H.order()
410
3
411
sage: G = H * 3; G.order()
412
1
413
sage: G = H * (1/2); G.order()
414
48
415
sage: J.torsion_subgroup(2) + H == G
416
True
417
sage: G = H*(3/2); G.order()
418
16
419
sage: J = J0(42)
420
sage: G = J.cuspidal_subgroup(); factor(G.order())
421
2^8 * 3^2
422
sage: (G * 3).order()
423
256
424
sage: (G * 0).order()
425
1
426
sage: (G * (1/5)).order()
427
22500000000
428
"""
429
lattice = self.lattice().scale(right)
430
return FiniteSubgroup_lattice(self.abelian_variety(), lattice,
431
field_of_definition = self.field_of_definition())
432
433
def __rmul__(self, left):
434
"""
435
Multiply this finite subgroup on the left by an integer.
436
437
EXAMPLES::
438
439
sage: J = J0(42)
440
sage: G = J.cuspidal_subgroup(); factor(G.order())
441
2^8 * 3^2
442
sage: H = G.__rmul__(2)
443
sage: H.order().factor()
444
2^4 * 3^2
445
sage: 2*G
446
Finite subgroup with invariants [6, 24] over QQ of Abelian variety J0(42) of dimension 5
447
"""
448
return self * left
449
450
def abelian_variety(self):
451
"""
452
Return the abelian variety that this is a finite subgroup of.
453
454
EXAMPLES::
455
456
sage: J = J0(42)
457
sage: G = J.rational_torsion_subgroup(); G
458
Torsion subgroup of Abelian variety J0(42) of dimension 5
459
sage: G.abelian_variety()
460
Abelian variety J0(42) of dimension 5
461
"""
462
return self.__abvar
463
464
def field_of_definition(self):
465
"""
466
Return the field over which this finite modular abelian variety
467
subgroup is defined. This is a field over which this subgroup is
468
defined.
469
470
EXAMPLES::
471
472
sage: J = J0(42)
473
sage: G = J.rational_torsion_subgroup(); G
474
Torsion subgroup of Abelian variety J0(42) of dimension 5
475
sage: G.field_of_definition()
476
Rational Field
477
"""
478
return self.__field_of_definition
479
480
def _repr_(self):
481
"""
482
Return string representation of this finite subgroup.
483
484
EXAMPLES::
485
486
sage: J = J0(42)
487
sage: G = J.torsion_subgroup(3); G._repr_()
488
'Finite subgroup with invariants [3, 3, 3, 3, 3, 3, 3, 3, 3, 3] over QQ of Abelian variety J0(42) of dimension 5'
489
"""
490
K = self.__field_of_definition
491
if K == QQbar:
492
field = "QQbar"
493
elif K == QQ:
494
field = "QQ"
495
else:
496
field = str(K)
497
return "Finite subgroup %sover %s of %s"%(self._invariants_repr(), field, self.__abvar)
498
499
def _invariants_repr(self):
500
"""
501
The string representation of the 'invariants' part of this group.
502
503
We make this a separate function so it is possible to create finite
504
subgroups that don't print their invariants, since printing them
505
could be expensive.
506
507
EXAMPLES::
508
509
sage: J0(42).cuspidal_subgroup()._invariants_repr()
510
'with invariants [2, 2, 12, 48] '
511
"""
512
return 'with invariants %s '%(self.invariants(), )
513
514
def order(self):
515
"""
516
Return the order (number of elements) of this finite subgroup.
517
518
EXAMPLES::
519
520
sage: J = J0(42)
521
sage: C = J.cuspidal_subgroup()
522
sage: C.order()
523
2304
524
"""
525
try:
526
return self.__order
527
except AttributeError:
528
if self.__abvar.dimension() == 0:
529
self.__order = ZZ(1)
530
return self.__order
531
o = prod(self.invariants())
532
self.__order = o
533
return o
534
535
def gens(self):
536
"""
537
Return generators for this finite subgroup.
538
539
EXAMPLES: We list generators for several cuspidal subgroups::
540
541
sage: J0(11).cuspidal_subgroup().gens()
542
[[(0, 1/5)]]
543
sage: J0(37).cuspidal_subgroup().gens()
544
[[(0, 0, 0, 1/3)]]
545
sage: J0(43).cuspidal_subgroup().gens()
546
[[(0, 1/7, 0, 6/7, 0, 5/7)]]
547
sage: J1(13).cuspidal_subgroup().gens()
548
[[(1/19, 0, 0, 9/19)], [(0, 1/19, 1/19, 18/19)]]
549
sage: J0(22).torsion_subgroup(6).gens()
550
[[(1/6, 0, 0, 0)], [(0, 1/6, 0, 0)], [(0, 0, 1/6, 0)], [(0, 0, 0, 1/6)]]
551
"""
552
try:
553
return self.__gens
554
except AttributeError:
555
pass
556
557
B = [TorsionPoint(self, v) for v in self.lattice().basis() if v.denominator() > 1]
558
self.__gens = Sequence(B, immutable=True)
559
return self.__gens
560
561
def gen(self, n):
562
r"""
563
Return `n^{th}` generator of self.
564
565
EXAMPLES::
566
567
sage: J = J0(23)
568
sage: C = J.torsion_subgroup(3)
569
sage: C.gens()
570
[[(1/3, 0, 0, 0)], [(0, 1/3, 0, 0)], [(0, 0, 1/3, 0)], [(0, 0, 0, 1/3)]]
571
sage: C.gen(0)
572
[(1/3, 0, 0, 0)]
573
sage: C.gen(3)
574
[(0, 0, 0, 1/3)]
575
sage: C.gen(4)
576
Traceback (most recent call last):
577
...
578
IndexError: list index out of range
579
580
Negative indices wrap around::
581
582
sage: C.gen(-1)
583
[(0, 0, 0, 1/3)]
584
"""
585
return self.gens()[n]
586
587
def __call__(self, x):
588
r"""
589
Coerce `x` into this finite subgroup.
590
591
This works when the abelian varieties that contains x and self are
592
the same, or if `x` is coercible into the rational homology
593
(viewed as an abstract `\QQ`-vector space).
594
595
EXAMPLES: We first construct the `11`-torsion subgroup of
596
`J_0(23)`::
597
598
sage: J = J0(23)
599
sage: G = J.torsion_subgroup(11)
600
sage: G.invariants()
601
[11, 11, 11, 11]
602
603
We also construct the cuspidal subgroup.
604
605
::
606
607
sage: C = J.cuspidal_subgroup()
608
sage: C.invariants()
609
[11]
610
611
Coercing something into its parent returns it::
612
613
sage: G(G.0) is G.0
614
True
615
616
We coerce an element from the cuspidal subgroup into the
617
`11`-torsion subgroup::
618
619
sage: z = G(C.0); z
620
[(1/11, 10/11, 0, 8/11)]
621
sage: z.parent() == G
622
True
623
624
We coerce a list, which defines an element of the underlying
625
``full_module`` into `G`, and verify an
626
equality::
627
628
sage: x = G([1/11, 1/11, 0, -1/11])
629
sage: x == G([1/11, 1/11, 0, 10/11])
630
True
631
632
Finally we attempt to coerce in an element that shouldn't work,
633
since is is not in `G`::
634
635
sage: G(J.torsion_subgroup(3).0)
636
Traceback (most recent call last):
637
...
638
TypeError: x does not define an element of self
639
"""
640
if isinstance(x, TorsionPoint):
641
if x.parent() is self:
642
return x
643
elif x.parent() == self:
644
return TorsionPoint(self, x.element(), check=False)
645
elif x.parent().abelian_variety() == self.abelian_variety():
646
return self(x.element())
647
else:
648
raise TypeError, "x does not define an element of self"
649
else:
650
z = self.abelian_variety().vector_space()(x)
651
if not z in self.lattice():
652
raise TypeError, "x does not define an element of self"
653
return TorsionPoint(self, z, check=False)
654
655
656
def __contains__(self, x):
657
"""
658
Returns True if x is contained in this finite subgroup.
659
660
EXAMPLES: We define two distinct finite subgroups of
661
`J_0(27)`::
662
663
sage: G1 = J0(27).rational_cusp_subgroup(); G1
664
Finite subgroup with invariants [3] over QQ of Abelian variety J0(27) of dimension 1
665
sage: G1.0
666
[(1/3, 0)]
667
sage: G2 = J0(27).cuspidal_subgroup(); G2
668
Finite subgroup with invariants [3, 3] over QQ of Abelian variety J0(27) of dimension 1
669
sage: G2.gens()
670
[[(1/3, 0)], [(0, 1/3)]]
671
672
Now we check whether various elements are in `G_1` and
673
`G_2`::
674
675
sage: G2.0 in G1
676
True
677
sage: G2.1 in G1
678
False
679
sage: G1.0 in G1
680
True
681
sage: G1.0 in G2
682
True
683
684
The integer `0` is in, since it coerces in::
685
686
sage: 0 in G1
687
True
688
689
Elements that have a completely different ambient product Jacobian
690
are never in `G`::
691
692
sage: J0(23).cuspidal_subgroup().0 in G1
693
False
694
sage: J0(23).cuspidal_subgroup()(0) in G1
695
False
696
"""
697
try:
698
self(x)
699
except TypeError:
700
return False
701
return True
702
703
def subgroup(self, gens):
704
"""
705
Return the subgroup of self spanned by the given generators, which
706
all must be elements of self.
707
708
EXAMPLES::
709
710
sage: J = J0(23)
711
sage: G = J.torsion_subgroup(11); G
712
Finite subgroup with invariants [11, 11, 11, 11] over QQ of Abelian variety J0(23) of dimension 2
713
714
We create the subgroup of the 11-torsion subgroup of
715
`J_0(23)` generated by the first `11`-torsion
716
point::
717
718
sage: H = G.subgroup([G.0]); H
719
Finite subgroup with invariants [11] over QQbar of Abelian variety J0(23) of dimension 2
720
sage: H.invariants()
721
[11]
722
723
We can also create a subgroup from a list of objects that coerce
724
into the ambient rational homology.
725
726
::
727
728
sage: H == G.subgroup([[1/11,0,0,0]])
729
True
730
"""
731
if not isinstance(gens, (tuple, list)):
732
raise TypeError, "gens must be a list or tuple"
733
A = self.abelian_variety()
734
lattice = A._ambient_lattice().span([self(g).element() for g in gens])
735
return FiniteSubgroup_lattice(self.abelian_variety(), lattice, field_of_definition=QQbar)
736
737
def invariants(self):
738
r"""
739
Return elementary invariants of this abelian group, by which we
740
mean a nondecreasing (immutable) sequence of integers
741
`n_i`, `1 \leq i \leq k`, with `n_i`
742
dividing `n_{i+1}`, and such that this group is abstractly
743
isomorphic to
744
`\ZZ/n_1\ZZ \times\cdots\times \ZZ/n_k\ZZ.`
745
746
EXAMPLES::
747
748
sage: J = J0(38)
749
sage: C = J.cuspidal_subgroup(); C
750
Finite subgroup with invariants [3, 45] over QQ of Abelian variety J0(38) of dimension 4
751
sage: v = C.invariants(); v
752
[3, 45]
753
sage: v[0] = 5
754
Traceback (most recent call last):
755
...
756
ValueError: object is immutable; please change a copy instead.
757
sage: type(v[0])
758
<type 'sage.rings.integer.Integer'>
759
760
::
761
762
sage: C * 3
763
Finite subgroup with invariants [15] over QQ of Abelian variety J0(38) of dimension 4
764
765
An example involving another cuspidal subgroup::
766
767
sage: C = J0(22).cuspidal_subgroup(); C
768
Finite subgroup with invariants [5, 5] over QQ of Abelian variety J0(22) of dimension 2
769
sage: C.lattice()
770
Free module of degree 4 and rank 4 over Integer Ring
771
Echelon basis matrix:
772
[1/5 1/5 4/5 0]
773
[ 0 1 0 0]
774
[ 0 0 1 0]
775
[ 0 0 0 1/5]
776
sage: C.invariants()
777
[5, 5]
778
"""
779
try:
780
return self.__invariants
781
except AttributeError:
782
pass
783
M = self.lattice().coordinate_module(self.abelian_variety().lattice())
784
E = M.basis_matrix().change_ring(ZZ).elementary_divisors()
785
v = [Integer(x) for x in E if x != 1]
786
I = Sequence(v)
787
I.sort()
788
I.set_immutable()
789
self.__invariants = I
790
return I
791
792
class FiniteSubgroup_lattice(FiniteSubgroup):
793
def __init__(self, abvar, lattice, field_of_definition=QQbar, check=True):
794
"""
795
A finite subgroup of a modular abelian variety that is defined by a
796
given lattice.
797
798
INPUT:
799
800
801
- ``abvar`` - a modular abelian variety
802
803
- ``lattice`` - a lattice that contains the lattice of
804
abvar
805
806
- ``field_of_definition`` - the field of definition
807
of this finite group scheme
808
809
- ``check`` - bool (default: True) whether or not to
810
check that lattice contains the abvar lattice.
811
812
813
EXAMPLES::
814
815
sage: J = J0(11)
816
sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G
817
Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1
818
"""
819
if check:
820
if not is_FreeModule(lattice) or lattice.base_ring() != ZZ:
821
raise TypeError, "lattice must be a free module over ZZ"
822
if not abelian_variety.is_ModularAbelianVariety(abvar):
823
raise TypeError, "abvar must be a modular abelian variety"
824
if not abvar.lattice().is_submodule(lattice):
825
lattice += abvar.lattice()
826
if lattice.rank() != abvar.lattice().rank():
827
raise ValueError, "lattice must contain the lattice of abvar with finite index"
828
FiniteSubgroup.__init__(self, abvar, field_of_definition)
829
self.__lattice = lattice
830
831
def lattice(self):
832
r"""
833
Return lattice that defines this finite subgroup.
834
835
EXAMPLES::
836
837
sage: J = J0(11)
838
sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G
839
Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1
840
sage: G.lattice()
841
Free module of degree 2 and rank 2 over Integer Ring
842
Echelon basis matrix:
843
[1/3 0]
844
[ 0 1/5]
845
"""
846
return self.__lattice
847
848
###########################################################################
849
# Elements of finite order
850
###########################################################################
851
852
class TorsionPoint(ModuleElement):
853
def __init__(self, parent, element, check=True):
854
"""
855
An element of a finite subgroup of a modular abelian variety.
856
857
INPUT:
858
859
860
- ``parent`` - a finite subgroup of a modular abelian
861
variety
862
863
- ``element`` - a QQ vector space element that
864
represents this element in terms of the ambient rational homology
865
866
- ``check`` - bool (default: True) whether to check
867
that element is in the appropriate vector space
868
869
870
EXAMPLES: The following calls the TorsionPoint constructor
871
implicitly::
872
873
sage: J = J0(11)
874
sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G
875
Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1
876
sage: type(G.0)
877
<class 'sage.modular.abvar.finite_subgroup.TorsionPoint'>
878
"""
879
ModuleElement.__init__(self, parent)
880
if check:
881
if not element in parent.abelian_variety().vector_space():
882
raise TypeError, "element must be a vector in the abelian variety's rational homology (embedded in the ambient Jacobian product)"
883
if element.denominator() == 1:
884
element = element.parent().zero_vector()
885
self.__element = element
886
887
def element(self):
888
"""
889
Return an underlying QQ-vector space element that defines this
890
element of a modular abelian variety. This is a vector in the
891
ambient Jacobian variety's rational homology.
892
893
EXAMPLES: We create some elements of `J_0(11)`::
894
895
sage: J = J0(11)
896
sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G
897
Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1
898
sage: G.0.element()
899
(1/3, 0)
900
901
The underlying element is a vector over the rational numbers::
902
903
sage: v = (G.0-G.1).element(); v
904
(1/3, -1/5)
905
sage: type(v)
906
<type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
907
"""
908
return self.__element
909
910
def _repr_(self):
911
r"""
912
Return string representation of this finite subgroup element. Since
913
they are represented as equivalences classes of rational homology
914
modulo integral homology, we represent an element corresponding to
915
`v` in the rational homology by ``[v]``.
916
917
EXAMPLES::
918
919
sage: J = J0(11)
920
sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G
921
Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1
922
sage: G.0._repr_()
923
'[(1/3, 0)]'
924
"""
925
return '[%s]'%self.__element
926
927
def _add_(self, other):
928
"""
929
Add two finite subgroup elements with the same parent. This is
930
called implicitly by +.
931
932
INPUT:
933
934
935
- ``other`` - a TorsionPoint with the same parent as
936
self
937
938
939
OUTPUT: a TorsionPoint
940
941
EXAMPLES::
942
943
sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
944
sage: G.0._add_(G.1)
945
[(1/3, 1/5)]
946
sage: G.0 + G.1
947
[(1/3, 1/5)]
948
"""
949
return TorsionPoint(self.parent(), self.__element + other.__element, check=False)
950
951
def _sub_(self, other):
952
"""
953
Subtract two finite subgroup elements with the same parent. This is
954
called implicitly by +.
955
956
INPUT:
957
958
959
- ``other`` - a TorsionPoint with the same parent as
960
self
961
962
963
OUTPUT: a TorsionPoint
964
965
EXAMPLES::
966
967
sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
968
sage: G.0._sub_(G.1)
969
[(1/3, -1/5)]
970
sage: G.0 - G.1
971
[(1/3, -1/5)]
972
"""
973
return TorsionPoint(self.parent(), self.__element - other.__element, check=False)
974
975
def _neg_(self):
976
"""
977
Negate a finite subgroup element.
978
979
EXAMPLES::
980
981
sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
982
sage: G.0._neg_()
983
[(-1/3, 0)]
984
"""
985
return TorsionPoint(self.parent(), -self.__element, check=False)
986
987
def _rmul_(self, left):
988
"""
989
Left multiply a finite subgroup element by an integer.
990
991
EXAMPLES::
992
993
sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
994
sage: G.0._rmul_(2)
995
[(2/3, 0)]
996
sage: 2*G.0
997
[(2/3, 0)]
998
"""
999
return TorsionPoint(self.parent(), ZZ(left) * self.__element, check=False)
1000
1001
def _lmul_(self, right):
1002
"""
1003
Right multiply a finite subgroup element by an integer.
1004
1005
EXAMPLES::
1006
1007
sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
1008
sage: G.0._lmul_(2)
1009
[(2/3, 0)]
1010
sage: G.0 * 2
1011
[(2/3, 0)]
1012
"""
1013
return TorsionPoint(self.parent(), self.__element * right, check=False)
1014
1015
def __cmp__(self, right):
1016
"""
1017
Compare self and right.
1018
1019
INPUT:
1020
1021
1022
- ``self, right`` - elements of the same finite
1023
abelian variety subgroup.
1024
1025
1026
OUTPUT: -1, 0, or 1
1027
1028
EXAMPLES::
1029
1030
sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
1031
sage: cmp(G.0, G.1)
1032
1
1033
sage: cmp(G.0, G.0)
1034
0
1035
sage: 3*G.0 == 0
1036
True
1037
sage: 3*G.0 == 5*G.1
1038
True
1039
1040
We make sure things that shouldn't be equal aren't::
1041
1042
sage: H = J0(14).finite_subgroup([[1/3,0]])
1043
sage: G.0 == H.0
1044
False
1045
sage: cmp(G.0, H.0)
1046
-1
1047
sage: G.0
1048
[(1/3, 0)]
1049
sage: H.0
1050
[(1/3, 0)]
1051
"""
1052
if not isinstance(right, TorsionPoint):
1053
return cmp(type(self), type(right))
1054
A = self.parent().abelian_variety()
1055
B = right.parent().abelian_variety()
1056
if A.groups() != B.groups():
1057
return cmp(A,B)
1058
elif self.__element.change_ring(QQ) - right.__element.change_ring(QQ) in A.lattice() + B.lattice():
1059
return 0
1060
else:
1061
return cmp(self.__element, right.__element)
1062
1063
def additive_order(self):
1064
"""
1065
Return the additive order of this element.
1066
1067
EXAMPLES::
1068
1069
sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
1070
sage: G.0.additive_order()
1071
3
1072
sage: G.1.additive_order()
1073
5
1074
sage: (G.0 + G.1).additive_order()
1075
15
1076
sage: (3*G.0).additive_order()
1077
1
1078
"""
1079
return self._relative_element().denominator()
1080
1081
def _relative_element(self):
1082
"""
1083
Return coordinates of this element in terms of basis for the
1084
integral homology of the containing abelian variety.
1085
1086
OUTPUT: vector
1087
1088
EXAMPLES::
1089
1090
sage: A = J0(43)[1]; A
1091
Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)
1092
sage: C = A.cuspidal_subgroup(); C
1093
Finite subgroup with invariants [7] over QQ of Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)
1094
sage: x = C.0; x
1095
[(0, 1/7, 0, 6/7, 0, 5/7)]
1096
sage: x._relative_element()
1097
(0, 1/7, 6/7, 5/7)
1098
"""
1099
return self.parent().abelian_variety().lattice().coordinate_vector(self.__element)
1100
1101
1102