Elliptic curves over a general ring¶
Sage defines an elliptic curve over a ring \(R\) as a Weierstrass Model with five coefficients \([a_1,a_2,a_3,a_4,a_6]\) in \(R\) given by
Note 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 nonzero. Also note that in Magma, “Weierstrass Model” refers to a model with \(a_1=a_2=a_3=0\), which is called Short Weierstrass Model in Sage; these do not always exist in characteristics 2 and 3.
EXAMPLES:
We construct an elliptic curve over an elaborate base ring:
sage: p, a, b = 97, 1, 3
sage: R.<u> = GF(p)[]
sage: S.<v> = R[]
sage: T = S.fraction_field()
sage: E = EllipticCurve(T, [a, b]); E
Elliptic 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 97
sage: latex(E)
y^2  = x^{3} + x + 3
>>> from sage.all import *
>>> p, a, b = Integer(97), Integer(1), Integer(3)
>>> R = GF(p)['u']; (u,) = R._first_ngens(1)
>>> S = R['v']; (v,) = S._first_ngens(1)
>>> T = S.fraction_field()
>>> E = EllipticCurve(T, [a, b]); E
Elliptic 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 97
>>> latex(E)
y^2  = x^{3} + x + 3
AUTHORS:
- William Stein (2005): Initial version 
- Robert Bradshaw et al…. 
- John Cremona (2008-01): isomorphisms, automorphisms and twists in all characteristics 
- Julian Rueth (2014-04-11): improved caching 
- Lorenz Panny (2022-04-14): added - .montgomery_model()
- class sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic(K, ainvs, category=None)[source]¶
- Bases: - WithEqualityById,- ProjectivePlaneCurve- Elliptic curve over a generic base ring. - EXAMPLES: - sage: E = EllipticCurve([1,2,3/4,7,19]); E Elliptic Curve defined by y^2 + x*y + 3/4*y = x^3 + 2*x^2 + 7*x + 19 over Rational Field sage: loads(E.dumps()) == E True sage: E = EllipticCurve([1,3]) sage: P = E([-1,1,1]) sage: -5*P (179051/80089 : -91814227/22665187 : 1) - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3)/Integer(4),Integer(7),Integer(19)]); E Elliptic Curve defined by y^2 + x*y + 3/4*y = x^3 + 2*x^2 + 7*x + 19 over Rational Field >>> loads(E.dumps()) == E True >>> E = EllipticCurve([Integer(1),Integer(3)]) >>> P = E([-Integer(1),Integer(1),Integer(1)]) >>> -Integer(5)*P (179051/80089 : -91814227/22665187 : 1) - a1()[source]¶
- Return the \(a_1\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a1() 1 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(6)]) >>> E.a1() 1 
 - a2()[source]¶
- Return the \(a_2\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a2() 2 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(6)]) >>> E.a2() 2 
 - a3()[source]¶
- Return the \(a_3\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a3() 3 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(6)]) >>> E.a3() 3 
 - a4()[source]¶
- Return the \(a_4\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a4() 4 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(6)]) >>> E.a4() 4 
 - a6()[source]¶
- Return the \(a_6\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a6() 6 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(6)]) >>> E.a6() 6 
 - a_invariants()[source]¶
- The \(a\)-invariants of this elliptic curve, as a tuple. - OUTPUT: - (tuple) - a 5-tuple of the \(a\)-invariants of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,5]) sage: E.a_invariants() (1, 2, 3, 4, 5) sage: E = EllipticCurve([0,1]); E Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field sage: E.a_invariants() (0, 0, 0, 0, 1) sage: E = EllipticCurve([GF(7)(3),5]) sage: E.a_invariants() (0, 0, 0, 3, 5) - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.a_invariants() (1, 2, 3, 4, 5) >>> E = EllipticCurve([Integer(0),Integer(1)]); E Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field >>> E.a_invariants() (0, 0, 0, 0, 1) >>> E = EllipticCurve([GF(Integer(7))(Integer(3)),Integer(5)]) >>> E.a_invariants() (0, 0, 0, 3, 5) 
 - ainvs()[source]¶
- The \(a\)-invariants of this elliptic curve, as a tuple. - OUTPUT: - (tuple) - a 5-tuple of the \(a\)-invariants of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,5]) sage: E.a_invariants() (1, 2, 3, 4, 5) sage: E = EllipticCurve([0,1]); E Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field sage: E.a_invariants() (0, 0, 0, 0, 1) sage: E = EllipticCurve([GF(7)(3),5]) sage: E.a_invariants() (0, 0, 0, 3, 5) - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.a_invariants() (1, 2, 3, 4, 5) >>> E = EllipticCurve([Integer(0),Integer(1)]); E Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field >>> E.a_invariants() (0, 0, 0, 0, 1) >>> E = EllipticCurve([GF(Integer(7))(Integer(3)),Integer(5)]) >>> E.a_invariants() (0, 0, 0, 3, 5) 
 - assume_base_ring_is_field(flag=True)[source]¶
- Set a flag to pretend that this elliptic curve is defined over a field while doing arithmetic, which is useful in some algorithms. - Warning - The flag affects all points created while the flag is set. Note that elliptic curves are unique parents, hence setting this flag may break seemingly unrelated parts of Sage. - Note - This method is a hack provided for educational purposes. - EXAMPLES: - sage: E = EllipticCurve(Zmod(35), [1,1]) sage: P = E(-5, 9) sage: 4*P (23 : 26 : 1) sage: 9*P (10 : 11 : 5) sage: E.assume_base_ring_is_field() sage: P = E(-5, 9) sage: 4*P (23 : 26 : 1) sage: 9*P Traceback (most recent call last): ... ZeroDivisionError: Inverse of 5 does not exist (characteristic = 35 = 5*7) - >>> from sage.all import * >>> E = EllipticCurve(Zmod(Integer(35)), [Integer(1),Integer(1)]) >>> P = E(-Integer(5), Integer(9)) >>> Integer(4)*P (23 : 26 : 1) >>> Integer(9)*P (10 : 11 : 5) >>> E.assume_base_ring_is_field() >>> P = E(-Integer(5), Integer(9)) >>> Integer(4)*P (23 : 26 : 1) >>> Integer(9)*P Traceback (most recent call last): ... ZeroDivisionError: Inverse of 5 does not exist (characteristic = 35 = 5*7) 
 - automorphisms(field=None)[source]¶
- Return the set of isomorphisms from - selfto itself (as a list).- The identity and negation morphisms are guaranteed to appear as the first and second entry of the returned list. - INPUT: - field– (default:- None) a field into which the coefficients of the curve may be coerced (by default, uses the base field of the curve)
 - OUTPUT: - A list of - WeierstrassIsomorphismobjects consisting of all the isomorphisms from the curve- selfto itself defined over- field.- EXAMPLES: - sage: E = EllipticCurve_from_j(QQ(0)) # a curve with j=0 over QQ sage: E.automorphisms() [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via: (u,r,s,t) = (-1, 0, 0, -1)] - >>> from sage.all import * >>> E = EllipticCurve_from_j(QQ(Integer(0))) # a curve with j=0 over QQ >>> E.automorphisms() [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via: (u,r,s,t) = (-1, 0, 0, -1)] - We can also find automorphisms defined over extension fields: - sage: x = polygen(ZZ, 'x') sage: K.<a> = NumberField(x^2 + 3) # adjoin roots of unity # needs sage.rings.number_field sage: E.automorphisms(K) # needs sage.rings.number_field [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1, 0, 0, -1), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1/2*a - 1/2, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1/2*a + 1/2, 0, 0, -1), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1/2*a - 1/2, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1/2*a + 1/2, 0, 0, -1)] - >>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> K = NumberField(x**Integer(2) + Integer(3), names=('a',)); (a,) = K._first_ngens(1)# adjoin roots of unity # needs sage.rings.number_field >>> E.automorphisms(K) # needs sage.rings.number_field [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1, 0, 0, -1), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1/2*a - 1/2, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1/2*a + 1/2, 0, 0, -1), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1/2*a - 1/2, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1/2*a + 1/2, 0, 0, -1)] - sage: [len(EllipticCurve_from_j(GF(q,'a')(0)).automorphisms()) # needs sage.rings.finite_rings ....: for q in [2,4,3,9,5,25,7,49]] [2, 24, 2, 12, 2, 6, 6, 6] - >>> from sage.all import * >>> [len(EllipticCurve_from_j(GF(q,'a')(Integer(0))).automorphisms()) # needs sage.rings.finite_rings ... for q in [Integer(2),Integer(4),Integer(3),Integer(9),Integer(5),Integer(25),Integer(7),Integer(49)]] [2, 24, 2, 12, 2, 6, 6, 6] 
 - b2()[source]¶
- Return the \(b_2\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b2() 9 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.b2() 9 
 - b4()[source]¶
- Return the \(b_4\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b4() 11 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.b4() 11 
 - b6()[source]¶
- Return the \(b_6\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b6() 29 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.b6() 29 
 - b8()[source]¶
- Return the \(b_8\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b8() 35 - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.b8() 35 
 - b_invariants()[source]¶
- Return the \(b\)-invariants of this elliptic curve, as a tuple. - OUTPUT: - (tuple) - a 4-tuple of the \(b\)-invariants of this elliptic curve. - This method is cached. - EXAMPLES: - sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.b_invariants() (-4, -20, -79, -21) sage: E = EllipticCurve([-4,0]) sage: E.b_invariants() (0, -8, 0, -16) sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b_invariants() (9, 11, 29, 35) sage: E.b2() 9 sage: E.b4() 11 sage: E.b6() 29 sage: E.b8() 35 - >>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)]) >>> E.b_invariants() (-4, -20, -79, -21) >>> E = EllipticCurve([-Integer(4),Integer(0)]) >>> E.b_invariants() (0, -8, 0, -16) >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.b_invariants() (9, 11, 29, 35) >>> E.b2() 9 >>> E.b4() 11 >>> E.b6() 29 >>> E.b8() 35 - ALGORITHM: - These are simple functions of the \(a\)-invariants. - AUTHORS: - William Stein (2005-04-25) 
 
 - base_extend(R)[source]¶
- Return the base extension of - selfto \(R\).- INPUT: - R– either a ring into which the \(a\)-invariants of- selfmay be converted, or a morphism which may be applied to them.
 - OUTPUT: - An elliptic curve over the new ring whose \(a\)-invariants are the images of the \(a\)-invariants of - self.- EXAMPLES: - sage: E = EllipticCurve(GF(5), [1,1]); E Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 sage: E1 = E.base_extend(GF(125,'a')); E1 # needs sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 5^3 - >>> from sage.all import * >>> E = EllipticCurve(GF(Integer(5)), [Integer(1),Integer(1)]); E Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 >>> E1 = E.base_extend(GF(Integer(125),'a')); E1 # needs sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 5^3 
 - base_ring()[source]¶
- Return the base ring of the elliptic curve. - EXAMPLES: - sage: E = EllipticCurve(GF(49, 'a'), [3,5]) # needs sage.rings.finite_rings sage: E.base_ring() # needs sage.rings.finite_rings Finite Field in a of size 7^2 - >>> from sage.all import * >>> E = EllipticCurve(GF(Integer(49), 'a'), [Integer(3),Integer(5)]) # needs sage.rings.finite_rings >>> E.base_ring() # needs sage.rings.finite_rings Finite Field in a of size 7^2 - sage: E = EllipticCurve([1,1]) sage: E.base_ring() Rational Field - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(1)]) >>> E.base_ring() Rational Field - sage: E = EllipticCurve(ZZ, [3,5]) sage: E.base_ring() Integer Ring - >>> from sage.all import * >>> E = EllipticCurve(ZZ, [Integer(3),Integer(5)]) >>> E.base_ring() Integer Ring 
 - c4()[source]¶
- Return the \(c_4\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.c4() 496 - >>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)]) >>> E.c4() 496 
 - c6()[source]¶
