AUTHORS:
Construct an elliptic curve.
In Sage, an elliptic curve is always specified by its a-invariants
INPUT:
There are several ways to construct an elliptic curve:
In each case above where the input is a list of length 2 or 5, one can instead give a 2 or 5-tuple instead.
EXAMPLES:
We illustrate creating elliptic curves:
sage: EllipticCurve([0,0,1,-1,0])
Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
We create a curve from a Cremona label:
sage: EllipticCurve('37b2')
Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field
sage: EllipticCurve('5077a')
Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field
sage: EllipticCurve('389a')
Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
Old Cremona labels are allowed:
sage: EllipticCurve('2400FF')
Elliptic Curve defined by y^2 = x^3 + x^2 + 2*x + 8 over Rational Field
Unicode labels are allowed:
sage: EllipticCurve(u'389a')
Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
We create curves over a finite field as follows:
sage: EllipticCurve([GF(5)(0),0,1,-1,0])
Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5
sage: EllipticCurve(GF(5), [0, 0,1,-1,0])
Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5
Elliptic curves over \(\ZZ/N\ZZ\) with \(N\) prime are of type “elliptic curve over a finite field”:
sage: F = Zmod(101)
sage: EllipticCurve(F, [2, 3])
Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 101
sage: E = EllipticCurve([F(2), F(3)])
sage: type(E)
<class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'>
sage: E.category()
Category of schemes over Ring of integers modulo 101
In contrast, elliptic curves over \(\ZZ/N\ZZ\) with \(N\) composite are of type “generic elliptic curve”:
sage: F = Zmod(95)
sage: EllipticCurve(F, [2, 3])
Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 95
sage: E = EllipticCurve([F(2), F(3)])
sage: type(E)
<class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'>
sage: E.category()
Category of schemes over Ring of integers modulo 95
The following is a curve over the complex numbers:
sage: E = EllipticCurve(CC, [0,0,1,-1,0])
sage: E
Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x over Complex Field with 53 bits of precision
sage: E.j_invariant()
2988.97297297297
We can also create elliptic curves by giving the Weierstrass equation:
sage: x, y = var('x,y')
sage: EllipticCurve(y^2 + y == x^3 + x - 9)
Elliptic Curve defined by y^2 + y = x^3 + x - 9 over Rational Field
sage: R.<x,y> = GF(5)[]
sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x)
Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 2 over Finite Field of size 5
We can explicitly specify the \(j\)-invariant:
sage: E = EllipticCurve(j=1728); E; E.j_invariant(); E.label()
Elliptic Curve defined by y^2 = x^3 - x over Rational Field
1728
'32a2'
sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant()
Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5
2
sage: EllipticCurve(GF(144169),j=1728)
Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169
By default, when a rational value of \(j\) is given, the constructed curve is a minimal twist (minimal conductor for curves with that \(j\)-invariant). This can be changed by setting the optional parameter minimal_twist, which is True by default, to False:
sage: EllipticCurve(j=100)
Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
sage: E =EllipticCurve(j=100); E
Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
sage: E.conductor()
33129800
sage: E.j_invariant()
100
sage: E =EllipticCurve(j=100, minimal_twist=False); E
Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field
sage: E.conductor()
298168200
sage: E.j_invariant()
100
Without this option, constructing the curve could take a long time since both \(j\) and \(j-1728\) have to be factored to compute the minimal twist (see trac ticket #13100):
sage: E = EllipticCurve_from_j(2^256+1,minimal_twist=False)
sage: E.j_invariant() == 2^256+1
True
TESTS:
sage: R = ZZ['u', 'v']
sage: EllipticCurve(R, [1,1])
Elliptic Curve defined by y^2 = x^3 + x + 1 over Multivariate Polynomial Ring in u, v
over Integer Ring
We create a curve and a point over QQbar (see #6879):
sage: E = EllipticCurve(QQbar,[0,1])
sage: E(0)
(0 : 1 : 0)
sage: E.base_field()
Algebraic Field
sage: E = EllipticCurve(RR,[1,2]); E; E.base_field()
Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision
Real Field with 53 bits of precision
sage: EllipticCurve(CC,[3,4]); E; E.base_field()
Elliptic Curve defined by y^2 = x^3 + 3.00000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision
Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision
Real Field with 53 bits of precision
sage: E = EllipticCurve(QQbar,[5,6]); E; E.base_field()
Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field
Algebraic Field
sage: EllipticCurve(3,j=1728)
Traceback (most recent call last):
...
ValueError: First parameter (if present) must be a ring when j is specified
sage: EllipticCurve(GF(5),j=3/5)
Traceback (most recent call last):
...
ValueError: First parameter must be a ring containing 3/5
If the universe of the coefficients is a general field, the object constructed has type EllipticCurve_field. Otherwise it is EllipticCurve_generic. See trac ticket #9816
sage: E = EllipticCurve([QQbar(1),3]); E
Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field
sage: type(E)
<class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
sage: E = EllipticCurve([RR(1),3]); E
Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 3.00000000000000 over Real Field with 53 bits of precision
sage: type(E)
<class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
sage: E = EllipticCurve([i,i]); E
Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring
sage: type(E)
<class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
sage: E.category()
Category of schemes over Symbolic Ring
sage: SR in Fields()
True
sage: F = FractionField(PolynomialRing(QQ,'t'))
sage: t = F.gen()
sage: E = EllipticCurve([t,0]); E
Elliptic Curve defined by y^2 = x^3 + t*x over Fraction Field of Univariate Polynomial Ring in t over Rational Field
sage: type(E)
<class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'>
sage: E.category()
Category of schemes over Fraction Field of Univariate Polynomial Ring in t over Rational Field
See trac ticket #12517:
sage: E = EllipticCurve([1..5])
sage: EllipticCurve(E.a_invariants())
Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
See trac ticket #11773:
sage: E = EllipticCurve()
Traceback (most recent call last):
...
TypeError: invalid input to EllipticCurve constructor
Return the elliptic curve defined by a cubic in (long) Weierstrass form.
INPUT:
OUTPUT:
The elliptic curve defined by it.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: f = y^2 + 1*x*y + 3*y - (x^3 + 2*x^2 + 4*x + 6)
sage: EllipticCurve(f)
Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 6 over Rational Field
sage: EllipticCurve(f).a_invariants()
(1, 2, 3, 4, 6)
The polynomial ring may have extra variables as long as they do not occur in the polynomial itself:
sage: R.<x,y,z,w> = QQ[]
sage: EllipticCurve(-y^2 + x^3 + 1)
Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
sage: EllipticCurve(-x^2 + y^3 + 1)
Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
sage: EllipticCurve(-w^2 + z^3 + 1)
Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
TESTS:
sage: from sage.schemes.elliptic_curves.constructor import EllipticCurve_from_Weierstrass_polynomial
sage: EllipticCurve_from_Weierstrass_polynomial(-w^2 + z^3 + 1)
Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
Return an elliptic curve with given \(c_4\) and \(c_6\) invariants.
EXAMPLES:
sage: E = EllipticCurve_from_c4c6(17, -2005)
sage: E
Elliptic Curve defined by y^2 = x^3 - 17/48*x + 2005/864 over Rational Field
sage: E.c_invariants()
(17, -2005)
Construct an elliptic curve from a ternary cubic with a rational point.
If you just want the Weierstrass form and are not interested in the morphism then it is easier to use Jacobian() instead. This will construct the same elliptic curve but you don’t have to supply the point P.
INPUT:
OUTPUT:
An elliptic curve in long Weierstrass form isomorphic to the curve \(F=0\).
If morphism=True is passed, then a birational equivalence between F and the Weierstrass curve is returned. If the point happens to be a flex, then this is an isomorphism.
EXAMPLES:
First we find that the Fermat cubic is isomorphic to the curve with Cremona label 27a1:
sage: R.<x,y,z> = QQ[]
sage: cubic = x^3+y^3+z^3
sage: P = [1,-1,0]
sage: E = EllipticCurve_from_cubic(cubic, P, morphism=False); E
Elliptic Curve defined by y^2 + 2*x*y + 1/3*y = x^3 - x^2 - 1/3*x - 1/27 over Rational Field
sage: E.cremona_label()
'27a1'
sage: EllipticCurve_from_cubic(cubic, [0,1,-1], morphism=False).cremona_label()
'27a1'
sage: EllipticCurve_from_cubic(cubic, [1,0,-1], morphism=False).cremona_label()
'27a1'
Next we find the minimal model and conductor of the Jacobian of the Selmer curve:
sage: R.<a,b,c> = QQ[]
sage: cubic = a^3+b^3+60*c^3
sage: P = [1,-1,0]
sage: E = EllipticCurve_from_cubic(cubic, P, morphism=False); E
Elliptic Curve defined by y^2 + 2*x*y + 20*y = x^3 - x^2 - 20*x - 400/3 over Rational Field
sage: E.minimal_model()
Elliptic Curve defined by y^2 = x^3 - 24300 over Rational Field
sage: E.conductor()
24300
We can also get the birational equivalence to and from the Weierstrass form. We start with an example where P is a flex and the equivalence is an isomorphism:
sage: f = EllipticCurve_from_cubic(cubic, P, morphism=True)
sage: f
Scheme morphism:
From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
a^3 + b^3 + 60*c^3
To: Elliptic Curve defined by y^2 + 2*x*y + 20*y = x^3 - x^2 - 20*x - 400/3
over Rational Field
Defn: Defined on coordinates by sending (a : b : c) to
(-c : -b + c : 1/20*a + 1/20*b)
sage: finv = f.inverse(); finv
Scheme morphism:
From: Elliptic Curve defined by y^2 + 2*x*y + 20*y = x^3 - x^2 - 20*x - 400/3
over Rational Field
To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
a^3 + b^3 + 60*c^3
Defn: Defined on coordinates by sending (x : y : z) to
(x + y + 20*z : -x - y : -x)
We verify that \(f\) maps the chosen point \(P=(1,-1,0)\) on the cubic to the origin of the elliptic curve:
sage: f([1,-1,0])
(0 : 1 : 0)
sage: finv([0,1,0])
(-1 : 1 : 0)
To verify the output, we plug in the polynomials to check that this indeed transforms the cubic into Weierstrass form:
sage: cubic(finv.defining_polynomials()) * finv.post_rescaling()
-x^3 + x^2*z + 2*x*y*z + y^2*z + 20*x*z^2 + 20*y*z^2 + 400/3*z^3
sage: E.defining_polynomial()(f.defining_polynomials()) * f.post_rescaling()
a^3 + b^3 + 60*c^3
If the point is not a flex then the cubic can not be transformed to a Weierstrass equation by a linear transformation. The general birational transformation is quadratic:
sage: cubic = a^3+7*b^3+64*c^3
sage: P = [2,2,-1]
sage: f = EllipticCurve_from_cubic(cubic, P, morphism=True)
sage: E = f.codomain(); E
Elliptic Curve defined by y^2 - 722*x*y - 21870000*y = x^3
+ 23579*x^2 over Rational Field
sage: E.minimal_model()
Elliptic Curve defined by y^2 + y = x^3 - 331 over Rational Field
sage: f
Scheme morphism:
From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
a^3 + 7*b^3 + 64*c^3
To: Elliptic Curve defined by y^2 - 722*x*y - 21870000*y =
x^3 + 23579*x^2 over Rational Field
Defn: Defined on coordinates by sending (a : b : c) to
(-5/112896*a^2 - 17/40320*a*b - 1/1280*b^2 - 29/35280*a*c
- 13/5040*b*c - 4/2205*c^2 :
-4055/112896*a^2 - 4787/40320*a*b - 91/1280*b^2 - 7769/35280*a*c
- 1993/5040*b*c - 724/2205*c^2 :
1/4572288000*a^2 + 1/326592000*a*b + 1/93312000*b^2 + 1/142884000*a*c
+ 1/20412000*b*c + 1/17860500*c^2)
sage: finv = f.inverse(); finv
Scheme morphism:
From: Elliptic Curve defined by y^2 - 722*x*y - 21870000*y =
x^3 + 23579*x^2 over Rational Field
To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
a^3 + 7*b^3 + 64*c^3
Defn: Defined on coordinates by sending (x : y : z) to
(2*x^2 + 227700*x*z - 900*y*z :
2*x^2 - 32940*x*z + 540*y*z :
-x^2 - 56520*x*z - 180*y*z)
sage: cubic(finv.defining_polynomials()) * finv.post_rescaling()
-x^3 - 23579*x^2*z - 722*x*y*z + y^2*z - 21870000*y*z^2
sage: E.defining_polynomial()(f.defining_polynomials()) * f.post_rescaling()
a^3 + 7*b^3 + 64*c^3
TESTS:
sage: R.<x,y,z> = QQ[]
sage: cubic = x^2*y + 4*x*y^2 + x^2*z + 8*x*y*z + 4*y^2*z + 9*x*z^2 + 9*y*z^2
sage: EllipticCurve_from_cubic(cubic, [1,-1,1], morphism=False)
Elliptic Curve defined by y^2 - 882*x*y - 2560000*y = x^3 - 127281*x^2 over Rational Field
Return an elliptic curve with given \(j\)-invariant.
INPUT:
OUTPUT:
An elliptic curve with \(j\)-invariant \(j\).
EXAMPLES:
sage: E = EllipticCurve_from_j(0); E; E.j_invariant(); E.label()
Elliptic Curve defined by y^2 + y = x^3 over Rational Field
0
'27a3'
sage: E = EllipticCurve_from_j(1728); E; E.j_invariant(); E.label()
Elliptic Curve defined by y^2 = x^3 - x over Rational Field
1728
'32a2'
sage: E = EllipticCurve_from_j(1); E; E.j_invariant()
Elliptic Curve defined by y^2 + x*y = x^3 + 36*x + 3455 over Rational Field
1
The minimal_twist parameter (ignored except over \(\QQ\) and True by default) controls whether or not a minimal twist is computed:
sage: EllipticCurve_from_j(100)
Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field
sage: _.conductor()
33129800
sage: EllipticCurve_from_j(100, minimal_twist=False)
Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field
sage: _.conductor()
298168200
Since computing the minimal twist requires factoring both \(j\) and \(j-1728\) the following example would take a long time without setting minimal_twist to False:
sage: E = EllipticCurve_from_j(2^256+1,minimal_twist=False)
sage: E.j_invariant() == 2^256+1
True
Deprecated way to construct an elliptic curve.
Use Jacobian() instead.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: C = Curve(x^3+y^3+z^3)
sage: P = C(1,-1,0)
sage: E = EllipticCurve_from_plane_curve(C,P); E # long time (3s on sage.math, 2013)
doctest:...: DeprecationWarning: use Jacobian(C) instead
See http://trac.sagemath.org/3416 for details.
Elliptic Curve defined by y^2 = x^3 - 27/4 over Rational Field
Returns a sorted list of all elliptic curves defined over \(Q\) with good reduction outside the set \(S\) of primes.
INPUT:
Note
Proof flag: The algorithm used requires determining all S-integral points on several auxiliary curves, which in turn requires the computation of their generators. This is not always possible (even in theory) using current knowledge.
The value of this flag is passed to the function which computes generators of various auxiliary elliptic curves, in order to find their S-integral points. Set to False if the default (True) causes warning messages, but note that you can then not rely on the set of curves returned being complete.
EXAMPLES:
sage: EllipticCurves_with_good_reduction_outside_S([])
[]
sage: elist = EllipticCurves_with_good_reduction_outside_S([2])
sage: elist
[Elliptic Curve defined by y^2 = x^3 + 4*x over Rational Field,
Elliptic Curve defined by y^2 = x^3 - x over Rational Field,
...
Elliptic Curve defined by y^2 = x^3 - x^2 - 13*x + 21 over Rational Field]
sage: len(elist)
24
sage: ', '.join([e.label() for e in elist])
'32a1, 32a2, 32a3, 32a4, 64a1, 64a2, 64a3, 64a4, 128a1, 128a2, 128b1, 128b2, 128c1, 128c2, 128d1, 128d2, 256a1, 256a2, 256b1, 256b2, 256c1, 256c2, 256d1, 256d2'
Without Proof=False, this example gives two warnings:
sage: elist = EllipticCurves_with_good_reduction_outside_S([11],proof=False) # long time (14s on sage.math, 2011)
sage: len(elist) # long time
12
sage: ', '.join([e.label() for e in elist]) # long time
'11a1, 11a2, 11a3, 121a1, 121a2, 121b1, 121b2, 121c1, 121c2, 121d1, 121d2, 121d3'
sage: elist = EllipticCurves_with_good_reduction_outside_S([2,3]) # long time (26s on sage.math, 2011)
sage: len(elist) # long time
752
sage: max([e.conductor() for e in elist]) # long time
62208
sage: [N.factor() for N in Set([e.conductor() for e in elist])] # long time
[2^7,
2^8,
2^3 * 3^4,
2^2 * 3^3,
2^8 * 3^4,
2^4 * 3^4,
2^3 * 3,
2^7 * 3,
2^3 * 3^5,
3^3,
2^8 * 3,
2^5 * 3^4,
2^4 * 3,
2 * 3^4,
2^2 * 3^2,
2^6 * 3^4,
2^6,
2^7 * 3^2,
2^4 * 3^5,
2^4 * 3^3,
2 * 3^3,
2^6 * 3^3,
2^6 * 3,
2^5,
2^2 * 3^4,
2^3 * 3^2,
2^5 * 3,
2^7 * 3^4,
2^2 * 3^5,
2^8 * 3^2,
2^5 * 3^2,
2^7 * 3^5,
2^8 * 3^5,
2^3 * 3^3,
2^8 * 3^3,
2^5 * 3^5,
2^4 * 3^2,
2 * 3^5,
2^5 * 3^3,
2^6 * 3^5,
2^7 * 3^3,
3^5,
2^6 * 3^2]
Test whether P and Q are projectively equivalent.
INPUT:
OUTPUT:
Boolean.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.constructor import are_projectively_equivalent
sage: are_projectively_equivalent([0,1,2,3], [0,1,2,2], base_ring=QQ)
False
sage: are_projectively_equivalent([0,1,2,3], [0,2,4,6], base_ring=QQ)
True
Use the chord and tangent method to get another point on a cubic.
INPUT:
OUTPUT:
Another point satisfying the equation F.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: from sage.schemes.elliptic_curves.constructor import chord_and_tangent
sage: F = x^3+y^3+60*z^3
sage: chord_and_tangent(F, [1,-1,0])
[1, -1, 0]
sage: F = x^3+7*y^3+64*z^3
sage: p0 = [2,2,-1]
sage: p1 = chord_and_tangent(F, p0); p1
[-5, 3, -1]
sage: p2 = chord_and_tangent(F, p1); p2
[1265, -183, -314]
TESTS:
sage: F(p2)
0
sage: map(type, p2)
[<type 'sage.rings.rational.Rational'>,
<type 'sage.rings.rational.Rational'>,
<type 'sage.rings.rational.Rational'>]
See trac ticket #16068:
sage: F = x**3 - 4*x**2*y - 65*x*y**2 + 3*x*y*z - 76*y*z**2
sage: chord_and_tangent(F, [0, 1, 0])
[0, 0, -1]
Return equivalent point with denominators removed
INPUT:
OUTPUT:
List of projective coordinates.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.constructor import projective_point
sage: projective_point([4/5, 6/5, 8/5])
[2, 3, 4]
sage: F = GF(11)
sage: projective_point([F(4), F(8), F(2)])
[4, 8, 2]