Path: blob/master/sage/schemes/elliptic_curves/ell_torsion.py
4156 views
# -*- coding: utf-8 -*-1r"""2Torsion subgroups of elliptic curves over number fields (including `\QQ`)34AUTHORS:56- Nick Alexander: original implementation over `\QQ`7- Chris Wuthrich: original implementation over number fields8- John Cremona: rewrote p-primary part to use division9polynomials, added some features, unified Number Field and `\QQ` code.10"""1112#*****************************************************************************13# Copyright (C) 2005 William Stein <[email protected]>14#15# Distributed under the terms of the GNU General Public License (GPL)16#17# This code is distributed in the hope that it will be useful,18# but WITHOUT ANY WARRANTY; without even the implied warranty of19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU20# General Public License for more details.21#22# The full text of the GPL is available at:23#24# http://www.gnu.org/licenses/25#*****************************************************************************2627from sage.misc.cachefunc import cached_method28from sage.rings.all import (Integer, RationalField, ZZ)29import sage.groups.additive_abelian.additive_abelian_wrapper as groups3031class EllipticCurveTorsionSubgroup(groups.AdditiveAbelianGroupWrapper):32r"""33The torsion subgroup of an elliptic curve over a number field.3435EXAMPLES:3637Examples over `\QQ`::3839sage: E = EllipticCurve([-4, 0]); E40Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field41sage: G = E.torsion_subgroup(); G42Torsion Subgroup isomorphic to Z/2 + Z/2 associated to the Elliptic Curve defined by y^2 = x^3 - 4*x over Rational Field43sage: G.order()44445sage: G.gen(0)46(2 : 0 : 1)47sage: G.gen(1)48(0 : 0 : 1)49sage: G.ngens()5025152::5354sage: E = EllipticCurve([17, -120, -60, 0, 0]); E55Elliptic Curve defined by y^2 + 17*x*y - 60*y = x^3 - 120*x^2 over Rational Field56sage: G = E.torsion_subgroup(); G57Torsion 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 Field58sage: G.gens()59()60sage: e = EllipticCurve([0, 33076156654533652066609946884,0,\61347897536144342179642120321790729023127716119338758604800,\621141128154369274295519023032806804247788154621049857648870032370285851781352816640000])63sage: e.torsion_order()64166566Constructing points from the torsion subgroup::6768sage: E = EllipticCurve('14a1')69sage: T = E.torsion_subgroup()70sage: [E(t) for t in T]71[(0 : 1 : 0),72(9 : 23 : 1),73(2 : 2 : 1),74(1 : -1 : 1),75(2 : -5 : 1),76(9 : -33 : 1)]7778An example where the torsion subgroup is not cyclic::7980sage: E = EllipticCurve([0,0,0,-49,0])81sage: T = E.torsion_subgroup()82sage: [E(t) for t in T]83[(0 : 1 : 0), (7 : 0 : 1), (0 : 0 : 1), (-7 : 0 : 1)]8485An example where the torsion subgroup is trivial::8687sage: E = EllipticCurve('37a1')88sage: T = E.torsion_subgroup()89sage: T90Torsion Subgroup isomorphic to Trivial group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field91sage: [E(t) for t in T]92[(0 : 1 : 0)]9394Examples over other Number Fields::9596sage: E=EllipticCurve('11a1')97sage: K.<i>=NumberField(x^2+1)98sage: EK=E.change_ring(K)99sage: from sage.schemes.elliptic_curves.ell_torsion import EllipticCurveTorsionSubgroup100sage: EllipticCurveTorsionSubgroup(EK)101Torsion 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 + 1102103sage: E=EllipticCurve('11a1')104sage: K.<i>=NumberField(x^2+1)105sage: EK=E.change_ring(K)106sage: T = EK.torsion_subgroup()107sage: T.ngens()1081109sage: T.gen(0)110(16 : 60 : 1)111112Note: this class is normally constructed indirectly as follows::113114sage: T = EK.torsion_subgroup(); T115Torsion 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 + 1116sage: type(T)117<class 'sage.schemes.elliptic_curves.ell_torsion.EllipticCurveTorsionSubgroup_with_category'>118119120AUTHORS:121122- Nick Alexander - initial implementation over `\QQ`.123- Chris Wuthrich - initial implementation over number fields.124- John Cremona - additional features and unification.125"""126def __init__(self, E, algorithm=None):127r"""128Initialization function for EllipticCurveTorsionSubgroup class129130INPUT:131132- ``E`` - An elliptic curve defined over a number field (including `\Q`)133134- ``algorithm`` - (string, default None): If not None, must be one135of 'PARI', 'doud', 'lutz_nagell'. For curves136defined over `\QQ`, PARI is then used with the137appropriate flag passed to PARI's ``elltors()``138function; this parameter is ignored for curves139whose base field is not `\QQ`.140141EXAMPLES::142143sage: from sage.schemes.elliptic_curves.ell_torsion import EllipticCurveTorsionSubgroup144sage: E=EllipticCurve('11a1')145sage: K.<i>=NumberField(x^2+1)146sage: EK=E.change_ring(K)147sage: EllipticCurveTorsionSubgroup(EK)148Torsion 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 + 1149150Note: this class is normally constructed indirectly as follows::151152sage: T = EK.torsion_subgroup(); T153Torsion 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 + 1154sage: type(T)155<class 'sage.schemes.elliptic_curves.ell_torsion.EllipticCurveTorsionSubgroup_with_category'>156157sage: T == loads(dumps(T)) # optional - pickling http://trac.sagemath.org/sage_trac/ticket/11599158True159160"""161self.__E = E162self.__K = E.base_field()163164pari_torsion_algorithms = ["pari","doud","lutz_nagell"]165166if self.__K is RationalField() and algorithm in pari_torsion_algorithms:167flag = pari_torsion_algorithms.index(algorithm)168169G = None170loop = 0171while G is None and loop < 3:172loop += 1173try:174G = self.__E.pari_curve(prec = 400).elltors(flag) # pari_curve will return the curve of maximum known precision175except RuntimeError:176self.__E.pari_curve(factor = 2) # caches a curve of twice the precision177if G is not None:178order = G[0].python()179structure = G[1].python()180gens = G[2].python()181182self.__torsion_gens = [ self.__E(P) for P in gens ]183from sage.groups.additive_abelian.additive_abelian_group import cover_and_relations_from_invariants184groups.AdditiveAbelianGroupWrapper.__init__(self, self.__E(0).parent(), self.__torsion_gens, structure)185return186187T1 = E(0) # these will be the two generators188T2 = E(0)189k1 = 1 # with their order190k2 = 1191192# find a multiple of the order of the torsion group193bound = E._torsion_bound(number_of_places=20)194195# now do prime by prime196for p,e in bound.factor():197ptor = E._p_primary_torsion_basis(p,e)198# print p,'-primary part is ',ptor199if len(ptor)>0:200T1 += ptor[0][0]201k1 *= p**(ptor[0][1])202if len(ptor)>1:203T2 += ptor[1][0]204k2 *= p**(ptor[1][1])205206order = k1*k2207if k1 == 1:208structure = []209gens = []210elif k2 == 1:211structure = [k1]212gens = [T1]213else:214structure = [k1,k2]215gens = [T1,T2]216217#self.__torsion_gens = gens218self._structure = structure219groups.AdditiveAbelianGroupWrapper.__init__(self, T1.parent(), [T1, T2], structure)220221222def _repr_(self):223"""224String representation of an instance of the EllipticCurveTorsionSubgroup class.225226EXAMPLES::227228sage: E=EllipticCurve('11a1')229sage: K.<i>=NumberField(x^2+1)230sage: EK=E.change_ring(K)231sage: 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"""234return "Torsion Subgroup isomorphic to %s associated to the %s" % (self.short_name(), self.__E)235236def __cmp__(self,other):237r"""238Compares two torsion groups by simply comparing the elliptic curves.239240EXAMPLES::241242sage: E = EllipticCurve('37a1')243sage: tor = E.torsion_subgroup()244sage: tor == tor245True246"""247c = cmp(type(self), type(other))248if c:249return c250return cmp(self.__E, other.__E)251252def curve(self):253"""254Return the curve of this torsion subgroup.255256EXAMPLES::257258sage: E=EllipticCurve('11a1')259sage: K.<i>=NumberField(x^2+1)260sage: EK=E.change_ring(K)261sage: T = EK.torsion_subgroup()262sage: T.curve() is EK263True264"""265return self.__E266267@cached_method268def points(self):269"""270Return a list of all the points in this torsion subgroup.271The list is cached.272273EXAMPLES::274275sage: K.<i>=NumberField(x^2 + 1)276sage: E = EllipticCurve(K,[0,0,0,1,0])277sage: tor = E.torsion_subgroup()278sage: tor.points()279[(0 : 1 : 0), (0 : 0 : 1), (i : 0 : 1), (-i : 0 : 1)]280"""281return [x.element() for x in self]282283284