- Return the \(c_6\) invariant of this elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.c6() 20008 - >>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)]) >>> E.c6() 20008 
 - c_invariants()[source]¶
- Return the \(c\)-invariants of this elliptic curve, as a tuple. - This method is cached. - OUTPUT: - (tuple) - a 2-tuple of the \(c\)-invariants of the elliptic curve. - EXAMPLES: - sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.c_invariants() (496, 20008) sage: E = EllipticCurve([-4,0]) sage: E.c_invariants() (192, 0) - >>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)]) >>> E.c_invariants() (496, 20008) >>> E = EllipticCurve([-Integer(4),Integer(0)]) >>> E.c_invariants() (192, 0) - ALGORITHM: - These are simple functions of the \(a\)-invariants. - AUTHORS: - William Stein (2005-04-25) 
 
 - change_ring(R)[source]¶
- Return the base change of - selfto \(R\).- This has the same effect as - self.base_extend(R).- EXAMPLES: - sage: # needs sage.rings.finite_rings sage: F2 = GF(5^2,'a'); a = F2.gen() sage: F4 = GF(5^4,'b'); b = F4.gen() sage: roots = a.charpoly().roots(ring=F4, multiplicities=False) sage: h = F2.hom([roots[0]], F4) sage: E = EllipticCurve(F2, [1,a]); E Elliptic Curve defined by y^2 = x^3 + x + a over Finite Field in a of size 5^2 sage: E.change_ring(h) Elliptic 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^4 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F2 = GF(Integer(5)**Integer(2),'a'); a = F2.gen() >>> F4 = GF(Integer(5)**Integer(4),'b'); b = F4.gen() >>> roots = a.charpoly().roots(ring=F4, multiplicities=False) >>> h = F2.hom([roots[Integer(0)]], F4) >>> E = EllipticCurve(F2, [Integer(1),a]); E Elliptic Curve defined by y^2 = x^3 + x + a over Finite Field in a of size 5^2 >>> E.change_ring(h) Elliptic 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^4 
 - change_weierstrass_model(*urst)[source]¶
- Return a new Weierstrass model of - selfunder the standard transformation \((u,r,s,t)\).\[(x,y) \mapsto (x',y') = (u^2x + r , u^3y + su^2x + t).\]- EXAMPLES: - sage: E = EllipticCurve('15a') sage: F1 = E.change_weierstrass_model([1/2,0,0,0]); F1 Elliptic Curve defined by y^2 + 2*x*y + 8*y = x^3 + 4*x^2 - 160*x - 640 over Rational Field sage: F2 = E.change_weierstrass_model([7,2,1/3,5]); F2 Elliptic 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 Field sage: F1.is_isomorphic(F2) True - >>> from sage.all import * >>> E = EllipticCurve('15a') >>> F1 = E.change_weierstrass_model([Integer(1)/Integer(2),Integer(0),Integer(0),Integer(0)]); F1 Elliptic Curve defined by y^2 + 2*x*y + 8*y = x^3 + 4*x^2 - 160*x - 640 over Rational Field >>> F2 = E.change_weierstrass_model([Integer(7),Integer(2),Integer(1)/Integer(3),Integer(5)]); F2 Elliptic 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 Field >>> F1.is_isomorphic(F2) True 
 - discriminant()[source]¶
- Return the discriminant of this elliptic curve. - This method is cached. - EXAMPLES: - sage: E = EllipticCurve([0,0,1,-1,0]) sage: E.discriminant() 37 sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.discriminant() -161051 sage: E = EllipticCurve([GF(7)(2),1]) sage: E.discriminant() 1 - >>> from sage.all import * >>> E = EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(1),Integer(0)]) >>> E.discriminant() 37 >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)]) >>> E.discriminant() -161051 >>> E = EllipticCurve([GF(Integer(7))(Integer(2)),Integer(1)]) >>> E.discriminant() 1 
 - division_polynomial(m, x=None, two_torsion_multiplicity=2, force_evaluate=None)[source]¶
- Return the \(m\)-th division polynomial of this elliptic curve evaluated at \(x\). - The division polynomial is cached if \(x\) is - None.- INPUT: - m– positive integer
- x– (optional) ring element to use as the \(x\) variable. If \(x\) is- None(omitted), then a new polynomial ring will be constructed over the base ring of the elliptic curve, and its generator will be used as \(x\). Note that \(x\) does not need to be a generator of a polynomial ring; any ring element works. This permits fast calculation of the torsion polynomial evaluated on any element of a ring.
- two_torsion_multiplicity– 0, 1, or 2- If 0: For even \(m\) when \(x\) is - None, a univariate polynomial over the base ring of the curve is returned, which omits factors whose roots are the \(x\)-coordinates of the \(2\)-torsion points. When \(x\) is not- None, the evaluation of such a polynomial at \(x\) is returned.- If 2: For even \(m\) when \(x\) is - None, a univariate polynomial over the base ring of the curve is returned, which includes a factor of degree 3 whose roots are the \(x\)-coordinates of the \(2\)-torsion points. Similarly, when \(x\) is not- None, the evaluation of such a polynomial at \(x\) is returned.- If 1: For even \(m\) when \(x\) is - None, a bivariate polynomial over the base ring of the curve is returned, which includes a factor \(2y+a_1x+a_3\) having simple zeros at the \(2\)-torsion points. When \(x\) is not- None, it should be a tuple of length 2, and the evaluation of such a polynomial at \(x\) is returned.
- force_evaluate– (optional) 0, 1, or 2- By default, this method makes use of previously cached generic division polynomials to compute the value of the polynomial at a given element \(x\) whenever it appears beneficial to do so. Explicitly setting this flag overrides the default behavior. - Note that the complexity of evaluating a generic division polynomial scales much worse than that of computing the value at a point directly (using the recursive formulas), hence setting this flag can be detrimental to performance. - If 0: Do not use cached generic division polynomials. - If 1: If the generic division polynomial for this \(m\) has been cached before, evaluate it at \(x\) to compute the result. - If 2: Compute the value at \(x\) by evaluating the generic division polynomial. If the generic \(m\)-division polynomial has not yet been cached, compute and cache it first. 
 - EXAMPLES: - sage: E = EllipticCurve([0,0,1,-1,0]) sage: E.division_polynomial(1) 1 sage: E.division_polynomial(2, two_torsion_multiplicity=0) 1 sage: E.division_polynomial(2, two_torsion_multiplicity=1) 2*y + 1 sage: E.division_polynomial(2, two_torsion_multiplicity=2) 4*x^3 - 4*x + 1 sage: E.division_polynomial(2) 4*x^3 - 4*x + 1 sage: [E.division_polynomial(3, two_torsion_multiplicity=i) for i in range(3)] [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] sage: [type(E.division_polynomial(3, two_torsion_multiplicity=i)) for i in range(3)] [<... 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>, <... 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>, <... 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>] - >>> from sage.all import * >>> E = EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(1),Integer(0)]) >>> E.division_polynomial(Integer(1)) 1 >>> E.division_polynomial(Integer(2), two_torsion_multiplicity=Integer(0)) 1 >>> E.division_polynomial(Integer(2), two_torsion_multiplicity=Integer(1)) 2*y + 1 >>> E.division_polynomial(Integer(2), two_torsion_multiplicity=Integer(2)) 4*x^3 - 4*x + 1 >>> E.division_polynomial(Integer(2)) 4*x^3 - 4*x + 1 >>> [E.division_polynomial(Integer(3), two_torsion_multiplicity=i) for i in range(Integer(3))] [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] >>> [type(E.division_polynomial(Integer(3), two_torsion_multiplicity=i)) for i in range(Integer(3))] [<... 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>, <... 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>, <... 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>] - sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: R.<z> = PolynomialRing(QQ) sage: E.division_polynomial(4, z, 0) 2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821 sage: E.division_polynomial(4, z) 8*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 + 459859 - >>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)]) >>> R = PolynomialRing(QQ, names=('z',)); (z,) = R._first_ngens(1) >>> E.division_polynomial(Integer(4), z, Integer(0)) 2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821 >>> E.division_polynomial(Integer(4), z) 8*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 + 459859 - This does not work, since when two_torsion_multiplicity is 1, we compute a bivariate polynomial, and must evaluate at a tuple of length 2: - sage: E.division_polynomial(4,z,1) Traceback (most recent call last): ... ValueError: x should be a tuple of length 2 (or None) when two_torsion_multiplicity is 1 sage: R.<z,w> = PolynomialRing(QQ, 2) sage: E.division_polynomial(4, (z,w), 1).factor() (2*w + 1) * (2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821) - >>> from sage.all import * >>> E.division_polynomial(Integer(4),z,Integer(1)) Traceback (most recent call last): ... ValueError: x should be a tuple of length 2 (or None) when two_torsion_multiplicity is 1 >>> R = PolynomialRing(QQ, Integer(2), names=('z', 'w',)); (z, w,) = R._first_ngens(2) >>> E.division_polynomial(Integer(4), (z,w), Integer(1)).factor() (2*w + 1) * (2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821) - We can also evaluate this bivariate polynomial at a point: - sage: P = E(5,5) sage: E.division_polynomial(4,P,two_torsion_multiplicity=1) -1771561 - >>> from sage.all import * >>> P = E(Integer(5),Integer(5)) >>> E.division_polynomial(Integer(4),P,two_torsion_multiplicity=Integer(1)) -1771561 
 - division_polynomial_0(n, x=None)[source]¶
- Return the \(n\)-th torsion (division) polynomial, without the 2-torsion factor if \(n\) is even, as a polynomial in \(x\). - These are the polynomials \(g_n\) defined in [MT1991], but with the sign flipped for even \(n\), so that the leading coefficient is always positive. - Note - This function is intended for internal use; users should use - division_polynomial().- See also 
- _multiple_x_numerator()
- _multiple_x_denominator()
 - INPUT: - n– positive integer, or the special values- -1and- -2which mean \(B_6 = (2y + a_1 x + a_3)^2\) and \(B_6^2\) respectively (in the notation of [MT1991]), or a list of integers
- x– a ring element to use as the “x” variable or- None(default:- None); if- None, then a new polynomial ring will be constructed over the base ring of the elliptic curve, and its generator will be used as- x. Note that- xdoes not need to be a generator of a polynomial ring; any ring element is ok. This permits fast calculation of the torsion polynomial evaluated on any element of a ring.
 - ALGORITHM: - Recursion described in [MT1991]. The recursive formulae are evaluated \(O(\log^2 n)\) times. - AUTHORS: - David Harvey (2006-09-24): initial version 
