Path: blob/master/src/sage/schemes/elliptic_curves/ell_generic.py
8821 views
r"""1Elliptic curves over a general ring23Sage defines an elliptic curve over a ring `R` as a 'Weierstrass Model' with4five coefficients `[a_1,a_2,a_3,a_4,a_6]` in `R` given by56`y^2 + a_1 xy + a_3 y = x^3 +a_2 x^2 +a_4 x +a_6`.78Note that the (usual) scheme-theoretic definition of an elliptic curve over `R` would require the discriminant to be a unit in `R`, Sage only imposes that the discriminant is non-zero. Also, in Magma, 'Weierstrass Model' means a model with `a1=a2=a3=0`, which is called 'Short Weierstrass Model' in Sage; these do not always exist in characteristics 2 and 3.910EXAMPLES:1112We construct an elliptic curve over an elaborate base ring::1314sage: p = 97; a=1; b=315sage: R, u = PolynomialRing(GF(p), 'u').objgen()16sage: S, v = PolynomialRing(R, 'v').objgen()17sage: T = S.fraction_field()18sage: E = EllipticCurve(T, [a, b]); E19Elliptic Curve defined by y^2 = x^3 + x + 3 over Fraction Field of Univariate Polynomial Ring in v over Univariate Polynomial Ring in u over Finite Field of size 9720sage: latex(E)21y^2 = x^{3} + x + 32223AUTHORS:2425- William Stein (2005): Initial version2627- Robert Bradshaw et al....2829- John Cremona (2008-01): isomorphisms, automorphisms and twists in all characteristics30"""3132#*****************************************************************************33# Copyright (C) 2005 William Stein <[email protected]>34#35# Distributed under the terms of the GNU General Public License (GPL)36#37# This code is distributed in the hope that it will be useful,38# but WITHOUT ANY WARRANTY; without even the implied warranty of39# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU40# General Public License for more details.41#42# The full text of the GPL is available at:43#44# http://www.gnu.org/licenses/45#*****************************************************************************4647import math4849from sage.rings.all import PolynomialRing50from sage.rings.polynomial.polynomial_ring import polygen, polygens51import sage.groups.additive_abelian.additive_abelian_group as groups52import sage.groups.generic as generic53import sage.plot.all as plot54from sage.plot.plot import generate_plot_points5556import sage.rings.arith as arith57import sage.rings.all as rings58from sage.rings.number_field.all import is_NumberField59import sage.misc.misc as misc606162# Schemes63import sage.schemes.projective.projective_space as projective_space64from sage.schemes.projective.projective_homset import SchemeHomset_points_abelian_variety_field6566import ell_point67import ell_torsion68import constructor69import formal_group70import weierstrass_morphism as wm717273factor = arith.factor74sqrt = math.sqrt75exp = math.exp76mul = misc.mul77next_prime = arith.next_prime7879oo = rings.infinity # infinity80O = rings.O # big oh8182import sage.schemes.plane_curves.projective_curve as plane_curve8384def is_EllipticCurve(x):85r"""86Utility function to test if ``x`` is an instance of an Elliptic Curve class.8788EXAMPLES::8990sage: from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve91sage: E = EllipticCurve([1,2,3/4,7,19])92sage: is_EllipticCurve(E)93True94sage: is_EllipticCurve(0)95False96"""97return isinstance(x, EllipticCurve_generic)9899class EllipticCurve_generic(plane_curve.ProjectiveCurve_generic):100r"""101Elliptic curve over a generic base ring.102103EXAMPLES::104105sage: E = EllipticCurve([1,2,3/4,7,19]); E106Elliptic Curve defined by y^2 + x*y + 3/4*y = x^3 + 2*x^2 + 7*x + 19 over Rational Field107sage: loads(E.dumps()) == E108True109sage: E = EllipticCurve([1,3])110sage: P = E([-1,1,1])111sage: -5*P112(179051/80089 : -91814227/22665187 : 1)113"""114def __init__(self, ainvs, extra=None):115r"""116Constructor from `a`-invariants (long or short Weierstrass coefficients).117118INPUT:119120- ``ainvs`` (list) -- either `[a_1,a_2,a_3,a_4,a_6]` or121`[a_4,a_6]` (with `a_1=a_2=a_3=0` in the second case).122123.. note::124125See constructor.py for more variants.126127EXAMPLES::128129sage: E = EllipticCurve([1,2,3,4,5]); E130Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field131sage: E = EllipticCurve(GF(7),[1,2,3,4,5]); E132Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 7133134Constructor from `[a_4,a_6]` sets `a_1=a_2=a_3=0`::135136sage: EllipticCurve([4,5]).ainvs()137(0, 0, 0, 4, 5)138139The base ring need not be a field::140141sage: EllipticCurve(IntegerModRing(91),[1,2,3,4,5])142Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Ring of integers modulo 91143"""144if extra != None: # possibility of two arguments145K, ainvs = ainvs, extra146else:147K = ainvs[0].parent()148assert len(ainvs) == 2 or len(ainvs) == 5149self.__base_ring = K150ainvs = [K(x) for x in ainvs]151if len(ainvs) == 2:152ainvs = [K(0),K(0),K(0)] + ainvs153self.__ainvs = tuple(ainvs)154if self.discriminant() == 0:155raise ArithmeticError, \156"Invariants %s define a singular curve."%ainvs157PP = projective_space.ProjectiveSpace(2, K, names='xyz');158x, y, z = PP.coordinate_ring().gens()159a1, a2, a3, a4, a6 = ainvs160f = y**2*z + (a1*x + a3*z)*y*z \161- (x**3 + a2*x**2*z + a4*x*z**2 + a6*z**3)162plane_curve.ProjectiveCurve_generic.__init__(self, PP, f)163# TODO: cleanup, are these two point classes redundant?164165# See #1975: we deliberately set the class to166# EllipticCurvePoint_finite_field for finite rings, so that we167# can do some arithmetic on points over Z/NZ, for teaching168# purposes.169from sage.rings.finite_rings.constructor import is_FiniteField170from sage.rings.finite_rings.integer_mod_ring import is_IntegerModRing171if is_FiniteField(K) or is_IntegerModRing(K):172self._morphism = self._point = ell_point.EllipticCurvePoint_finite_field173elif K.is_field():174if is_NumberField(K):175self._morphism = self._point = ell_point.EllipticCurvePoint_number_field176else:177self._morphism = self._point = ell_point.EllipticCurvePoint_field178else:179self._morphism = self._point = ell_point.EllipticCurvePoint180181def _defining_params_(self):182r"""183Internal function. Returns a tuple of the base ring of this184elliptic curve and its `a`-invariants, from which it can be185reconstructed.186187EXAMPLES::188189sage: E=EllipticCurve(QQ,[1,1])190sage: E._defining_params_()191(Rational Field, [0, 0, 0, 1, 1])192sage: EllipticCurve(*E._defining_params_()) == E193True194"""195return (self.__base_ring, list(self.__ainvs))196197def __hash__(self):198"""199TESTS::200201sage: E = EllipticCurve('37a')202sage: hash(E)203-1437250549 # 32-bit204-2189969105152029685 # 64-bit205sage: hash(E) != hash(E.change_ring(GF(7)))206True207"""208return hash((self.__base_ring, self.__ainvs))209210def _repr_(self):211"""212String representation of elliptic curve.213214EXAMPLES::215216sage: E=EllipticCurve([1,2,3,4,5]); E._repr_()217'Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field'218219::220221sage: R.<x> = QQ['x']222sage: K.<a> = NumberField(x^3-17)223sage: EllipticCurve([a^2-3, -2/3*a + 3])224Elliptic Curve defined by y^2 = x^3 + (a^2-3)*x + (-2/3*a+3) over Number Field in a225with defining polynomial x^3 - 17226"""227#return "Elliptic Curve with a-invariants %s over %s"%(self.ainvs(), self.base_ring())228b = self.ainvs()229#return "y^2 + %s*x*y + %s*y = x^3 + %s*x^2 + %s*x + %s"%\230# (a[0], a[2], a[1], a[3], a[4])231a = [z._coeff_repr() for z in b]232s = "Elliptic Curve defined by "233s += "y^2 "234if a[0] == "-1":235s += "- x*y "236elif a[0] == '1':237s += "+ x*y "238elif b[0]:239s += "+ %s*x*y "%a[0]240if a[2] == "-1":241s += "- y "242elif a[2] == '1':243s += "+ y "244elif b[2]:245s += "+ %s*y "%a[2]246s += "= x^3 "247if a[1] == "-1":248s += "- x^2 "249elif a[1] == '1':250s += "+ x^2 "251elif b[1]:252s += "+ %s*x^2 "%a[1]253if a[3] == "-1":254s += "- x "255elif a[3] == '1':256s += "+ x "257elif b[3]:258s += "+ %s*x "%a[3]259if a[4] == '-1':260s += "- 1 "261elif a[4] == '1':262s += "+ 1 "263elif b[4]:264s += "+ %s "%a[4]265s = s.replace("+ -","- ")266s += "over %s"%self.base_ring()267return s268269def _latex_(self):270"""271Internal function. Returns a latex string for this elliptic curve.272273Users will normally use latex() instead.274275EXAMPLES::276277sage: E = EllipticCurve(QQ, [1,1])278sage: E._latex_()279'y^2 = x^{3} + x + 1 '280281sage: E = EllipticCurve(QQ, [1,2,3,4,5])282sage: E._latex_()283'y^2 + x y + 3 y = x^{3} + 2 x^{2} + 4 x + 5 '284285Check that :trac:`12524` is solved::286287sage: K.<phi> = NumberField(x^2-x-1)288sage: E = EllipticCurve([0,0,phi,27*phi-43,-80*phi+128])289sage: E._latex_()290'y^2 + \\phi y = x^{3} + \\left(27 \\phi - 43\\right) x - 80 \\phi + 128 '291"""292from sage.rings.polynomial.polynomial_ring import polygen293a = self.ainvs()294x, y = polygen(self.base_ring(), 'x, y')295s = "y^2"296if a[0] or a[2]:297s += " + " + (a[0]*x*y + a[2]*y)._latex_()298s += " = "299s += (x**3 + a[1]*x**2 + a[3]*x + a[4])._latex_()300s += " "301s = s.replace("+ -","- ")302return s303304def _pari_init_(self):305"""306Internal function. Returns a string to initialize this elliptic307curve in the PARI system.308309EXAMPLES::310311sage: E=EllipticCurve(QQ,[1,1])312sage: E._pari_init_()313'ellinit([0/1,0/1,0/1,1/1,1/1])'314"""315return 'ellinit([%s])'%(','.join([x._pari_init_() for x in self.ainvs()]))316317def _magma_init_(self, magma):318"""319Internal function. Returns a string to initialize this elliptic320curve in the Magma subsystem.321322EXAMPLES::323324sage: E = EllipticCurve(QQ,[1,1])325sage: E._magma_init_(magma) # optional - magma326'EllipticCurve([_sage_ref...|0/1,0/1,0/1,1/1,1/1])'327sage: E = EllipticCurve(GF(41),[2,5]) # optional - magma328sage: E._magma_init_(magma) # optional - magma329'EllipticCurve([_sage_ref...|GF(41)!0,GF(41)!0,GF(41)!0,GF(41)!2,GF(41)!5])'330sage: E = EllipticCurve(GF(25,'a'), [0,0,1,4,0])331sage: magma(E) # optional - magma332Elliptic Curve defined by y^2 + y = x^3 + 4*x over GF(5^2)333sage: magma(EllipticCurve([1/2,2/3,-4/5,6/7,8/9])) # optional - magma334Elliptic Curve defined by y^2 + 1/2*x*y - 4/5*y = x^3 + 2/3*x^2 + 6/7*x + 8/9 over Rational Field335sage: R.<x> = Frac(QQ['x'])336sage: magma(EllipticCurve([x,1+x])) # optional - magma337Elliptic Curve defined by y^2 = x^3 + x*x + (x + 1) over Univariate rational function field over Rational Field338"""339kmn = magma(self.base_ring())._ref()340return 'EllipticCurve([%s|%s])'%(kmn,','.join([x._magma_init_(magma) for x in self.ainvs()]))341342343def _symbolic_(self, SR):344r"""345Many elliptic curves can be converted into a symbolic expression346using the ``symbolic_expression`` command.347348EXAMPLES: We find a torsion point on 11a.349350::351352sage: E = EllipticCurve('11a')353sage: E._symbolic_(SR)354y^2 + y == x^3 - x^2 - 10*x - 20355sage: E.torsion_subgroup().gens()356((5 : 5 : 1),)357358We find the corresponding symbolic equality::359360sage: eqn = symbolic_expression(E); eqn361y^2 + y == x^3 - x^2 - 10*x - 20362363We verify that the given point is on the curve::364365sage: eqn(x=5,y=5)36630 == 30367sage: bool(eqn(x=5,y=5))368True369370We create a single expression::371372sage: F = eqn.lhs() - eqn.rhs(); F373-x^3 + x^2 + y^2 + 10*x + y + 20374sage: y = var('y')375sage: F.solve(y)376[y == -1/2*sqrt(4*x^3 - 4*x^2 - 40*x - 79) - 1/2,377y == 1/2*sqrt(4*x^3 - 4*x^2 - 40*x - 79) - 1/2]378379You can also solve for x in terms of y, but the result is380horrendous. Continuing with the above example, we can explicitly381find points over random fields by substituting in values for x::382383sage: v = F.solve(y)[0].rhs(); v384-1/2*sqrt(4*x^3 - 4*x^2 - 40*x - 79) - 1/2385sage: v = v.function(x)386sage: v(3)387-1/2*sqrt(-127) - 1/2388sage: v(7)389-1/2*sqrt(817) - 1/2390sage: v(-7)391-1/2*sqrt(-1367) - 1/2392sage: v(sqrt(2))393-1/2*sqrt(-32*sqrt(2) - 87) - 1/2394395We can even do arithmetic with them, as follows::396397sage: E2 = E.change_ring(SR); E2398Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Symbolic Ring399sage: P = E2.point((3, v(3), 1), check=False) # the check=False option doesn't verify that y^2 = f(x)400sage: P401(3 : -1/2*sqrt(-127) - 1/2 : 1)402sage: P + P403(-756/127 : 41143/32258*sqrt(-127) - 1/2 : 1)404405We can even throw in a transcendental::406407sage: w = E2.point((pi,v(pi),1), check=False); w408(pi : -1/2*sqrt(-40*pi + 4*pi^3 - 4*pi^2 - 79) - 1/2 : 1)409sage: x, y, z = w; ((y^2 + y) - (x^3 - x^2 - 10*x - 20)).expand()4100411412sage: 2*w413(-2*pi + (2*pi - 3*pi^2 + 10)^2/(-40*pi + 4*pi^3 - 4*pi^2 - 79) + 1 : (3*pi - (2*pi - 3*pi^2 + 10)^2/(-40*pi + 4*pi^3 - 4*pi^2 - 79) - 1)*(2*pi - 3*pi^2 + 10)/sqrt(-40*pi + 4*pi^3 - 4*pi^2 - 79) + 1/2*sqrt(-40*pi + 4*pi^3 - 4*pi^2 - 79) - 1/2 : 1)414415sage: x, y, z = 2*w; temp = ((y^2 + y) - (x^3 - x^2 - 10*x - 20))416417This is a point on the curve::418419sage: bool(temp == 0)420True421"""422a = [SR(x) for x in self.a_invariants()]423x, y = SR.var('x, y')424return y**2 + a[0]*x*y + a[2]*y == x**3 + a[1]*x**2 + a[3]*x + a[4]425426def __cmp__(self, other):427"""428Standard comparison function for elliptic curves, to allow sorting429and equality testing.430431EXAMPLES::432433sage: E=EllipticCurve(QQ,[1,1])434sage: F=EllipticCurve(QQ,[0,0,0,1,1])435sage: E==F436True437"""438if not isinstance(other, EllipticCurve_generic):439return -1440t = cmp(self.base_ring(), other.base_ring())441if t:442return t443return cmp(self.ainvs(), other.ainvs())444445def __contains__(self, P):446"""447Returns True if and only if P is a point on the elliptic curve. P448just has to be something that can be coerced to a point.449450EXAMPLES::451452sage: E = EllipticCurve([0, 0, 1, -1, 0])453sage: (0,0) in E454True455sage: (1,3) in E456False457sage: E = EllipticCurve([GF(7)(0), 1])458sage: [0,0] in E459False460sage: [0,8] in E461True462sage: P = E(0,8)463sage: P464(0 : 1 : 1)465sage: P in E466True467"""468if not isinstance(P, ell_point.EllipticCurvePoint):469try:470P = self(P)471except TypeError:472return False473if P.curve() == self:474return True475x, y, a = P[0], P[1], self.ainvs()476return y**2 + a[0]*x*y + a[2]*y == x**3 + a[1]*x**2 + a[3]*x + a[4]477478def __call__(self, *args, **kwds):479r"""480EXAMPLES::481482sage: E = EllipticCurve([0, 0, 1, -1, 0])483484The point at infinity, which is the 0 element of the group::485486sage: E(0)487(0 : 1 : 0)488489The origin is a point on our curve::490491sage: P = E([0,0])492sage: P493(0 : 0 : 1)494495The curve associated to a point::496497sage: P.curve()498Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field499500Points can be specified by given a 2-tuple or 3-tuple::501502sage: E([0,0])503(0 : 0 : 1)504sage: E([0,1,0])505(0 : 1 : 0)506507Over a field, points are normalized so the 3rd entry (if non-zero)508is 1::509510sage: E(105, -69, 125)511(21/25 : -69/125 : 1)512513We create points on an elliptic curve over a prime finite field::514515sage: E = EllipticCurve([GF(7)(0), 1])516sage: E([2,3])517(2 : 3 : 1)518sage: E([0,0])519Traceback (most recent call last):520...521TypeError: Coordinates [0, 0, 1] do not define a point on Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7522523We create a point on an elliptic curve over a number field::524525sage: x = polygen(RationalField())526sage: K = NumberField(x**3 + x + 1, 'a'); a = K.gen()527sage: E = EllipticCurve([a,a])528sage: E529Elliptic Curve defined by y^2 = x^3 + a*x + a over Number Field in a with defining polynomial x^3 + x + 1530sage: E = EllipticCurve([K(1),1])531sage: E532Elliptic Curve defined by y^2 = x^3 + x + 1 over Number Field in a with defining polynomial x^3 + x + 1533sage: P = E([a,0,1])534sage: P535(a : 0 : 1)536sage: P+P537(0 : 1 : 0)538539Another example involving p-adics::540541sage: E = EllipticCurve('37a1')542sage: P = E([0,0]); P543(0 : 0 : 1)544sage: R = pAdicField(3,20)545sage: Ep = E.base_extend(R); Ep546Elliptic Curve defined by y^2 + (1+O(3^20))*y = x^3 + (2+2*3+2*3^2+2*3^3+2*3^4+2*3^5+2*3^6+2*3^7+2*3^8+2*3^9+2*3^10+2*3^11+2*3^12+2*3^13+2*3^14+2*3^15+2*3^16+2*3^17+2*3^18+2*3^19+O(3^20))*x over 3-adic Field with capped relative precision 20547sage: Ep(P)548(0 : 0 : 1 + O(3^20))549550Constructing points from the torsion subgroup (which is an abstract551abelian group)::552553sage: E = EllipticCurve('14a1')554sage: T = E.torsion_subgroup()555sage: [E(t) for t in T]556[(0 : 1 : 0),557(9 : 23 : 1),558(2 : 2 : 1),559(1 : -1 : 1),560(2 : -5 : 1),561(9 : -33 : 1)]562563::564565sage: E = EllipticCurve([0,0,0,-49,0])566sage: T = E.torsion_subgroup()567sage: [E(t) for t in T]568[(0 : 1 : 0), (7 : 0 : 1), (0 : 0 : 1), (-7 : 0 : 1)]569570::571572sage: E = EllipticCurve('37a1')573sage: T = E.torsion_subgroup()574sage: [E(t) for t in T]575[(0 : 1 : 0)]576"""577if len(args) == 1 and args[0] == 0:578R = self.base_ring()579return self.point([R(0),R(1),R(0)], check=False)580P = args[0]581if isinstance(P, groups.AdditiveAbelianGroupElement) and isinstance(P.parent(),ell_torsion.EllipticCurveTorsionSubgroup):582return self(P.element())583if isinstance(args[0],584(ell_point.EllipticCurvePoint_field, \585ell_point.EllipticCurvePoint_number_field, \586ell_point.EllipticCurvePoint)):587# check if denominator of the point contains a factor of the588# characteristic of the base ring. if so, coerce the point to589# infinity.590characteristic = self.base_ring().characteristic()591if characteristic != 0 and isinstance(args[0][0], rings.Rational) and isinstance(args[0][1], rings.Rational):592if rings.mod(args[0][0].denominator(),characteristic) == 0 or rings.mod(args[0][1].denominator(),characteristic) == 0:593return self._reduce_point(args[0], characteristic)594args = tuple(args[0])595596return plane_curve.ProjectiveCurve_generic.__call__(self, *args, **kwds)597598def _reduce_point(self, R, p):599r"""600Reduces a point R on an ellipitc curve to the corresponding point on601the elliptic curve reduced modulo p. Used to coerce points between602curves when p is a factor of the denominator of one of the603coordinates.604605This functionality is used internally in the \code{call} method for606elliptic curves.607608INPUT:609R -- a point on an elliptic curve610p -- a prime611612OUTPUT:613S -- the corresponding point of the elliptic curve containing R, but614reduced modulo p615616EXAMPLES:617Suppose we have a point with large height on a rational elliptic curve618whose denominator contains a factor of 11::619620sage: E = EllipticCurve([1,-1,0,94,9])621sage: R = E([0,3]) + 5*E([8,31])622sage: factor(R.xy()[0].denominator())6232^2 * 11^2 * 1457253032371^2624625Since 11 is a factor of the denominator, this point corresponds to the626point at infinity on the same curve but reduced modulo 11. The reduce627function tells us this::628629sage: E11 = E.change_ring(GF(11))630sage: S = E11._reduce_point(R, 11)631sage: E11(S)632(0 : 1 : 0)633634The 0 point reduces as expected::635636sage: E11._reduce_point(E(0), 11)637(0 : 1 : 0)638639Note that one need not explicitly call640\code{EllipticCurve._reduce_point}641"""642if R.is_zero():643return R.curve().change_ring(rings.GF(p))(0)644x, y = R.xy()645d = arith.LCM(x.denominator(), y.denominator())646return R.curve().change_ring(rings.GF(p))([x*d, y*d, d])647648def is_x_coord(self, x):649r"""650Returns True if ``x`` is the `x`-coordinate of a point on this curve.651652.. note::653654See also ``lift_x()`` to find the point(s) with a given655`x`-coordinate. This function may be useful in cases where656testing an element of the base field for being a square is657faster than finding its square root.658659EXAMPLES::660661sage: E = EllipticCurve('37a'); E662Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field663sage: E.is_x_coord(1)664True665sage: E.is_x_coord(2)666True667668There are no rational points with x-coordinate 3::669670sage: E.is_x_coord(3)671False672673However, there are such points in `E(\RR)`::674675sage: E.change_ring(RR).is_x_coord(3)676True677678And of course it always works in `E(\CC)`::679680sage: E.change_ring(RR).is_x_coord(-3)681False682sage: E.change_ring(CC).is_x_coord(-3)683True684685AUTHORS:686687- John Cremona (2008-08-07): adapted from lift_x()688689TEST::690691sage: E=EllipticCurve('5077a1')692sage: [x for x in srange(-10,10) if E.is_x_coord (x)]693[-3, -2, -1, 0, 1, 2, 3, 4, 8]694695::696697sage: F=GF(32,'a')698sage: E=EllipticCurve(F,[1,0,0,0,1])699sage: set([P[0] for P in E.points() if P!=E(0)]) == set([x for x in F if E.is_x_coord(x)])700True701"""702K = self.base_ring()703try:704x = K(x)705except TypeError:706raise TypeError, 'x must be coercible into the base ring of the curve'707a1, a2, a3, a4, a6 = self.ainvs()708fx = ((x + a2) * x + a4) * x + a6709if a1.is_zero() and a3.is_zero():710return fx.is_square()711b = (a1*x + a3)712if K.characteristic() == 2:713R = PolynomialRing(K, 'y')714F = R([-fx,b,1])715return len(F.roots())>0716D = b*b + 4*fx717return D.is_square()718719def lift_x(self, x, all=False):720r"""721Returns one or all points with given `x`-coordinate.722723INPUT:724725- ``x`` -- an element of the base ring of the curve.726727- ``all`` (bool, default False) -- if True, return a (possibly728empty) list of all points; if False, return just one point,729or raise a ValueError if there are none.730731.. note::732733See also ``is_x_coord()``.734735EXAMPLES::736737sage: E = EllipticCurve('37a'); E738Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field739sage: E.lift_x(1)740(1 : 0 : 1)741sage: E.lift_x(2)742(2 : 2 : 1)743sage: E.lift_x(1/4, all=True)744[(1/4 : -3/8 : 1), (1/4 : -5/8 : 1)]745746There are no rational points with `x`-coordinate 3::747748sage: E.lift_x(3)749Traceback (most recent call last):750...751ValueError: No point with x-coordinate 3 on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field752753However, there are two such points in `E(\RR)`::754755sage: E.change_ring(RR).lift_x(3, all=True)756[(3.00000000000000 : 4.42442890089805 : 1.00000000000000), (3.00000000000000 : -5.42442890089805 : 1.00000000000000)]757758And of course it always works in `E(\CC)`::759760sage: E.change_ring(RR).lift_x(.5, all=True)761[]762sage: E.change_ring(CC).lift_x(.5)763(0.500000000000000 : -0.500000000000000 + 0.353553390593274*I : 1.00000000000000)764765We can perform these operations over finite fields too::766767sage: E = E.change_ring(GF(17)); E768Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17769sage: E.lift_x(7)770(7 : 11 : 1)771sage: E.lift_x(3)772Traceback (most recent call last):773...774ValueError: No point with x-coordinate 3 on Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17775776Note that there is only one lift with `x`-coordinate 10 in777`E(\GF{17})`::778779sage: E.lift_x(10, all=True)780[(10 : 8 : 1)]781782We can lift over more exotic rings too::783784sage: E = EllipticCurve('37a');785sage: E.lift_x(pAdicField(17, 5)(6))786(6 + O(17^5) : 2 + 16*17 + 16*17^2 + 16*17^3 + 16*17^4 + O(17^5) : 1 + O(17^5))787sage: K.<t> = PowerSeriesRing(QQ, 't', 5)788sage: E.lift_x(1+t)789(1 + t : 2*t - t^2 + 5*t^3 - 21*t^4 + O(t^5) : 1)790sage: K.<a> = GF(16)791sage: E = E.change_ring(K)792sage: E.lift_x(a^3)793(a^3 : a^3 + a : 1)794795AUTHOR:796797- Robert Bradshaw (2007-04-24)798799TEST::800801sage: E = EllipticCurve('37a').short_weierstrass_model().change_ring(GF(17))802sage: E.lift_x(3, all=True)803[]804sage: E.lift_x(7, all=True)805[(7 : 3 : 1), (7 : 14 : 1)]806"""807a1, a2, a3, a4, a6 = self.ainvs()808f = ((x + a2) * x + a4) * x + a6809K = self.base_ring()810x += K(0)811one = x.parent()(1)812if a1.is_zero() and a3.is_zero():813if f.is_square():814if all:815ys = f.sqrt(all=True)816return [self.point([x, y, one], check=False) for y in ys]817else:818return self.point([x, f.sqrt(), one], check=False)819else:820b = (a1*x + a3)821D = b*b + 4*f822if K.characteristic() == 2:823R = PolynomialRing(K, 'y')824F = R([-f,b,1])825ys = F.roots(multiplicities=False)826if all:827return [self.point([x, y, one], check=False) for y in ys]828elif len(ys) > 0:829return self.point([x, ys[0], one], check=False)830elif D.is_square():831if all:832return [self.point([x, (-b+d)/2, one], check=False) for d in D.sqrt(all=True)]833else:834return self.point([x, (-b+D.sqrt())/2, one], check=False)835if all:836return []837else:838raise ValueError, "No point with x-coordinate %s on %s"%(x, self)839840def _point_homset(self, *args, **kwds):841r"""842Internal function. Returns the (abstract) group of points on this843elliptic curve over a ring.844845EXAMPLES::846847sage: E=EllipticCurve(GF(5),[1,1])848sage: E._point_homset(Spec(GF(5^10,'a'),GF(5)), E)849Abelian group of points on Elliptic Curve defined850by y^2 = x^3 + x + 1 over Finite Field in a of size 5^10851"""852return SchemeHomset_points_abelian_variety_field(*args, **kwds)853854def __getitem__(self, n):855r"""856Placeholder for standard indexing function.857858EXAMPLES::859860sage: E=EllipticCurve(QQ,[1,1])861sage: E[2]862Traceback (most recent call last):863...864NotImplementedError: not implemented.865"""866raise NotImplementedError, "not implemented."867868def __is_over_RationalField(self):869r"""870Internal function. Returns true iff the base ring of this elliptic871curve is the field of rational numbers.872873EXAMPLES::874875sage: E=EllipticCurve(QQ,[1,1])876sage: E._EllipticCurve_generic__is_over_RationalField()877True878sage: E=EllipticCurve(GF(5),[1,1])879sage: E._EllipticCurve_generic__is_over_RationalField()880False881"""882return isinstance(self.base_ring(), rings.RationalField)883884def is_on_curve(self, x, y):885r"""886Returns True if `(x,y)` is an affine point on this curve.887888INPUT:889890- ``x``, ``y`` - elements of the base ring of the curve.891892EXAMPLES::893894sage: E=EllipticCurve(QQ,[1,1])895sage: E.is_on_curve(0,1)896True897sage: E.is_on_curve(1,1)898False899"""900a = self.ainvs()901return y**2 +a[0]*x*y + a[2]*y == x**3 + a[1]*x**2 + a[3]*x + a[4]902903def a_invariants(self):904r"""905The `a`-invariants of this elliptic curve, as a tuple.906907OUTPUT:908909(tuple) - a 5-tuple of the `a`-invariants of this elliptic curve.910911EXAMPLES::912913sage: E = EllipticCurve([1,2,3,4,5])914sage: E.a_invariants()915(1, 2, 3, 4, 5)916sage: E = EllipticCurve([0,1])917sage: E918Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field919sage: E.a_invariants()920(0, 0, 0, 0, 1)921sage: E = EllipticCurve([GF(7)(3),5])922sage: E.a_invariants()923(0, 0, 0, 3, 5)924925::926927sage: E = EllipticCurve([1,0,0,0,1])928sage: E.a_invariants()[0] = 100000000929Traceback (most recent call last):930...931TypeError: 'tuple' object does not support item assignment932933"""934return self.__ainvs935936ainvs = a_invariants937938def a1(self):939r"""940Returns the `a_1` invariant of this elliptic curve.941942EXAMPLES::943944sage: E = EllipticCurve([1,2,3,4,6])945sage: E.a1()9461947"""948return self.__ainvs[0]949950def a2(self):951r"""952Returns the `a_2` invariant of this elliptic curve.953954EXAMPLES::955956sage: E = EllipticCurve([1,2,3,4,6])957sage: E.a2()9582959"""960return self.__ainvs[1]961962def a3(self):963r"""964Returns the `a_3` invariant of this elliptic curve.965966EXAMPLES::967968sage: E = EllipticCurve([1,2,3,4,6])969sage: E.a3()9703971"""972return self.__ainvs[2]973974def a4(self):975r"""976Returns the `a_4` invariant of this elliptic curve.977978EXAMPLES::979980sage: E = EllipticCurve([1,2,3,4,6])981sage: E.a4()9824983"""984return self.__ainvs[3]985986def a6(self):987r"""988Returns the `a_6` invariant of this elliptic curve.989990EXAMPLES::991992sage: E = EllipticCurve([1,2,3,4,6])993sage: E.a6()9946995"""996return self.__ainvs[4]997998def b_invariants(self):999r"""1000Returns the `b`-invariants of this elliptic curve, as a tuple.10011002OUTPUT:10031004(tuple) - a 4-tuple of the `b`-invariants of this elliptic curve.10051006EXAMPLES::10071008sage: E = EllipticCurve([0, -1, 1, -10, -20])1009sage: E.b_invariants()1010(-4, -20, -79, -21)1011sage: E = EllipticCurve([-4,0])1012sage: E.b_invariants()1013(0, -8, 0, -16)10141015::10161017sage: E = EllipticCurve([1,2,3,4,5])1018sage: E.b_invariants()1019(9, 11, 29, 35)1020sage: E.b2()102191022sage: E.b4()1023111024sage: E.b6()1025291026sage: E.b8()10273510281029ALGORITHM:10301031These are simple functions of the `a`-invariants.10321033AUTHORS:10341035- William Stein (2005-04-25)1036"""1037try:1038return self.__b_invariants1039except AttributeError:1040a1,a2,a3,a4,a6 = self.ainvs()1041self.__b_invariants = a1*a1 + 4*a2, \1042a1*a3 + 2*a4, \1043a3**2 + 4*a6, \1044a1**2 * a6 + 4*a2*a6 - a1*a3*a4 + a2*a3**2 - a4**21045return self.__b_invariants10461047def b2(self):1048r"""1049Returns the `b_2` invariant of this elliptic curve.10501051EXAMPLES::10521053sage: E = EllipticCurve([1,2,3,4,5])1054sage: E.b2()105591056"""1057try:1058return self.__b_invariants[0]1059except AttributeError:1060return self.b_invariants()[0]10611062def b4(self):1063r"""1064Returns the `b_4` invariant of this elliptic curve.10651066EXAMPLES::10671068sage: E = EllipticCurve([1,2,3,4,5])1069sage: E.b4()1070111071"""1072try:1073return self.__b_invariants[1]1074except AttributeError:1075return self.b_invariants()[1]10761077def b6(self):1078r"""1079Returns the `b_6` invariant of this elliptic curve.10801081EXAMPLES::10821083sage: E = EllipticCurve([1,2,3,4,5])1084sage: E.b6()1085291086"""1087try:1088return self.__b_invariants[2]1089except AttributeError:1090return self.b_invariants()[2]10911092def b8(self):1093r"""1094Returns the `b_8` invariant of this elliptic curve.10951096EXAMPLES::10971098sage: E = EllipticCurve([1,2,3,4,5])1099sage: E.b8()1100351101"""1102try:1103return self.__b_invariants[3]1104except AttributeError:1105return self.b_invariants()[3]11061107def c_invariants(self):1108r"""1109Returns the `c`-invariants of this elliptic curve, as a tuple.11101111OUTPUT:11121113(tuple) - a 2-tuple of the `c`-invariants of the elliptic curve.11141115EXAMPLES::11161117sage: E = EllipticCurve([0, -1, 1, -10, -20])1118sage: E.c_invariants()1119(496, 20008)1120sage: E = EllipticCurve([-4,0])1121sage: E.c_invariants()1122(192, 0)11231124ALGORITHM:11251126These are simple functions of the `a`-invariants.11271128AUTHORS:11291130- William Stein (2005-04-25)1131"""1132try:1133return self.__c_invariants1134except AttributeError:1135b2,b4,b6,b8 = self.b_invariants()1136self.__c_invariants = b2**2 - 24*b4,\1137-b2**3 + 36*b2*b4 - 216*b6 # note: c6 is wrong in Silverman, but right in Cremona1138return self.__c_invariants11391140def c4(self):1141r"""1142Returns the `c_4` invariant of this elliptic curve.11431144EXAMPLES::11451146sage: E = EllipticCurve([0, -1, 1, -10, -20])1147sage: E.c4()11484961149"""1150try:1151return self.__c_invariants[0]1152except AttributeError:1153pass1154return self.c_invariants()[0]11551156def c6(self):1157r"""1158Returns the `c_6` invariant of this elliptic curve.11591160EXAMPLES::11611162sage: E = EllipticCurve([0, -1, 1, -10, -20])1163sage: E.c6()1164200081165"""1166try:1167return self.__c_invariants[1]1168except AttributeError:1169pass1170return self.c_invariants()[1]11711172def discriminant(self):1173r"""1174Returns the discriminant of this elliptic curve.11751176EXAMPLES::11771178sage: E = EllipticCurve([0,0,1,-1,0])1179sage: E.discriminant()1180371181sage: E = EllipticCurve([0, -1, 1, -10, -20])1182sage: E.discriminant()1183-16105111841185::11861187sage: E = EllipticCurve([GF(7)(2),1])1188sage: E.discriminant()118911190"""1191try:1192return self.__discriminant1193except AttributeError:1194b2, b4, b6, b8 = self.b_invariants()1195self.__discriminant = -b2**2*b8 - 8*b4**3 - 27*b6**2 + 9*b2*b4*b61196return self.__discriminant11971198def j_invariant(self):1199r"""1200Returns the `j`-invariant of this elliptic curve.12011202EXAMPLES::12031204sage: E = EllipticCurve([0,0,1,-1,0])1205sage: E.j_invariant()1206110592/371207sage: E = EllipticCurve([0, -1, 1, -10, -20])1208sage: E.j_invariant()1209-122023936/1610511210sage: E = EllipticCurve([-4,0])1211sage: E.j_invariant()1212172812131214::12151216sage: E = EllipticCurve([GF(7)(2),1])1217sage: E.j_invariant()121811219"""1220try:1221return self.__j_invariant1222except AttributeError:1223c4, _ = self.c_invariants()1224self.__j_invariant = c4**3 / self.discriminant()1225return self.__j_invariant122612271228def base_extend(self, R):1229r"""1230Returns a new curve with the same `a`-invariants but defined over a new ring.12311232INPUT:12331234- ``R`` -- either a ring into which the curve's `a`-invariants1235may be coerced, or a morphism which may be applied to them.12361237OUTPUT:12381239A new elliptic curve with the same `a`-invariants, defined over the new ring.12401241EXAMPLES::12421243sage: E=EllipticCurve(GF(5),[1,1]); E1244Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 51245sage: E1=E.base_extend(GF(125,'a')); E11246Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 5^31247sage: F2=GF(5^2,'a'); a=F2.gen()1248sage: F4=GF(5^4,'b'); b=F4.gen()1249sage: h=F2.hom([a.charpoly().roots(ring=F4,multiplicities=False)[0]],F4)1250sage: E=EllipticCurve(F2,[1,a]); E1251Elliptic Curve defined by y^2 = x^3 + x + a over Finite Field in a of size 5^21252sage: E.base_extend(h)1253Elliptic Curve defined by y^2 = x^3 + x + (4*b^3+4*b^2+4*b+3) over Finite Field in b of size 5^41254"""1255return constructor.EllipticCurve([R(a) for a in self.a_invariants()])12561257change_ring = base_extend12581259def base_ring(self):1260r"""1261Returns the base ring of the elliptic curve.12621263EXAMPLES::12641265sage: E = EllipticCurve(GF(49, 'a'), [3,5])1266sage: E.base_ring()1267Finite Field in a of size 7^212681269::12701271sage: E = EllipticCurve([1,1])1272sage: E.base_ring()1273Rational Field12741275::12761277sage: E = EllipticCurve(ZZ, [3,5])1278sage: E.base_ring()1279Integer Ring1280"""1281return self.__base_ring12821283def gens(self):1284r"""1285Placeholder function to return generators of an elliptic curve.12861287.. note::12881289This functionality is implemented in certain derived1290classes, such as EllipticCurve_rational_field.12911292EXAMPLES::12931294sage: R.<a1,a2,a3,a4,a6>=QQ[]1295sage: E=EllipticCurve([a1,a2,a3,a4,a6])1296sage: E.gens()1297Traceback (most recent call last):1298...1299NotImplementedError: not implemented.1300sage: E=EllipticCurve(QQ,[1,1])1301sage: E.gens()1302[(0 : 1 : 1)]1303"""1304raise NotImplementedError, "not implemented."13051306def gen(self, i):1307r"""1308Function returning the i'th generator of this elliptic curve.13091310.. note::13111312Relies on gens() being implemented.13131314EXAMPLES::13151316sage: R.<a1,a2,a3,a4,a6>=QQ[]1317sage: E=EllipticCurve([a1,a2,a3,a4,a6])1318sage: E.gen(0)1319Traceback (most recent call last):1320...1321NotImplementedError: not implemented.1322"""1323return self.gens()[i]13241325def rst_transform(self, r, s, t):1326r"""1327Returns the transform of the curve by `(r,s,t)` (with `u=1`).13281329INPUT:13301331- ``r``, ``s``, ``t`` -- three elements of the base ring.13321333OUTPUT:13341335The elliptic curve obtained from self by the standard1336Weierstrass transformation `(u,r,s,t)` with `u=1`.13371338.. note::13391340This is just a special case of ``change_weierstrass_model()``, with `u=1`.13411342EXAMPLES::13431344sage: R.<r,s,t>=QQ[]1345sage: E=EllipticCurve([1,2,3,4,5])1346sage: E.rst_transform(r,s,t)1347Elliptic Curve defined by y^2 + (2*s+1)*x*y + (r+2*t+3)*y = x^3 + (-s^2+3*r-s+2)*x^2 + (3*r^2-r*s-2*s*t+4*r-3*s-t+4)*x + (r^3+2*r^2-r*t-t^2+4*r-3*t+5) over Multivariate Polynomial Ring in r, s, t over Rational Field1348"""1349return self.change_weierstrass_model(1,r,s,t)13501351def scale_curve(self, u):1352r"""1353Returns the transform of the curve by scale factor `u`.13541355INPUT:13561357- ``u`` -- an invertible element of the base ring.13581359OUTPUT:13601361The elliptic curve obtained from self by the standard1362Weierstrass transformation `(u,r,s,t)` with `r=s=t=0`.13631364.. note::13651366This is just a special case of ``change_weierstrass_model()``, with `r=s=t=0`.13671368EXAMPLES::13691370sage: K=Frac(PolynomialRing(QQ,'u'))1371sage: u=K.gen()1372sage: E=EllipticCurve([1,2,3,4,5])1373sage: E.scale_curve(u)1374Elliptic Curve defined by y^2 + u*x*y + 3*u^3*y = x^3 + 2*u^2*x^2 + 4*u^4*x + 5*u^6 over Fraction Field of Univariate Polynomial Ring in u over Rational Field1375"""1376if isinstance(u, (int,long)):1377u=self.base_ring()(u) # because otherwise 1/u would round!1378return self.change_weierstrass_model(1/u,0,0,0)13791380def discriminant(self):1381r"""1382Returns the discriminant of this elliptic curve.13831384EXAMPLES::13851386sage: E = EllipticCurve([0,0,1,-1,0])1387sage: E.discriminant()1388371389sage: E = EllipticCurve([0, -1, 1, -10, -20])1390sage: E.discriminant()1391-16105113921393::13941395sage: E = EllipticCurve([GF(7)(2),1])1396sage: E.discriminant()139711398"""1399try:1400return self.__discriminant1401except AttributeError:1402b2, b4, b6, b8 = self.b_invariants()1403self.__discriminant = -b2**2*b8 - 8*b4**3 - 27*b6**2 + 9*b2*b4*b61404return self.__discriminant14051406def j_invariant(self):1407r"""1408Returns the j-invariant of this elliptic curve.14091410EXAMPLES::14111412sage: E = EllipticCurve([0,0,1,-1,0])1413sage: E.j_invariant()1414110592/371415sage: E = EllipticCurve([0, -1, 1, -10, -20])1416sage: E.j_invariant()1417-122023936/1610511418sage: E = EllipticCurve([-4,0])1419sage: E.j_invariant()1420172814211422::14231424sage: E = EllipticCurve([GF(7)(2),1])1425sage: E.j_invariant()142611427"""1428try:1429return self.__j_invariant1430except AttributeError:1431c4, _ = self.c_invariants()1432self.__j_invariant = c4**3 / self.discriminant()1433return self.__j_invariant14341435#############################################################1436#1437# Explanation of the division (also known as torsion) polynomial1438# functions in Sage.1439#1440# The main user function division_polynomial() (also aliased as1441# torsion_polynomial()) is used to compute polynomials whose roots1442# determine the $m$-torsion points on the curve. Three options are1443# available, which effect the result when $m$ is even and also the1444# parent ring of the returned value. The function can return either a1445# polynomial or the evaluation of that polynomial at a point,1446# depending on the input. Values are cached.1447#1448# The options are controlled by the value of the parameter1449# two_torsion_multiplicity, which may be 0, 1 or 2. If it is 0 or 2,1450# then a univariate polynomial will be returned (or evaluated at the1451# parameter x if x is not None). This is the polynomial whose roots1452# are the values of $x(P)$ at the nonzero points $P$ where $m*P=0$1453# (when two_torsion_multiplicity==2), or the points where $m*P=0$ but1454# $2*P\not=0$ (when two_torsion_multiplicity==0).1455#1456# If two_torsion_multiplicity==1, then a bivariate polynomial is1457# returned, which (as a function on the curve) has a simple zero at1458# each nonzero point $P$ such that $m*P=0$. When $m$ is odd this is a1459# polynomial in $x$ alone, but is still returned as an element of a1460# polynomial ring in two variables; when $m$ is even it has a factor1461# $2y+a_1x+a_3$. In this case if the parameter x is not None then it1462# should be a tuple of length 2, or a point P on the curve, and the1463# returned value is the value of the bivariate polynomial at this1464# point.1465#1466# Comparison with Magma: Magma's function DivisionPolynomial(E,m)1467# returns a triple of univariate polynomials $f,g,h$ where $f$ is1468# \code{E.division_polynomial(m,two_torsion_multiplicity=2)}, $g$ is1469# \code{E.division_polynomial(m,two_torsion_multiplicity=0)} and $h$1470# is the quotient, so that $h=1$ when $m$ is odd.14711472#############################################################14731474def division_polynomial_0(self, n, x=None, cache=None):1475r"""1476Returns the `n^{th}` torsion (division) polynomial, without1477the 2-torsion factor if `n` is even, as a polynomial in `x`.14781479These are the polynomials `g_n` defined in Mazur/Tate1480("The p-adic sigma function"), but with the sign flipped for even1481`n`, so that the leading coefficient is always positive.14821483.. note::14841485This function is intended for internal use; users should use1486:meth:`.division_polynomial`.14871488.. seealso::14891490:meth:`multiple_x_numerator`1491:meth:`multiple_x_denominator`1492:meth:`division_polynomial`14931494INPUT:149514961497- ``n`` - positive integer, or the special values `-1`1498and `-2` which mean `B_6 = (2y + a_1 x + a_3)^2` and1499`B_6^2` respectively (in the notation of Mazur/Tate).15001501- ``x`` - optional ring element to use as the "x"1502variable. If x is None, then a new polynomial ring will be1503constructed over the base ring of the elliptic curve, and its1504generator will be used as x. Note that x does not need to be a1505generator of a polynomial ring; any ring element is ok. This1506permits fast calculation of the torsion polynomial *evaluated* on1507any element of a ring.15081509- ``cache`` - optional dictionary, with integer keys.1510If the key m is in cache, then cache[m] is assumed to be the value1511of division_polynomial_0(m) for the supplied x. New entries will1512be added to the cache as they are computed.151315141515ALGORITHM:15161517Recursion described in Mazur/Tate. The recursive1518formulae are evaluated `O((log n)^2)` times.15191520AUTHORS:15211522- David Harvey (2006-09-24): initial version15231524- John Cremona (2008-08-26): unified division polynomial code15251526EXAMPLES::15271528sage: E = EllipticCurve("37a")1529sage: E.division_polynomial_0(1)153011531sage: E.division_polynomial_0(2)153211533sage: E.division_polynomial_0(3)15343*x^4 - 6*x^2 + 3*x - 11535sage: E.division_polynomial_0(4)15362*x^6 - 10*x^4 + 10*x^3 - 10*x^2 + 2*x + 11537sage: E.division_polynomial_0(5)15385*x^12 - 62*x^10 + 95*x^9 - 105*x^8 - 60*x^7 + 285*x^6 - 174*x^5 - 5*x^4 - 5*x^3 + 35*x^2 - 15*x + 21539sage: E.division_polynomial_0(6)15403*x^16 - 72*x^14 + 168*x^13 - 364*x^12 + 1120*x^10 - 1144*x^9 + 300*x^8 - 540*x^7 + 1120*x^6 - 588*x^5 - 133*x^4 + 252*x^3 - 114*x^2 + 22*x - 11541sage: E.division_polynomial_0(7)15427*x^24 - 308*x^22 + 986*x^21 - 2954*x^20 + 28*x^19 + 17171*x^18 - 23142*x^17 + 511*x^16 - 5012*x^15 + 43804*x^14 - 7140*x^13 - 96950*x^12 + 111356*x^11 - 19516*x^10 - 49707*x^9 + 40054*x^8 - 124*x^7 - 18382*x^6 + 13342*x^5 - 4816*x^4 + 1099*x^3 - 210*x^2 + 35*x - 31543sage: E.division_polynomial_0(8)15444*x^30 - 292*x^28 + 1252*x^27 - 5436*x^26 + 2340*x^25 + 39834*x^24 - 79560*x^23 + 51432*x^22 - 142896*x^21 + 451596*x^20 - 212040*x^19 - 1005316*x^18 + 1726416*x^17 - 671160*x^16 - 954924*x^15 + 1119552*x^14 + 313308*x^13 - 1502818*x^12 + 1189908*x^11 - 160152*x^10 - 399176*x^9 + 386142*x^8 - 220128*x^7 + 99558*x^6 - 33528*x^5 + 6042*x^4 + 310*x^3 - 406*x^2 + 78*x - 515451546::15471548sage: E.division_polynomial_0(18) % E.division_polynomial_0(6) == 01549True15501551An example to illustrate the relationship with torsion points::15521553sage: F = GF(11)1554sage: E = EllipticCurve(F, [0, 2]); E1555Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field of size 111556sage: f = E.division_polynomial_0(5); f15575*x^12 + x^9 + 8*x^6 + 4*x^3 + 71558sage: f.factor()1559(5) * (x^2 + 5) * (x^2 + 2*x + 5) * (x^2 + 5*x + 7) * (x^2 + 7*x + 7) * (x^2 + 9*x + 5) * (x^2 + 10*x + 7)15601561This indicates that the x-coordinates of all the 5-torsion points1562of `E` are in `GF(11^2)`, and therefore the1563`y`-coordinates are in `\GF(11^4)`::15641565sage: K = GF(11^4, 'a')1566sage: X = E.change_ring(K)1567sage: f = X.division_polynomial_0(5)1568sage: x_coords = f.roots(multiplicities=False); x_coords1569[10*a^3 + 4*a^2 + 5*a + 6,15709*a^3 + 8*a^2 + 10*a + 8,15718*a^3 + a^2 + 4*a + 10,15728*a^3 + a^2 + 4*a + 8,15738*a^3 + a^2 + 4*a + 4,15746*a^3 + 9*a^2 + 3*a + 4,15755*a^3 + 2*a^2 + 8*a + 7,15763*a^3 + 10*a^2 + 7*a + 8,15773*a^3 + 10*a^2 + 7*a + 3,15783*a^3 + 10*a^2 + 7*a + 1,15792*a^3 + 3*a^2 + a + 7,1580a^3 + 7*a^2 + 6*a]15811582Now we check that these are exactly the `x`-coordinates of the15835-torsion points of `E`::15841585sage: for x in x_coords:1586... assert X.lift_x(x).order() == 515871588The roots of the polynomial are the `x`-coordinates of the points `P`1589such that `mP=0` but `2P\not=0`::15901591sage: E=EllipticCurve('14a1')1592sage: T=E.torsion_subgroup()1593sage: [n*T.0 for n in range(6)]1594[(0 : 1 : 0),1595(9 : 23 : 1),1596(2 : 2 : 1),1597(1 : -1 : 1),1598(2 : -5 : 1),1599(9 : -33 : 1)]1600sage: pol=E.division_polynomial_0(6)1601sage: xlist=pol.roots(multiplicities=False); xlist1602[9, 2, -1/3, -5]1603sage: [E.lift_x(x, all=True) for x in xlist]1604[[(9 : 23 : 1), (9 : -33 : 1)], [(2 : 2 : 1), (2 : -5 : 1)], [], []]16051606.. note::16071608The point of order 2 and the identity do not appear.1609The points with `x=-1/3` and `x=-5` are not rational.1610"""1611if x is None:1612x = rings.PolynomialRing(self.base_ring(), 'x').gen()16131614if cache is None:1615cache = {}1616else:1617try:1618return cache[(n,x)]1619except KeyError:1620pass16211622b2, b4, b6, b8 = self.b_invariants()16231624n = int(n)1625if n <= 4:1626if n == -1:1627answer = 4*x**3 + b2*x**2 + 2*b4*x + b61628elif n == -2:1629answer = self.division_polynomial_0(-1, x, cache) ** 21630elif n == 1 or n == 2:1631answer = x.parent()(1)1632elif n == 3:1633answer = 3*x**4 + b2*x**3 + 3*b4*x**2 + 3*b6*x + b81634elif n == 4:1635answer = -self.division_polynomial_0(-2, x, cache) + \1636(6*x**2 + b2*x + b4) * \1637self.division_polynomial_0(3, x, cache)1638else:1639raise ValueError, "n must be a positive integer (or -1 or -2)"1640else:1641if n % 2 == 0:1642m = (n-2) // 21643g_mplus3 = self.division_polynomial_0(m+3, x, cache)1644g_mplus2 = self.division_polynomial_0(m+2, x, cache)1645g_mplus1 = self.division_polynomial_0(m+1, x, cache)1646g_m = self.division_polynomial_0(m, x, cache)1647g_mless1 = self.division_polynomial_0(m-1, x, cache)1648answer = g_mplus1 * \1649(g_mplus3 * g_m**2 - g_mless1 * g_mplus2**2)1650else:1651m = (n-1) // 21652g_mplus2 = self.division_polynomial_0(m+2, x, cache)1653g_mplus1 = self.division_polynomial_0(m+1, x, cache)1654g_m = self.division_polynomial_0(m, x, cache)1655g_mless1 = self.division_polynomial_0(m-1, x, cache)1656B6_sqr = self.division_polynomial_0(-2, x, cache)1657if m % 2 == 0:1658answer = B6_sqr * g_mplus2 * g_m**3 - \1659g_mless1 * g_mplus1**31660else:1661answer = g_mplus2 * g_m**3 - \1662B6_sqr * g_mless1 * g_mplus1**316631664cache[(n,x)] = answer1665return answer16661667def two_division_polynomial(self, x = None):1668r"""1669Returns the 2-division polynomial of this elliptic curve evaluated1670at ``x``.16711672INPUT:16731674- ``x`` - optional ring element to use as the `x` variable. If1675``x`` is ``None``, then a new polynomial ring will be1676constructed over the base ring of the elliptic curve, and1677its generator will be used as ``x``. Note that ``x`` does1678not need to be a generator of a polynomial ring; any ring1679element is ok. This permits fast calculation of the torsion1680polynomial *evaluated* on any element of a ring.168116821683EXAMPLES::16841685sage: E=EllipticCurve('5077a1')1686sage: E.two_division_polynomial()16874*x^3 - 28*x + 251688sage: E=EllipticCurve(GF(3^2,'a'),[1,1,1,1,1])1689sage: E.two_division_polynomial()1690x^3 + 2*x^2 + 21691sage: E.two_division_polynomial().roots()1692[(2, 1), (2*a, 1), (a + 2, 1)]1693"""1694return self.division_polynomial_0(-1,x)16951696def division_polynomial(self, m, x=None, two_torsion_multiplicity=2):1697r"""1698Returns the `m^{th}` division polynomial of this elliptic1699curve evaluated at ``x``.17001701INPUT:170217031704- ``m`` - positive integer.17051706- ``x`` - optional ring element to use as the "x"1707variable. If x is None, then a new polynomial ring will be1708constructed over the base ring of the elliptic curve, and its1709generator will be used as x. Note that x does not need to be a1710generator of a polynomial ring; any ring element is ok. This1711permits fast calculation of the torsion polynomial *evaluated* on1712any element of a ring.17131714- ``two_torsion_multiplicity`` - 0,1 or 217151716If 0: for even `m` when x is None, a univariate polynomial1717over the base ring of the curve is returned, which omits1718factors whose roots are the `x`-coordinates of the1719`2`-torsion points. Similarly when `x` is not none, the1720evaluation of such a polynomial at `x` is returned.17211722If 2: for even `m` when x is None, a univariate polynomial1723over the base ring of the curve is returned, which includes a1724factor of degree 3 whose roots are the `x`-coordinates of1725the `2`-torsion points. Similarly when `x` is not1726none, the evaluation of such a polynomial at `x` is1727returned.17281729If 1: when x is None, a bivariate polynomial over the base1730ring of the curve is returned, which includes a factor1731`2*y+a1*x+a3` which has simple zeros at the `2`-torsion1732points. When `x` is not none, it should be a tuple of1733length 2, and the evaluation of such a polynomial at `x`1734is returned.17351736EXAMPLES::17371738sage: E = EllipticCurve([0,0,1,-1,0])1739sage: E.division_polynomial(1)174011741sage: E.division_polynomial(2, two_torsion_multiplicity=0)174211743sage: E.division_polynomial(2, two_torsion_multiplicity=1)17442*y + 11745sage: E.division_polynomial(2, two_torsion_multiplicity=2)17464*x^3 - 4*x + 11747sage: E.division_polynomial(2)17484*x^3 - 4*x + 11749sage: [E.division_polynomial(3, two_torsion_multiplicity=i) for i in range(3)]1750[3*x^4 - 6*x^2 + 3*x - 1, 3*x^4 - 6*x^2 + 3*x - 1, 3*x^4 - 6*x^2 + 3*x - 1]1751sage: [type(E.division_polynomial(3, two_torsion_multiplicity=i)) for i in range(3)]1752[<type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>,1753<type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>,1754<type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>]17551756::17571758sage: E = EllipticCurve([0, -1, 1, -10, -20])1759sage: R.<z>=PolynomialRing(QQ)1760sage: E.division_polynomial(4,z,0)17612*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 58211762sage: E.division_polynomial(4,z)17638*z^9 - 24*z^8 - 464*z^7 - 2758*z^6 + 6636*z^5 + 34356*z^4 + 53510*z^3 + 99714*z^2 + 351024*z + 45985917641765This does not work, since when two_torsion_multiplicity is 1, we1766compute a bivariate polynomial, and must evaluate at a tuple of1767length 2::17681769sage: E.division_polynomial(4,z,1)1770Traceback (most recent call last):1771...1772ValueError: x should be a tuple of length 2 (or None) when two_torsion_multiplicity is 11773sage: R.<z,w>=PolynomialRing(QQ,2)1774sage: E.division_polynomial(4,(z,w),1).factor()1775(2*w + 1) * (2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821)17761777We can also evaluate this bivariate polynomial at a point::17781779sage: P = E(5,5)1780sage: E.division_polynomial(4,P,two_torsion_multiplicity=1)1781-17715611782"""17831784if not two_torsion_multiplicity in [0,1,2]:1785raise ValueError, "two_torsion_multiplicity must be 0,1 or 2"17861787# Coerce the input m to be an integer1788m = rings.Integer(m)17891790if two_torsion_multiplicity == 0:1791try:1792return self.__divpoly0[(m,x)]1793except AttributeError:1794self.__divpoly0 = {}1795except KeyError:1796pass1797f = self.division_polynomial_0(m,x)1798self.__divpoly0[(m,x)] = f1799return f18001801if two_torsion_multiplicity == 1:1802try:1803return self.__divpoly1[(m,x)]1804except AttributeError:1805self.__divpoly1 = {}1806except KeyError:1807pass1808xy = x1809R, (x,y) = PolynomialRing(self.base_ring(), 2, 'x,y').objgens()1810a1,a2,a3,a4,a6 = self.a_invariants()1811f = self.division_polynomial_0(m,x)1812if m % 2 == 0:1813f *= (2*y+a1*x+a3)1814if xy is None:1815self.__divpoly1[(m,(x,y))] = f1816return f1817else:1818if isinstance(xy,tuple) and len(xy)==2 or isinstance(xy, ell_point.EllipticCurvePoint_field):1819fxy = f(xy[0],xy[1])1820self.__divpoly1[(m,xy)] = fxy1821return fxy1822else:1823raise ValueError, "x should be a tuple of length 2 (or None) when two_torsion_multiplicity is 1"18241825if two_torsion_multiplicity == 2:1826try:1827return self.__divpoly2[(m,x)]1828except AttributeError:1829self.__divpoly2 = {}1830except KeyError:1831pass1832f = self.division_polynomial_0(m,x)1833if m%2 == 0:1834f *= self.division_polynomial_0(-1,x)1835self.__divpoly2[(m,x)] = f1836return f18371838torsion_polynomial = division_polynomial18391840def _multiple_x_numerator(self, n, x=None, cache=None):1841r"""1842Returns the numerator of the `x`-coordinate of the `n\th` multiple of a1843point, using torsion polynomials (division polynomials).18441845INPUT:18461847- ``n``, ``x``, ``cache`` -- as described in ``division_polynomial_0()``.18481849The result is cached. This is so that on calling1850``P.division_points(n)`` for the same `n` and different1851points `P` (on the same curve), we do not have to recompute1852the polynomials.18531854.. warning::18551856There may of course be cancellation between the numerator1857and the denominator (_multiple_x_denominator()). Be1858careful. E.g. if a point on an elliptic curve with1859coefficients in ZZ reduces to a singular point modulo a1860prime, then there will be cancellation, otherwise not, see1861Chris Wuthrich' p-adic heights in families of elliptic1862curves'.18631864.. seealso::18651866:meth:`_multiple_x_denominator`18671868AUTHORS:18691870- David Harvey (2006-09-24)18711872EXAMPLES::18731874sage: E = EllipticCurve("37a")1875sage: P = E.gens()[0]1876sage: x = P[0]18771878::18791880sage: (35*P)[0]1881-804287518035141565236193151/10631982599010279006006657961882sage: E._multiple_x_numerator(35, x)1883-8042875180351415652361931511884sage: E._multiple_x_denominator(35, x)1885106319825990102790060066579618861887::18881889sage: (36*P)[0]189054202648602164057575419038802/154025439973241468921987904011891sage: E._multiple_x_numerator(36, x)1892542026486021640575754190388021893sage: E._multiple_x_denominator(36, x)18941540254399732414689219879040118951896An example where cancellation occurs::18971898sage: E = EllipticCurve("88a1")1899sage: P = E([2,2]) # fixed choice of generator1900sage: n = E._multiple_x_numerator(11, P[0]); n19014424467847388475631280686505293434922786514534401902sage: d = E._multiple_x_denominator(11, P[0]); d190314272476927059598810582859694494951363827466241904sage: n/d19053101906sage: 11*P1907(310 : -5458 : 1)1908"""1909if x is None:1910x = rings.PolynomialRing(self.base_ring(), 'x').gen()19111912try:1913return self._mul_x_num_cache[(n,x)]1914except AttributeError:1915self._mul_x_num_cache = {}1916except KeyError:1917pass19181919if cache is None:1920cache = {}19211922n = int(n)1923if n < 2:1924print "n must be at least 2"19251926self.division_polynomial_0( -2, x, cache)1927self.division_polynomial_0(n-1, x, cache)1928self.division_polynomial_0(n , x, cache)1929self.division_polynomial_0(n+1, x, cache)19301931if n % 2 == 0:1932self._mul_x_num_cache[(n,x)] = x * cache[(-1,x)] * cache[(n,x)]**2 - cache[(n-1,x)] * cache[(n+1,x)]1933else:1934self._mul_x_num_cache[(n,x)] = x * cache[(n,x)]**2 - cache[(-1,x)] * cache[(n-1,x)] * cache[(n+1,x)]1935return self._mul_x_num_cache[(n,x)]193619371938def _multiple_x_denominator(self, n, x=None, cache=None):1939r"""1940Returns the denominator of the x-coordinate of the nth multiple of1941a point, using torsion polynomials (division polynomials).19421943INPUT:19441945- ``n``, ``x``, ``cache`` -- as described in ``division_polynomial_0()``.19461947The result is cached. This is so that calling1948P.division_points(n) for the same n and different points P1949(on the same curve) does not have to recompute the1950polynomials.19511952.. seealso::19531954:meth:`multiple_x_numerator`19551956TODO: the numerator and denominator versions share a calculation,1957namely squaring `\psi_n`. Maybe would be good to offer a1958combined version to make this more efficient.19591960EXAMPLES::19611962sage: E = EllipticCurve("43a")1963sage: P = E.gens()[0]1964sage: x = P[0]1965sage: (31*P)[0]1966-33058398375463796474831580/1546936377542239700569753211967sage: E._multiple_x_numerator(31, x)1968-330583983754637964748315801969sage: E._multiple_x_denominator(31, x)197015469363775422397005697532119711972AUTHORS:19731974- David Harvey (2006-09-24)1975"""1976if x is None:1977x = rings.PolynomialRing(self.base_ring(), 'x').gen()19781979try:1980return self._mul_x_den_cache[(n,x)]1981except AttributeError:1982self._mul_x_den_cache = {}1983except KeyError:1984pass19851986if cache is None:1987cache = {}19881989n = int(n)1990if n < 2:1991print "n must be at least 2"19921993self.division_polynomial_0(-2, x, cache)1994self.division_polynomial_0(n , x, cache)19951996if n % 2 == 0:1997self._mul_x_den_cache[(n,x)] = cache[(-1,x)] * cache[(n,x)]**21998else:1999self._mul_x_den_cache[(n,x)] = cache[(n,x)]**22000return self._mul_x_den_cache[(n,x)]200120022003def multiplication_by_m(self, m, x_only=False):2004r"""2005Return the multiplication-by-`m` map from ``self`` to ``self``20062007The result is a pair of rational functions in two variables2008`x`, `y` (or a rational function in one variable `x` if2009``x_only`` is ``True``).20102011INPUT:20122013- ``m`` - a nonzero integer20142015- ``x_only`` - boolean (default: ``False``) if ``True``, return2016only the `x`-coordinate of the map (as a rational function2017in one variable).20182019OUTPUT:20202021- a pair `(f(x), g(x,y))`, where `f` and `g` are rational2022functions with the degree of `y` in `g(x,y)` exactly 1,20232024- or just `f(x)` if ``x_only`` is ``True``20252026.. NOTE::20272028- The result is not cached.20292030- ``m`` is allowed to be negative (but not 0).20312032EXAMPLES::20332034sage: E = EllipticCurve([-1,3])20352036We verify that multiplication by 1 is just the identity::20372038sage: E.multiplication_by_m(1)2039(x, y)20402041Multiplication by 2 is more complicated::20422043sage: f = E.multiplication_by_m(2)2044sage: f2045((x^4 + 2*x^2 - 24*x + 1)/(4*x^3 - 4*x + 12), (8*x^6*y - 40*x^4*y + 480*x^3*y - 40*x^2*y + 96*x*y - 568*y)/(64*x^6 - 128*x^4 + 384*x^3 + 64*x^2 - 384*x + 576))20462047Grab only the x-coordinate (less work)::20482049sage: mx = E.multiplication_by_m(2, x_only=True); mx2050(x^4 + 2*x^2 - 24*x + 1)/(4*x^3 - 4*x + 12)2051sage: mx.parent()2052Fraction Field of Univariate Polynomial Ring in x over Rational Field20532054We check that it works on a point::20552056sage: P = E([2,3])2057sage: eval = lambda f,P: [fi(P[0],P[1]) for fi in f]2058sage: assert E(eval(f,P)) == 2*P20592060We do the same but with multiplication by 3::20612062sage: f = E.multiplication_by_m(3)2063sage: assert E(eval(f,P)) == 3*P20642065And the same with multiplication by 4::20662067sage: f = E.multiplication_by_m(4)2068sage: assert E(eval(f,P)) == 4*P20692070And the same with multiplication by -1,-2,-3,-4::20712072sage: for m in [-1,-2,-3,-4]:2073....: f = E.multiplication_by_m(m)2074....: assert E(eval(f,P)) == m*P20752076TESTS:20772078Verify for this fairly random looking curve and point that2079multiplication by m returns the right result for the first 102080integers::20812082sage: E = EllipticCurve([23,-105])2083sage: P = E([129/4, 1479/8])2084sage: for n in [1..10]:2085....: f = E.multiplication_by_m(n)2086....: Q = n*P2087....: assert Q == E(eval(f,P))2088....: f = E.multiplication_by_m(-n)2089....: Q = -n*P2090....: assert Q == E(eval(f,P))20912092The following test shows that :trac:`4364` is indeed fixed::20932094sage: p = next_prime(2^30-41)2095sage: a = GF(p)(1)2096sage: b = GF(p)(1)2097sage: E = EllipticCurve([a, b])2098sage: P = E.random_point()2099sage: my_eval = lambda f,P: [fi(P[0],P[1]) for fi in f]2100sage: f = E.multiplication_by_m(2)2101sage: assert(E(eval(f,P)) == 2*P)2102"""2103# Coerce the input m to be an integer2104m = rings.Integer(m)2105if m == 0:2106raise ValueError("m must be a non-zero integer")21072108if x_only:2109x = polygen(self.base_ring(), 'x')2110else:2111x, y = polygens(self.base_ring(), 'x,y')21122113# Special case of multiplication by 1 is easy.2114if m == 1:2115if not x_only:2116return (x, y)2117else:2118return x21192120# Grab curve invariants2121a1, a2, a3, a4, a6 = self.a_invariants()21222123if m == -1:2124if not x_only:2125return (x, -y-a1*x-a3)2126else:2127return x21282129# the x-coordinate does not depend on the sign of m. The work2130# here is done by functions defined earlier:21312132mx = (x.parent()(self._multiple_x_numerator(m.abs(), x))2133/ x.parent()(self._multiple_x_denominator(m.abs(), x)))21342135if x_only:2136# Return it if the optional parameter x_only is set.2137return mx21382139# Consideration of the invariant differential2140# w=dx/(2*y+a1*x+a3) shows that m*w = d(mx)/(2*my+a1*mx+a3)2141# and hence 2*my+a1*mx+a3 = (1/m)*(2*y+a1*x+a3)*d(mx)/dx21422143my = ((2*y+a1*x+a3)*mx.derivative(x)/m - a1*mx-a3)/221442145return mx, my21462147def multiplication_by_m_isogeny(self, m):2148r"""2149Return the ``EllipticCurveIsogeny`` object associated to the2150multiplication-by-`m` map on self. The resulting isogeny will2151have the associated rational maps (i.e. those returned by2152`self.multiplication_by_m()`) already computed.21532154NOTE: This function is currently *much* slower than the2155result of ``self.multiplication_by_m()``, because2156constructing an isogeny precomputes a significant amount2157of information. See trac tickets #7368 and #8014 for the2158status of improving this situation.21592160INPUT:21612162- ``m`` - a nonzero integer21632164OUTPUT:21652166- An ``EllipticCurveIsogeny`` object associated to the2167multiplication-by-`m` map on self.21682169EXAMPLES::21702171sage: E = EllipticCurve('11a1')2172sage: E.multiplication_by_m_isogeny(7)2173Isogeny of degree 49 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 - 10*x - 20 over Rational Field21742175"""2176mx, my = self.multiplication_by_m(m)21772178torsion_poly = self.torsion_polynomial(m).monic()2179phi = self.isogeny(torsion_poly, codomain=self)2180phi._EllipticCurveIsogeny__initialize_rational_maps(precomputed_maps=(mx, my))21812182return phi21832184def isomorphism_to(self, other):2185"""2186Given another weierstrass model ``other`` of self, return an2187isomorphism from self to ``other``.21882189INPUT:21902191- ``other`` -- an elliptic curve isomorphic to ``self``.21922193OUTPUT:21942195(Weierstrassmorphism) An isomorphism from self to other.21962197.. note::21982199If the curves in question are not isomorphic, a ValueError is raised.22002201EXAMPLES::22022203sage: E = EllipticCurve('37a')2204sage: F = E.short_weierstrass_model()2205sage: w = E.isomorphism_to(F); w2206Generic morphism:2207From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field2208To: Abelian group of points on Elliptic Curve defined by y^2 = x^3 - 16*x + 16 over Rational Field2209Via: (u,r,s,t) = (1/2, 0, 0, -1/2)2210sage: P = E(0,-1,1)2211sage: w(P)2212(0 : -4 : 1)2213sage: w(5*P)2214(1 : 1 : 1)2215sage: 5*w(P)2216(1 : 1 : 1)2217sage: 120*w(P) == w(120*P)2218True22192220We can also handle injections to different base rings::22212222sage: K.<a> = NumberField(x^3-7)2223sage: E.isomorphism_to(E.change_ring(K))2224Generic morphism:2225From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field2226To: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in a with defining polynomial x^3 - 72227Via: (u,r,s,t) = (1, 0, 0, 0)2228"""2229return wm.WeierstrassIsomorphism(self, None, other)22302231def automorphisms(self, field=None):2232"""2233Return the set of isomorphisms from self to itself (as a list).22342235INPUT:22362237- ``field`` (default None) -- a field into which the2238coefficients of the curve may be coerced (by default, uses2239the base field of the curve).22402241OUTPUT:22422243(list) A list of ``WeierstrassIsomorphism`` objects2244consisting of all the isomorphisms from the curve ``self`` to2245itself defined over ``field``.22462247EXAMPLES::22482249sage: E = EllipticCurve_from_j(QQ(0)) # a curve with j=0 over QQ2250sage: E.automorphisms();2251[Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field2252Via: (u,r,s,t) = (-1, 0, 0, -1), Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field2253Via: (u,r,s,t) = (1, 0, 0, 0)]22542255We can also find automorphisms defined over extension fields::22562257sage: K.<a> = NumberField(x^2+3) # adjoin roots of unity2258sage: E.automorphisms(K)2259[Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 32260Via: (u,r,s,t) = (-1, 0, 0, -1),2261...2262Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 32263Via: (u,r,s,t) = (1, 0, 0, 0)]22642265::22662267sage: [ len(EllipticCurve_from_j(GF(q,'a')(0)).automorphisms()) for q in [2,4,3,9,5,25,7,49]]2268[2, 24, 2, 12, 2, 6, 6, 6]2269"""2270if field==None:2271return [wm.WeierstrassIsomorphism(self, urst, self)2272for urst in wm.isomorphisms(self,self)]2273E=self.change_ring(field)2274return [wm.WeierstrassIsomorphism(E, urst, E)2275for urst in wm.isomorphisms(E,E)]22762277def isomorphisms(self, other, field=None):2278"""2279Return the set of isomorphisms from self to other (as a list).22802281INPUT:22822283- ``other`` -- another elliptic curve.22842285- ``field`` (default None) -- a field into which the2286coefficients of the curves may be coerced (by default, uses2287the base field of the curves).22882289OUTPUT:22902291(list) A list of ``WeierstrassIsomorphism`` objects consisting of all2292the isomorphisms from the curve ``self`` to the curve2293``other`` defined over ``field``.22942295EXAMPLES::22962297sage: E = EllipticCurve_from_j(QQ(0)) # a curve with j=0 over QQ2298sage: F = EllipticCurve('27a3') # should be the same one2299sage: E.isomorphisms(F);2300[Generic morphism:2301From: Abelian group of points on Elliptic Curve defined2302by y^2 + y = x^3 over Rational Field2303To: Abelian group of points on Elliptic Curve defined2304by y^2 + y = x^3 over Rational Field2305Via: (u,r,s,t) = (-1, 0, 0, -1), Generic morphism:2306From: Abelian group of points on Elliptic Curve defined2307by y^2 + y = x^3 over Rational Field2308To: Abelian group of points on Elliptic Curve defined2309by y^2 + y = x^3 over Rational Field2310Via: (u,r,s,t) = (1, 0, 0, 0)]231123122313We can also find isomorphisms defined over extension fields::23142315sage: E=EllipticCurve(GF(7),[0,0,0,1,1])2316sage: F=EllipticCurve(GF(7),[0,0,0,1,-1])2317sage: E.isomorphisms(F)2318[]2319sage: E.isomorphisms(F,GF(49,'a'))2320[Generic morphism:2321From: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 7^22322To: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + 6 over Finite Field in a of size 7^22323Via: (u,r,s,t) = (a + 3, 0, 0, 0), Generic morphism:2324From: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 7^22325To: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + 6 over Finite Field in a of size 7^22326Via: (u,r,s,t) = (6*a + 4, 0, 0, 0)]2327"""2328if field==None:2329return [wm.WeierstrassIsomorphism(self, urst, other)2330for urst in wm.isomorphisms(self,other)]2331E=self.change_ring(field)2332F=other.change_ring(field)2333return [wm.WeierstrassIsomorphism(E, urst, F)2334for urst in wm.isomorphisms(E,F)]23352336def is_isomorphic(self, other, field=None):2337"""2338Returns whether or not self is isomorphic to other.23392340INPUT:23412342- ``other`` -- another elliptic curve.23432344- ``field`` (default None) -- a field into which the2345coefficients of the curves may be coerced (by default, uses2346the base field of the curves).23472348OUTPUT:23492350(bool) True if there is an isomorphism from curve ``self`` to2351curve ``other`` defined over ``field``.23522353EXAMPLES::23542355sage: E = EllipticCurve('389a')2356sage: F = E.change_weierstrass_model([2,3,4,5]); F2357Elliptic Curve defined by y^2 + 4*x*y + 11/8*y = x^3 - 3/2*x^2 - 13/16*x over Rational Field2358sage: E.is_isomorphic(F)2359True2360sage: E.is_isomorphic(F.change_ring(CC))2361False2362"""2363if not is_EllipticCurve(other):2364return False2365if field==None:2366if self.base_ring() != other.base_ring():2367return False2368elif self.j_invariant() != other.j_invariant(): # easy check2369return False2370else:2371return wm.isomorphisms(self,other,True) != None2372else:2373E=self.base_extend(field)2374F=other.base_extend(field)2375if E.j_invariant() != F.j_invariant(): # easy check2376return False2377else:2378return wm.isomorphisms(E,other,F) != None23792380def change_weierstrass_model(self, *urst):2381r"""2382Return a new Weierstrass model of self under the standard transformation `(u,r,s,t)`23832384.. math::23852386(x,y) \mapsto (x',y') = (u^2x + r , u^3y + su^2x + t).238723882389EXAMPLES::23902391sage: E = EllipticCurve('15a')2392sage: F1 = E.change_weierstrass_model([1/2,0,0,0]); F12393Elliptic Curve defined by y^2 + 2*x*y + 8*y = x^3 + 4*x^2 - 160*x - 640 over Rational Field2394sage: F2 = E.change_weierstrass_model([7,2,1/3,5]); F22395Elliptic Curve defined by y^2 + 5/21*x*y + 13/343*y = x^3 + 59/441*x^2 - 10/7203*x - 58/117649 over Rational Field2396sage: F1.is_isomorphic(F2)2397True2398"""2399if isinstance(urst[0], (tuple, list)):2400urst = urst[0]2401return constructor.EllipticCurve((wm.baseWI(*urst))(self.ainvs()))24022403def short_weierstrass_model(self, complete_cube=True):2404"""2405Returns a short Weierstrass model for self.24062407INPUT:24082409- ``complete_cube`` - bool (default: True); for2410meaning, see below.24112412OUTPUT:24132414An elliptic curve.24152416If ``complete_cube=True``: Return a model of the form2417`y^2 = x^3 + a*x + b` for this curve. The characteristic2418must not be 2; in characteristic 3, it is only possible if `b_2=0`.24192420If ``complete_cube=False``: Return a model of the form2421`y^2 = x^3 + ax^2 + bx + c` for this curve. The2422characteristic must not be 2.24232424EXAMPLES::24252426sage: E = EllipticCurve([1,2,3,4,5])2427sage: print E2428Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field2429sage: F = E.short_weierstrass_model()2430sage: print F2431Elliptic Curve defined by y^2 = x^3 + 4941*x + 185166 over Rational Field2432sage: E.is_isomorphic(F)2433True2434sage: F = E.short_weierstrass_model(complete_cube=False)2435sage: print F2436Elliptic Curve defined by y^2 = x^3 + 9*x^2 + 88*x + 464 over Rational Field2437sage: print E.is_isomorphic(F)2438True24392440::24412442sage: E = EllipticCurve(GF(3),[1,2,3,4,5])2443sage: E.short_weierstrass_model(complete_cube=False)2444Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 324452446This used to be different see trac #3973::24472448sage: E.short_weierstrass_model()2449Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 324502451More tests in characteristic 3::24522453sage: E = EllipticCurve(GF(3),[0,2,1,2,1])2454sage: E.short_weierstrass_model()2455Traceback (most recent call last):2456...2457ValueError: short_weierstrass_model(): no short model for Elliptic Curve defined by y^2 + y = x^3 + 2*x^2 + 2*x + 1 over Finite Field of size 3 (characteristic is 3)2458sage: E.short_weierstrass_model(complete_cube=False)2459Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x + 2 over Finite Field of size 32460sage: E.short_weierstrass_model(complete_cube=False).is_isomorphic(E)2461True2462"""2463import constructor2464K = self.base_ring()24652466# any curve of the form y^2 = x^3 +.. is singular in characteristic 22467if K.characteristic() == 2:2468raise ValueError, "short_weierstrass_model(): no short model for %s (characteristic is %s)"%(self,K.characteristic())24692470# in characteristic 3 we can complete the square but we can only complete the cube if b2 is 02471if K.characteristic() == 3:2472b2,b4,b6,_ = self.b_invariants()2473if complete_cube and b2 != 0:2474raise ValueError, "short_weierstrass_model(): no short model for %s (characteristic is %s)"%(self,K.characteristic())2475else:2476return constructor.EllipticCurve([0,b2,0,8*b4,16*b6])24772478a1,a2,a3,_,_ = self.a_invariants()2479if complete_cube:2480if a1==0 and a2==0 and a3==0:2481return self2482else:2483b2,b4,b6,_ = self.b_invariants()2484if b2==0:2485return constructor.EllipticCurve([0,0,0,8*b4,16*b6])2486else:2487c4, c6 = self.c_invariants()2488return constructor.EllipticCurve([0,0,0,-27*c4, -54*c6])2489else:2490if a1==0 and a3==0:2491return self2492else:2493b2,b4,b6,_ = self.b_invariants()2494return constructor.EllipticCurve([0,b2,0,8*b4,16*b6])2495249624972498# Plotting249925002501def plot(self, xmin=None, xmax=None, components='both', **args):2502"""2503Draw a graph of this elliptic curve.25042505INPUT:25062507- ``xmin, xmax`` - (optional) points will be computed at2508least within this range, but possibly farther.25092510- ``components`` - a string, one of the following:25112512- ``both`` -- (default), scale so that both bounded and2513unbounded components appear25142515- ``bounded`` -- scale the plot to show the bounded2516component. Raises an error if there is only one real2517component.25182519- ``unbounded`` -- scale the plot to show the unbounded2520component, including the two flex points.25212522- ``plot_points`` -- passed to2523:func:`sage.plot.generate_plot_points`25242525- ``adaptive_tolerance`` -- passed to2526:func:`sage.plot.generate_plot_points`25272528- ``adaptive_recursion`` -- passed to2529:func:`sage.plot.generate_plot_points`25302531- ``randomize`` -- passed to2532:func:`sage.plot.generate_plot_points`25332534- ``**args`` - all other options are passed to2535:class:`sage.plot.line.Line`25362537EXAMPLES::25382539sage: E = EllipticCurve([0,-1])2540sage: plot(E, rgbcolor=hue(0.7))2541sage: E = EllipticCurve('37a')2542sage: plot(E)2543sage: plot(E, xmin=25,xmax=26)25442545With #12766 we added the components keyword::25462547sage: E.real_components()254822549sage: E.plot(components='bounded')2550sage: E.plot(components='unbounded')25512552If there is only one component then specifying2553components='bounded' raises a ValueError::25542555sage: E = EllipticCurve('9990be2')2556sage: E.plot(components='bounded')2557Traceback (most recent call last):2558...2559ValueError: no bounded component for this curve2560"""2561RR = rings.RealField()2562K = self.base_ring()2563try:2564RR._coerce_(K(1))2565except TypeError:2566raise NotImplementedError, "Plotting of curves over %s not implemented yet"%K2567if components not in ['both', 'bounded', 'unbounded']:2568raise ValueError("component must be one of 'both', 'bounded' or 'unbounded'")25692570a1, a2, a3, a4, a6 = self.ainvs()2571d = self.division_polynomial(2)2572# Internal function for plotting first branch of the curve2573f1 = lambda z: (-(a1*z + a3) + sqrt(abs(d(z))))/22574# Internal function for plotting second branch of the curve2575f2 = lambda z: (-(a1*z + a3) - sqrt(abs(d(z))))/22576r = d.roots(RR, multiplicities=False)2577r.sort()2578if components == 'bounded' and len(r) == 1:2579raise ValueError("no bounded component for this curve")2580if isinstance(xmin, (tuple, list)):2581if xmax is not None:2582raise ValueError("xmax must be None if xmin is a tuple")2583if len(xmin) != 2:2584raise ValueError("if xmin is a tuple it must have length 2")2585xmin, xmax = xmin2586if xmin is None or xmax is None:2587xmins = []2588xmaxs = []2589if components in ['both','bounded'] and len(r) > 1:2590xmins.append(r[0])2591xmaxs.append(r[1])25922593# The following 3 is an aesthetic choice. It's possible2594# that we should compute both of the following when2595# components=='both' and len(r) > 1 and take the maximum2596# generated xmax.2597if components == 'unbounded' or components == 'both' and (len(r) == 1 or r[2] - r[1] > 3*(r[1] - r[0])):2598flex = self.division_polynomial(3).roots(RR, multiplicities=False)2599flex.sort()2600flex = flex[-1]2601xmins.append(r[-1])2602# The doubling here is an aesthetic choice2603xmaxs.append(flex + 2*(flex - r[-1]))2604elif components == 'both':2605# First the easy part.2606xmins.append(r[-1])2607# There are two components and the unbounded component2608# is not too far from the bounded one. We scale so2609# that the unbounded component is twice as tall as the2610# bounded component. The y values corresponding to2611# horizontal tangent lines are determined as follows.2612# We implicitly differentiate the equation for this2613# curve and get2614# 2 yy' + a1 y + a1 xy' + a3 y' = 3 x^2 + 2a2 x + a426152616R = RR['x']2617x = R.gen()2618if a1 == 0:2619# a horizontal tangent line can only occur at a root of2620Ederiv = 3*x**2 + 2*a2*x + a42621else:2622# y' = 0 ==> y = (3*x^2 + 2*a2*x + a4) / a12623y = (3*x**2 + 2*a2*x + a4) / a12624Ederiv = y**2 + a1*x*y + a3*y - (x**3 + a2*x**2 + a4*x + a6)2625critx = [a for a in Ederiv.roots(RR, multiplicities=False) if r[0] < a < r[1]]2626if len(critx) == 0:2627raise RuntimeError("No horizontal tangent lines on bounded component")2628# The 2.5 here is an aesthetic choice2629ymax = 2.5 * max([f1(a) for a in critx])2630ymin = 2.5 * min([f2(a) for a in critx])2631top_branch = ymax**2 + a1*x*ymax + a3*ymax - (x**3 + a2*x**2 + a4*x + a6)2632bottom_branch = ymin**2 + a1*x*ymin + a3*ymin - (x**3 + a2*x**2 + a4*x + a6)2633xmaxs.append(max(top_branch.roots(RR,multiplicities=False) + bottom_branch.roots(RR,multiplicities=False)))2634xmins = min(xmins)2635xmaxs = max(xmaxs)2636span = xmaxs - xmins2637if xmin is None:2638xmin = xmins - .02*span2639if xmax is None:2640xmax = xmaxs + .02*span2641elif xmin >= xmax:2642raise ValueError("xmin must be less than xmax")26432644I = []2645if components in ['unbounded', 'both'] and xmax > r[-1]:2646# one real root; 1 component2647if xmin <= r[-1]:2648I.append((r[-1],xmax,'<'))2649else:2650I.append((xmin, xmax,'='))2651if components in ['bounded','both'] and len(r) > 1 and (xmin < r[1] or xmax > r[0]):2652if xmin <= r[0]:2653if xmax >= r[1]:2654I.append((r[0],r[1],'o'))2655else:2656I.append((r[0],xmax,'<'))2657elif xmax >= r[1]:2658I.append((xmin, r[1], '>'))2659else:2660I.append((xmin, xmax, '='))26612662g = plot.Graphics()2663plot_points = int(args.pop('plot_points',200))2664adaptive_tolerance = args.pop('adaptive_tolerance',0.01)2665adaptive_recursion = args.pop('adaptive_recursion',5)2666randomize = args.pop('randomize',True)2667for j in range(len(I)):2668a,b,shape = I[j]2669v = generate_plot_points(f1, (a, b), plot_points, adaptive_tolerance, adaptive_recursion, randomize)2670w = generate_plot_points(f2, (a, b), plot_points, adaptive_tolerance, adaptive_recursion, randomize)2671if shape == 'o':2672g += plot.line(v + list(reversed(w)) + [v[0]], **args)2673elif shape == '<':2674g += plot.line(list(reversed(v)) + w, **args)2675elif shape == '>':2676g += plot.line(v + list(reversed(w)), **args)2677else:2678g += plot.line(v, **args)2679g += plot.line(w, **args)2680return g26812682def formal_group(self):2683r"""2684The formal group associated to this elliptic curve.26852686EXAMPLES::26872688sage: E = EllipticCurve("37a")2689sage: E.formal_group()2690Formal Group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field2691"""2692try:2693return self.__formal_group2694except AttributeError:2695self.__formal_group = formal_group.EllipticCurveFormalGroup(self)2696return self.__formal_group26972698formal = formal_group26992700def _p_primary_torsion_basis(self,p,m=None):2701r"""2702Find a basis for the `p`-primary part of the torsion2703subgroup of this elliptic curve.27042705INPUT:27062707- ``p`` (integer) -- a prime number.27082709- ``m`` (integer or None) -- if not None, the $p$-primary torsion will be assumed to have order at most $p^m$.27102711OUTPUT:27122713A list of 0, 1 or 2 pairs `[T,k]` where `T` is a generator of2714order `p^k`. That is, either `[]` or `[[T_1,k_1]]` or2715`[[T_1,k_1],[T_2,k_2]]` with `[]`, `[T_1]`, or `[T_1,T_2]` a2716basis and `p^{k_1} \ge p^{k_2} \ge 1` their orders.27172718.. warning::271927201. Do not call this on a curve whose group is2721`p`-divisible (i.e., whose `p`-primary part2722is infinite)!272327242. The code uses division polynomials and will be slow for2725large `p`.27262727EXAMPLES::27282729sage: E = EllipticCurve('11a1')2730sage: E._p_primary_torsion_basis(5)2731[[(5 : -6 : 1), 1]]2732sage: K.<t> = NumberField(x^4 + x^3 + 11*x^2 + 41*x + 101)2733sage: EK = E.base_extend(K)2734sage: EK._p_primary_torsion_basis(5) # long time (2s on sage.math, 2011)2735[[(16 : 60 : 1), 1], [(t : 1/11*t^3 + 6/11*t^2 + 19/11*t + 48/11 : 1), 1]]2736sage: EF = E.change_ring(GF(101))2737sage: EF._p_primary_torsion_basis(5)2738[[(0 : 13 : 1), 1], [(5 : 5 : 1), 1]]27392740sage: F.<z> = CyclotomicField(21)2741sage: E = EllipticCurve([2,-z^7,-z^7,0,0])2742sage: E._p_primary_torsion_basis(7,2) # long time (8s on sage.math, 2011)2743[[(0 : z^7 : 1), 1],2744[(z^7 - z^6 + z^4 - z^3 + z^2 - 1 : z^8 - 2*z^7 + z^6 + 2*z^5 - 3*z^4 + 2*z^3 - 2*z + 2 : 1), 1]]27452746TESTS:27472748This shows that the bug at trac #4937 is fixed::27492750sage: a=8045159777348605664942397709822820638954804843023637154948732751sage: b=5847722216036328666656823228992971417931882520006742566620712752sage: E = EllipticCurve(GF(10^60+3201),[0,a,0,b,0])2753sage: [t[1] for t in E._p_primary_torsion_basis(2)] # long time (3s on sage.math, 2011)2754[16, 1]2755"""2756p = rings.Integer(p)2757if not p.is_prime():2758raise ValueError("p (=%s) should be prime" % p)27592760if m is None:2761from sage.rings.infinity import Infinity2762m = Infinity27632764if m == 0:2765return []27662767# First find the p-torsion:2768Ep = self(0).division_points(p)2769p_rank = rings.Integer(len(Ep)).exact_log(p)2770assert p_rank in [0,1,2]27712772if p_rank == 0:2773return []27742775assert p_rank in [1,2]27762777if p_rank == 1:2778P = Ep[0]2779if P.is_zero(): P=Ep[1]2780k = 12781if m==1:2782return [[P,k]]2783pts = P.division_points(p) # length 0 or p2784while len(pts)>0:2785k += 12786P = pts[0]2787if m<=k:2788return [[P,k]]2789pts = P.division_points(p)2790# now P generates the p-power-torsion and has order p^k2791return [[P,k]]27922793assert p_rank == 227942795Epi = iter(Ep) # used to iterate through Ep2796# Find P1,P2 which generate the p-torsion:2797P1 = Epi.next()2798while P1.is_zero(): P1 = Epi.next()2799P2 = Epi.next()2800while generic.linear_relation(P1,P2,'+')[0] != 0: P2 = Epi.next()28012802k = 12803log_order = 22804if m<=log_order:2805return [[P1,1],[P2,1]]28062807pts1 = P1.division_points(p)2808pts2 = P2.division_points(p)2809while len(pts1)>0 and len(pts2)>0:2810k += 12811P1 = pts1[0]2812P2 = pts2[0]2813log_order += 22814if m<=log_order:2815return [[P1,k],[P2,k]]2816pts1 = P1.division_points(p)2817pts2 = P2.division_points(p)28182819# Now P1,P2 are a basis for the p^k torsion, which is2820# isomorphic to (Z/p^k)^2, and k is the maximal integer for2821# which this is the case.28222823# We now determine whether a combination (P2 or P1+a*P2 for2824# some a) can be further divided for some a mod p; if so,2825# replace P1 by that combination, set pts to be the list of2826# solutions Q to p*Q=P1. If no combination can be divided,2827# then the structure is (p^k,p^k) and we can stop.28282829if len(pts1) > 0:2830pts = pts12831elif len(pts2) > 0:2832P1, P2 = P2, P12833pts = pts22834else:2835for Q in generic.multiples(P2,p-1,P1+P2,operation='+'):2836# Q runs through P1+a*P2 for a=1,2,...,p-12837pts = Q.division_points(p)2838if len(pts) > 0:2839P1 = Q2840break28412842if len(pts)==0:2843return [[P1,k],[P2,k]]28442845# Now the structure is (p^n,p^k) for some n>k. We need to2846# replace P1 by an element of maximal order p^n. So far we2847# have pts = list of Q satisfying p*Q=P1, and all such Q have2848# order p^{k+1}.28492850# We keep trying to divide P1 by p. At each step, if we2851# succeed, replace P1 by any of the results and increment n.2852# If we fails try again with P1+a*P2 for a in [1..p-1]. If any2853# succeed, replace P1 by one of the resulting divided points.2854# If all fail, the structure is (p^n,p^k) and P1,P2 are2855# generators.28562857n=k2858while True:2859P1=pts[0]2860n += 12861log_order += 12862if m<=log_order:2863return [[P1,n],[P2,k]]2864pts = P1.division_points(p)2865if len(pts)==0:2866for Q in generic.multiples(P2,p-1,P1+P2,operation='+'):2867# Q runs through P1+a*P2 for a=1,2,...,p-12868pts = Q.division_points(p)2869if len(pts)>0:2870break2871if len(pts)==0:2872return [[P1,n],[P2,k]]287328742875def hyperelliptic_polynomials(self):2876r"""2877Returns a pair of polynomials `g(x)`, `h(x)` such that this elliptic2878curve can be defined by the standard hyperelliptic equation28792880.. math::28812882y^2 + h(x)y = g(x).28832884EXAMPLES::28852886sage: R.<a1,a2,a3,a4,a6>=QQ[]2887sage: E=EllipticCurve([a1,a2,a3,a4,a6])2888sage: E.hyperelliptic_polynomials()2889(x^3 + a2*x^2 + a4*x + a6, a1*x + a3)2890"""2891K = self.base_ring()2892R = PolynomialRing(K, 'x')2893x = R.gen(0)2894a1, a2, a3, a4, a6 = self.ainvs()2895return R([a6, a4, a2, 1]), R([a3, a1])28962897def pari_curve(self):2898"""2899Return the PARI curve corresponding to this elliptic curve.29002901The result is cached.29022903EXAMPLES::29042905sage: E = EllipticCurve([RR(0), RR(0), RR(1), RR(-1), RR(0)])2906sage: e = E.pari_curve()2907sage: type(e)2908<type 'sage.libs.pari.gen.gen'>2909sage: e.type()2910't_VEC'2911sage: e.disc()291237.000000000000029132914Over a finite field::29152916sage: EllipticCurve(GF(41),[2,5]).pari_curve()2917[Mod(0, 41), Mod(0, 41), Mod(0, 41), Mod(2, 41), Mod(5, 41), Mod(0, 41), Mod(4, 41), Mod(20, 41), Mod(37, 41), Mod(27, 41), Mod(26, 41), Mod(4, 41), Mod(11, 41), 0, 0, 0, 0, 0, 0]29182919Over a `p`-adic field::29202921sage: Qp = pAdicField(5, prec=3)2922sage: E = EllipticCurve(Qp,[3, 4])2923sage: E.pari_curve()2924[O(5^3), O(5^3), O(5^3), 3 + O(5^3), 4 + O(5^3), O(5^3), 1 + 5 + O(5^3), 1 + 3*5 + O(5^3), 1 + 3*5 + 4*5^2 + O(5^3), 1 + 5 + 4*5^2 + O(5^3), 4 + 3*5 + 5^2 + O(5^3), 2*5 + 4*5^2 + O(5^3), 3*5^-1 + O(5), [4 + 4*5 + 4*5^2 + O(5^3)], 1 + 2*5 + 4*5^2 + O(5^3), 1 + 5 + 4*5^2 + O(5^3), 2*5 + 4*5^2 + O(5^3), 3 + 3*5 + 3*5^2 + O(5^3), 0]2925sage: E.j_invariant()29263*5^-1 + O(5)29272928The `j`-invariant must have negative `p`-adic valuation::29292930sage: E = EllipticCurve(Qp,[1, 1])2931sage: E.j_invariant() # the j-invariant is a p-adic integer29322 + 4*5^2 + O(5^3)2933sage: E.pari_curve()2934Traceback (most recent call last):2935...2936PariError: valuation of j must be negative in p-adic ellinit2937"""2938try:2939return self._pari_curve2940except AttributeError:2941pass29422943from sage.libs.pari.all import pari2944self._pari_curve = pari(list(self.a_invariants())).ellinit()2945return self._pari_curve29462947# This method is defined so that pari(E) returns exactly the same2948# as E.pari_curve(). This works even for classes that inherit from2949# EllipticCurve_generic, such as EllipticCurve_rational_field.2950def _pari_(self):2951"""2952Return the PARI curve corresponding to this elliptic curve2953with the default precision of 64 bits.29542955EXAMPLES::29562957sage: E = EllipticCurve('11a1')2958sage: pari(E)2959[0, -1, 1, -10, -20, -4, -20, -79, -21, 496, 20008, -161051, -122023936/161051, [4.34630815820539, -1.67315407910270 + 1.32084892226908*I, -1.67315407910270 - 1.32084892226908*I]~, ...]2960sage: E.pari_curve(prec=64)2961[0, -1, 1, -10, -20, -4, -20, -79, -21, 496, 20008, -161051, -122023936/161051, [4.34630815820539, -1.67315407910270 + 1.32084892226908*I, -1.67315407910270 - 1.32084892226908*I]~, ...]29622963Over a finite field::29642965sage: EllipticCurve(GF(2), [0,0,1,1,1])._pari_()2966[Mod(0, 2), Mod(0, 2), Mod(1, 2), Mod(1, 2), Mod(1, 2), Mod(0, 2), Mod(0, 2), Mod(1, 2), Mod(1, 2), Mod(0, 2), Mod(0, 2), Mod(1, 2), Mod(0, 2), 0, 0, 0, 0, 0, 0]2967"""2968return self.pari_curve()296929702971