Path: blob/master/src/sage/schemes/elliptic_curves/ell_field.py
8820 views
r"""1Elliptic curves over a general field23This module defines the class ``EllipticCurve_field``, based on4``EllipticCurve_generic``, for elliptic curves over general fields.56"""78#*****************************************************************************9# Copyright (C) 2006 William Stein <[email protected]>10#11# Distributed under the terms of the GNU General Public License (GPL)12#13# http://www.gnu.org/licenses/14#*****************************************************************************1516import ell_generic17import sage.rings.all as rings18from sage.rings.complex_field import is_ComplexField19from sage.rings.real_mpfr import is_RealField20from constructor import EllipticCurve2122from ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel23from ell_wp import weierstrass_p2425class EllipticCurve_field(ell_generic.EllipticCurve_generic):2627base_field = ell_generic.EllipticCurve_generic.base_ring2829# Twists: rewritten by John Cremona as follows:30#31# Quadratic twist allowed except when char=2, j=032# Quartic twist allowed only if j=1728!=0 (so char!=2,3)33# Sextic twist allowed only if j=0!=1728 (so char!=2,3)34#35# More complicated twists exist in theory for char=2,3 and36# j=0=1728, but I have never worked them out or seen them used!37#3839r"""40Twists: rewritten by John Cremona as follows:4142The following twists are implemented:4344- Quadratic twist: except when char=2 and `j=0`.45- Quartic twist: only if `j=1728\not=0` (so not if char=2,3).46- Sextic twist: only if `j=0\not=1728` (so not if char=2,3).4748More complicated twists exist in theory for char=2,3 and j=0=1728,49but are not implemented.50"""5152def quadratic_twist(self, D=None):53"""54Return the quadratic twist of this curve by ``D``.5556INPUT:5758- ``D`` (default None) the twisting parameter (see below).5960In characteristics other than 2, `D` must be nonzero, and the61twist is isomorphic to self after adjoining `\sqrt(D)` to the62base.6364In characteristic 2, `D` is arbitrary, and the twist is65isomorphic to self after adjoining a root of `x^2+x+D` to the66base.6768In characteristic 2 when `j=0`, this is not implemented.6970If the base field `F` is finite, `D` need not be specified,71and the curve returned is the unique curve (up to isomorphism)72defined over `F` isomorphic to the original curve over the73quadratic extension of `F` but not over `F` itself. Over74infinite fields, an error is raised if `D` is not given.7576EXAMPLES::7778sage: E = EllipticCurve([GF(1103)(1), 0, 0, 107, 340]); E79Elliptic Curve defined by y^2 + x*y = x^3 + 107*x + 340 over Finite Field of size 110380sage: F=E.quadratic_twist(-1); F81Elliptic Curve defined by y^2 = x^3 + 1102*x^2 + 609*x + 300 over Finite Field of size 110382sage: E.is_isomorphic(F)83False84sage: E.is_isomorphic(F,GF(1103^2,'a'))85True8687A characteristic 2 example::8889sage: E=EllipticCurve(GF(2),[1,0,1,1,1])90sage: E1=E.quadratic_twist(1)91sage: E.is_isomorphic(E1)92False93sage: E.is_isomorphic(E1,GF(4,'a'))94True9596Over finite fields, the twisting parameter may be omitted::9798sage: k.<a> = GF(2^10)99sage: E = EllipticCurve(k,[a^2,a,1,a+1,1])100sage: Et = E.quadratic_twist()101sage: Et # random (only determined up to isomorphism)102Elliptic Curve defined by y^2 + x*y = x^3 + (a^7+a^4+a^3+a^2+a+1)*x^2 + (a^8+a^6+a^4+1) over Finite Field in a of size 2^10103sage: E.is_isomorphic(Et)104False105sage: E.j_invariant()==Et.j_invariant()106True107108sage: p=next_prime(10^10)109sage: k = GF(p)110sage: E = EllipticCurve(k,[1,2,3,4,5])111sage: Et = E.quadratic_twist()112sage: Et # random (only determined up to isomorphism)113Elliptic Curve defined by y^2 = x^3 + 7860088097*x^2 + 9495240877*x + 3048660957 over Finite Field of size 10000000019114sage: E.is_isomorphic(Et)115False116sage: k2 = GF(p^2,'a')117sage: E.change_ring(k2).is_isomorphic(Et.change_ring(k2))118True119"""120K=self.base_ring()121char=K.characteristic()122123if D is None:124if K.is_finite():125x = rings.polygen(K)126if char==2:127# We find D such that x^2+x+D is irreducible. If the128# degree is odd we can take D=1; otherwise it suffices to129# consider odd powers of a generator.130D = K(1)131if K.degree()%2==0:132D = K.gen()133a = D**2134while len((x**2+x+D).roots())>0:135D *= a136else:137# We could take a multiplicative generator but138# that might be expensive to compute; otherwise139# half the elements will do140D = K.random_element()141while len((x**2-D).roots())>0:142D = K.random_element()143else:144raise ValueError, "twisting parameter D must be specified over infinite fields."145else:146try:147D=K(D)148except ValueError:149raise ValueError, "twisting parameter D must be in the base field."150151if char!=2 and D.is_zero():152raise ValueError, "twisting parameter D must be nonzero when characteristic is not 2"153154if char!=2:155b2,b4,b6,b8=self.b_invariants()156# E is isomorphic to [0,b2,0,8*b4,16*b6]157return EllipticCurve(K,[0,b2*D,0,8*b4*D**2,16*b6*D**3])158159# now char==2160if self.j_invariant() !=0: # iff a1!=0161a1,a2,a3,a4,a6=self.ainvs()162E0=self.change_weierstrass_model(a1,a3/a1,0,(a1**2*a4+a3**2)/a1**3)163# which has the form = [1,A2,0,0,A6]164assert E0.a1()==K(1)165assert E0.a3()==K(0)166assert E0.a4()==K(0)167return EllipticCurve(K,[1,E0.a2()+D,0,0,E0.a6()])168else:169raise ValueError, "Quadratic twist not implemented in char 2 when j=0"170171def two_torsion_rank(self):172r"""173Return the dimension of the 2-torsion subgroup of174`E(K)`.175176This will be 0, 1 or 2.177178EXAMPLES::179180sage: E=EllipticCurve('11a1')181sage: E.two_torsion_rank()1820183sage: K.<alpha>=QQ.extension(E.division_polynomial(2).monic())184sage: E.base_extend(K).two_torsion_rank()1851186sage: E.reduction(53).two_torsion_rank()1872188189::190191sage: E = EllipticCurve('14a1')192sage: E.two_torsion_rank()1931194sage: K.<alpha>=QQ.extension(E.division_polynomial(2).monic().factor()[1][0])195sage: E.base_extend(K).two_torsion_rank()1962197198::199200sage: EllipticCurve('15a1').two_torsion_rank()2012202203"""204f=self.division_polynomial(rings.Integer(2))205n=len(f.roots())+1206return rings.Integer(n).ord(rings.Integer(2))207208209def quartic_twist(self, D):210r"""211Return the quartic twist of this curve by `D`.212213INPUT:214215- ``D`` (must be nonzero) -- the twisting parameter..216217.. note::218219The characteristic must not be 2 or 3, and the `j`-invariant must be 1728.220221EXAMPLES::222223sage: E=EllipticCurve_from_j(GF(13)(1728)); E224Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 13225sage: E1=E.quartic_twist(2); E1226Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 13227sage: E.is_isomorphic(E1)228False229sage: E.is_isomorphic(E1,GF(13^2,'a'))230False231sage: E.is_isomorphic(E1,GF(13^4,'a'))232True233"""234K=self.base_ring()235char=K.characteristic()236D=K(D)237238if char==2 or char==3:239raise ValueError, "Quartic twist not defined in chars 2,3"240241if self.j_invariant() !=K(1728):242raise ValueError, "Quartic twist not defined when j!=1728"243244if D.is_zero():245raise ValueError, "quartic twist requires a nonzero argument"246247c4,c6=self.c_invariants()248# E is isomorphic to [0,0,0,-27*c4,0]249assert c6==0250return EllipticCurve(K,[0,0,0,-27*c4*D,0])251252def sextic_twist(self, D):253r"""254Return the quartic twist of this curve by `D`.255256INPUT:257258- ``D`` (must be nonzero) -- the twisting parameter..259260.. note::261262The characteristic must not be 2 or 3, and the `j`-invariant must be 0.263264EXAMPLES::265266sage: E=EllipticCurve_from_j(GF(13)(0)); E267Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 13268sage: E1=E.sextic_twist(2); E1269Elliptic Curve defined by y^2 = x^3 + 11 over Finite Field of size 13270sage: E.is_isomorphic(E1)271False272sage: E.is_isomorphic(E1,GF(13^2,'a'))273False274sage: E.is_isomorphic(E1,GF(13^4,'a'))275False276sage: E.is_isomorphic(E1,GF(13^6,'a'))277True278"""279K=self.base_ring()280char=K.characteristic()281D=K(D)282283if char==2 or char==3:284raise ValueError, "Sextic twist not defined in chars 2,3"285286if self.j_invariant() !=K(0):287raise ValueError, "Sextic twist not defined when j!=0"288289if D.is_zero():290raise ValueError, "Sextic twist requires a nonzero argument"291292c4,c6=self.c_invariants()293# E is isomorphic to [0,0,0,0,-54*c6]294assert c4==0295return EllipticCurve(K,[0,0,0,0,-54*c6*D])296297def is_quadratic_twist(self, other):298r"""299Determine whether this curve is a quadratic twist of another.300301INPUT:302303- ``other`` -- an elliptic curves with the same base field as self.304305OUTPUT:306307Either 0, if the curves are not quadratic twists, or `D` if308``other`` is ``self.quadratic_twist(D)`` (up to isomorphism).309If ``self`` and ``other`` are isomorphic, returns 1.310311If the curves are defined over `\mathbb{Q}`, the output `D` is312a squarefree integer.313314.. note::315316Not fully implemented in characteristic 2, or in317characteristic 3 when both `j`-invariants are 0.318319EXAMPLES::320321sage: E = EllipticCurve('11a1')322sage: Et = E.quadratic_twist(-24)323sage: E.is_quadratic_twist(Et)324-6325326sage: E1=EllipticCurve([0,0,1,0,0])327sage: E1.j_invariant()3280329sage: E2=EllipticCurve([0,0,0,0,2])330sage: E1.is_quadratic_twist(E2)3312332sage: E1.is_quadratic_twist(E1)3331334sage: type(E1.is_quadratic_twist(E1)) == type(E1.is_quadratic_twist(E2)) #trac 6574335True336337::338339sage: E1=EllipticCurve([0,0,0,1,0])340sage: E1.j_invariant()3411728342sage: E2=EllipticCurve([0,0,0,2,0])343sage: E1.is_quadratic_twist(E2)3440345sage: E2=EllipticCurve([0,0,0,25,0])346sage: E1.is_quadratic_twist(E2)3475348349::350351sage: F = GF(101)352sage: E1 = EllipticCurve(F,[4,7])353sage: E2 = E1.quadratic_twist()354sage: D = E1.is_quadratic_twist(E2); D!=0355True356sage: F = GF(101)357sage: E1 = EllipticCurve(F,[4,7])358sage: E2 = E1.quadratic_twist()359sage: D = E1.is_quadratic_twist(E2)360sage: E1.quadratic_twist(D).is_isomorphic(E2)361True362sage: E1.is_isomorphic(E2)363False364sage: F2 = GF(101^2,'a')365sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2))366True367368A characteristic 3 example::369370sage: F = GF(3^5,'a')371sage: E1 = EllipticCurve_from_j(F(1))372sage: E2 = E1.quadratic_twist(-1)373sage: D = E1.is_quadratic_twist(E2); D!=0374True375sage: E1.quadratic_twist(D).is_isomorphic(E2)376True377378::379380sage: E1 = EllipticCurve_from_j(F(0))381sage: E2 = E1.quadratic_twist()382sage: D = E1.is_quadratic_twist(E2); D3831384sage: E1.is_isomorphic(E2)385True386387"""388from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve389E = self390F = other391if not is_EllipticCurve(E) or not is_EllipticCurve(F):392raise ValueError, "arguments are not elliptic curves"393K = E.base_ring()394zero = K.zero_element()395if not K == F.base_ring():396return zero397j=E.j_invariant()398if j != F.j_invariant():399return zero400401if E.is_isomorphic(F):402if K is rings.QQ:403return rings.ZZ(1)404return K.one_element()405406char=K.characteristic()407408if char==2:409raise NotImplementedError, "not implemented in characteristic 2"410elif char==3:411if j==0:412raise NotImplementedError, "not implemented in characteristic 3 for curves of j-invariant 0"413D = E.b2()/F.b2()414415else:416# now char!=2,3:417c4E,c6E = E.c_invariants()418c4F,c6F = F.c_invariants()419420if j==0:421um = c6E/c6F422x=rings.polygen(K)423ulist=(x**3-um).roots(multiplicities=False)424if len(ulist)==0:425D = zero426else:427D = ulist[0]428elif j==1728:429um=c4E/c4F430x=rings.polygen(K)431ulist=(x**2-um).roots(multiplicities=False)432if len(ulist)==0:433D = zero434else:435D = ulist[0]436else:437D = (c6E*c4F)/(c6F*c4E)438439# Normalization of output:440441if D.is_zero():442return D443444if K is rings.QQ:445D = D.squarefree_part()446447assert E.quadratic_twist(D).is_isomorphic(F)448449return D450451def is_quartic_twist(self, other):452r"""453Determine whether this curve is a quartic twist of another.454455INPUT:456457- ``other`` -- an elliptic curves with the same base field as self.458459OUTPUT:460461Either 0, if the curves are not quartic twists, or `D` if462``other`` is ``self.quartic_twist(D)`` (up to isomorphism).463If ``self`` and ``other`` are isomorphic, returns 1.464465.. note::466467Not fully implemented in characteristics 2 or 3.468469EXAMPLES::470471sage: E = EllipticCurve_from_j(GF(13)(1728))472sage: E1 = E.quartic_twist(2)473sage: D = E.is_quartic_twist(E1); D!=0474True475sage: E.quartic_twist(D).is_isomorphic(E1)476True477478::479480sage: E = EllipticCurve_from_j(1728)481sage: E1 = E.quartic_twist(12345)482sage: D = E.is_quartic_twist(E1); D48315999120484sage: (D/12345).is_perfect_power(4)485True486"""487from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve488E = self489F = other490if not is_EllipticCurve(E) or not is_EllipticCurve(F):491raise ValueError, "arguments are not elliptic curves"492K = E.base_ring()493zero = K.zero_element()494if not K == F.base_ring():495return zero496j=E.j_invariant()497if j != F.j_invariant() or j!=K(1728):498return zero499500if E.is_isomorphic(F):501return K.one_element()502503char=K.characteristic()504505if char==2:506raise NotImplementedError, "not implemented in characteristic 2"507elif char==3:508raise NotImplementedError, "not implemented in characteristic 3"509else:510# now char!=2,3:511D = F.c4()/E.c4()512513if D.is_zero():514return D515516assert E.quartic_twist(D).is_isomorphic(F)517518return D519520def is_sextic_twist(self, other):521r"""522Determine whether this curve is a sextic twist of another.523524INPUT:525526- ``other`` -- an elliptic curves with the same base field as self.527528OUTPUT:529530Either 0, if the curves are not sextic twists, or `D` if531``other`` is ``self.sextic_twist(D)`` (up to isomorphism).532If ``self`` and ``other`` are isomorphic, returns 1.533534.. note::535536Not fully implemented in characteristics 2 or 3.537538EXAMPLES::539540sage: E = EllipticCurve_from_j(GF(13)(0))541sage: E1 = E.sextic_twist(2)542sage: D = E.is_sextic_twist(E1); D!=0543True544sage: E.sextic_twist(D).is_isomorphic(E1)545True546547::548549sage: E = EllipticCurve_from_j(0)550sage: E1 = E.sextic_twist(12345)551sage: D = E.is_sextic_twist(E1); D552575968320553sage: (D/12345).is_perfect_power(6)554True555"""556from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve557E = self558F = other559if not is_EllipticCurve(E) or not is_EllipticCurve(F):560raise ValueError, "arguments are not elliptic curves"561K = E.base_ring()562zero = K.zero_element()563if not K == F.base_ring():564return zero565j=E.j_invariant()566if j != F.j_invariant() or not j.is_zero():567return zero568569if E.is_isomorphic(F):570return K.one_element()571572char=K.characteristic()573574if char==2:575raise NotImplementedError, "not implemented in characteristic 2"576elif char==3:577raise NotImplementedError, "not implemented in characteristic 3"578else:579# now char!=2,3:580D = F.c6()/E.c6()581582if D.is_zero():583return D584585assert E.sextic_twist(D).is_isomorphic(F)586587return D588589def descend_to(self, K, f=None):590r"""591Given a subfield `K` and an elliptic curve self defined over a field `L`,592this function determines whether there exists an elliptic curve over `K`593which is isomorphic over `L` to self. If one exists, it finds it.594595INPUT:596597- `K` -- a subfield of the base field of self.598- `f` -- an embedding of `K` into the base field of self.599600OUTPUT:601602Either an elliptic curve defined over `K` which is isomorphic to self603or None if no such curve exists.604605.. NOTE::606607This only works over number fields and QQ.608609EXAMPLES::610611sage: E = EllipticCurve([1,2,3,4,5])612sage: E.descend_to(ZZ)613Traceback (most recent call last):614...615TypeError: Input must be a field.616617::618619sage: F.<b> = QuadraticField(23)620sage: G.<a> = F.extension(x^3+5)621sage: E = EllipticCurve(j=1728*b).change_ring(G)622sage: E.descend_to(F)623Elliptic Curve defined by y^2 = x^3 + (8957952*b-206032896)*x + (-247669456896*b+474699792384) over Number Field in b with defining polynomial x^2 - 23624625::626627sage: L.<a> = NumberField(x^4 - 7)628sage: K.<b> = NumberField(x^2 - 7)629sage: E = EllipticCurve([a^6,0])630sage: E.descend_to(K)631Elliptic Curve defined by y^2 = x^3 + 1296/49*b*x over Number Field in b with defining polynomial x^2 - 7632633::634635sage: K.<a> = QuadraticField(17)636sage: E = EllipticCurve(j = 2*a)637sage: print E.descend_to(QQ)638None639"""640if not K.is_field():641raise TypeError, "Input must be a field."642if self.base_field()==K:643return self644j = self.j_invariant()645from sage.rings.all import QQ646if K == QQ:647f = QQ.embeddings(self.base_field())[0]648if j in QQ:649jbase = QQ(j)650else:651return None652elif f == None:653embeddings = K.embeddings(self.base_field())654if len(embeddings) == 0:655raise TypeError, "Input must be a subfield of the base field of the curve."656for g in embeddings:657try:658jbase = g.preimage(j)659f = g660break661except Exception:662pass663if f == None:664return None665else:666try:667jbase = f.preimage(j)668except Exception:669return None670E = EllipticCurve(j=jbase)671E2 = EllipticCurve(self.base_field(), [f(a) for a in E.a_invariants()])672if jbase==0:673d = self.is_sextic_twist(E2)674if d == 1:675return E676if d == 0:677return None678Etwist = E2.sextic_twist(d)679elif jbase==1728:680d = self.is_quartic_twist(E2)681if d == 1:682return E683if d == 0:684return None685Etwist = E2.quartic_twist(d)686else:687d = self.is_quadratic_twist(E2)688if d == 1:689return E690if d == 0:691return None692Etwist = E2.quadratic_twist(d)693if Etwist.is_isomorphic(self):694try:695Eout = EllipticCurve(K, [f.preimage(a) for a in Etwist.a_invariants()])696except Exception:697return None698else:699return Eout700701def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True):702r"""703Returns an elliptic curve isogeny from self.704705The isogeny can be determined in two ways, either by a706polynomial or a set of torsion points. The methods used are:707708- Velu's Formulas: Velu's original formulas for computing709isogenies. This algorithm is selected by giving as the710``kernel`` parameter a point or a list of points which711generate a finite subgroup.712713- Kohel's Formulas: Kohel's original formulas for computing714isogenies. This algorithm is selected by giving as the715``kernel`` parameter a polynomial (or a coefficient list716(little endian)) which will define the kernel of the717isogeny.718719INPUT:720721- ``E`` - an elliptic curve, the domain of the isogeny to722initialize.723724- ``kernel`` - a kernel, either a point in ``E``, a list of points725in ``E``, a univariate kernel polynomial or ``None``.726If initiating from a domain/codomain, this must be727set to None. Validity of input is *not* fully checked.728729- ``codomain`` - an elliptic curve (default:None). If ``kernel`` is730None, then this must be the codomain of a separable731normalized isogeny, furthermore, ``degree`` must be732the degree of the isogeny from ``E`` to ``codomain``.733If ``kernel`` is not None, then this must be734isomorphic to the codomain of the normalized separable735isogeny defined by ``kernel``, in this case, the736isogeny is post composed with an isomorphism so that737this parameter is the codomain.738739- ``degree`` - an integer (default:None). If ``kernel`` is None,740then this is the degree of the isogeny from ``E`` to741``codomain``. If ``kernel`` is not None, then this is742used to determine whether or not to skip a gcd of the743kernel polynomial with the two torsion polynomial of744``E``.745746- ``model`` - a string (default:None). Only supported variable is747"minimal", in which case if``E`` is a curve over the748rationals, then the codomain is set to be the unique749global minimum model.750751- ``check`` (default: True) does some partial checks that the752input is valid (e.g., that the points753defined by the kernel polynomial are754torsion); however, invalid input can in some755cases still pass, since that the points define756a group is not checked.757758OUTPUT:759760An isogeny between elliptic curves. This is a morphism of curves.761762EXAMPLES::763764sage: F = GF(2^5, 'alpha'); alpha = F.gen()765sage: E = EllipticCurve(F, [1,0,1,1,1])766sage: R.<x> = F[]767sage: phi = E.isogeny(x+1)768sage: phi.rational_maps()769((x^2 + x + 1)/(x + 1), (x^2*y + x)/(x^2 + 1))770771sage: E = EllipticCurve('11a1')772sage: P = E.torsion_points()[1]773sage: E.isogeny(P)774Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field775776sage: E = EllipticCurve(GF(19),[1,1])777sage: P = E(15,3); Q = E(2,12);778sage: (P.order(), Q.order())779(7, 3)780sage: phi = E.isogeny([P,Q]); phi781Isogeny of degree 21 from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 19782sage: phi(E.random_point()) # all points defined over GF(19) are in the kernel783(0 : 1 : 0)784785786# not all polynomials define a finite subgroup trac #6384787sage: E = EllipticCurve(GF(31),[1,0,0,1,2])788sage: phi = E.isogeny([14,27,4,1])789Traceback (most recent call last):790...791ValueError: The polynomial does not define a finite subgroup of the elliptic curve.792793An example in which we construct an invalid morphism, which794illustrates that the check for correctness of the input is not795sufficient. (See trac 11578.)::796797sage: R.<x> = QQ[]798sage: K.<a> = NumberField(x^2-x-1)799sage: E = EllipticCurve(K, [-13392, -1080432])800sage: R.<x> = K[]801sage: phi = E.isogeny( (x-564)*(x - 396/5*a + 348/5) )802sage: phi.codomain().conductor().norm().factor()8035^2 * 11^2 * 3271 * 15806939 * 4169267639351804sage: phi.domain().conductor().norm().factor()80511^2806"""807return EllipticCurveIsogeny(self, kernel, codomain, degree, model, check=check)808809810def isogeny_codomain(self, kernel, degree=None):811r"""812Returns the codomain of the isogeny from self with given813kernel.814815INPUT:816817- ``kernel`` - Either a list of points in the kernel of the isogeny,818or a kernel polynomial (specified as a either a819univariate polynomial or a coefficient list.)820821- ``degree`` - an integer, (default:None) optionally specified degree822of the kernel.823824OUTPUT:825826An elliptic curve, the codomain of the separable normalized827isogeny from this kernel828829EXAMPLES::830831sage: E = EllipticCurve('17a1')832sage: R.<x> = QQ[]833sage: E2 = E.isogeny_codomain(x - 11/4); E2834Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 1461/16*x - 19681/64 over Rational Field835836"""837return isogeny_codomain_from_kernel(self, kernel, degree=None)838839def isogenies_prime_degree(self, l=None, max_l=31):840"""841Generic code, valid for all fields, for arbitrary prime `l` not equal to the characteristic.842843INPUT:844845- ``l`` -- either None, a prime or a list of primes.846- ``max_l`` -- a bound on the primes to be tested (ignored unless `l` is None).847848OUTPUT:849850(list) All `l`-isogenies for the given `l` with domain self.851852METHOD:853854Calls the generic function855``isogenies_prime_degree()``. This requires that856certain operations have been implemented over the base field,857such as root-finding for univariate polynomials.858859EXAMPLES::860861sage: F = QQbar862sage: E = EllipticCurve(F, [1,18]); E863Elliptic Curve defined by y^2 = x^3 + x + 18 over Algebraic Field864sage: E.isogenies_prime_degree()865Traceback (most recent call last):866...867NotImplementedError: This code could be implemented for QQbar, but has not been yet.868869sage: F = CC870sage: E = EllipticCurve(F, [1,18]); E871Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision872sage: E.isogenies_prime_degree(11)873Traceback (most recent call last):874...875NotImplementedError: This code could be implemented for general complex fields, but has not been yet.876877Examples over finite fields::878879sage: E = EllipticCurve(GF(next_prime(1000000)), [7,8])880sage: E.isogenies_prime_degree()881[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 347438*x + 594729 over Finite Field of size 1000003, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 674846*x + 7392 over Finite Field of size 1000003, Isogeny of degree 23 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 390065*x + 605596 over Finite Field of size 1000003]882sage: E.isogenies_prime_degree(2)883[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003]884sage: E.isogenies_prime_degree(3)885[]886sage: E.isogenies_prime_degree(5)887[]888sage: E.isogenies_prime_degree(7)889[]890sage: E.isogenies_prime_degree(13)891[Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003,892Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003]893894sage: E.isogenies_prime_degree([2, 3, 5, 7, 13])895[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003]896sage: E.isogenies_prime_degree([2, 4])897Traceback (most recent call last):898...899ValueError: 4 is not prime.900sage: E.isogenies_prime_degree(4)901Traceback (most recent call last):902...903ValueError: 4 is not prime.904sage: E.isogenies_prime_degree(11)905[]906sage: E = EllipticCurve(GF(17),[2,0])907sage: E.isogenies_prime_degree(3)908[]909sage: E.isogenies_prime_degree(2)910[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 17, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 5*x + 9 over Finite Field of size 17, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 5*x + 8 over Finite Field of size 17]911912sage: E = EllipticCurve(GF(13^4, 'a'),[2,8])913sage: E.isogenies_prime_degree(2)914[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 7*x + 4 over Finite Field in a of size 13^4, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + (8*a^3+2*a^2+7*a+5)*x + (12*a^3+3*a^2+4*a+4) over Finite Field in a of size 13^4, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + (5*a^3+11*a^2+6*a+11)*x + (a^3+10*a^2+9*a) over Finite Field in a of size 13^4]915916sage: E.isogenies_prime_degree(3)917[Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 9*x + 11 over Finite Field in a of size 13^4]918919Example to show that separable isogenies of degree equal to the characteristic are now implemented::920921sage: E.isogenies_prime_degree(13)922[Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 6*x + 5 over Finite Field in a of size 13^4]923924Examples over number fields (other than QQ)::925926sage: QQroot2.<e> = NumberField(x^2-2)927sage: E = EllipticCurve(QQroot2, j=8000)928sage: E.isogenies_prime_degree()929[Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (-602112000)*x + 5035261952000 over Number Field in e with defining polynomial x^2 - 2,930Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (903168000*e-1053696000)*x + (14161674240000*e-23288086528000) over Number Field in e with defining polynomial x^2 - 2,931Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (-903168000*e-1053696000)*x + (-14161674240000*e-23288086528000) over Number Field in e with defining polynomial x^2 - 2]932933sage: E = EllipticCurve(QQroot2, [1,0,1,4, -6]); E934Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2935sage: E.isogenies_prime_degree(2)936[Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-36)*x + (-70) over Number Field in e with defining polynomial x^2 - 2]937sage: E.isogenies_prime_degree(3)938[Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-128/3)*x + 5662/27 over Number Field in e with defining polynomial x^2 - 2, Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-171)*x + (-874) over Number Field in e with defining polynomial x^2 - 2]939"""940F = self.base_ring()941if is_RealField(F):942raise NotImplementedError, "This code could be implemented for general real fields, but has not been yet."943if is_ComplexField(F):944raise NotImplementedError, "This code could be implemented for general complex fields, but has not been yet."945if F == rings.QQbar:946raise NotImplementedError, "This code could be implemented for QQbar, but has not been yet."947948from isogeny_small_degree import isogenies_prime_degree949if l is None:950from sage.rings.all import prime_range951l = prime_range(max_l+1)952953if type(l) != list:954try:955l = rings.ZZ(l)956except TypeError:957raise ValueError, "%s is not prime."%l958if l.is_prime():959return isogenies_prime_degree(self, l)960else:961raise ValueError, "%s is not prime."%l962963L = list(set(l))964try:965L = [rings.ZZ(l) for l in L]966except TypeError:967raise ValueError, "%s is not a list of primes."%l968969L.sort()970return sum([isogenies_prime_degree(self,l) for l in L],[])971972def is_isogenous(self, other, field=None):973"""974Returns whether or not self is isogenous to other.975976INPUT:977978- ``other`` -- another elliptic curve.979980- ``field`` (default None) -- Currently not implemented. A981field containing the base fields of the two elliptic curves982onto which the two curves may be extended to test if they983are isogenous over this field. By default is_isogenous will984not try to find this field unless one of the curves can be985be extended into the base field of the other, in which case986it will test over the larger base field.987988OUTPUT:989990(bool) True if there is an isogeny from curve ``self`` to991curve ``other`` defined over ``field``.992993METHOD:994995Over general fields this is only implemented in trivial cases.996997EXAMPLES::998999sage: E1 = EllipticCurve(CC, [1,18]); E11000Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision1001sage: E2 = EllipticCurve(CC, [2,7]); E21002Elliptic Curve defined by y^2 = x^3 + 2.00000000000000*x + 7.00000000000000 over Complex Field with 53 bits of precision1003sage: E1.is_isogenous(E2)1004Traceback (most recent call last):1005...1006NotImplementedError: Only implemented for isomorphic curves over general fields.10071008sage: E1 = EllipticCurve(Frac(PolynomialRing(ZZ,'t')), [2,19]); E11009Elliptic Curve defined by y^2 = x^3 + 2*x + 19 over Fraction Field of Univariate Polynomial Ring in t over Integer Ring1010sage: E2 = EllipticCurve(CC, [23,4]); E21011Elliptic Curve defined by y^2 = x^3 + 23.0000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision1012sage: E1.is_isogenous(E2)1013Traceback (most recent call last):1014...1015NotImplementedError: Only implemented for isomorphic curves over general fields.1016"""1017from ell_generic import is_EllipticCurve1018if not is_EllipticCurve(other):1019raise ValueError, "Second argument is not an Elliptic Curve."1020if self.is_isomorphic(other):1021return True1022else:1023raise NotImplementedError, "Only implemented for isomorphic curves over general fields."10241025def weierstrass_p(self, prec=20, algorithm=None):1026r"""1027Computes the Weierstrass `\wp`-function of the elliptic curve.10281029INPUT:10301031- ``mprec`` - precision10321033- ``algorithm`` - string (default:``None``) an algorithm identifier1034indicating using the ``pari``, ``fast`` or ``quadratic``1035algorithm. If the algorithm is ``None``, then this1036function determines the best algorithm to use.10371038OUTPUT:10391040a Laurent series in one variable `z` with coefficients in the1041base field `k` of `E`.10421043EXAMPLES::10441045sage: E = EllipticCurve('11a1')1046sage: E.weierstrass_p(prec=10)1047z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + O(z^10)1048sage: E.weierstrass_p(prec=8)1049z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + O(z^8)1050sage: Esh = E.short_weierstrass_model()1051sage: Esh.weierstrass_p(prec=8)1052z^-2 + 13392/5*z^2 + 1080432/7*z^4 + 59781888/25*z^6 + O(z^8)10531054sage: E.weierstrass_p(prec=8, algorithm='pari')1055z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + O(z^8)1056sage: E.weierstrass_p(prec=8, algorithm='quadratic')1057z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + O(z^8)10581059sage: k = GF(101)1060sage: E = EllipticCurve(k, [2,3])1061sage: E.weierstrass_p(prec=30)1062z^-2 + 40*z^2 + 14*z^4 + 62*z^6 + 15*z^8 + 47*z^10 + 66*z^12 + 61*z^14 + 79*z^16 + 98*z^18 + 93*z^20 + 82*z^22 + 15*z^24 + 71*z^26 + 27*z^28 + O(z^30)10631064sage: k = GF(11)1065sage: E = EllipticCurve(k, [1,1])1066sage: E.weierstrass_p(prec=6, algorithm='fast')1067z^-2 + 2*z^2 + 3*z^4 + O(z^6)1068sage: E.weierstrass_p(prec=7, algorithm='fast')1069Traceback (most recent call last):1070...1071ValueError: For computing the Weierstrass p-function via the fast algorithm, the characteristic (11) of the underlying field must be greater than prec + 4 = 11.1072sage: E.weierstrass_p(prec=8 ,algorithm='pari')1073z^-2 + 2*z^2 + 3*z^4 + 5*z^6 + O(z^8)1074sage: E.weierstrass_p(prec=9, algorithm='pari')1075Traceback (most recent call last):1076...1077ValueError: For computing the Weierstrass p-function via pari, the characteristic (11) of the underlying field must be greater than prec + 2 = 11.10781079"""1080return weierstrass_p(self, prec=prec, algorithm=algorithm)108110821083def hasse_invariant(self):1084r"""1085Returns the Hasse invariant of this elliptic curve.10861087OUTPUT:10881089The Hasse invariant of this elliptic curve, as an element of1090the base field. This is only defined over fields of positive1091characteristic, and is an element of the field which is zero1092if and only if the curve is supersingular. Over a field of1093characteristic zero, where the Hasse invariant is undefined,1094a ``ValueError`` is returned.10951096EXAMPLES::10971098sage: E = EllipticCurve([Mod(1,2),Mod(1,2),0,0,Mod(1,2)])1099sage: E.hasse_invariant()110011101sage: E = EllipticCurve([0,0,Mod(1,3),Mod(1,3),Mod(1,3)])1102sage: E.hasse_invariant()110301104sage: E = EllipticCurve([0,0,Mod(1,5),0,Mod(2,5)])1105sage: E.hasse_invariant()110601107sage: E = EllipticCurve([0,0,Mod(1,5),Mod(1,5),Mod(2,5)])1108sage: E.hasse_invariant()1109211101111Some examples over larger fields::11121113sage: EllipticCurve(GF(101),[0,0,0,0,1]).hasse_invariant()111401115sage: EllipticCurve(GF(101),[0,0,0,1,1]).hasse_invariant()1116981117sage: EllipticCurve(GF(103),[0,0,0,0,1]).hasse_invariant()1118201119sage: EllipticCurve(GF(103),[0,0,0,1,1]).hasse_invariant()1120171121sage: F.<a> = GF(107^2)1122sage: EllipticCurve(F,[0,0,0,a,1]).hasse_invariant()112362*a + 751124sage: EllipticCurve(F,[0,0,0,0,a]).hasse_invariant()1125011261127Over fields of characteristic zero, the Hasse invariant is1128undefined::11291130sage: E = EllipticCurve([0,0,0,0,1])1131sage: E.hasse_invariant()1132Traceback (most recent call last):1133...1134ValueError: Hasse invariant only defined in positive characteristic1135"""1136k = self.base_field()1137p = k.characteristic()1138if p == 0:1139raise ValueError('Hasse invariant only defined in positive characteristic')1140elif p == 2:1141return self.a1()1142elif p == 3:1143return self.b2()1144elif p == 5:1145return self.c4()1146elif p == 7:1147return -self.c6()1148else:1149R = k['x']1150x = R.gen()1151E = self.short_weierstrass_model()1152f=(x**3+E.a4()*x+E.a6())**((p-1)//2)1153return f.coeffs()[p-1]115411551156