- John Cremona (2008-08-26): unified division polynomial code 
 - EXAMPLES: - sage: E = EllipticCurve("37a") sage: E.division_polynomial_0(1) 1 sage: E.division_polynomial_0(2) 1 sage: E.division_polynomial_0(3) 3*x^4 - 6*x^2 + 3*x - 1 sage: E.division_polynomial_0(4) 2*x^6 - 10*x^4 + 10*x^3 - 10*x^2 + 2*x + 1 sage: E.division_polynomial_0(5) 5*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 + 2 sage: E.division_polynomial_0(6) 3*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 - 1 sage: E.division_polynomial_0(7) 7*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 - 3 sage: E.division_polynomial_0(8) 4*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 - 5 - >>> from sage.all import * >>> E = EllipticCurve("37a") >>> E.division_polynomial_0(Integer(1)) 1 >>> E.division_polynomial_0(Integer(2)) 1 >>> E.division_polynomial_0(Integer(3)) 3*x^4 - 6*x^2 + 3*x - 1 >>> E.division_polynomial_0(Integer(4)) 2*x^6 - 10*x^4 + 10*x^3 - 10*x^2 + 2*x + 1 >>> E.division_polynomial_0(Integer(5)) 5*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 + 2 >>> E.division_polynomial_0(Integer(6)) 3*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 - 1 >>> E.division_polynomial_0(Integer(7)) 7*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 - 3 >>> E.division_polynomial_0(Integer(8)) 4*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 - 5 - sage: E.division_polynomial_0(18) % E.division_polynomial_0(6) == 0 True - >>> from sage.all import * >>> E.division_polynomial_0(Integer(18)) % E.division_polynomial_0(Integer(6)) == Integer(0) True - An example to illustrate the relationship with torsion points: - sage: F = GF(11) sage: E = EllipticCurve(F, [0, 2]); E Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field of size 11 sage: f = E.division_polynomial_0(5); f 5*x^12 + x^9 + 8*x^6 + 4*x^3 + 7 sage: f.factor() (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) - >>> from sage.all import * >>> F = GF(Integer(11)) >>> E = EllipticCurve(F, [Integer(0), Integer(2)]); E Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field of size 11 >>> f = E.division_polynomial_0(Integer(5)); f 5*x^12 + x^9 + 8*x^6 + 4*x^3 + 7 >>> f.factor() (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) - This indicates that the \(x\)-coordinates of all the 5-torsion points of \(E\) are in \(\GF{11^2}\), and therefore the \(y\)-coordinates are in \(\GF{11^4}\): - sage: # needs sage.rings.finite_rings sage: K = GF(11^4, 'a') sage: X = E.change_ring(K) sage: f = X.division_polynomial_0(5) sage: x_coords = f.roots(multiplicities=False); x_coords [10*a^3 + 4*a^2 + 5*a + 6, 9*a^3 + 8*a^2 + 10*a + 8, 8*a^3 + a^2 + 4*a + 10, 8*a^3 + a^2 + 4*a + 8, 8*a^3 + a^2 + 4*a + 4, 6*a^3 + 9*a^2 + 3*a + 4, 5*a^3 + 2*a^2 + 8*a + 7, 3*a^3 + 10*a^2 + 7*a + 8, 3*a^3 + 10*a^2 + 7*a + 3, 3*a^3 + 10*a^2 + 7*a + 1, 2*a^3 + 3*a^2 + a + 7, a^3 + 7*a^2 + 6*a] - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(11)**Integer(4), 'a') >>> X = E.change_ring(K) >>> f = X.division_polynomial_0(Integer(5)) >>> x_coords = f.roots(multiplicities=False); x_coords [10*a^3 + 4*a^2 + 5*a + 6, 9*a^3 + 8*a^2 + 10*a + 8, 8*a^3 + a^2 + 4*a + 10, 8*a^3 + a^2 + 4*a + 8, 8*a^3 + a^2 + 4*a + 4, 6*a^3 + 9*a^2 + 3*a + 4, 5*a^3 + 2*a^2 + 8*a + 7, 3*a^3 + 10*a^2 + 7*a + 8, 3*a^3 + 10*a^2 + 7*a + 3, 3*a^3 + 10*a^2 + 7*a + 1, 2*a^3 + 3*a^2 + a + 7, a^3 + 7*a^2 + 6*a] - Now we check that these are exactly the \(x\)-coordinates of the 5-torsion points of \(E\): - sage: for x in x_coords: # needs sage.rings.finite_rings ....: assert X.lift_x(x).order() == 5 - >>> from sage.all import * >>> for x in x_coords: # needs sage.rings.finite_rings ... assert X.lift_x(x).order() == Integer(5) - The roots of the polynomial are the \(x\)-coordinates of the points \(P\) such that \(mP=0\) but \(2P\not=0\): - sage: E = EllipticCurve('14a1') sage: T = E.torsion_subgroup() sage: [n*T.0 for n in range(6)] [(0 : 1 : 0), (9 : 23 : 1), (2 : 2 : 1), (1 : -1 : 1), (2 : -5 : 1), (9 : -33 : 1)] sage: pol = E.division_polynomial_0(6) sage: xlist = pol.roots(multiplicities=False); xlist [9, 2, -1/3, -5] sage: [E.lift_x(x, all=True) for x in xlist] [[(9 : -33 : 1), (9 : 23 : 1)], [(2 : -5 : 1), (2 : 2 : 1)], [], []] - >>> from sage.all import * >>> E = EllipticCurve('14a1') >>> T = E.torsion_subgroup() >>> [n*T.gen(0) for n in range(Integer(6))] [(0 : 1 : 0), (9 : 23 : 1), (2 : 2 : 1), (1 : -1 : 1), (2 : -5 : 1), (9 : -33 : 1)] >>> pol = E.division_polynomial_0(Integer(6)) >>> xlist = pol.roots(multiplicities=False); xlist [9, 2, -1/3, -5] >>> [E.lift_x(x, all=True) for x in xlist] [[(9 : -33 : 1), (9 : 23 : 1)], [(2 : -5 : 1), (2 : 2 : 1)], [], []] - Note - The point of order 2 and the identity do not appear. The points with \(x=-1/3\) and \(x=-5\) are not rational. 
 - formal()[source]¶
- Return the formal group associated to this elliptic curve. - This method is cached. - EXAMPLES: - sage: E = EllipticCurve("37a") sage: E.formal_group() Formal Group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - >>> from sage.all import * >>> E = EllipticCurve("37a") >>> E.formal_group() Formal Group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field 
 - formal_group()[source]¶
- Return the formal group associated to this elliptic curve. - This method is cached. - EXAMPLES: - sage: E = EllipticCurve("37a") sage: E.formal_group() Formal Group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - >>> from sage.all import * >>> E = EllipticCurve("37a") >>> E.formal_group() Formal Group associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field 
 - frobenius_isogeny(n=1)[source]¶
- Return the \(n\)-power Frobenius isogeny from this curve to its Galois conjugate. - The Frobenius endomorphism is the special case where \(n\) is divisible by the degree of the base ring of the curve. - See also - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: z3, = GF(13^3).gens() sage: E = EllipticCurve([z3, z3^2]) sage: E.frobenius_isogeny() Frobenius isogeny of degree 13: From: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 To: Elliptic Curve defined by y^2 = x^3 + (5*z3^2+7*z3+11)*x + (5*z3^2+12*z3+1) over Finite Field in z3 of size 13^3 sage: E.frobenius_isogeny(3) Frobenius endomorphism of degree 2197 = 13^3: From: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 To: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> z3, = GF(Integer(13)**Integer(3)).gens() >>> E = EllipticCurve([z3, z3**Integer(2)]) >>> E.frobenius_isogeny() Frobenius isogeny of degree 13: From: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 To: Elliptic Curve defined by y^2 = x^3 + (5*z3^2+7*z3+11)*x + (5*z3^2+12*z3+1) over Finite Field in z3 of size 13^3 >>> E.frobenius_isogeny(Integer(3)) Frobenius endomorphism of degree 2197 = 13^3: From: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 To: Elliptic Curve defined by y^2 = x^3 + z3*x + z3^2 over Finite Field in z3 of size 13^3 
 - gen(i)[source]¶
- Function returning the i’th generator of this elliptic curve. - Note - Relies on gens() being implemented. - EXAMPLES: - sage: R.<a1,a2,a3,a4,a6> = QQ[] sage: E = EllipticCurve([a1,a2,a3,a4,a6]) sage: E.gen(0) Traceback (most recent call last): ... NotImplementedError: not implemented. - >>> from sage.all import * >>> R = QQ['a1, a2, a3, a4, a6']; (a1, a2, a3, a4, a6,) = R._first_ngens(5) >>> E = EllipticCurve([a1,a2,a3,a4,a6]) >>> E.gen(Integer(0)) Traceback (most recent call last): ... NotImplementedError: not implemented. 
 - gens()[source]¶
- Placeholder function to return generators of an elliptic curve. - Note - This functionality is implemented in certain derived classes, such as EllipticCurve_rational_field. - EXAMPLES: - sage: R.<a1,a2,a3,a4,a6> = QQ[] sage: E = EllipticCurve([a1,a2,a3,a4,a6]) sage: E.gens() Traceback (most recent call last): ... NotImplementedError: not implemented. sage: E = EllipticCurve(QQ, [1,1]) sage: E.gens() [(0 : 1 : 1)] - >>> from sage.all import * >>> R = QQ['a1, a2, a3, a4, a6']; (a1, a2, a3, a4, a6,) = R._first_ngens(5) >>> E = EllipticCurve([a1,a2,a3,a4,a6]) >>> E.gens() Traceback (most recent call last): ... NotImplementedError: not implemented. >>> E = EllipticCurve(QQ, [Integer(1),Integer(1)]) >>> E.gens() [(0 : 1 : 1)] 
 - hyperelliptic_polynomials()[source]¶
- Return a pair of polynomials \(g(x)\), \(h(x)\) such that this elliptic curve can be defined by the standard hyperelliptic equation \[y^2 + h(x)y = g(x).\]- EXAMPLES: - sage: R.<a1,a2,a3,a4,a6>=QQ[] sage: E = EllipticCurve([a1,a2,a3,a4,a6]) sage: E.hyperelliptic_polynomials() (x^3 + a2*x^2 + a4*x + a6, a1*x + a3) - >>> from sage.all import * >>> R = QQ['a1, a2, a3, a4, a6']; (a1, a2, a3, a4, a6,) = R._first_ngens(5) >>> E = EllipticCurve([a1,a2,a3,a4,a6]) >>> E.hyperelliptic_polynomials() (x^3 + a2*x^2 + a4*x + a6, a1*x + a3) 
 - identity_morphism()[source]¶
- Return the identity endomorphism of this elliptic curve as an - EllipticCurveHomobject.- EXAMPLES: - sage: E = EllipticCurve(j=42) sage: E.identity_morphism() Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + 5901*x + 1105454 over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0) sage: E.identity_morphism() == E.scalar_multiplication(1) True - >>> from sage.all import * >>> E = EllipticCurve(j=Integer(42)) >>> E.identity_morphism() Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + 5901*x + 1105454 over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0) >>> E.identity_morphism() == E.scalar_multiplication(Integer(1)) True 
 - is_exact()[source]¶
- Test whether elements of this elliptic curve are represented exactly. - EXAMPLES: - sage: EllipticCurve(QQ, [1, 2]).is_exact() True sage: EllipticCurve(RR, [1, 2]).is_exact() False - >>> from sage.all import * >>> EllipticCurve(QQ, [Integer(1), Integer(2)]).is_exact() True >>> EllipticCurve(RR, [Integer(1), Integer(2)]).is_exact() False 
 - is_isomorphic(other, field=None)[source]¶
