Path: blob/master/src/sage/schemes/elliptic_curves/ell_torsion.py
8820 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(5 : -6 : 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)) # known bug, see http://trac.sagemath.org/sage_trac/ticket/11599#comment:7158True159"""160self.__E = E161self.__K = E.base_field()162163pari_torsion_algorithms = ["pari","doud","lutz_nagell"]164165if self.__K is RationalField() and algorithm in pari_torsion_algorithms:166flag = pari_torsion_algorithms.index(algorithm)167168G = None169loop = 0170while G is None and loop < 3:171loop += 1172try:173G = self.__E.pari_curve(prec = 400).elltors(flag) # pari_curve will return the curve of maximum known precision174except RuntimeError:175self.__E.pari_curve(factor = 2) # caches a curve of twice the precision176if G is not None:177order = G[0].python()178structure = G[1].python()179gens = G[2].python()180181self.__torsion_gens = [ self.__E(P) for P in gens ]182from sage.groups.additive_abelian.additive_abelian_group import cover_and_relations_from_invariants183groups.AdditiveAbelianGroupWrapper.__init__(self, self.__E(0).parent(), self.__torsion_gens, structure)184return185186T1 = E(0) # these will be the two generators187T2 = E(0)188k1 = 1 # with their order189k2 = 1190191# find a multiple of the order of the torsion group192bound = E._torsion_bound(number_of_places=20)193194# now do prime by prime195for p,e in bound.factor():196ptor = E._p_primary_torsion_basis(p,e)197# print p,'-primary part is ',ptor198if len(ptor)>0:199T1 += ptor[0][0]200k1 *= p**(ptor[0][1])201if len(ptor)>1:202T2 += ptor[1][0]203k2 *= p**(ptor[1][1])204205order = k1*k2206if k1 == 1:207structure = []208gens = []209elif k2 == 1:210structure = [k1]211gens = [T1]212else:213structure = [k1,k2]214gens = [T1,T2]215216#self.__torsion_gens = gens217self._structure = structure218groups.AdditiveAbelianGroupWrapper.__init__(self, T1.parent(), [T1, T2], structure)219220221def _repr_(self):222"""223String representation of an instance of the EllipticCurveTorsionSubgroup class.224225EXAMPLES::226227sage: E=EllipticCurve('11a1')228sage: K.<i>=NumberField(x^2+1)229sage: EK=E.change_ring(K)230sage: T = EK.torsion_subgroup(); T._repr_()231'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'232"""233return "Torsion Subgroup isomorphic to %s associated to the %s" % (self.short_name(), self.__E)234235def __cmp__(self,other):236r"""237Compares two torsion groups by simply comparing the elliptic curves.238239EXAMPLES::240241sage: E = EllipticCurve('37a1')242sage: tor = E.torsion_subgroup()243sage: tor == tor244True245"""246c = cmp(type(self), type(other))247if c:248return c249return cmp(self.__E, other.__E)250251def curve(self):252"""253Return the curve of this torsion subgroup.254255EXAMPLES::256257sage: E=EllipticCurve('11a1')258sage: K.<i>=NumberField(x^2+1)259sage: EK=E.change_ring(K)260sage: T = EK.torsion_subgroup()261sage: T.curve() is EK262True263"""264return self.__E265266@cached_method267def points(self):268"""269Return a list of all the points in this torsion subgroup.270The list is cached.271272EXAMPLES::273274sage: K.<i>=NumberField(x^2 + 1)275sage: E = EllipticCurve(K,[0,0,0,1,0])276sage: tor = E.torsion_subgroup()277sage: tor.points()278[(0 : 1 : 0), (-i : 0 : 1), (0 : 0 : 1), (i : 0 : 1)]279"""280return [x.element() for x in self]281282283