Path: blob/master/sage/schemes/elliptic_curves/ell_field.py
4145 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 constructor import EllipticCurve1920from ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel21from ell_wp import weierstrass_p2223class EllipticCurve_field(ell_generic.EllipticCurve_generic):2425base_field = ell_generic.EllipticCurve_generic.base_ring2627# Twists: rewritten by John Cremona as follows:28#29# Quadratic twist allowed except when char=2, j=030# Quartic twist allowed only if j=1728!=0 (so char!=2,3)31# Sextic twist allowed only if j=0!=1728 (so char!=2,3)32#33# More complicated twists exist in theory for char=2,3 and34# j=0=1728, but I have never worked them out or seen them used!35#3637r"""38Twists: rewritten by John Cremona as follows:3940The following twists are implemented:4142- Quadratic twist: except when char=2 and `j=0`.43- Quartic twist: only if `j=1728\not=0` (so not if char=2,3).44- Sextic twist: only if `j=0\not=1728` (so not if char=2,3).4546More complicated twists exist in theory for char=2,3 and j=0=1728,47but are not implemented.48"""4950def quadratic_twist(self, D=None):51"""52Return the quadratic twist of this curve by ``D``.5354INPUT:5556- ``D`` (default None) the twisting parameter (see below).5758In characteristics other than 2, `D` must be nonzero, and the59twist is isomorphic to self after adjoining `\sqrt(D)` to the60base.6162In characteristic 2, `D` is arbitrary, and the twist is63isomorphic to self after adjoining a root of `x^2+x+D` to the64base.6566In characteristic 2 when `j=0`, this is not implemented.6768If the base field `F` is finite, `D` need not be specified,69and the curve returned is the unique curve (up to isomorphism)70defined over `F` isomorphic to the original curve over the71quadratic extension of `F` but not over `F` itself. Over72infinite fields, an error is raised if `D` is not given.7374EXAMPLES::7576sage: E = EllipticCurve([GF(1103)(1), 0, 0, 107, 340]); E77Elliptic Curve defined by y^2 + x*y = x^3 + 107*x + 340 over Finite Field of size 110378sage: F=E.quadratic_twist(-1); F79Elliptic Curve defined by y^2 = x^3 + 1102*x^2 + 609*x + 300 over Finite Field of size 110380sage: E.is_isomorphic(F)81False82sage: E.is_isomorphic(F,GF(1103^2,'a'))83True8485A characteristic 2 example::8687sage: E=EllipticCurve(GF(2),[1,0,1,1,1])88sage: E1=E.quadratic_twist(1)89sage: E.is_isomorphic(E1)90False91sage: E.is_isomorphic(E1,GF(4,'a'))92True9394Over finite fields, the twisting parameter may be omitted::9596sage: k.<a> = GF(2^10)97sage: E = EllipticCurve(k,[a^2,a,1,a+1,1])98sage: Et = E.quadratic_twist()99sage: Et # random (only determined up to isomorphism)100Elliptic 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^10101sage: E.is_isomorphic(Et)102False103sage: E.j_invariant()==Et.j_invariant()104True105106sage: p=next_prime(10^10)107sage: k = GF(p)108sage: E = EllipticCurve(k,[1,2,3,4,5])109sage: Et = E.quadratic_twist()110sage: Et # random (only determined up to isomorphism)111Elliptic Curve defined by y^2 = x^3 + 7860088097*x^2 + 9495240877*x + 3048660957 over Finite Field of size 10000000019112sage: E.is_isomorphic(Et)113False114sage: k2 = GF(p^2,'a')115sage: E.change_ring(k2).is_isomorphic(Et.change_ring(k2))116True117"""118K=self.base_ring()119char=K.characteristic()120121if D is None:122if K.is_finite():123x = rings.polygen(K)124if char==2:125# We find D such that x^2+x+D is irreducible. If the126# degree is odd we can take D=1; otherwise it suffices to127# consider odd powers of a generator.128D = K(1)129if K.degree()%2==0:130D = K.gen()131a = D**2132while len((x**2+x+D).roots())>0:133D *= a134else:135# We could take a multiplicative generator but136# that might be expensive to compute; otherwise137# half the elements will do138D = K.random_element()139while len((x**2-D).roots())>0:140D = K.random_element()141else:142raise ValueError, "twisting parameter D must be specified over infinite fields."143else:144try:145D=K(D)146except ValueError:147raise ValueError, "twisting parameter D must be in the base field."148149if char!=2 and D.is_zero():150raise ValueError, "twisting parameter D must be nonzero when characteristic is not 2"151152if char!=2:153b2,b4,b6,b8=self.b_invariants()154# E is isomorphic to [0,b2,0,8*b4,16*b6]155return EllipticCurve(K,[0,b2*D,0,8*b4*D**2,16*b6*D**3])156157# now char==2158if self.j_invariant() !=0: # iff a1!=0159a1,a2,a3,a4,a6=self.ainvs()160E0=self.change_weierstrass_model(a1,a3/a1,0,(a1**2*a4+a3**2)/a1**3)161# which has the form = [1,A2,0,0,A6]162assert E0.a1()==K(1)163assert E0.a3()==K(0)164assert E0.a4()==K(0)165return EllipticCurve(K,[1,E0.a2()+D,0,0,E0.a6()])166else:167raise ValueError, "Quadratic twist not implemented in char 2 when j=0"168169def two_torsion_rank(self):170r"""171Return the dimension of the 2-torsion subgroup of172`E(K)`.173174This will be 0, 1 or 2.175176EXAMPLES::177178sage: E=EllipticCurve('11a1')179sage: E.two_torsion_rank()1800181sage: K.<alpha>=QQ.extension(E.division_polynomial(2).monic())182sage: E.base_extend(K).two_torsion_rank()1831184sage: E.reduction(53).two_torsion_rank()1852186187::188189sage: E = EllipticCurve('14a1')190sage: E.two_torsion_rank()1911192sage: K.<alpha>=QQ.extension(E.division_polynomial(2).monic().factor()[1][0])193sage: E.base_extend(K).two_torsion_rank()1942195196::197198sage: EllipticCurve('15a1').two_torsion_rank()1992200201"""202f=self.division_polynomial(rings.Integer(2))203n=len(f.roots())+1204return rings.Integer(n).ord(rings.Integer(2))205206207def quartic_twist(self, D):208r"""209Return the quartic twist of this curve by `D`.210211INPUT:212213- ``D`` (must be nonzero) -- the twisting parameter..214215.. note::216217The characteristic must not be 2 or 3, and the `j`-invariant must be 1728.218219EXAMPLES::220221sage: E=EllipticCurve_from_j(GF(13)(1728)); E222Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 13223sage: E1=E.quartic_twist(2); E1224Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 13225sage: E.is_isomorphic(E1)226False227sage: E.is_isomorphic(E1,GF(13^2,'a'))228False229sage: E.is_isomorphic(E1,GF(13^4,'a'))230True231"""232K=self.base_ring()233char=K.characteristic()234D=K(D)235236if char==2 or char==3:237raise ValueError, "Quartic twist not defined in chars 2,3"238239if self.j_invariant() !=K(1728):240raise ValueError, "Quartic twist not defined when j!=1728"241242if D.is_zero():243raise ValueError, "quartic twist requires a nonzero argument"244245c4,c6=self.c_invariants()246# E is isomorphic to [0,0,0,-27*c4,0]247assert c6==0248return EllipticCurve(K,[0,0,0,-27*c4*D,0])249250def sextic_twist(self, D):251r"""252Return the quartic twist of this curve by `D`.253254INPUT:255256- ``D`` (must be nonzero) -- the twisting parameter..257258.. note::259260The characteristic must not be 2 or 3, and the `j`-invariant must be 0.261262EXAMPLES::263264sage: E=EllipticCurve_from_j(GF(13)(0)); E265Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 13266sage: E1=E.sextic_twist(2); E1267Elliptic Curve defined by y^2 = x^3 + 11 over Finite Field of size 13268sage: E.is_isomorphic(E1)269False270sage: E.is_isomorphic(E1,GF(13^2,'a'))271False272sage: E.is_isomorphic(E1,GF(13^4,'a'))273False274sage: E.is_isomorphic(E1,GF(13^6,'a'))275True276"""277K=self.base_ring()278char=K.characteristic()279D=K(D)280281if char==2 or char==3:282raise ValueError, "Sextic twist not defined in chars 2,3"283284if self.j_invariant() !=K(0):285raise ValueError, "Sextic twist not defined when j!=0"286287if D.is_zero():288raise ValueError, "Sextic twist requires a nonzero argument"289290c4,c6=self.c_invariants()291# E is isomorphic to [0,0,0,0,-54*c6]292assert c4==0293return EllipticCurve(K,[0,0,0,0,-54*c6*D])294295def is_quadratic_twist(self, other):296r"""297Determine whether this curve is a quadratic twist of another.298299INPUT:300301- ``other`` -- an elliptic curves with the same base field as self.302303OUTPUT:304305Either 0, if the curves are not quadratic twists, or `D` if306``other`` is ``self.quadratic_twist(D)`` (up to isomorphism).307If ``self`` and ``other`` are isomorphic, returns 1.308309If the curves are defined over `\mathbb{Q}`, the output `D` is310a squarefree integer.311312.. note::313314Not fully implemented in characteristic 2, or in315characteristic 3 when both `j`-invariants are 0.316317EXAMPLES::318319sage: E = EllipticCurve('11a1')320sage: Et = E.quadratic_twist(-24)321sage: E.is_quadratic_twist(Et)322-6323324sage: E1=EllipticCurve([0,0,1,0,0])325sage: E1.j_invariant()3260327sage: E2=EllipticCurve([0,0,0,0,2])328sage: E1.is_quadratic_twist(E2)3292330sage: E1.is_quadratic_twist(E1)3311332sage: type(E1.is_quadratic_twist(E1)) == type(E1.is_quadratic_twist(E2)) #trac 6574333True334335::336337sage: E1=EllipticCurve([0,0,0,1,0])338sage: E1.j_invariant()3391728340sage: E2=EllipticCurve([0,0,0,2,0])341sage: E1.is_quadratic_twist(E2)3420343sage: E2=EllipticCurve([0,0,0,25,0])344sage: E1.is_quadratic_twist(E2)3455346347::348349sage: F = GF(101)350sage: E1 = EllipticCurve(F,[4,7])351sage: E2 = E1.quadratic_twist()352sage: D = E1.is_quadratic_twist(E2); D!=0353True354sage: F = GF(101)355sage: E1 = EllipticCurve(F,[4,7])356sage: E2 = E1.quadratic_twist()357sage: D = E1.is_quadratic_twist(E2)358sage: E1.quadratic_twist(D).is_isomorphic(E2)359True360sage: E1.is_isomorphic(E2)361False362sage: F2 = GF(101^2,'a')363sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2))364True365366A characteristic 3 example::367368sage: F = GF(3^5,'a')369sage: E1 = EllipticCurve_from_j(F(1))370sage: E2 = E1.quadratic_twist(-1)371sage: D = E1.is_quadratic_twist(E2); D!=0372True373sage: E1.quadratic_twist(D).is_isomorphic(E2)374True375376::377378sage: E1 = EllipticCurve_from_j(F(0))379sage: E2 = E1.quadratic_twist()380sage: D = E1.is_quadratic_twist(E2); D3811382sage: E1.is_isomorphic(E2)383True384385"""386from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve387E = self388F = other389if not is_EllipticCurve(E) or not is_EllipticCurve(F):390raise ValueError, "arguments are not elliptic curves"391K = E.base_ring()392zero = K.zero_element()393if not K == F.base_ring():394return zero395j=E.j_invariant()396if j != F.j_invariant():397return zero398399if E.is_isomorphic(F):400if K is rings.QQ:401return rings.ZZ(1)402return K.one_element()403404char=K.characteristic()405406if char==2:407raise NotImplementedError, "not implemented in characteristic 2"408elif char==3:409if j==0:410raise NotImplementedError, "not implemented in characteristic 3 for curves of j-invariant 0"411D = E.b2()/F.b2()412413else:414# now char!=2,3:415c4E,c6E = E.c_invariants()416c4F,c6F = F.c_invariants()417418if j==0:419um = c6E/c6F420x=rings.polygen(K)421ulist=(x**3-um).roots(multiplicities=False)422if len(ulist)==0:423D = zero424else:425D = ulist[0]426elif j==1728:427um=c4E/c4F428x=rings.polygen(K)429ulist=(x**2-um).roots(multiplicities=False)430if len(ulist)==0:431D = zero432else:433D = ulist[0]434else:435D = (c6E*c4F)/(c6F*c4E)436437# Normalization of output:438439if D.is_zero():440return D441442if K is rings.QQ:443D = D.squarefree_part()444445assert E.quadratic_twist(D).is_isomorphic(F)446447return D448449def is_quartic_twist(self, other):450r"""451Determine whether this curve is a quartic twist of another.452453INPUT:454455- ``other`` -- an elliptic curves with the same base field as self.456457OUTPUT:458459Either 0, if the curves are not quartic twists, or `D` if460``other`` is ``self.quartic_twist(D)`` (up to isomorphism).461If ``self`` and ``other`` are isomorphic, returns 1.462463.. note::464465Not fully implemented in characteristics 2 or 3.466467EXAMPLES::468469sage: E = EllipticCurve_from_j(GF(13)(1728))470sage: E1 = E.quartic_twist(2)471sage: D = E.is_quartic_twist(E1); D!=0472True473sage: E.quartic_twist(D).is_isomorphic(E1)474True475476::477478sage: E = EllipticCurve_from_j(1728)479sage: E1 = E.quartic_twist(12345)480sage: D = E.is_quartic_twist(E1); D48115999120482sage: (D/12345).is_perfect_power(4)483True484"""485from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve486E = self487F = other488if not is_EllipticCurve(E) or not is_EllipticCurve(F):489raise ValueError, "arguments are not elliptic curves"490K = E.base_ring()491zero = K.zero_element()492if not K == F.base_ring():493return zero494j=E.j_invariant()495if j != F.j_invariant() or j!=K(1728):496return zero497498if E.is_isomorphic(F):499return K.one_element()500501char=K.characteristic()502503if char==2:504raise NotImplementedError, "not implemented in characteristic 2"505elif char==3:506raise NotImplementedError, "not implemented in characteristic 3"507else:508# now char!=2,3:509D = F.c4()/E.c4()510511if D.is_zero():512return D513514assert E.quartic_twist(D).is_isomorphic(F)515516return D517518def is_sextic_twist(self, other):519r"""520Determine whether this curve is a sextic twist of another.521522INPUT:523524- ``other`` -- an elliptic curves with the same base field as self.525526OUTPUT:527528Either 0, if the curves are not sextic twists, or `D` if529``other`` is ``self.sextic_twist(D)`` (up to isomorphism).530If ``self`` and ``other`` are isomorphic, returns 1.531532.. note::533534Not fully implemented in characteristics 2 or 3.535536EXAMPLES::537538sage: E = EllipticCurve_from_j(GF(13)(0))539sage: E1 = E.sextic_twist(2)540sage: D = E.is_sextic_twist(E1); D!=0541True542sage: E.sextic_twist(D).is_isomorphic(E1)543True544545::546547sage: E = EllipticCurve_from_j(0)548sage: E1 = E.sextic_twist(12345)549sage: D = E.is_sextic_twist(E1); D550575968320551sage: (D/12345).is_perfect_power(6)552True553"""554from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve555E = self556F = other557if not is_EllipticCurve(E) or not is_EllipticCurve(F):558raise ValueError, "arguments are not elliptic curves"559K = E.base_ring()560zero = K.zero_element()561if not K == F.base_ring():562return zero563j=E.j_invariant()564if j != F.j_invariant() or not j.is_zero():565return zero566567if E.is_isomorphic(F):568return K.one_element()569570char=K.characteristic()571572if char==2:573raise NotImplementedError, "not implemented in characteristic 2"574elif char==3:575raise NotImplementedError, "not implemented in characteristic 3"576else:577# now char!=2,3:578D = F.c6()/E.c6()579580if D.is_zero():581return D582583assert E.sextic_twist(D).is_isomorphic(F)584585return D586587def descend_to(self, K, f=None):588r"""589Given a subfield `K` and an elliptic curve self defined over a field `L`,590this function determines whether there exists an elliptic curve over `K`591which is isomorphic over `L` to self. If one exists, it finds it.592593INPUT:594595- `K` -- a subfield of the base field of self.596- `f` -- an embedding of `K` into the base field of self.597598OUTPUT:599600Either an elliptic curve defined over `K` which is isomorphic to self601or None if no such curve exists.602603.. NOTE::604605This only works over number fields and QQ.606607EXAMPLES::608609sage: E = EllipticCurve([1,2,3,4,5])610sage: E.descend_to(ZZ)611Traceback (most recent call last):612...613TypeError: Input must be a field.614615::616617sage: F.<b> = QuadraticField(23)618sage: G.<a> = F.extension(x^3+5)619sage: E = EllipticCurve(j=1728*b).change_ring(G)620sage: E.descend_to(F)621Elliptic Curve defined by y^2 = x^3 + (8957952*b-206032896)*x + (-247669456896*b+474699792384) over Number Field in b with defining polynomial x^2 - 23622623::624625sage: L.<a> = NumberField(x^4 - 7)626sage: K.<b> = NumberField(x^2 - 7)627sage: E = EllipticCurve([a^6,0])628sage: E.descend_to(K)629Elliptic Curve defined by y^2 = x^3 + 1296/49*b*x over Number Field in b with defining polynomial x^2 - 7630631::632633sage: K.<a> = QuadraticField(17)634sage: E = EllipticCurve(j = 2*a)635sage: print E.descend_to(QQ)636None637"""638if not K.is_field():639raise TypeError, "Input must be a field."640if self.base_field()==K:641return self642j = self.j_invariant()643from sage.rings.all import QQ644if K == QQ:645f = QQ.embeddings(self.base_field())[0]646if j in QQ:647jbase = QQ(j)648else:649return None650elif f == None:651embeddings = K.embeddings(self.base_field())652if len(embeddings) == 0:653raise TypeError, "Input must be a subfield of the base field of the curve."654for g in embeddings:655try:656jbase = g.preimage(j)657f = g658break659except:660pass661if f == None:662return None663else:664try:665jbase = f.preimage(j)666except:667return None668E = EllipticCurve(j=jbase)669E2 = EllipticCurve(self.base_field(), [f(a) for a in E.a_invariants()])670if jbase==0:671d = self.is_sextic_twist(E2)672if d == 1:673return E674if d == 0:675return None676Etwist = E2.sextic_twist(d)677elif jbase==1728:678d = self.is_quartic_twist(E2)679if d == 1:680return E681if d == 0:682return None683Etwist = E2.quartic_twist(d)684else:685d = self.is_quadratic_twist(E2)686if d == 1:687return E688if d == 0:689return None690Etwist = E2.quadratic_twist(d)691if Etwist.is_isomorphic(self):692try:693Eout = EllipticCurve(K, [f.preimage(a) for a in Etwist.a_invariants()])694except:695return None696else:697return Eout698699def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True):700r"""701Returns an elliptic curve isogeny from self.702703The isogeny can be determined in two ways, either by a704polynomial or a set of torsion points. The methods used are:705706- Velu's Formulas: Velu's original formulas for computing707isogenies. This algorithm is selected by giving as the708``kernel`` parameter a point or a list of points which709generate a finite subgroup.710711- Kohel's Formulas: Kohel's original formulas for computing712isogenies. This algorithm is selected by giving as the713``kernel`` parameter a polynomial (or a coefficient list714(little endian)) which will define the kernel of the715isogeny.716717INPUT:718719- ``E`` - an elliptic curve, the domain of the isogeny to720initialize.721722- ``kernel`` - a kernel, either a point in ``E``, a list of points723in ``E``, a univariate kernel polynomial or ``None``.724If initiating from a domain/codomain, this must be725set to None. Validity of input is *not* fully checked.726727- ``codomain`` - an elliptic curve (default:None). If ``kernel`` is728None, then this must be the codomain of a separable729normalized isogeny, furthermore, ``degree`` must be730the degree of the isogeny from ``E`` to ``codomain``.731If ``kernel`` is not None, then this must be732isomorphic to the codomain of the normalized separable733isogeny defined by ``kernel``, in this case, the734isogeny is post composed with an isomorphism so that735this parameter is the codomain.736737- ``degree`` - an integer (default:None). If ``kernel`` is None,738then this is the degree of the isogeny from ``E`` to739``codomain``. If ``kernel`` is not None, then this is740used to determine whether or not to skip a gcd of the741kernel polynomial with the two torsion polynomial of742``E``.743744- ``model`` - a string (default:None). Only supported variable is745"minimal", in which case if``E`` is a curve over the746rationals, then the codomain is set to be the unique747global minimum model.748749- ``check`` (default: True) does some partial checks that the750input is valid (e.g., that the points751defined by the kernel polynomial are752torsion); however, invalid input can in some753cases still pass, since that the points define754a group is not checked.755756OUTPUT:757758An isogeny between elliptic curves. This is a morphism of curves.759760EXAMPLES::761762sage: F = GF(2^5, 'alpha'); alpha = F.gen()763sage: E = EllipticCurve(F, [1,0,1,1,1])764sage: R.<x> = F[]765sage: phi = E.isogeny(x+1)766sage: phi.rational_maps()767((x^2 + x + 1)/(x + 1), (x^2*y + x)/(x^2 + 1))768769sage: E = EllipticCurve('11a1')770sage: P = E.torsion_points()[1]771sage: E.isogeny(P)772Isogeny 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 Field773774sage: E = EllipticCurve(GF(19),[1,1])775sage: P = E(15,3); Q = E(2,12);776sage: (P.order(), Q.order())777(7, 3)778sage: phi = E.isogeny([P,Q]); phi779Isogeny 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 19780sage: phi(E.random_point()) # all points defined over GF(19) are in the kernel781(0 : 1 : 0)782783784# not all polynomials define a finite subgroup trac #6384785sage: E = EllipticCurve(GF(31),[1,0,0,1,2])786sage: phi = E.isogeny([14,27,4,1])787Traceback (most recent call last):788...789ValueError: The polynomial does not define a finite subgroup of the elliptic curve.790791An example in which we construct an invalid morphism, which792illustrates that the check for correctness of the input is not793sufficient. (See trac 11578.)::794795sage: R.<x> = QQ[]796sage: K.<a> = NumberField(x^2-x-1)797sage: E = EllipticCurve(K, [-13392, -1080432])798sage: R.<x> = K[]799sage: phi = E.isogeny( (x-564)*(x - 396/5*a + 348/5) )800sage: phi.codomain().conductor().norm().factor()8015^2 * 11^2 * 3271 * 15806939 * 4169267639351802sage: phi.domain().conductor().norm().factor()80311^2804"""805return EllipticCurveIsogeny(self, kernel, codomain, degree, model, check=check)806807808def isogeny_codomain(self, kernel, degree=None):809r"""810Returns the codomain of the isogeny from self with given811kernel.812813INPUT:814815- ``kernel`` - Either a list of points in the kernel of the isogeny,816or a kernel polynomial (specified as a either a817univariate polynomial or a coefficient list.)818819- ``degree`` - an integer, (default:None) optionally specified degree820of the kernel.821822OUTPUT:823824An elliptic curve, the codomain of the separable normalized825isogeny from this kernel826827EXAMPLES::828829sage: E = EllipticCurve('17a1')830sage: R.<x> = QQ[]831sage: E2 = E.isogeny_codomain(x - 11/4); E2832Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 1461/16*x - 19681/64 over Rational Field833834"""835return isogeny_codomain_from_kernel(self, kernel, degree=None)836837def isogenies_prime_degree(self, l=None):838"""839Generic code, valid for all fields, for those l for which the840modular curve has genus 0.841842INPUT:843844- ``l`` -- either None, a prime or a list of primes, from [2,3,5,7,13].845846OUTPUT:847848(list) All `l`-isogenies for the given `l` with domain self.849850METHOD:851852Calls the generic function853``isogenies_prime_degree_genus_0()``. This requires that854certain operations have been implemented over the base field,855such as root-finding for univariate polynomials.856857EXAMPLES::858859sage: F = QQbar860sage: E = EllipticCurve(F, [1,18]); E861Elliptic Curve defined by y^2 = x^3 + x + 18 over Algebraic Field862863sage: F = CC864sage: E = EllipticCurve(F, [1,18]); E865Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision866sage: E.isogenies_prime_degree(11)867Traceback (most recent call last):868...869NotImplementedError: This code could be implemented for general complex fields, but has not been yet.870871Examples over finite fields::872873sage: E = EllipticCurve(GF(next_prime(1000000)), [7,8])874sage: E.isogenies_prime_degree()875[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]876sage: E.isogenies_prime_degree(2)877[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]878sage: E.isogenies_prime_degree(3)879[]880sage: E.isogenies_prime_degree(5)881[]882sage: E.isogenies_prime_degree(7)883[]884sage: E.isogenies_prime_degree(13)885[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,886Isogeny 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]887888sage: E.isogenies_prime_degree([2, 3, 5, 7, 13])889[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]890sage: E.isogenies_prime_degree([2, 4])891Traceback (most recent call last):892...893ValueError: 4 is not prime.894sage: E.isogenies_prime_degree([2, 29])895Traceback (most recent call last):896...897NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.898sage: E.isogenies_prime_degree(4)899Traceback (most recent call last):900...901ValueError: 4 is not prime.902sage: E.isogenies_prime_degree(11)903Traceback (most recent call last):904...905NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.906907sage: E = EllipticCurve(GF(17),[2,0])908sage: E.isogenies_prime_degree(3)909[]910sage: E.isogenies_prime_degree(2)911[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]912913sage: E = EllipticCurve(GF(13^4, 'a'),[2,8])914sage: E.isogenies_prime_degree(2)915[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]916917sage: E.isogenies_prime_degree(3)918[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]919sage: E.isogenies_prime_degree([2, 3, 5, 7, 13])920Traceback (most recent call last):921...922NotImplementedError: 2, 3, 5, 7 and 13-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.923sage: E.isogenies_prime_degree([2, 3, 5, 7])924[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, 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, Isogeny of degree 7 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 + 3*x + 11 over Finite Field in a of size 13^4, Isogeny of degree 7 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 + 2 over Finite Field in a of size 13^4]925926Examples over number fields (other than QQ)::927928sage: QQroot2.<e> = NumberField(x^2-2)929sage: E = EllipticCurve(QQroot2,[1,1])930sage: E.isogenies_prime_degree(11)931Traceback (most recent call last):932...933NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.934sage: E.isogenies_prime_degree(5)935[]936937sage: E = EllipticCurve(QQroot2, [1,0,1,4, -6]); E938Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2939sage: E.isogenies_prime_degree(2)940[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]941sage: E.isogenies_prime_degree(3)942[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, 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]943944945"""946F = self.base_ring()947if rings.is_RealField(F):948raise NotImplementedError, "This code could be implemented for general real fields, but has not been yet."949if rings.is_ComplexField(F):950raise NotImplementedError, "This code could be implemented for general complex fields, but has not been yet."951if F == rings.QQbar:952raise NotImplementedError, "This code could be implemented for QQbar, but has not been yet."953954from ell_curve_isogeny import isogenies_prime_degree_genus_0955if l is None:956l = [2, 3, 5, 7, 13]957if l in [2, 3, 5, 7, 13]:958return isogenies_prime_degree_genus_0(self, l)959if type(l) != list:960if l.is_prime():961raise NotImplementedError, "Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented."962else:963raise ValueError, "%s is not prime."%l964isogs = []965i = 0966while i<len(l):967isogenies = [f for f in self.isogenies_prime_degree(l[i]) if not f in isogs]968isogs.extend(isogenies)969i = i+1970return isogs971972def 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