- Return whether or not - selfis isomorphic to- other.- INPUT: - other– another elliptic curve
- field– (default:- None) a field into which the coefficients of the curves may be coerced (by default, uses the base field of the curves).
 - OUTPUT: - boolean; - Trueif there is an isomorphism from curve- selfto curve- otherdefined over- field.- EXAMPLES: - sage: E = EllipticCurve('389a') sage: F = E.change_weierstrass_model([2,3,4,5]); F Elliptic Curve defined by y^2 + 4*x*y + 11/8*y = x^3 - 3/2*x^2 - 13/16*x over Rational Field sage: E.is_isomorphic(F) True sage: E.is_isomorphic(F.change_ring(CC)) False - >>> from sage.all import * >>> E = EllipticCurve('389a') >>> F = E.change_weierstrass_model([Integer(2),Integer(3),Integer(4),Integer(5)]); F Elliptic Curve defined by y^2 + 4*x*y + 11/8*y = x^3 - 3/2*x^2 - 13/16*x over Rational Field >>> E.is_isomorphic(F) True >>> E.is_isomorphic(F.change_ring(CC)) False 
 - is_on_curve(x, y)[source]¶
- Return - Trueif \((x,y)\) is an affine point on this curve.- INPUT: - x,- y– elements of the base ring of the curve
 - EXAMPLES: - sage: E = EllipticCurve(QQ,[1,1]) sage: E.is_on_curve(0,1) True sage: E.is_on_curve(1,1) False - >>> from sage.all import * >>> E = EllipticCurve(QQ,[Integer(1),Integer(1)]) >>> E.is_on_curve(Integer(0),Integer(1)) True >>> E.is_on_curve(Integer(1),Integer(1)) False 
 - is_x_coord(x)[source]¶
- Return - Trueif- xis the \(x\)-coordinate of a point on this curve.- Note - See also - lift_x()to find the point(s) with a given \(x\)-coordinate. This function may be useful in cases where testing an element of the base field for being a square is faster than finding its square root.- EXAMPLES: - sage: E = EllipticCurve('37a'); E Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field sage: E.is_x_coord(1) True sage: E.is_x_coord(2) True - >>> from sage.all import * >>> E = EllipticCurve('37a'); E Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field >>> E.is_x_coord(Integer(1)) True >>> E.is_x_coord(Integer(2)) True - There are no rational points with x-coordinate 3: - sage: E.is_x_coord(3) False - >>> from sage.all import * >>> E.is_x_coord(Integer(3)) False - However, there are such points in \(E(\RR)\): - sage: E.change_ring(RR).is_x_coord(3) True - >>> from sage.all import * >>> E.change_ring(RR).is_x_coord(Integer(3)) True - And of course it always works in \(E(\CC)\): - sage: E.change_ring(RR).is_x_coord(-3) False sage: E.change_ring(CC).is_x_coord(-3) True - >>> from sage.all import * >>> E.change_ring(RR).is_x_coord(-Integer(3)) False >>> E.change_ring(CC).is_x_coord(-Integer(3)) True - AUTHORS: - John Cremona (2008-08-07): adapted from - lift_x()
 
 - isomorphism(u, r, s=0, t=0, is_codomain=0)[source]¶
- Given four values \(u,r,s,t\) in the base ring of this curve, return the - WeierstrassIsomorphismdefined by \(u,r,s,t\) with this curve as its codomain. (The value \(u\) must be a unit; the values \(r,s,t\) default to zero.)- Optionally, if the keyword argument - is_codomainis set to- True, return the isomorphism defined by \(u,r,s,t\) with this curve as its codomain.- EXAMPLES: - sage: E = EllipticCurve([1, 2, 3, 4, 5]) sage: iso = E.isomorphism(6); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field To: Elliptic Curve defined by y^2 + 1/6*x*y + 1/72*y = x^3 + 1/18*x^2 + 1/324*x + 5/46656 over Rational Field Via: (u,r,s,t) = (6, 0, 0, 0) sage: iso.domain() == E True sage: iso.codomain() == E.scale_curve(1 / 6) True sage: iso = E.isomorphism(1, 7, 8, 9); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field To: Elliptic Curve defined by y^2 + 17*x*y + 28*y = x^3 - 49*x^2 - 54*x + 303 over Rational Field Via: (u,r,s,t) = (1, 7, 8, 9) sage: iso.domain() == E True sage: iso.codomain() == E.rst_transform(7, 8, 9) True sage: iso = E.isomorphism(6, 7, 8, 9); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field To: Elliptic Curve defined by y^2 + 17/6*x*y + 7/54*y = x^3 - 49/36*x^2 - 1/24*x + 101/15552 over Rational Field Via: (u,r,s,t) = (6, 7, 8, 9) sage: iso.domain() == E True sage: iso.codomain() == E.rst_transform(7, 8, 9).scale_curve(1 / 6) True - >>> from sage.all import * >>> E = EllipticCurve([Integer(1), Integer(2), Integer(3), Integer(4), Integer(5)]) >>> iso = E.isomorphism(Integer(6)); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field To: Elliptic Curve defined by y^2 + 1/6*x*y + 1/72*y = x^3 + 1/18*x^2 + 1/324*x + 5/46656 over Rational Field Via: (u,r,s,t) = (6, 0, 0, 0) >>> iso.domain() == E True >>> iso.codomain() == E.scale_curve(Integer(1) / Integer(6)) True >>> iso = E.isomorphism(Integer(1), Integer(7), Integer(8), Integer(9)); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field To: Elliptic Curve defined by y^2 + 17*x*y + 28*y = x^3 - 49*x^2 - 54*x + 303 over Rational Field Via: (u,r,s,t) = (1, 7, 8, 9) >>> iso.domain() == E True >>> iso.codomain() == E.rst_transform(Integer(7), Integer(8), Integer(9)) True >>> iso = E.isomorphism(Integer(6), Integer(7), Integer(8), Integer(9)); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field To: Elliptic Curve defined by y^2 + 17/6*x*y + 7/54*y = x^3 - 49/36*x^2 - 1/24*x + 101/15552 over Rational Field Via: (u,r,s,t) = (6, 7, 8, 9) >>> iso.domain() == E True >>> iso.codomain() == E.rst_transform(Integer(7), Integer(8), Integer(9)).scale_curve(Integer(1) / Integer(6)) True - The - is_codomainargument reverses the role of domain and codomain:- sage: E = EllipticCurve([1, 2, 3, 4, 5]) sage: iso = E.isomorphism(6, is_codomain=True); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + 6*x*y + 648*y = x^3 + 72*x^2 + 5184*x + 233280 over Rational Field To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field Via: (u,r,s,t) = (6, 0, 0, 0) sage: iso.domain() == E.scale_curve(6) True sage: iso.codomain() == E True sage: iso = E.isomorphism(1, 7, 8, 9, is_codomain=True); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 - 15*x*y + 90*y = x^3 - 75*x^2 + 796*x - 2289 over Rational Field To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field Via: (u,r,s,t) = (1, 7, 8, 9) sage: iso.domain().rst_transform(7, 8, 9) == E True sage: iso.codomain() == E True sage: iso = E.isomorphism(6, 7, 8, 9, is_codomain=True); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 - 10*x*y + 700*y = x^3 + 35*x^2 + 9641*x + 169486 over Rational Field To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field Via: (u,r,s,t) = (6, 7, 8, 9) sage: iso.domain().rst_transform(7, 8, 9) == E.scale_curve(6) True sage: iso.codomain() == E True - >>> from sage.all import * >>> E = EllipticCurve([Integer(1), Integer(2), Integer(3), Integer(4), Integer(5)]) >>> iso = E.isomorphism(Integer(6), is_codomain=True); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + 6*x*y + 648*y = x^3 + 72*x^2 + 5184*x + 233280 over Rational Field To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field Via: (u,r,s,t) = (6, 0, 0, 0) >>> iso.domain() == E.scale_curve(Integer(6)) True >>> iso.codomain() == E True >>> iso = E.isomorphism(Integer(1), Integer(7), Integer(8), Integer(9), is_codomain=True); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 - 15*x*y + 90*y = x^3 - 75*x^2 + 796*x - 2289 over Rational Field To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field Via: (u,r,s,t) = (1, 7, 8, 9) >>> iso.domain().rst_transform(Integer(7), Integer(8), Integer(9)) == E True >>> iso.codomain() == E True >>> iso = E.isomorphism(Integer(6), Integer(7), Integer(8), Integer(9), is_codomain=True); iso Elliptic-curve morphism: From: Elliptic Curve defined by y^2 - 10*x*y + 700*y = x^3 + 35*x^2 + 9641*x + 169486 over Rational Field To: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field Via: (u,r,s,t) = (6, 7, 8, 9) >>> iso.domain().rst_transform(Integer(7), Integer(8), Integer(9)) == E.scale_curve(Integer(6)) True >>> iso.codomain() == E True 
 - isomorphism_to(other)[source]¶
- Given another weierstrass model - otherof- self, return an isomorphism from- selfto- other.- INPUT: - other– an elliptic curve isomorphic to- self
 - OUTPUT: - (Weierstrassmorphism) An isomorphism from - selfto- other.- Note - If the curves in question are not isomorphic, a - ValueErroris raised.- EXAMPLES: - sage: E = EllipticCurve('37a') sage: F = E.short_weierstrass_model() sage: w = E.isomorphism_to(F); w Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field To: Elliptic Curve defined by y^2 = x^3 - 16*x + 16 over Rational Field Via: (u,r,s,t) = (1/2, 0, 0, -1/2) sage: P = E(0,-1,1) sage: w(P) (0 : -4 : 1) sage: w(5*P) (1 : 1 : 1) sage: 5*w(P) (1 : 1 : 1) sage: 120*w(P) == w(120*P) True - >>> from sage.all import * >>> E = EllipticCurve('37a') >>> F = E.short_weierstrass_model() >>> w = E.isomorphism_to(F); w Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field To: Elliptic Curve defined by y^2 = x^3 - 16*x + 16 over Rational Field Via: (u,r,s,t) = (1/2, 0, 0, -1/2) >>> P = E(Integer(0),-Integer(1),Integer(1)) >>> w(P) (0 : -4 : 1) >>> w(Integer(5)*P) (1 : 1 : 1) >>> Integer(5)*w(P) (1 : 1 : 1) >>> Integer(120)*w(P) == w(Integer(120)*P) True - We can also handle injections to different base rings: - sage: x = polygen(ZZ, 'x') sage: K.<a> = NumberField(x^3 - 7) # needs sage.rings.number_field sage: E.isomorphism_to(E.change_ring(K)) # needs sage.rings.number_field Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field To: Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in a with defining polynomial x^3 - 7 Via: (u,r,s,t) = (1, 0, 0, 0) - >>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> K = NumberField(x**Integer(3) - Integer(7), names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.number_field >>> E.isomorphism_to(E.change_ring(K)) # needs sage.rings.number_field Elliptic-curve morphism: From: Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field To: Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in a with defining polynomial x^3 - 7 Via: (u,r,s,t) = (1, 0, 0, 0) 
 - isomorphisms(other, field=None)[source]¶
