Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/elliptic_curves/ell_torsion.py
8820 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
(5 : -6 : 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)) # known bug, see http://trac.sagemath.org/sage_trac/ticket/11599#comment:7
159
True
160
"""
161
self.__E = E
162
self.__K = E.base_field()
163
164
pari_torsion_algorithms = ["pari","doud","lutz_nagell"]
165
166
if self.__K is RationalField() and algorithm in pari_torsion_algorithms:
167
flag = pari_torsion_algorithms.index(algorithm)
168
169
G = None
170
loop = 0
171
while G is None and loop < 3:
172
loop += 1
173
try:
174
G = self.__E.pari_curve(prec = 400).elltors(flag) # pari_curve will return the curve of maximum known precision
175
except RuntimeError:
176
self.__E.pari_curve(factor = 2) # caches a curve of twice the precision
177
if G is not None:
178
order = G[0].python()
179
structure = G[1].python()
180
gens = G[2].python()
181
182
self.__torsion_gens = [ self.__E(P) for P in gens ]
183
from sage.groups.additive_abelian.additive_abelian_group import cover_and_relations_from_invariants
184
groups.AdditiveAbelianGroupWrapper.__init__(self, self.__E(0).parent(), self.__torsion_gens, structure)
185
return
186
187
T1 = E(0) # these will be the two generators
188
T2 = E(0)
189
k1 = 1 # with their order
190
k2 = 1
191
192
# find a multiple of the order of the torsion group
193
bound = E._torsion_bound(number_of_places=20)
194
195
# now do prime by prime
196
for p,e in bound.factor():
197
ptor = E._p_primary_torsion_basis(p,e)
198
# print p,'-primary part is ',ptor
199
if len(ptor)>0:
200
T1 += ptor[0][0]
201
k1 *= p**(ptor[0][1])
202
if len(ptor)>1:
203
T2 += ptor[1][0]
204
k2 *= p**(ptor[1][1])
205
206
order = k1*k2
207
if k1 == 1:
208
structure = []
209
gens = []
210
elif k2 == 1:
211
structure = [k1]
212
gens = [T1]
213
else:
214
structure = [k1,k2]
215
gens = [T1,T2]
216
217
#self.__torsion_gens = gens
218
self._structure = structure
219
groups.AdditiveAbelianGroupWrapper.__init__(self, T1.parent(), [T1, T2], structure)
220
221
222
def _repr_(self):
223
"""
224
String representation of an instance of the EllipticCurveTorsionSubgroup class.
225
226
EXAMPLES::
227
228
sage: E=EllipticCurve('11a1')
229
sage: K.<i>=NumberField(x^2+1)
230
sage: EK=E.change_ring(K)
231
sage: T = EK.torsion_subgroup(); T._repr_()
232
'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'
233
"""
234
return "Torsion Subgroup isomorphic to %s associated to the %s" % (self.short_name(), self.__E)
235
236
def __cmp__(self,other):
237
r"""
238
Compares two torsion groups by simply comparing the elliptic curves.
239
240
EXAMPLES::
241
242
sage: E = EllipticCurve('37a1')
243
sage: tor = E.torsion_subgroup()
244
sage: tor == tor
245
True
246
"""
247
c = cmp(type(self), type(other))
248
if c:
249
return c
250
return cmp(self.__E, other.__E)
251
252
def curve(self):
253
"""
254
Return the curve of this torsion subgroup.
255
256
EXAMPLES::
257
258
sage: E=EllipticCurve('11a1')
259
sage: K.<i>=NumberField(x^2+1)
260
sage: EK=E.change_ring(K)
261
sage: T = EK.torsion_subgroup()
262
sage: T.curve() is EK
263
True
264
"""
265
return self.__E
266
267
@cached_method
268
def points(self):
269
"""
270
Return a list of all the points in this torsion subgroup.
271
The list is cached.
272
273
EXAMPLES::
274
275
sage: K.<i>=NumberField(x^2 + 1)
276
sage: E = EllipticCurve(K,[0,0,0,1,0])
277
sage: tor = E.torsion_subgroup()
278
sage: tor.points()
279
[(0 : 1 : 0), (-i : 0 : 1), (0 : 0 : 1), (i : 0 : 1)]
280
"""
281
return [x.element() for x in self]
282
283