Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/elliptic_curves/ell_torsion.py
4156 views
1
# -*- coding: utf-8 -*-
2
r"""
3
Torsion subgroups of elliptic curves over number fields (including `\QQ`)
4
5
AUTHORS:
6
7
- Nick Alexander: original implementation over `\QQ`
8
- Chris Wuthrich: original implementation over number fields
9
- John Cremona: rewrote p-primary part to use division
10
polynomials, added some features, unified Number Field and `\QQ` code.
11
"""
12
13
#*****************************************************************************
14
# Copyright (C) 2005 William Stein <[email protected]>
15
#
16
# Distributed under the terms of the GNU General Public License (GPL)
17
#
18
# This code is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
# General Public License for more details.
22
#
23
# The full text of the GPL is available at:
24
#
25
# http://www.gnu.org/licenses/
26
#*****************************************************************************
27
28
from sage.misc.cachefunc import cached_method
29
from sage.rings.all import (Integer, RationalField, ZZ)
30
import sage.groups.additive_abelian.additive_abelian_wrapper as groups
31
32
class EllipticCurveTorsionSubgroup(groups.AdditiveAbelianGroupWrapper):
33
r"""
34
The torsion subgroup of an elliptic curve over a number field.
35
36
EXAMPLES:
37
38
Examples over `\QQ`::
39
40
sage: E = EllipticCurve([-4, 0]); E
41
Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field
42
sage: G = E.torsion_subgroup(); G
43
Torsion Subgroup isomorphic to Z/2 + Z/2 associated to the Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field
44
sage: G.order()
45
4
46
sage: G.gen(0)
47
(2 : 0 : 1)
48
sage: G.gen(1)
49
(0 : 0 : 1)
50
sage: G.ngens()
51
2
52
53
::
54
55
sage: E = EllipticCurve([17, -120, -60, 0, 0]); E
56
Elliptic Curve defined by y^2 + 17*x*y - 60*y = x^3 - 120*x^2 over Rational Field
57
sage: G = E.torsion_subgroup(); G
58
Torsion Subgroup isomorphic to Trivial group associated to the Elliptic Curve defined by y^2 + 17*x*y - 60*y = x^3 - 120*x^2 over Rational Field
59
sage: G.gens()
60
()
61
sage: e = EllipticCurve([0, 33076156654533652066609946884,0,\
62
347897536144342179642120321790729023127716119338758604800,\
63
1141128154369274295519023032806804247788154621049857648870032370285851781352816640000])
64
sage: e.torsion_order()
65
16
66
67
Constructing points from the torsion subgroup::
68
69
sage: E = EllipticCurve('14a1')
70
sage: T = E.torsion_subgroup()
71
sage: [E(t) for t in T]
72
[(0 : 1 : 0),
73
(9 : 23 : 1),
74
(2 : 2 : 1),
75
(1 : -1 : 1),
76
(2 : -5 : 1),
77
(9 : -33 : 1)]
78
79
An example where the torsion subgroup is not cyclic::
80
81
sage: E = EllipticCurve([0,0,0,-49,0])
82
sage: T = E.torsion_subgroup()
83
sage: [E(t) for t in T]
84
[(0 : 1 : 0), (7 : 0 : 1), (0 : 0 : 1), (-7 : 0 : 1)]
85
86
An example where the torsion subgroup is trivial::
87
88
sage: E = EllipticCurve('37a1')
89
sage: T = E.torsion_subgroup()
90
sage: T
91
Torsion Subgroup isomorphic to Trivial group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
92
sage: [E(t) for t in T]
93
[(0 : 1 : 0)]
94
95
Examples over other Number Fields::
96
97
sage: E=EllipticCurve('11a1')
98
sage: K.<i>=NumberField(x^2+1)
99
sage: EK=E.change_ring(K)
100
sage: from sage.schemes.elliptic_curves.ell_torsion import EllipticCurveTorsionSubgroup
101
sage: EllipticCurveTorsionSubgroup(EK)
102
Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1
103
104
sage: E=EllipticCurve('11a1')
105
sage: K.<i>=NumberField(x^2+1)
106
sage: EK=E.change_ring(K)
107
sage: T = EK.torsion_subgroup()
108
sage: T.ngens()
109
1
110
sage: T.gen(0)
111
(16 : 60 : 1)
112
113
Note: this class is normally constructed indirectly as follows::
114
115
sage: T = EK.torsion_subgroup(); T
116
Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1
117
sage: type(T)
118
<class 'sage.schemes.elliptic_curves.ell_torsion.EllipticCurveTorsionSubgroup_with_category'>
119
120
121
AUTHORS:
122
123
- Nick Alexander - initial implementation over `\QQ`.
124
- Chris Wuthrich - initial implementation over number fields.
125
- John Cremona - additional features and unification.
126
"""
127
def __init__(self, E, algorithm=None):
128
r"""
129
Initialization function for EllipticCurveTorsionSubgroup class
130
131
INPUT:
132
133
- ``E`` - An elliptic curve defined over a number field (including `\Q`)
134
135
- ``algorithm`` - (string, default None): If not None, must be one
136
of 'PARI', 'doud', 'lutz_nagell'. For curves
137
defined over `\QQ`, PARI is then used with the
138
appropriate flag passed to PARI's ``elltors()``
139
function; this parameter is ignored for curves
140
whose base field is not `\QQ`.
141
142
EXAMPLES::
143
144
sage: from sage.schemes.elliptic_curves.ell_torsion import EllipticCurveTorsionSubgroup
145
sage: E=EllipticCurve('11a1')
146
sage: K.<i>=NumberField(x^2+1)
147
sage: EK=E.change_ring(K)
148
sage: EllipticCurveTorsionSubgroup(EK)
149
Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1
150
151
Note: this class is normally constructed indirectly as follows::
152
153
sage: T = EK.torsion_subgroup(); T
154
Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1
155
sage: type(T)
156
<class 'sage.schemes.elliptic_curves.ell_torsion.EllipticCurveTorsionSubgroup_with_category'>
157
158
sage: T == loads(dumps(T)) # optional - pickling http://trac.sagemath.org/sage_trac/ticket/11599
159
True
160
161
"""
162
self.__E = E
163
self.__K = E.base_field()
164
165
pari_torsion_algorithms = ["pari","doud","lutz_nagell"]
166
167
if self.__K is RationalField() and algorithm in pari_torsion_algorithms:
168
flag = pari_torsion_algorithms.index(algorithm)
169
170
G = None
171
loop = 0
172
while G is None and loop < 3:
173
loop += 1
174
try:
175
G = self.__E.pari_curve(prec = 400).elltors(flag) # pari_curve will return the curve of maximum known precision
176
except RuntimeError:
177
self.__E.pari_curve(factor = 2) # caches a curve of twice the precision
178
if G is not None:
179
order = G[0].python()
180
structure = G[1].python()
181
gens = G[2].python()
182
183
self.__torsion_gens = [ self.__E(P) for P in gens ]
184
from sage.groups.additive_abelian.additive_abelian_group import cover_and_relations_from_invariants
185
groups.AdditiveAbelianGroupWrapper.__init__(self, self.__E(0).parent(), self.__torsion_gens, structure)
186
return
187
188
T1 = E(0) # these will be the two generators
189
T2 = E(0)
190
k1 = 1 # with their order
191
k2 = 1
192
193
# find a multiple of the order of the torsion group
194
bound = E._torsion_bound(number_of_places=20)
195
196
# now do prime by prime
197
for p,e in bound.factor():
198
ptor = E._p_primary_torsion_basis(p,e)
199
# print p,'-primary part is ',ptor
200
if len(ptor)>0:
201
T1 += ptor[0][0]
202
k1 *= p**(ptor[0][1])
203
if len(ptor)>1:
204
T2 += ptor[1][0]
205
k2 *= p**(ptor[1][1])
206
207
order = k1*k2
208
if k1 == 1:
209
structure = []
210
gens = []
211
elif k2 == 1:
212
structure = [k1]
213
gens = [T1]
214
else:
215
structure = [k1,k2]
216
gens = [T1,T2]
217
218
#self.__torsion_gens = gens
219
self._structure = structure
220
groups.AdditiveAbelianGroupWrapper.__init__(self, T1.parent(), [T1, T2], structure)
221
222
223
def _repr_(self):
224
"""
225
String representation of an instance of the EllipticCurveTorsionSubgroup class.
226
227
EXAMPLES::
228
229
sage: E=EllipticCurve('11a1')
230
sage: K.<i>=NumberField(x^2+1)
231
sage: EK=E.change_ring(K)
232
sage: T = EK.torsion_subgroup(); T._repr_()
233
'Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1'
234
"""
235
return "Torsion Subgroup isomorphic to %s associated to the %s" % (self.short_name(), self.__E)
236
237
def __cmp__(self,other):
238
r"""
239
Compares two torsion groups by simply comparing the elliptic curves.
240
241
EXAMPLES::
242
243
sage: E = EllipticCurve('37a1')
244
sage: tor = E.torsion_subgroup()
245
sage: tor == tor
246
True
247
"""
248
c = cmp(type(self), type(other))
249
if c:
250
return c
251
return cmp(self.__E, other.__E)
252
253
def curve(self):
254
"""
255
Return the curve of this torsion subgroup.
256
257
EXAMPLES::
258
259
sage: E=EllipticCurve('11a1')
260
sage: K.<i>=NumberField(x^2+1)
261
sage: EK=E.change_ring(K)
262
sage: T = EK.torsion_subgroup()
263
sage: T.curve() is EK
264
True
265
"""
266
return self.__E
267
268
@cached_method
269
def points(self):
270
"""
271
Return a list of all the points in this torsion subgroup.
272
The list is cached.
273
274
EXAMPLES::
275
276
sage: K.<i>=NumberField(x^2 + 1)
277
sage: E = EllipticCurve(K,[0,0,0,1,0])
278
sage: tor = E.torsion_subgroup()
279
sage: tor.points()
280
[(0 : 1 : 0), (0 : 0 : 1), (i : 0 : 1), (-i : 0 : 1)]
281
"""
282
return [x.element() for x in self]
283
284