- Return the set of isomorphisms from - selfto- other(as a list).- INPUT: - other– another elliptic curve
- field– (default:- None) a field into which the coefficients of the curves may be coerced (by default, uses the base field of the curves)
 - OUTPUT: - A list of - WeierstrassIsomorphismobjects consisting of all the isomorphisms from the curve- selfto the curve- otherdefined over- field.- EXAMPLES: - sage: E = EllipticCurve_from_j(QQ(0)) # a curve with j=0 over QQ sage: F = EllipticCurve('27a3') # should be the same one sage: E.isomorphisms(F) [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via: (u,r,s,t) = (-1, 0, 0, -1)] - >>> from sage.all import * >>> E = EllipticCurve_from_j(QQ(Integer(0))) # a curve with j=0 over QQ >>> F = EllipticCurve('27a3') # should be the same one >>> E.isomorphisms(F) [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0), Elliptic-curve endomorphism of Elliptic Curve defined by y^2 + y = x^3 over Rational Field Via: (u,r,s,t) = (-1, 0, 0, -1)] - We can also find isomorphisms defined over extension fields: - sage: # needs sage.rings.finite_rings sage: E = EllipticCurve(GF(7), [0,0,0,1,1]) sage: F = EllipticCurve(GF(7), [0,0,0,1,-1]) sage: E.isomorphisms(F) [] sage: E.isomorphisms(F, GF(49,'a')) [Elliptic-curve morphism: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 7^2 To: Elliptic Curve defined by y^2 = x^3 + x + 6 over Finite Field in a of size 7^2 Via: (u,r,s,t) = (a + 3, 0, 0, 0), Elliptic-curve morphism: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 7^2 To: Elliptic Curve defined by y^2 = x^3 + x + 6 over Finite Field in a of size 7^2 Via: (u,r,s,t) = (6*a + 4, 0, 0, 0)] - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> E = EllipticCurve(GF(Integer(7)), [Integer(0),Integer(0),Integer(0),Integer(1),Integer(1)]) >>> F = EllipticCurve(GF(Integer(7)), [Integer(0),Integer(0),Integer(0),Integer(1),-Integer(1)]) >>> E.isomorphisms(F) [] >>> E.isomorphisms(F, GF(Integer(49),'a')) [Elliptic-curve morphism: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 7^2 To: Elliptic Curve defined by y^2 = x^3 + x + 6 over Finite Field in a of size 7^2 Via: (u,r,s,t) = (a + 3, 0, 0, 0), Elliptic-curve morphism: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 7^2 To: Elliptic Curve defined by y^2 = x^3 + x + 6 over Finite Field in a of size 7^2 Via: (u,r,s,t) = (6*a + 4, 0, 0, 0)] 
 - j_invariant()[source]¶
- Return the \(j\)-invariant of this elliptic curve. - This method is cached. - EXAMPLES: - sage: E = EllipticCurve([0,0,1,-1,0]) sage: E.j_invariant() 110592/37 sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.j_invariant() -122023936/161051 sage: E = EllipticCurve([-4,0]) sage: E.j_invariant() 1728 sage: E = EllipticCurve([GF(7)(2),1]) sage: E.j_invariant() 1 - >>> from sage.all import * >>> E = EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(1),Integer(0)]) >>> E.j_invariant() 110592/37 >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)]) >>> E.j_invariant() -122023936/161051 >>> E = EllipticCurve([-Integer(4),Integer(0)]) >>> E.j_invariant() 1728 >>> E = EllipticCurve([GF(Integer(7))(Integer(2)),Integer(1)]) >>> E.j_invariant() 1 
 - lift_x(x, all=False, extend=False)[source]¶
- Return one or all points with given \(x\)-coordinate. - This method is deterministic: It returns the same data each time when called again with the same \(x\). - INPUT: - x– an element of the base ring of the curve, or of an extension
- all– boolean (default:- False); if- True, return a (possibly empty) list of all points; if- False, return just one point, or raise a- ValueErrorif there are none.
- extend– boolean (default:- False);- if - False, extend the base if necessary and possible to include \(x\), and only return point(s) defined over this ring, or raise an error when there are none with this \(x\)-coordinate;
- If - True, the base ring will be extended if necessary to contain the \(y\)-coordinates of the point(s) with this \(x\)-coordinate, in addition to a possible base change to include \(x\).
 
 - OUTPUT: - A point or list of up to 2 points on this curve, or a base-change of this curve to a larger ring. - See also - EXAMPLES: - sage: E = EllipticCurve('37a'); E Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field sage: E.lift_x(1) (1 : -1 : 1) sage: E.lift_x(2) (2 : -3 : 1) sage: E.lift_x(1/4, all=True) [(1/4 : -5/8 : 1), (1/4 : -3/8 : 1)] - >>> from sage.all import * >>> E = EllipticCurve('37a'); E Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field >>> E.lift_x(Integer(1)) (1 : -1 : 1) >>> E.lift_x(Integer(2)) (2 : -3 : 1) >>> E.lift_x(Integer(1)/Integer(4), all=True) [(1/4 : -5/8 : 1), (1/4 : -3/8 : 1)] - There are no rational points with \(x\)-coordinate 3: - sage: E.lift_x(3) Traceback (most recent call last): ... ValueError: No point with x-coordinate 3 on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - >>> from sage.all import * >>> E.lift_x(Integer(3)) Traceback (most recent call last): ... ValueError: No point with x-coordinate 3 on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - We can use the - extendparameter to make the necessary quadratic extension. Note that in such cases the returned point is a point on a new curve object, the result of changing the base ring to the parent of \(x\):- sage: P = E.lift_x(3, extend=True); P # needs sage.rings.number_field (3 : -y - 1 : 1) sage: P.curve() # needs sage.rings.number_field Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in y with defining polynomial y^2 + y - 24 - >>> from sage.all import * >>> P = E.lift_x(Integer(3), extend=True); P # needs sage.rings.number_field (3 : -y - 1 : 1) >>> P.curve() # needs sage.rings.number_field Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in y with defining polynomial y^2 + y - 24 - Or we can extend scalars. There are two such points in \(E(\RR)\): - sage: E.change_ring(RR).lift_x(3, all=True) [(3.00000000000000 : -5.42442890089805 : 1.00000000000000), (3.00000000000000 : 4.42442890089805 : 1.00000000000000)] - >>> from sage.all import * >>> E.change_ring(RR).lift_x(Integer(3), all=True) [(3.00000000000000 : -5.42442890089805 : 1.00000000000000), (3.00000000000000 : 4.42442890089805 : 1.00000000000000)] - And of course it always works in \(E(\CC)\): - sage: E.change_ring(RR).lift_x(.5, all=True) [] sage: E.change_ring(CC).lift_x(.5) (0.500000000000000 : -0.500000000000000 - 0.353553390593274*I : 1.00000000000000) - >>> from sage.all import * >>> E.change_ring(RR).lift_x(RealNumber('.5'), all=True) [] >>> E.change_ring(CC).lift_x(RealNumber('.5')) (0.500000000000000 : -0.500000000000000 - 0.353553390593274*I : 1.00000000000000) - In this example we start with a curve defined over \(\QQ\) which has no rational points with \(x=0\), but using - extend = Truewe can construct such a point over a quadratic field:- sage: E = EllipticCurve([0,0,0,0,2]); E Elliptic Curve defined by y^2 = x^3 + 2 over Rational Field sage: P = E.lift_x(0, extend=True); P # needs sage.rings.number_field (0 : -y : 1) sage: P.curve() # needs sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + 2 over Number Field in y with defining polynomial y^2 - 2 - >>> from sage.all import * >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),Integer(2)]); E Elliptic Curve defined by y^2 = x^3 + 2 over Rational Field >>> P = E.lift_x(Integer(0), extend=True); P # needs sage.rings.number_field (0 : -y : 1) >>> P.curve() # needs sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + 2 over Number Field in y with defining polynomial y^2 - 2 - We can perform these operations over finite fields too: - sage: E = EllipticCurve('37a').change_ring(GF(17)); E Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17 sage: E.lift_x(7) (7 : 5 : 1) sage: E.lift_x(3) Traceback (most recent call last): ... ValueError: No point with x-coordinate 3 on Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17 - >>> from sage.all import * >>> E = EllipticCurve('37a').change_ring(GF(Integer(17))); E Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17 >>> E.lift_x(Integer(7)) (7 : 5 : 1) >>> E.lift_x(Integer(3)) Traceback (most recent call last): ... ValueError: No point with x-coordinate 3 on Elliptic Curve defined by y^2 + y = x^3 + 16*x over Finite Field of size 17 - Note that there is only one lift with \(x\)-coordinate 10 in \(E(\GF{17})\): - sage: E.lift_x(10, all=True) [(10 : 8 : 1)] - >>> from sage.all import * >>> E.lift_x(Integer(10), all=True) [(10 : 8 : 1)] - We can lift over more exotic rings too. If the supplied x value is in an extension of the base, note that the point returned is on the base-extended curve: - sage: E = EllipticCurve('37a') sage: P = E.lift_x(pAdicField(17, 5)(6)); P # needs sage.rings.padics (6 + O(17^5) : 14 + O(17^5) : 1 + O(17^5)) sage: P.curve() # needs sage.rings.padics Elliptic Curve defined by y^2 + (1+O(17^5))*y = x^3 + (16+16*17+16*17^2+16*17^3+16*17^4+O(17^5))*x over 17-adic Field with capped relative precision 5 sage: K.<t> = PowerSeriesRing(QQ, 't', 5) sage: P = E.lift_x(1 + t); P (1 + t : -1 - 2*t + t^2 - 5*t^3 + 21*t^4 + O(t^5) : 1) sage: K.<a> = GF(16) # needs sage.rings.finite_rings sage: P = E.change_ring(K).lift_x(a^3); P # needs sage.rings.finite_rings (a^3 : a^3 + a : 1) sage: P.curve() # needs sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + x over Finite Field in a of size 2^4 - >>> from sage.all import * >>> E = EllipticCurve('37a') >>> P = E.lift_x(pAdicField(Integer(17), Integer(5))(Integer(6))); P # needs sage.rings.padics (6 + O(17^5) : 14 + O(17^5) : 1 + O(17^5)) >>> P.curve() # needs sage.rings.padics Elliptic Curve defined by y^2 + (1+O(17^5))*y = x^3 + (16+16*17+16*17^2+16*17^3+16*17^4+O(17^5))*x over 17-adic Field with capped relative precision 5 >>> K = PowerSeriesRing(QQ, 't', Integer(5), names=('t',)); (t,) = K._first_ngens(1) >>> P = E.lift_x(Integer(1) + t); P (1 + t : -1 - 2*t + t^2 - 5*t^3 + 21*t^4 + O(t^5) : 1) >>> K = GF(Integer(16), names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.finite_rings >>> P = E.change_ring(K).lift_x(a**Integer(3)); P # needs sage.rings.finite_rings (a^3 : a^3 + a : 1) >>> P.curve() # needs sage.rings.finite_rings Elliptic Curve defined by y^2 + y = x^3 + x over Finite Field in a of size 2^4 - We can extend the base field to include the associated \(y\) value(s): - sage: E = EllipticCurve([0,0,0,0,2]); E Elliptic Curve defined by y^2 = x^3 + 2 over Rational Field sage: x = polygen(QQ) sage: P = E.lift_x(x, extend=True); P (x : -y : 1) - >>> from sage.all import * >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),Integer(2)]); E Elliptic Curve defined by y^2 = x^3 + 2 over Rational Field >>> x = polygen(QQ) >>> P = E.lift_x(x, extend=True); P (x : -y : 1) - This point is a generic point on E: - sage: P.curve() Elliptic Curve defined by y^2 = x^3 + 2 over Univariate Quotient Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field with modulus y^2 - x^3 - 2 sage: -P (x : y : 1) sage: 2*P ((1/4*x^4 - 4*x)/(x^3 + 2) : ((-1/8*x^6 - 5*x^3 + 4)/(x^6 + 4*x^3 + 4))*y : 1) - >>> from sage.all import * >>> P.curve() Elliptic Curve defined by y^2 = x^3 + 2 over Univariate Quotient Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field with modulus y^2 - x^3 - 2 >>> -P (x : y : 1) >>> Integer(2)*P ((1/4*x^4 - 4*x)/(x^3 + 2) : ((-1/8*x^6 - 5*x^3 + 4)/(x^6 + 4*x^3 + 4))*y : 1) - Check that Issue #30297 is fixed: - sage: K = Qp(5) # needs sage.rings.padics sage: E = EllipticCurve([K(0), K(1)]) # needs sage.rings.padics sage: E.lift_x(1, extend=True) # needs sage.rings.padics (1 + O(5^20) : y + O(5^20) : 1 + O(5^20)) - >>> from sage.all import * >>> K = Qp(Integer(5)) # needs sage.rings.padics >>> E = EllipticCurve([K(Integer(0)), K(Integer(1))]) # needs sage.rings.padics >>> E.lift_x(Integer(1), extend=True) # needs sage.rings.padics (1 + O(5^20) : y + O(5^20) : 1 + O(5^20)) - AUTHORS: - Robert Bradshaw (2007-04-24) 
