Module: sage.schemes.elliptic_curves.ell_generic
Elliptic curves over a general ring
Elliptic curves are always represented by `Weierstass Models' with
five coefficients
in standard notation. In
Magma, `Weierstrass Model' means a model with a1=a2=a3=0, which is
called `Short Weierstrass Model' in Sage; these only exist in
characteristics other than 2 and 3.
We construct an elliptic curve over an elaborate base ring:
sage: p = 97; a=1; b=3 sage: R, u = PolynomialRing(GF(p), 'u').objgen() sage: S, v = PolynomialRing(R, 'v').objgen() 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
Author Log:
Module-level Functions
q, [genus=1]) |
Return the Hasse bounds (lb,ub) for the cardinality of a curve of genus g (default 1) defined over GF(q)
sage: Hasse_bounds(2) (1, 5) sage: Hasse_bounds(next_prime(10^30)) (999999999999998000000000000058, 1000000000000002000000000000058)
x) |
sage: E = EllipticCurve([1,2,3/4,7,19]) sage: is_EllipticCurve(E) True sage: is_EllipticCurve(0) False
Class: EllipticCurve_generic
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)
self, ainvs, [extra=None]) |
Constructor from [a1,a2,a3,a4,a6] or [a4,a6] (see constructor.py for more variants)
sage: E = EllipticCurve([1,2,3,4,5]); E Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field sage: E = EllipticCurve(GF(7),[1,2,3,4,5]); E Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 7
Constructor from [a4,a6] sets a1=a2=a3=0:
sage: EllipticCurve([4,5]).ainvs() [0, 0, 0, 4, 5]
Base need not be a field:
sage: EllipticCurve(IntegerModRing(91),[1,2,3,4,5]) Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Ring of integers modulo 91
Functions: a1,
a2,
a3,
a4,
a6,
a_invariants,
ainvs,
automorphisms,
b2,
b4,
b6,
b8,
b_invariants,
base_extend,
base_field,
base_ring,
c4,
c6,
c_invariants,
change_ring,
change_weierstrass_model,
discriminant,
division_polynomial,
formal,
formal_group,
full_division_polynomial,
gen,
gens,
hyperelliptic_polynomials,
is_isomorphic,
is_on_curve,
isomorphism_to,
isomorphisms,
j_invariant,
lift_x,
multiplication_by_m,
plot,
quadratic_twist,
quartic_twist,
rst_transform,
scale_curve,
sextic_twist,
short_weierstrass_model,
torsion_polynomial
self) |
sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a1() 1
self) |
sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a2() 2
self) |
sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a3() 3
self) |
sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a4() 4
self) |
sage: E = EllipticCurve([1,2,3,4,6]) sage: E.a6() 6
self) |
The a-invariants of this elliptic curve.
sage: E = EllipticCurve([1,2,3,4,5]) sage: E.a_invariants() [1, 2, 3, 4, 5] sage: E = EllipticCurve([0,1]) sage: 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]
self) |
The a-invariants of this elliptic curve.
sage: E = EllipticCurve([1,2,3,4,5]) sage: E.a_invariants() [1, 2, 3, 4, 5] sage: E = EllipticCurve([0,1]) sage: 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]
self, [field=None]) |
Return the set of isomorphisms from self to itself (as a list).
sage: E = EllipticCurve(QQ(0)) # a curve with j=0 over QQ sage: E.automorphisms(); [Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 = x^3 +1 over Rational Field Via: (u,r,s,t) = (-1, 0, 0, 0), Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 = x^3 +1 over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0)]
We can also find automorphisms defined over extension fields:
sage: K.<a> = NumberField(x^2+3) # adjoin roots of unity sage: E.automorphisms(K) [Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 = x^3 +1 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (1, 0, 0, 0), ... Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 = x^3 +1 over Number Field in a with defining polynomial x^2 + 3 Via: (u,r,s,t) = (-1/2*a - 1/2, 0, 0, 0)]
sage: [ len(EllipticCurve(GF(q,'a')(0)).automorphisms()) for q in [2,4,3,9,5,25,7,49]] [2, 24, 2, 12, 2, 6, 6, 6]
self) |
sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b2() 9
self) |
sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b4() 11
self) |
sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b6() 29
self) |
sage: E = EllipticCurve([1,2,3,4,5]) sage: E.b8() 35
self) |
The b-invariants of this elliptic curve.
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
ALGORITHM: These are simple functions of the a invariants.
Author: William Stein, 2005-04-25
self, R) |
Returns a new curve with the same a-invariants but defined over a new ring into which the original's a-invariants may be mapped. R is either a ring into which they may be coerced, or a morphism which may be applied to them.
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 Elliptic Curve defined by y^2 = x^3 + x +1 over Finite Field in a of size 5^3 sage: F2=GF(5^2,'a'); a=F2.gen() sage: F4=GF(5^4,'b'); b=F4.gen() sage: h=F2.hom([a.charpoly().roots(ring=F4,multiplicities=False)[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.base_extend(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
self) |
Returns the base ring of the elliptic curves.
sage: E = EllipticCurve(GF(49, 'a'), [3,5]) sage: E.base_ring() Finite Field in a of size 7^2
sage: E = EllipticCurve([1,1]) sage: E.base_ring() Rational Field
self) |
Returns the base ring of the elliptic curves.
sage: E = EllipticCurve(GF(49, 'a'), [3,5]) sage: E.base_ring() Finite Field in a of size 7^2
sage: E = EllipticCurve([1,1]) sage: E.base_ring() Rational Field
self) |
sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.c4() 496
self) |
sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.c6() 20008
self) |
The c-invariants of this elliptic curve.
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)
ALGORITHM: These are simple functions of the b invariants.
Author: William Stein, 2005-04-25
self, R) |
Return the elliptic curve defined by coercing the a-invariants of this elliptic curve into the ring R.
Input:
sage: E = EllipticCurve([0, 0, 1, -1, 0]) sage: E.change_ring(GF(3)) Elliptic Curve defined by y^2 + y = x^3 + 2*x over Finite Field of size 3
self) |
Return a new Weierstrass model of self under the transformation (on points)
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
self) |
Returns the discriminant of this elliptic curve.
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
self, n, [var=x], [i=0]) |
Returns the n-th torsion polynomial (a.k.a., division polynomial).
Input:
SEE ALSO: full_division_polynomial
ALIASES: division_polynomial, torsion_polynomial
sage: E = EllipticCurve([0,0,1,-1,0]) sage: E.division_polynomial(1) 1 sage: E.division_polynomial(2) 4*x^3 - 4*x + 1 sage: E.division_polynomial(3, 'z') 3*z^4 - 6*z^2 + 3*z - 1
sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.torsion_polynomial(0) 0 sage: E.torsion_polynomial(1) 1 sage: E.torsion_polynomial(2) 4*x^3 - 4*x^2 - 40*x - 79 sage: E.torsion_polynomial(3) 3*x^4 - 4*x^3 - 60*x^2 - 237*x - 21 sage: E.torsion_polynomial(4) 8*x^9 - 24*x^8 - 464*x^7 - 2758*x^6 + 6636*x^5 + 34356*x^4 + 53510*x^3 + 99714*x^2 + 351024*x + 459859
sage: E = EllipticCurve([-4,0]) sage: E.torsion_polynomial(2) 4*x^3 - 16*x sage: E.torsion_polynomial(5) 5*x^12 - 248*x^10 - 1680*x^8 + 19200*x^6 - 32000*x^4 + 51200*x^2 + 4096 sage: E.torsion_polynomial(6) 12*x^19 - 1200*x^17 - 18688*x^15 + 422912*x^13 - 2283520*x^11 + 9134080*x^9 - 27066368*x^7 + 19136512*x^5 + 19660800*x^3 - 3145728*x
Author: David Kohel (kohel@maths.usyd.edu.au), 2005-04-25
self) |
The formal group associated to this elliptic curve.
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
self) |
The formal group associated to this elliptic curve.
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
self, m, [use_divpoly=True]) |
Return the
-th bivariate division polynomial in
and
. When
is odd this is exactly the same as the usual
th division polynomial.
For the usual division polynomial only in
, see the
division_polynomial function.
Input:
NOTE: The result is cached.
REFERENCE: Exercise III.3.7 of Silverman AEC 1, 1986, page 105.
We create a curve and compute the first two full division polynomials.
sage: E = EllipticCurve([2,3]) sage: E.full_division_polynomial(1) 1 sage: E.full_division_polynomial(2) 2*y
Note that for odd input the full division polynomial is just the usual division polynomial, but not for even input:
sage: E.division_polynomial(2) 4*x^3 + 8*x + 12 sage: E.full_division_polynomial(3) 3*x^4 + 12*x^2 + 36*x - 4 sage: E.division_polynomial(3) 3*x^4 + 12*x^2 + 36*x - 4 sage: E.full_division_polynomial(4) 4*y*x^6 + 40*y*x^4 + 240*y*x^3 - 80*y*x^2 - 96*y*x - 320*y sage: E.full_division_polynomial(5) 5*x^12 + 124*x^10 + 1140*x^9 - 420*x^8 + 1440*x^7 - 4560*x^6 - 8352*x^5 - 36560*x^4 - 45120*x^3 - 10240*x^2 - 39360*x - 22976
TESTS:
We test that the full division polynomial as computed using
the recurrence agrees with the norml division polynomial for
a certain curve and all odd
up to
:
sage: E = EllipticCurve([23,-105]) sage: for n in [1,3,..,23]: ... assert E.full_division_polynomial(n, use_divpoly=False) == E.division_polynomial(n)
self, i) |
Function returning the i'th generator of this elliptic curve. Relies on gens() being implemented.
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.
self) |
Placeholder function to return generators of an elliptic curve: derived classes such as EllipticCurve_rational_field implement this functionality
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)]
self) |
.
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)
self, other, [field=None]) |
Returns whether or not self is isomorphic to other, i.e. they define the same curve over the same basering.
If field!=None then both curves must base_extend-able to it and the isomorphism is then checked over that field
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
self, x, y) |
Returns True if the (x,y) is an affine point on this curve.
sage: E=EllipticCurve(QQ,[1,1]) sage: E.is_on_curve(0,1) True sage: E.is_on_curve(1,1) False
self, other) |
Given another weierstrass model other
of self, return a morphism
from self to other
.
If the curves in question are not isomorphic, raise a ValueError
sage: E = EllipticCurve('37a') sage: F = E.short_weierstrass_model() sage: w = E.isomorphism_to(F); w Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field To: Abelian group of points on 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
We can also handle injections to different base rings:
sage: K.<a> = NumberField(x^3-7) sage: E.isomorphism_to(E.change_ring(K)) Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field To: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in a with defining polynomial x^3 - 7 Via: (u,r,s,t) = (1, 0, 0, 0)
self, other, [field=None]) |
Return the set of isomorphisms from self to other (as a list).
sage: E = EllipticCurve(QQ(0)) # a curve with j=0 over QQ sage: F = EllipticCurve('36a1') # should be the same one sage: E.isomorphisms(F); [Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 = x^3 +1 over Rational Field To: Abelian group of points on Elliptic Curve defined by y^2 = x^3 +1 over Rational Field Via: (u,r,s,t) = (-1, 0, 0, 0), Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 = x^3 +1 over Rational Field To: Abelian group of points on Elliptic Curve defined by y^2 = x^3 +1 over Rational Field Via: (u,r,s,t) = (1, 0, 0, 0)]
We can also find istomorphisms defined over extension fields:
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')) [Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x +1 over Finite Field in a of size 7^2 To: Abelian group of points on 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), Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x +1 over Finite Field in a of size 7^2 To: Abelian group of points on 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)]
self) |
Returns the j-invariant of this elliptic curve.
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
self, x, [all=False]) |
Given the x-coordinate of a point on the curve, use the defining polynomial to find all affine points on this curve with the given x-coordinate.
sage: E = EllipticCurve('37a'); E Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field sage: E.lift_x(1) (1 : 0 : 1) sage: E.lift_x(2) (2 : 2 : 1) sage: E.lift_x(1/4, all=True) [(1/4 : -3/8 : 1), (1/4 : -5/8 : 1)]
There are no rational points with x-cordinate 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
However, there are two such points in
:
sage: E.change_ring(RR).lift_x(3, all=True) [(3.00000000000000 : 4.42442890089805 : 1.00000000000000), (3.00000000000000 : -5.42442890089805 : 1.00000000000000)]
And of course it always works in
:
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)
We can perform these operations over finite fields too:
sage: E = E.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 : 11 : 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
Note that there is only one lift with x-coordinate 10 in
.
sage: E.lift_x(10, all=True) [(10 : 8 : 1)]
We can lift over more exotic rings too.
sage: E = EllipticCurve('37a'); sage: E.lift_x(pAdicField(17, 5)(6)) (6 + O(17^5) : 2 + 16*17 + 16*17^2 + 16*17^3 + 16*17^4 + O(17^5) : 1 + O(17^5)) sage: K.<t> = PowerSeriesRing(QQ, 't', 5) sage: E.lift_x(1+t) (1 + t : 2*t - t^2 + 5*t^3 - 21*t^4 + O(t^5) : 1) sage: K.<a> = GF(16) sage: E = E.change_ring(K) sage: E.lift_x(a^3) (a^3 : a^3 + a : 1)
Author: Robert Bradshaw, 2007-04-24
TEST:
sage: E = EllipticCurve('37a').short_weierstrass_model().change_ring(GF(17)) sage: E.lift_x(3, all=True) [] sage: E.lift_x(7, all=True) [(7 : 3 : 1), (7 : 14 : 1)]
self, m, [x_only=False]) |
Return the multiplication-by-m map from self to self as a rational function.
Input:
NOTE: The result is not cached.
We create an elliptic curve.
sage: E = EllipticCurve([-1,3])
We verify that multiplication by 1 is just the identity:
sage: E.multiplication_by_m(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), (2*x^6 - 10*x^4 + 120*x^3 - 10*x^2 + 24*x - 142)/(16*y*x^3 - 16*y*x + 48*y))
Grab only the x-coordinate (less work):
sage: E.multiplication_by_m(2, x_only=True) (x^4 + 2*x^2 - 24*x + 1)/(4*x^3 - 4*x + 12)
We check that it works on a point:
sage: P = E([2,3]) sage: f[0].subs(x=2,y=3) -23/36 sage: f[1].subs(x=2,y=3) 397/216 sage: 2*P (-23/36 : 397/216 : 1)
We do the same but with multiplication by 3:
sage: f = E.multiplication_by_m(3) sage: f[0].subs(x=2,y=3) -10534/9025 sage: f[1].subs(x=2,y=3) -1376361/857375 sage: 3*P (-10534/9025 : -1376361/857375 : 1)
And the same with multiplication by 4:
sage: f = E.multiplication_by_m(4) sage: f[0].subs(x=2,y=3) 29084737/22695696 sage: f[1].subs(x=2,y=3) -211407941663/108122295744 sage: 4*P (29084737/22695696 : -211407941663/108122295744 : 1)
TESTS: Verify for this fairly random looking curve and point that multiplication by m returns the right result for the first 10 integers.
sage: E = EllipticCurve([23,-105]) sage: P = E([129/4, 1479/8]) sage: for n in [1..10]: ... f = E.multiplication_by_m(n) ... Q = n*P ... assert f[0].subs(x=P[0],y=P[1]) == Q[0] and f[1].subs(x=P[0],y=P[1]) == Q[1]
self, [xmin=None], [xmax=None]) |
Draw a graph of this elliptic curve.
Input:
sage: E = EllipticCurve([0,-1]) sage: plot(E, rgbcolor=hue(0.7))
self, D) |
Return the quadratic twist of this curve by D, which must be nonzero except in characteristic 2.
In characteristic!=2, D must be nonzero, and the twist is isomorphic to self after adjoining sqrt(D) to the base
In characteristic==2, D is arbitrary, and the twist is
isomorphic to self after adjoining a root of
to the
base
In characteristics 2 when j==0 this is not implemented (the twists are more complicated than quadratic!)
sage: E = EllipticCurve([GF(1103)(1), 0, 0, 107, 340]); E Elliptic Curve defined by y^2 + x*y = x^3 + 107*x + 340 over Finite Field of size 1103 sage: F=E.quadratic_twist(-1); F Elliptic Curve defined by y^2 = x^3 + 1102*x^2 + 609*x + 300 over Finite Field of size 1103 sage: E.is_isomorphic(F) False sage: E.is_isomorphic(F,GF(1103^2,'a')) True
A characteristic 2 example:
sage: E=EllipticCurve(GF(2),[1,0,1,1,1]) sage: E1=E.quadratic_twist(1) sage: E.is_isomorphic(E1) False sage: E.is_isomorphic(E1,GF(4,'a')) True
self, D) |
Return the quartic twist of this curve by D, which must be nonzero.
The characteristic must not be 2 or 3 and the j-invariant must be 1728
sage: E=EllipticCurve(GF(13)(1728)); E Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 13 sage: E1=E.quartic_twist(2); E1 Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 13 sage: E.is_isomorphic(E1) False sage: E.is_isomorphic(E1,GF(13^2,'a')) False sage: E.is_isomorphic(E1,GF(13^4,'a')) True
self, r, s, t) |
Transforms the elliptic curve using the unimodular (u=1) transform with standard parameters [r,s,t]. This is just a special case of change_weierstrass_model().
Returns the transformed curve.
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
self, u) |
Transforms the elliptic curve using scale factor
,
i.e. multiplies
by
. This is another
special case of change_weierstrass_model().
Returns the transformed curve.
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
self, D) |
Return the sextic twist of this curve by D, which must be nonzero.
The characteristic must not be 2 or 3 and the j-invariant must be 0
sage: E=EllipticCurve(GF(13)(0)); E Elliptic Curve defined by y^2 = x^3 +1 over Finite Field of size 13 sage: E1=E.sextic_twist(2); E1 Elliptic Curve defined by y^2 = x^3 + 11 over Finite Field of size 13 sage: E.is_isomorphic(E1) False sage: E.is_isomorphic(E1,GF(13^2,'a')) False sage: E.is_isomorphic(E1,GF(13^4,'a')) False sage: E.is_isomorphic(E1,GF(13^6,'a')) True
self, [complete_cube=True]) |
Return a short Weierstrass model for self.
Input:
If complete_cube=True:
Return a model of the form
for this curve.
The characteristic must not be 2 or 3.
a,b = -27*c4, -54*c6
If complete_cube=False:
Return a model of the form
for this curve.
The characteristic must not be 2.
a,b,c = b2, 8*b4, 16*b6
sage: E = EllipticCurve([1,2,3,4,5]) sage: print 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: print 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: print F Elliptic Curve defined by y^2 = x^3 + 9*x^2 + 88*x + 464 over Rational Field sage: print 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 sage: E.short_weierstrass_model() Traceback (most recent call last): ... ValueError: short_weierstrass_model(): no short model for Elliptic Curve defined by y^2 + x*y = x^3 + 2*x^2 + x + 2 over Finite Field of size 3 (characteristic is 3)
self, n, [var=x], [i=0]) |
Returns the n-th torsion polynomial (a.k.a., division polynomial).
Input:
SEE ALSO: full_division_polynomial
ALIASES: division_polynomial, torsion_polynomial
sage: E = EllipticCurve([0,0,1,-1,0]) sage: E.division_polynomial(1) 1 sage: E.division_polynomial(2) 4*x^3 - 4*x + 1 sage: E.division_polynomial(3, 'z') 3*z^4 - 6*z^2 + 3*z - 1
sage: E = EllipticCurve([0, -1, 1, -10, -20]) sage: E.torsion_polynomial(0) 0 sage: E.torsion_polynomial(1) 1 sage: E.torsion_polynomial(2) 4*x^3 - 4*x^2 - 40*x - 79 sage: E.torsion_polynomial(3) 3*x^4 - 4*x^3 - 60*x^2 - 237*x - 21 sage: E.torsion_polynomial(4) 8*x^9 - 24*x^8 - 464*x^7 - 2758*x^6 + 6636*x^5 + 34356*x^4 + 53510*x^3 + 99714*x^2 + 351024*x + 459859
sage: E = EllipticCurve([-4,0]) sage: E.torsion_polynomial(2) 4*x^3 - 16*x sage: E.torsion_polynomial(5) 5*x^12 - 248*x^10 - 1680*x^8 + 19200*x^6 - 32000*x^4 + 51200*x^2 + 4096 sage: E.torsion_polynomial(6) 12*x^19 - 1200*x^17 - 18688*x^15 + 422912*x^13 - 2283520*x^11 + 9134080*x^9 - 27066368*x^7 + 19136512*x^5 + 19660800*x^3 - 3145728*x
Author: David Kohel (kohel@maths.usyd.edu.au), 2005-04-25
Special Functions: __call__,
__cmp__,
__contains__,
__getitem__,
__init__,
_defining_params_,
_EllipticCurve_generic__is_over_RationalField,
_homset_class,
_latex_,
_magma_init_,
_pari_init_,
_repr_,
_symbolic_
self) |
sage: E = EllipticCurve([0, 0, 1, -1, 0])
The point at infinity, which is the 0 element of the group:
sage: E(0) (0 : 1 : 0)
The origin is a point on our curve:
sage: P = E([0,0]) sage: P (0 : 0 : 1)
The curve associated to a point:
sage: P.curve() Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
Points can be specified by given a 2-tuple or 3-tuple
sage: E([0,0]) (0 : 0 : 1) sage: E([0,1,0]) (0 : 1 : 0)
Over a field, points are normalized so the right-most nonzero entry is 1:
sage: E(105, -69, 125) (21/25 : -69/125 : 1)
We create points on an elliptic curve over a prime finite field.
sage: E = EllipticCurve([GF(7)(0), 1]) sage: E([2,3]) (2 : 3 : 1) sage: E([0,0]) Traceback (most recent call last): ... TypeError: coordinates [0, 0, 1] do not define a point on Elliptic Curve defined by y^2 = x^3 +1 over Finite Field of size 7
We create a point on an elliptic curve over a number field.
sage: x = polygen(RationalField()) sage: K = NumberField(x**3 + x + 1, 'a'); a = K.gen() sage: E = EllipticCurve([a,a]) sage: E Elliptic Curve defined by y^2 = x^3 + a*x + a over Number Field in a with defining polynomial x^3 + x + 1 sage: E = EllipticCurve([K(1),1]) sage: E Elliptic Curve defined by y^2 = x^3 + x +1 over Number Field in a with defining polynomial x^3 + x + 1 sage: P = E([a,0,1]) sage: P (a : 0 : 1) sage: P+P (0 : 1 : 0)
Another example involving p-adics:
sage: E = EllipticCurve('37a1') sage: P = E([0,0]); P (0 : 0 : 1) sage: R = pAdicField(3,20) sage: Ep = E.base_extend(R); Ep Elliptic Curve defined by y^2 + (1+O(3^20))*y = x^3 + (2+2*3+2*3^2+2*3^3+2*3^4+2*3^5+2*3^6+2*3^7+2*3^8+2*3^9+2*3^10+2*3^11+2*3^12 +2*3^13+2*3^14+2*3^15+2*3^16+2*3^17+2*3^18+2*3^19+O(3^20))*x over 3-adic Field with capped relative precision 20 sage: Ep(P) (0 : 0 : 1 + O(3^20))
self, other) |
Standard comparison function for elliptic curves, to allow sorting and equality testing.
sage: E=EllipticCurve(QQ,[1,1]) sage: F=EllipticCurve(QQ,[0,0,0,1,1]) sage: E==F True
self, P) |
Returns True if and only if P defines is a point on the elliptic curve. P just has to be something that can be coerced to a point.
sage: E = EllipticCurve([0, 0, 1, -1, 0]) sage: (0,0) in E True sage: (1,3) in E False sage: E = EllipticCurve([GF(7)(0), 1]) sage: [0,0] in E False sage: [0,8] in E True sage: P = E(0,8) sage: P (0 : 1 : 1) sage: P in E True
self, n) |
Placeholder for standard indexing function.
sage: E=EllipticCurve(QQ,[1,1]) sage: E[2] Traceback (most recent call last): ... NotImplementedError: not implemented.
self) |
Internal function. Returns a tuple of the base ring of this elliptic curve and its a-invariants, from which it can be reconstructed.
sage: E=EllipticCurve(QQ,[1,1]) sage: E._defining_params_() (Rational Field, [0, 0, 0, 1, 1]) sage: EllipticCurve(*E._defining_params_()) == E True
self) |
Internal function. Returns true iff the base ring of this elliptic curve is the field of rational numbers.
sage: E=EllipticCurve(QQ,[1,1]) sage: E._EllipticCurve_generic__is_over_RationalField() True sage: E=EllipticCurve(GF(5),[1,1]) sage: E._EllipticCurve_generic__is_over_RationalField() False
self) |
Internal function. Returns the (abstract) group of points on this elliptic curve over a ring.
sage: E=EllipticCurve(GF(5),[1,1]) sage: E._homset_class(GF(5^10,'a'),GF(5)) Abelian group of points on Finite Field in a of size 5^10
self) |
Internal function. Returns a latex string for this elliptic curve. Users will normally use latex() instead.
sage: E=EllipticCurve(QQ,[1,1]) sage: E._latex_() 'y^2 = x^3 + x +1 ' sage: latex(E) y^2 = x^3 + x +1
self) |
Internal function. Returns a string to initialize this elliptic curve in the Magma subsystem.
sage: E=EllipticCurve(QQ,[1,1]) sage: E._magma_init_() 'EllipticCurve([0/1,0/1,0/1,1/1,1/1])'
self) |
Internal function. Returns a string to initialize this elliptic curve in the pari system.
sage: E=EllipticCurve(QQ,[1,1]) sage: E._pari_init_() 'ellinit([0/1,0/1,0/1,1/1,1/1])'
self) |
String representation of elliptic curve.
sage: EllipticCurve([1,2,3,4,5]) Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
sage: R.<x> = QQ['x'] sage: K.<a> = NumberField(x^3-17) sage: EllipticCurve([a^2-3, -2/3*a + 3]) Elliptic Curve defined by y^2 = x^3 + (a^2-3)*x + (-2/3*a+3) over Number Field in a with defining polynomial x^3 - 17
self, SR) |
Many elliptic curves can be converted into a symbolic expression
using the symbolic_expression
command.
We find a torsion point on 11a.
sage: E = EllipticCurve('11a') sage: E.torsion_subgroup().gens() ((5 : 5 : 1),)
We find the corresponding symbolic equality:
sage: eqn = symbolic_expression(E); eqn y^2 + y == x^3 - x^2 - 10*x - 20 sage: print eqn 2 3 2 y + y == x - x - 10 x - 20
We verify that the given point is on the curve:
sage: eqn(x=5,y=5) 30 == 30 sage: bool(eqn(x=5,y=5)) True
We create a single expression:
sage: F = eqn.lhs() - eqn.rhs(); print F 2 3 2 y + y - x + x + 10 x + 20 sage: y = var('y') sage: print F.solve(y) [ 3 2 - sqrt(4 x - 4 x - 40 x - 79) - 1 y == ----------------------------------- 2, 3 2 sqrt(4 x - 4 x - 40 x - 79) - 1 y == --------------------------------- 2 ]
You can also solve for x in terms of y, but the result is horrendous. Continuing with the above example, we can explicitly find points over random fields by substituting in values for x:
sage: v = F.solve(y)[0].rhs() sage: print v 3 2 - sqrt(4 x - 4 x - 40 x - 79) - 1 ----------------------------------- 2 sage: v(3) (-sqrt(127)*I - 1)/2 sage: v(7) (-sqrt(817) - 1)/2 sage: v(-7) (-sqrt(1367)*I - 1)/2 sage: v(sqrt(2)) (-sqrt(-32*sqrt(2) - 87) - 1)/2
We can even do arithmetic with them, as follows:
sage: E2 = E.change_ring(SR); E2 Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Symbolic Ring sage: P = E2.point((3, v(3), 1), check=False) sage: P (3 : (-sqrt(127)*I - 1)/2 : 1) sage: P + P (-756/127 : (sqrt(127)*I + 1)/2 + 12507*I/(127*sqrt(127)) - 1 : 1)
We can even throw in a transcendental:
sage: w = E2.point((pi,v(pi),1), check=False); w (pi : (-sqrt(4*pi^3 - 4*pi^2 - 40*pi - 79) - 1)/2 : 1) sage: 2*w ((3*pi^2 - 2*pi - 10)^2/(4*pi^3 - 4*pi^2 - 40*pi - 79) - 2*pi + 1 : (sqrt(4*pi^3 - 4*pi^2 - 40*pi - 79) + 1)/2 - (3*pi^2 - 2*pi - 10)*(-(3*pi^2 - 2*pi - 10)^2/(4*pi^3 - 4*pi^2 - 40*pi - 79) + 3*pi - 1)/sqrt(4*pi^3 - 4*pi^2 - 40*pi - 79) - 1 : 1)