- John Cremona (2017-11-10) 
 
 - montgomery_model(twisted=False, morphism=False)[source]¶
- Return a (twisted or untwisted) Montgomery model for this elliptic curve, if possible. - A Montgomery curve is a smooth projective curve of the form \[BY^2 = X^3 + AX^2 + X.\]- The Montgomery curve is called untwisted if \(B=1\). - INPUT: - twisted– boolean (default:- False); allow \(B \neq 1\)
- morphism– boolean (default:- False); also return an isomorphism from this curve to the computed Montgomery model
 - OUTPUT: - If - twistedis- False(the default), an- EllipticCurve_genericobject encapsulating an untwisted Montgomery curve. Otherwise, a- ProjectivePlaneCurveobject encapsulating a (potentially twisted) Montgomery curve.- If - morphismis- True, this method returns a tuple consisting of such a curve together with an isomorphism of suitable type (either- WeierstrassIsomorphismor- WeierstrassTransformationWithInverse) from this curve to the Montgomery model.- EXAMPLES: - sage: E = EllipticCurve(QQbar, '11a1') # needs sage.rings.number_field sage: E.montgomery_model() # needs sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + (-1.953522420987248?)*x^2 + x over Algebraic Field - >>> from sage.all import * >>> E = EllipticCurve(QQbar, '11a1') # needs sage.rings.number_field >>> E.montgomery_model() # needs sage.rings.number_field Elliptic Curve defined by y^2 = x^3 + (-1.953522420987248?)*x^2 + x over Algebraic Field - sage: E = EllipticCurve(GF(431^2), [7,7]) # needs sage.rings.finite_rings sage: E.montgomery_model() # needs sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2 - >>> from sage.all import * >>> E = EllipticCurve(GF(Integer(431)**Integer(2)), [Integer(7),Integer(7)]) # needs sage.rings.finite_rings >>> E.montgomery_model() # needs sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2 - An isomorphism between the Montgomery and Weierstrass form can be obtained using the - morphismparameter:- sage: E.montgomery_model(morphism=True) # needs sage.rings.finite_rings (Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2, Elliptic-curve morphism: From: Elliptic Curve defined by y^2 = x^3 + 7*x + 7 over Finite Field in z2 of size 431^2 To: Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2 Via: (u,r,s,t) = (64*z2 + 407, 159, 0, 0)) - >>> from sage.all import * >>> E.montgomery_model(morphism=True) # needs sage.rings.finite_rings (Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2, Elliptic-curve morphism: From: Elliptic Curve defined by y^2 = x^3 + 7*x + 7 over Finite Field in z2 of size 431^2 To: Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2 Via: (u,r,s,t) = (64*z2 + 407, 159, 0, 0)) - Not all elliptic curves have a Montgomery model over their field of definition: - sage: E = EllipticCurve(GF(257), [1,1]) sage: E.montgomery_model() Traceback (most recent call last): ... ValueError: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 257 has no Montgomery model - >>> from sage.all import * >>> E = EllipticCurve(GF(Integer(257)), [Integer(1),Integer(1)]) >>> E.montgomery_model() Traceback (most recent call last): ... ValueError: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 257 has no Montgomery model - sage: E = EllipticCurve(GF(257), [10,10]) sage: E.montgomery_model() Traceback (most recent call last): ... ValueError: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 has no untwisted Montgomery model - >>> from sage.all import * >>> E = EllipticCurve(GF(Integer(257)), [Integer(10),Integer(10)]) >>> E.montgomery_model() Traceback (most recent call last): ... ValueError: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 has no untwisted Montgomery model - However, as hinted by the error message, the latter curve does admit a twisted Montgomery model, which can be computed by passing - twisted=True:- sage: E.montgomery_model(twisted=True) Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 - >>> from sage.all import * >>> E.montgomery_model(twisted=True) Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 - Since Sage internally represents elliptic curves as (long) Weierstrass curves, which do not feature the Montgomery \(B\) coefficient, the returned curve in this case is merely a - ProjectivePlaneCurverather than the usual- EllipticCurve_generic.- Arithmetic on curves of this type is not implemented natively, but can easily be emulated by mapping back and forth to the corresponding Weierstrass curve: - sage: C, f = E.montgomery_model(twisted=True, morphism=True) sage: f Scheme morphism: From: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 To: Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 Defn: Defined on coordinates by sending (x : y : z) to (x + 116*z : -y : -85*z) sage: g = f.inverse(); g Scheme morphism: From: Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 To: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 Defn: Defined on coordinates by sending (x : y : z) to (-85*x - 116*z : 85*y : z) sage: P = C(70, 8) sage: Q = C(17, 17) sage: P + Q # this doesn't work... Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: ... sage: f(g(P) + g(Q)) # ...but this does (107 : 168 : 1) - >>> from sage.all import * >>> C, f = E.montgomery_model(twisted=True, morphism=True) >>> f Scheme morphism: From: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 To: Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 Defn: Defined on coordinates by sending (x : y : z) to (x + 116*z : -y : -85*z) >>> g = f.inverse(); g Scheme morphism: From: Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 To: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 Defn: Defined on coordinates by sending (x : y : z) to (-85*x - 116*z : 85*y : z) >>> P = C(Integer(70), Integer(8)) >>> Q = C(Integer(17), Integer(17)) >>> P + Q # this doesn't work... Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: ... >>> f(g(P) + g(Q)) # ...but this does (107 : 168 : 1) - Using the fact that the Weil pairing satisfies \(e(\psi(P),\psi(Q)) = e(P,Q)^{\deg\psi}\), even pairings can be emulated in this way (note that isomorphisms have degree \(1\)): - sage: # needs sage.rings.finite_rings sage: F.<z2> = GF(257^2) sage: C_ = C.change_ring(F) sage: g_ = g.change_ring(F) sage: g_(P).order() 12 sage: T = C_(-7 * z2 - 57, 31 * z2 - 52, 1) sage: g_(T).order() 12 sage: g_(P).weil_pairing(g_(T), 12) 15*z2 + 204 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(257)**Integer(2), names=('z2',)); (z2,) = F._first_ngens(1) >>> C_ = C.change_ring(F) >>> g_ = g.change_ring(F) >>> g_(P).order() 12 >>> T = C_(-Integer(7) * z2 - Integer(57), Integer(31) * z2 - Integer(52), Integer(1)) >>> g_(T).order() 12 >>> g_(P).weil_pairing(g_(T), Integer(12)) 15*z2 + 204 - Another alternative is to simply extend the base field enough for the curve to have an untwisted Montgomery model: - sage: C_ = E.change_ring(F).montgomery_model(); C_ # needs sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 249*x^2 + x over Finite Field in z2 of size 257^2 sage: h = C.defining_polynomial().change_ring(F); h # needs sage.rings.finite_rings -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 sage: C_.is_isomorphic(EllipticCurve_from_cubic(h).codomain()) # needs sage.rings.finite_rings True - >>> from sage.all import * >>> C_ = E.change_ring(F).montgomery_model(); C_ # needs sage.rings.finite_rings Elliptic Curve defined by y^2 = x^3 + 249*x^2 + x over Finite Field in z2 of size 257^2 >>> h = C.defining_polynomial().change_ring(F); h # needs sage.rings.finite_rings -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 >>> C_.is_isomorphic(EllipticCurve_from_cubic(h).codomain()) # needs sage.rings.finite_rings True - See also - The inverse conversion — computing a Weierstrass model for a given Montgomery curve — can be performed using - EllipticCurve_from_cubic().- ALGORITHM: [CS2018], §2.4 - REFERENCES: - Original publication: [Mont1987], §10.3.1 
- More recent survey article: [CS2018] 
 
 - multiplication_by_m(m, x_only=False)[source]¶
- Return the multiplication-by-\(m\) map from - selfto- self.- The result is a pair of rational functions in two variables \(x\), \(y\) (or a rational function in one variable \(x\) if - x_onlyis- True).- INPUT: - m– nonzero integer
- x_only– boolean (default:- False); if- True, return only the \(x\)-coordinate of the map (as a rational function in one variable)
 - OUTPUT: - a pair \((f(x), g(x,y))\), where \(f\) and \(g\) are rational functions with the degree of \(y\) in \(g(x,y)\) exactly 1, 
- or just \(f(x)\) if - x_onlyis- True
 - Note - The result is not cached. 
- mis allowed to be negative (but not 0).
 - EXAMPLES: - sage: E = EllipticCurve([-1,3]) - >>> from sage.all import * >>> E = EllipticCurve([-Integer(1),Integer(3)]) - We verify that multiplication by 1 is just the identity: - sage: E.multiplication_by_m(1) (x, y) - >>> from sage.all import * >>> E.multiplication_by_m(Integer(1)) (x, y) - Multiplication by 2 is more complicated: - sage: f = E.multiplication_by_m(2) sage: f ((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)) - >>> from sage.all import * >>> f = E.multiplication_by_m(Integer(2)) >>> f ((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)) - Grab only the x-coordinate (less work): - sage: mx = E.multiplication_by_m(2, x_only=True); mx (1/4*x^4 + 1/2*x^2 - 6*x + 1/4)/(x^3 - x + 3) sage: mx.parent() Fraction Field of Univariate Polynomial Ring in x over Rational Field - >>> from sage.all import * >>> mx = E.multiplication_by_m(Integer(2), x_only=True); mx (1/4*x^4 + 1/2*x^2 - 6*x + 1/4)/(x^3 - x + 3) >>> mx.parent() Fraction Field of Univariate Polynomial Ring in x over Rational Field - We check that it works on a point: - sage: P = E([2,3]) sage: eval = lambda f,P: [fi(P[0],P[1]) for fi in f] sage: assert E(eval(f,P)) == 2*P - >>> from sage.all import * >>> P = E([Integer(2),Integer(3)]) >>> eval = lambda f,P: [fi(P[Integer(0)],P[Integer(1)]) for fi in f] >>> assert E(eval(f,P)) == Integer(2)*P - We do the same but with multiplication by 3: - sage: f = E.multiplication_by_m(3) sage: assert E(eval(f,P)) == 3*P - >>> from sage.all import * >>> f = E.multiplication_by_m(Integer(3)) >>> assert E(eval(f,P)) == Integer(3)*P - And the same with multiplication by 4: - sage: f = E.multiplication_by_m(4) sage: assert E(eval(f,P)) == 4*P - >>> from sage.all import * >>> f = E.multiplication_by_m(Integer(4)) >>> assert E(eval(f,P)) == Integer(4)*P - And the same with multiplication by -1,-2,-3,-4: - sage: for m in [-1,-2,-3,-4]: ....: f = E.multiplication_by_m(m) ....: assert E(eval(f,P)) == m*P - >>> from sage.all import * >>> for m in [-Integer(1),-Integer(2),-Integer(3),-Integer(4)]: ... f = E.multiplication_by_m(m) ... assert E(eval(f,P)) == m*P 
 - pari_curve()[source]¶
- Return the PARI curve corresponding to this elliptic curve. - The result is cached. - EXAMPLES: - sage: # needs sage.libs.pari sage: E = EllipticCurve([RR(0), RR(0), RR(1), RR(-1), RR(0)]) sage: e = E.pari_curve() sage: type(e) <... 'cypari2.gen.Gen'> sage: e.type() 't_VEC' sage: e.disc() 37.0000000000000 - >>> from sage.all import * >>> # needs sage.libs.pari >>> E = EllipticCurve([RR(Integer(0)), RR(Integer(0)), RR(Integer(1)), RR(-Integer(1)), RR(Integer(0))]) >>> e = E.pari_curve() >>> type(e) <... 'cypari2.gen.Gen'> >>> e.type() 't_VEC' >>> e.disc() 37.0000000000000 - Over a finite field: - sage: EllipticCurve(GF(41), [2,5]).pari_curve() # needs sage.libs.pari [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), Vecsmall([3]), [41, [9, 31, [6, 0, 0, 0]]], [0, 0, 0, 0]] - >>> from sage.all import * >>> EllipticCurve(GF(Integer(41)), [Integer(2),Integer(5)]).pari_curve() # needs sage.libs.pari [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), Vecsmall([3]), [41, [9, 31, [6, 0, 0, 0]]], [0, 0, 0, 0]] - Over a \(p\)-adic field: - sage: # needs sage.libs.pari sage.rings.padics sage: Qp = pAdicField(5, prec=3) sage: E = EllipticCurve(Qp, [3, 4]) sage: E.pari_curve() [0, 0, 0, 3, 4, 0, 6, 16, -9, -144, -3456, -8640, 1728/5, Vecsmall([2]), [O(5^3)], [0, 0]] sage: E.j_invariant() 3*5^-1 + O(5) - >>> from sage.all import * >>> # needs sage.libs.pari sage.rings.padics >>> Qp = pAdicField(Integer(5), prec=Integer(3)) >>> E = EllipticCurve(Qp, [Integer(3), Integer(4)]) >>> E.pari_curve() [0, 0, 0, 3, 4, 0, 6, 16, -9, -144, -3456, -8640, 1728/5, Vecsmall([2]), [O(5^3)], [0, 0]] >>> E.j_invariant() 3*5^-1 + O(5) - Over a number field: - sage: K.<a> = QuadraticField(2) # needs sage.libs.pari sage.rings.number_field sage: E = EllipticCurve([1,a]) # needs sage.libs.pari sage.rings.number_field sage: E.pari_curve() # needs sage.libs.pari sage.rings.number_field [0, 0, 0, Mod(1, y^2 - 2), Mod(y, y^2 - 2), 0, Mod(2, y^2 - 2), Mod(4*y, y^2 - 2), Mod(-1, y^2 - 2), Mod(-48, y^2 - 2), Mod(-864*y, y^2 - 2), Mod(-928, y^2 - 2), Mod(3456/29, y^2 - 2), Vecsmall([5]), [[y^2 - 2, [2, 0], 8, 1, [[1, -1.41421356237310; 1, 1.41421356237310], [1, -1.41421356237310; 1, 1.41421356237310], [16, -23; 16, 23], [2, 0; 0, 4], [4, 0; 0, 2], [2, 0; 0, 1], [2, [0, 2; 1, 0]], [2]], [-1.41421356237310, 1.41421356237310], [1, y], [1, 0; 0, 1], [1, 0, 0, 2; 0, 1, 1, 0]]], [0, 0, 0, 0, 0]] - >>> from sage.all import * >>> K = QuadraticField(Integer(2), names=('a',)); (a,) = K._first_ngens(1)# needs sage.libs.pari sage.rings.number_field >>> E = EllipticCurve([Integer(1),a]) # needs sage.libs.pari sage.rings.number_field >>> E.pari_curve() # needs sage.libs.pari sage.rings.number_field [0, 0, 0, Mod(1, y^2 - 2), Mod(y, y^2 - 2), 0, Mod(2, y^2 - 2), Mod(4*y, y^2 - 2), Mod(-1, y^2 - 2), Mod(-48, y^2 - 2), Mod(-864*y, y^2 - 2), Mod(-928, y^2 - 2), Mod(3456/29, y^2 - 2), Vecsmall([5]), [[y^2 - 2, [2, 0], 8, 1, [[1, -1.41421356237310; 1, 1.41421356237310], [1, -1.41421356237310; 1, 1.41421356237310], [16, -23; 16, 23], [2, 0; 0, 4], [4, 0; 0, 2], [2, 0; 0, 1], [2, [0, 2; 1, 0]], [2]], [-1.41421356237310, 1.41421356237310], [1, y], [1, 0; 0, 1], [1, 0, 0, 2; 0, 1, 1, 0]]], [0, 0, 0, 0, 0]] - PARI no longer requires that the \(j\)-invariant has negative \(p\)-adic valuation: - sage: E = EllipticCurve(Qp,[1, 1]) # needs sage.libs.pari sage.rings.padics sage: E.j_invariant() # the j-invariant is a p-adic integer # needs sage.libs.pari sage.rings.padics 2 + 4*5^2 + O(5^3) sage: E.pari_curve() # needs sage.libs.pari sage.rings.padics [0, 0, 0, 1, 1, 0, 2, 4, -1, -48, -864, -496, 6912/31, Vecsmall([2]), [O(5^3)], [0, 0]] - >>> from sage.all import * >>> E = EllipticCurve(Qp,[Integer(1), Integer(1)]) # needs sage.libs.pari sage.rings.padics >>> E.j_invariant() # the j-invariant is a p-adic integer # needs sage.libs.pari sage.rings.padics 2 + 4*5^2 + O(5^3) >>> E.pari_curve() # needs sage.libs.pari sage.rings.padics [0, 0, 0, 1, 1, 0, 2, 4, -1, -48, -864, -496, 6912/31, Vecsmall([2]), [O(5^3)], [0, 0]] 
 - plot(xmin=None, xmax=None, components='both', **args)[source]¶
- Draw a graph of this elliptic curve. - The plot method is only implemented when there is a natural coercion from the base ring of - selfto- RR. In this case,- selfis plotted as if it was defined over- RR.- INPUT: - xmin,- xmax– (optional) points will be computed at least within this range, but possibly farther
- components– string; one of the following:- both– (default), scale so that both bounded and unbounded components appear
- bounded– scale the plot to show the bounded component. Raises an error if there is only one real component.
- unbounded– scale the plot to show the unbounded component, including the two flex points
 
- plot_points– passed to- sage.plot.generate_plot_points()
- adaptive_tolerance– passed to- sage.plot.generate_plot_points()
- adaptive_recursion– passed to- sage.plot.generate_plot_points()
- randomize– passed to- sage.plot.generate_plot_points()
- **args– all other options are passed to- sage.plot.line.Line
 - EXAMPLES: - sage: E = EllipticCurve([0, -1]) sage: plot(E, rgbcolor=hue(0.7)) # needs sage.plot Graphics object consisting of 1 graphics primitive sage: E = EllipticCurve('37a') sage: plot(E) # needs sage.plot Graphics object consisting of 2 graphics primitives sage: plot(E, xmin=25, xmax=26) # needs sage.plot Graphics object consisting of 2 graphics primitives - >>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1)]) >>> plot(E, rgbcolor=hue(RealNumber('0.7'))) # needs sage.plot Graphics object consisting of 1 graphics primitive >>> E = EllipticCurve('37a') >>> plot(E) # needs sage.plot Graphics object consisting of 2 graphics primitives >>> plot(E, xmin=Integer(25), xmax=Integer(26)) # needs sage.plot Graphics object consisting of 2 graphics primitives - With Issue #12766 we added the components keyword: - sage: E.real_components() 2 sage: E.plot(components='bounded') # needs sage.plot Graphics object consisting of 1 graphics primitive sage: E.plot(components='unbounded') # needs sage.plot Graphics object consisting of 1 graphics primitive - >>> from sage.all import * >>> E.real_components() 2 >>> E.plot(components='bounded') # needs sage.plot Graphics object consisting of 1 graphics primitive >>> E.plot(components='unbounded') # needs sage.plot Graphics object consisting of 1 graphics primitive - If there is only one component then specifying components=’bounded’ raises a ValueError: - sage: E = EllipticCurve('9990be2') sage: E.plot(components='bounded') # needs sage.plot Traceback (most recent call last): ... ValueError: no bounded component for this curve - >>> from sage.all import * >>> E = EllipticCurve('9990be2') >>> E.plot(components='bounded') # needs sage.plot Traceback (most recent call last): ... ValueError: no bounded component for this curve - An elliptic curve defined over the Complex Field can not be plotted: - sage: E = EllipticCurve(CC, [0,0,1,-1,0]) sage: E.plot() # needs sage.plot Traceback (most recent call last): ... NotImplementedError: plotting of curves over Complex Field with 53 bits of precision is not implemented yet - >>> from sage.all import * >>> E = EllipticCurve(CC, [Integer(0),Integer(0),Integer(1),-Integer(1),Integer(0)]) >>> E.plot() # needs sage.plot Traceback (most recent call last): ... NotImplementedError: plotting of curves over Complex Field with 53 bits of precision is not implemented yet 
 - rst_transform(r, s, t)[source]¶
- Return the transform of the curve by \((r,s,t)\) (with \(u=1\)). - INPUT: - r,- s,- t– three elements of the base ring
 - OUTPUT: - The elliptic curve obtained from - selfby the standard Weierstrass transformation \((u,r,s,t)\) with \(u=1\).- Note - This is just a special case of - change_weierstrass_model(), with \(u=1\).- EXAMPLES: - sage: R.<r,s,t> = QQ[] sage: E = EllipticCurve([1,2,3,4,5]) sage: E.rst_transform(r, s, t) Elliptic 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 Field - >>> from sage.all import * >>> R = QQ['r, s, t']; (r, s, t,) = R._first_ngens(3) >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.rst_transform(r, s, t) Elliptic 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 Field 
 - scalar_multiplication(m)[source]¶
- Return the scalar-multiplication map \([m]\) on this elliptic curve as a - sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalarobject.- EXAMPLES: - sage: E = EllipticCurve('77a1') sage: m = E.scalar_multiplication(-7); m Scalar-multiplication endomorphism [-7] of Elliptic Curve defined by y^2 + y = x^3 + 2*x over Rational Field sage: m.degree() 49 sage: P = E(2,3) sage: m(P) (-26/225 : -2132/3375 : 1) sage: m.rational_maps() == E.multiplication_by_m(-7) True - >>> from sage.all import * >>> E = EllipticCurve('77a1') >>> m = E.scalar_multiplication(-Integer(7)); m Scalar-multiplication endomorphism [-7] of Elliptic Curve defined by y^2 + y = x^3 + 2*x over Rational Field >>> m.degree() 49 >>> P = E(Integer(2),Integer(3)) >>> m(P) (-26/225 : -2132/3375 : 1) >>> m.rational_maps() == E.multiplication_by_m(-Integer(7)) True - sage: E = EllipticCurve('11a1') sage: E.scalar_multiplication(7) Scalar-multiplication endomorphism [7] of Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field - >>> from sage.all import * >>> E = EllipticCurve('11a1') >>> E.scalar_multiplication(Integer(7)) Scalar-multiplication endomorphism [7] of Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field 
 - scale_curve(u)[source]¶
- Return the transform of the curve by scale factor \(u\). - INPUT: - u– an invertible element of the base ring
 - OUTPUT: - The elliptic curve obtained from - selfby the standard Weierstrass transformation \((u,r,s,t)\) with \(r=s=t=0\).- Note - This is just a special case of - change_weierstrass_model(), with \(r=s=t=0\).- EXAMPLES: - sage: K = Frac(PolynomialRing(QQ, 'u')) sage: u = K.gen() sage: E = EllipticCurve([1,2,3,4,5]) sage: E.scale_curve(u) Elliptic 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 Field - >>> from sage.all import * >>> K = Frac(PolynomialRing(QQ, 'u')) >>> u = K.gen() >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.scale_curve(u) Elliptic 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 Field 
 - short_weierstrass_model(complete_cube=True)[source]¶
- Return a short Weierstrass model for - self.- INPUT: - complete_cube– boolean (default:- True); for meaning, see below
 - OUTPUT: an elliptic curve - If - complete_cube=True: Return a model of the form \(y^2 = x^3 + a*x + b\) for this curve. The characteristic must not be 2; in characteristic 3, it is only possible if \(b_2=0\).- If - complete_cube=False: Return a model of the form \(y^2 = x^3 + ax^2 + bx + c\) for this curve. The characteristic must not be 2.- EXAMPLES: - sage: E = EllipticCurve([1,2,3,4,5]) sage: E Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field sage: F = E.short_weierstrass_model() sage: F Elliptic Curve defined by y^2 = x^3 + 4941*x + 185166 over Rational Field sage: E.is_isomorphic(F) True sage: F = E.short_weierstrass_model(complete_cube=False) sage: F Elliptic Curve defined by y^2 = x^3 + 9*x^2 + 88*x + 464 over Rational Field sage: E.is_isomorphic(F) True - >>> from sage.all import * >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field >>> F = E.short_weierstrass_model() >>> F Elliptic Curve defined by y^2 = x^3 + 4941*x + 185166 over Rational Field >>> E.is_isomorphic(F) True >>> F = E.short_weierstrass_model(complete_cube=False) >>> F Elliptic Curve defined by y^2 = x^3 + 9*x^2 + 88*x + 464 over Rational Field >>> E.is_isomorphic(F) True - sage: E = EllipticCurve(GF(3), [1,2,3,4,5]) sage: E.short_weierstrass_model(complete_cube=False) Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 3 - >>> from sage.all import * >>> E = EllipticCurve(GF(Integer(3)), [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]) >>> E.short_weierstrass_model(complete_cube=False) Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 3 - This used to be different see Issue #3973: - sage: E.short_weierstrass_model() Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 3 - >>> from sage.all import * >>> E.short_weierstrass_model() Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 3 - More tests in characteristic 3: - sage: E = EllipticCurve(GF(3), [0,2,1,2,1]) sage: E.short_weierstrass_model() Traceback (most recent call last): ... ValueError: 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) sage: E.short_weierstrass_model(complete_cube=False) Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x + 2 over Finite Field of size 3 sage: E.short_weierstrass_model(complete_cube=False).is_isomorphic(E) True - >>> from sage.all import * >>> E = EllipticCurve(GF(Integer(3)), [Integer(0),Integer(2),Integer(1),Integer(2),Integer(1)]) >>> E.short_weierstrass_model() Traceback (most recent call last): ... ValueError: 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) >>> E.short_weierstrass_model(complete_cube=False) Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x + 2 over Finite Field of size 3 >>> E.short_weierstrass_model(complete_cube=False).is_isomorphic(E) True 
 - torsion_polynomial(m, x=None, two_torsion_multiplicity=2, force_evaluate=None)[source]¶
- Return the \(m\)-th division polynomial of this elliptic curve evaluated at \(x\). - The division polynomial is cached if \(x\) is - None.- INPUT: - m– positive integer
- x– (optional) ring element to use as the \(x\) variable. If \(x\) is- None(omitted), then a new polynomial ring will be constructed over the base ring of the elliptic curve, and its generator will be used as \(x\). Note that \(x\) does not need to be a generator of a polynomial ring; any ring element works. This permits fast calculation of the torsion polynomial evaluated on any element of a ring.
- two_torsion_multiplicity– 0, 1, or 2- If 0: For even \(m\) when \(x\) is - None, a univariate polynomial over the base ring of the curve is returned, which omits factors whose roots are the \(x\)-coordinates of the \(2\)-torsion points. When \(x\) is not- None, the evaluation of such a polynomial at \(x\) is returned.- If 2: For even \(m\) when \(x\) is - None, a univariate polynomial over the base ring of the curve is returned, which includes a factor of degree 3 whose roots are the \(x\)-coordinates of the \(2\)-torsion points. Similarly, when \(x\) is not- None, the evaluation of such a polynomial at \(x\) is returned.- If 1: For even \(m\) when \(x\) is - None, a bivariate polynomial over the base ring of the curve is returned, which includes a factor \(2y+a_1x+a_3\) having simple zeros at the \(2\)-torsion points. When \(x\) is not- None, it should be a tuple of length 2, and the evaluation of such a polynomial at \(x\) is returned.
- force_evaluate– (optional) 0, 1, or 2- By default, this method makes use of previously cached generic division polynomials to compute the value of the polynomial at a given element \(x\) whenever it appears beneficial to do so. Explicitly setting this flag overrides the default behavior. - Note that the complexity of evaluating a generic division polynomial scales much worse than that of computing the value at a point directly (using the recursive formulas), hence setting this flag can be detrimental to performance. - If 0: Do not use cached generic division polynomials. - If 1: If the generic division polynomial for this \(m\) has been cached before, evaluate it at \(x\) to compute the result. - If 2: Compute the value at \(x\) by evaluating the generic division polynomial. If the generic \(m\)-division polynomial has not yet been cached, compute and cache it first. 
 - EXAMPLES: - sage: E = EllipticCurve([0,0,1,-1,0]) sage: E.division_polynomial(1) 1 sage: E.division_polynomial(2, two_torsion_multiplicity=0) 1 sage: E.division_polynomial(2, two_torsion_multiplicity=1) 2*y + 1 sage: E.division_polynomial(2, two_torsion_multiplicity=2) 4*x^3 - 4*x + 1 sage: E.division_polynomial(2) 4*x^3 - 4*x + 1 sage: [E.division_polynomial(3, two_torsion_multiplicity=i) for i in range(3)] [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] sage: [type(E.division_polynomial(3, two_torsion_multiplicity=i)) for i in range(3)] [<... 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>, <... 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>, <... 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>] - >>> from sage.all import * >>> E = EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(1),Integer(0)]) >>> E.division_polynomial(Integer(1)) 1 >>> E.division_polynomial(Integer(2), two_torsion_multiplicity=Integer(0)) 1 >>> E.division_polynomial(Integer(2), two_torsion_multiplicity=Integer(1)) 2*y + 1 >>> E.division_polynomial(Integer(2), two_torsion_multiplicity=Integer(2)) 4*x^3 - 4*x + 1 >>> E.division_polynomial(Integer(2)) 4*x^3 - 4*x + 1 >>> [E.division_polynomial(Integer(3), two_torsion_multiplicity=i) for i in range(Integer(3))] [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] >>> [type(E.division_polynomial(Integer(3), two_torsion_multiplicity=i)) for i in range(Integer(3))] [<... 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>, <... 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>, <... 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>] - sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: R.<z> = PolynomialRing(QQ) sage: E.division_polynomial(4, z, 0) 2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821 sage: E.division_polynomial(4, z) 8*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 + 459859 - >>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)]) >>> R = PolynomialRing(QQ, names=('z',)); (z,) = R._first_ngens(1) >>> E.division_polynomial(Integer(4), z, Integer(0)) 2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821 >>> E.division_polynomial(Integer(4), z) 8*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 + 459859 - This does not work, since when two_torsion_multiplicity is 1, we compute a bivariate polynomial, and must evaluate at a tuple of length 2: - sage: E.division_polynomial(4,z,1) Traceback (most recent call last): ... ValueError: x should be a tuple of length 2 (or None) when two_torsion_multiplicity is 1 sage: R.<z,w> = PolynomialRing(QQ, 2) sage: E.division_polynomial(4, (z,w), 1).factor() (2*w + 1) * (2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821) - >>> from sage.all import * >>> E.division_polynomial(Integer(4),z,Integer(1)) Traceback (most recent call last): ... ValueError: x should be a tuple of length 2 (or None) when two_torsion_multiplicity is 1 >>> R = PolynomialRing(QQ, Integer(2), names=('z', 'w',)); (z, w,) = R._first_ngens(2) >>> E.division_polynomial(Integer(4), (z,w), Integer(1)).factor() (2*w + 1) * (2*z^6 - 4*z^5 - 100*z^4 - 790*z^3 - 210*z^2 - 1496*z - 5821) - We can also evaluate this bivariate polynomial at a point: - sage: P = E(5,5) sage: E.division_polynomial(4,P,two_torsion_multiplicity=1) -1771561 - >>> from sage.all import * >>> P = E(Integer(5),Integer(5)) >>> E.division_polynomial(Integer(4),P,two_torsion_multiplicity=Integer(1)) -1771561 
 - two_division_polynomial(x=None)[source]¶
- Return the 2-division polynomial of this elliptic curve evaluated at - x.- INPUT: - x– (optional) ring element to use as the \(x\) variable. If- xis- None, then a new polynomial ring will be constructed over the base ring of the elliptic curve, and its generator will be used as- x. Note that- xdoes not need to be a generator of a polynomial ring; any ring element is acceptable. This permits fast calculation of the torsion polynomial evaluated on any element of a ring.
 - EXAMPLES: - sage: E = EllipticCurve('5077a1') sage: E.two_division_polynomial() 4*x^3 - 28*x + 25 sage: E = EllipticCurve(GF(3^2,'a'), [1,1,1,1,1]) # needs sage.rings.finite_rings sage: E.two_division_polynomial() # needs sage.rings.finite_rings x^3 + 2*x^2 + 2 sage: E.two_division_polynomial().roots() # needs sage.rings.finite_rings [(2, 1), (2*a, 1), (a + 2, 1)] - >>> from sage.all import * >>> E = EllipticCurve('5077a1') >>> E.two_division_polynomial() 4*x^3 - 28*x + 25 >>> E = EllipticCurve(GF(Integer(3)**Integer(2),'a'), [Integer(1),Integer(1),Integer(1),Integer(1),Integer(1)]) # needs sage.rings.finite_rings >>> E.two_division_polynomial() # needs sage.rings.finite_rings x^3 + 2*x^2 + 2 >>> E.two_division_polynomial().roots() # needs sage.rings.finite_rings [(2, 1), (2*a, 1), (a + 2, 1)] 
 
- sage.schemes.elliptic_curves.ell_generic.is_EllipticCurve(x)[source]¶
- Utility function to test if - xis an instance of an Elliptic Curve class.- EXAMPLES: - sage: from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve sage: E = EllipticCurve([1,2,3/4,7,19]) sage: is_EllipticCurve(E) doctest:warning... DeprecationWarning: The function is_EllipticCurve is deprecated; use 'isinstance(..., EllipticCurve_generic)' instead. See https://github.com/sagemath/sage/issues/38022 for details. True sage: is_EllipticCurve(0) False - >>> from sage.all import * >>> from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3)/Integer(4),Integer(7),Integer(19)]) >>> is_EllipticCurve(E) doctest:warning... DeprecationWarning: The function is_EllipticCurve is deprecated; use 'isinstance(..., EllipticCurve_generic)' instead. See https://github.com/sagemath/sage/issues/38022 for details. True >>> is_EllipticCurve(Integer(0)) False