Galois representations attached to elliptic curves¶
Given an elliptic curve \(E\) over \(\QQ\) and a rational prime number \(p\), the \(p^n\)-torsion \(E[p^n]\) points of \(E\) is a representation of the absolute Galois group \(G_{\QQ}\) of \(\QQ\). As \(n\) varies we obtain the Tate module \(T_p E\) which is a a representation of \(G_\QQ\) on a free \(\ZZ_p\)-module of rank \(2\). As \(p\) varies the representations are compatible.
Currently sage can decide whether the Galois module \(E[p]\) is reducible, i.e., if \(E\) admits an isogeny of degree \(p\), and whether the image of the representation on \(E[p]\) is surjective onto \(\text{Aut}(E[p]) = GL_2(\GF{p})\).
The following are the most useful functions for the class GaloisRepresentation
.
For the reducibility:
is_reducible(p)
is_irreducible(p)
reducible_primes()
For the image:
is_surjective(p)
non_surjective()
image_type(p)
For the classification of the representation
is_semistable(p)
is_unramified(p, ell)
is_crystalline(p)
EXAMPLES:
sage: E = EllipticCurve('196a1')
sage: rho = E.galois_representation()
sage: rho.is_irreducible(7)
True
sage: rho.is_reducible(3)
True
sage: rho.is_irreducible(2)
True
sage: rho.is_surjective(2)
False
sage: rho.is_surjective(3)
False
sage: rho.is_surjective(5)
True
sage: rho.reducible_primes()
[3]
sage: rho.non_surjective()
[2, 3]
sage: rho.image_type(2)
'The image is cyclic of order 3.'
sage: rho.image_type(3)
'The image is contained in a Borel subgroup as there is a 3-isogeny.'
sage: rho.image_type(5)
'The image is all of GL_2(F_5).'
>>> from sage.all import *
>>> E = EllipticCurve('196a1')
>>> rho = E.galois_representation()
>>> rho.is_irreducible(Integer(7))
True
>>> rho.is_reducible(Integer(3))
True
>>> rho.is_irreducible(Integer(2))
True
>>> rho.is_surjective(Integer(2))
False
>>> rho.is_surjective(Integer(3))
False
>>> rho.is_surjective(Integer(5))
True
>>> rho.reducible_primes()
[3]
>>> rho.non_surjective()
[2, 3]
>>> rho.image_type(Integer(2))
'The image is cyclic of order 3.'
>>> rho.image_type(Integer(3))
'The image is contained in a Borel subgroup as there is a 3-isogeny.'
>>> rho.image_type(Integer(5))
'The image is all of GL_2(F_5).'
E = EllipticCurve('196a1') rho = E.galois_representation() rho.is_irreducible(7) rho.is_reducible(3) rho.is_irreducible(2) rho.is_surjective(2) rho.is_surjective(3) rho.is_surjective(5) rho.reducible_primes() rho.non_surjective() rho.image_type(2) rho.image_type(3) rho.image_type(5)
For semi-stable curve it is known that the representation is surjective if and only if it is irreducible:
sage: E = EllipticCurve('11a1')
sage: rho = E.galois_representation()
sage: rho.non_surjective()
[5]
sage: rho.reducible_primes()
[5]
>>> from sage.all import *
>>> E = EllipticCurve('11a1')
>>> rho = E.galois_representation()
>>> rho.non_surjective()
[5]
>>> rho.reducible_primes()
[5]
E = EllipticCurve('11a1') rho = E.galois_representation() rho.non_surjective() rho.reducible_primes()
For cm curves it is not true that there are only finitely many primes for which the Galois representation mod p is surjective onto \(GL_2(\GF{p})\):
sage: E = EllipticCurve('27a1')
sage: rho = E.galois_representation()
sage: rho.non_surjective()
[0]
sage: rho.reducible_primes()
[3]
sage: E.has_cm()
True
sage: rho.image_type(11)
'The image is contained in the normalizer of a non-split Cartan group. (cm)'
>>> from sage.all import *
>>> E = EllipticCurve('27a1')
>>> rho = E.galois_representation()
>>> rho.non_surjective()
[0]
>>> rho.reducible_primes()
[3]
>>> E.has_cm()
True
>>> rho.image_type(Integer(11))
'The image is contained in the normalizer of a non-split Cartan group. (cm)'
E = EllipticCurve('27a1') rho = E.galois_representation() rho.non_surjective() rho.reducible_primes() E.has_cm() rho.image_type(11)
REFERENCES:
AUTHORS:
chris wuthrich (02/10): moved from ell_rational_field.py.
- class sage.schemes.elliptic_curves.gal_reps.GaloisRepresentation(E)[source]¶
Bases:
SageObject
The compatible family of Galois representation attached to an elliptic curve over the rational numbers.
Given an elliptic curve \(E\) over \(\QQ\) and a rational prime number \(p\), the \(p^n\)-torsion \(E[p^n]\) points of \(E\) is a representation of the absolute Galois group. As \(n\) varies we obtain the Tate module \(T_p E\) which is a representation of the absolute Galois group on a free \(\ZZ_p\)-module of rank \(2\). As \(p\) varies the representations are compatible.
EXAMPLES:
sage: rho = EllipticCurve('11a1').galois_representation() sage: rho Compatible family of Galois representations associated to the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
>>> from sage.all import * >>> rho = EllipticCurve('11a1').galois_representation() >>> rho Compatible family of Galois representations associated to the Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
rho = EllipticCurve('11a1').galois_representation() rho
- elliptic_curve()[source]¶
The elliptic curve associated to this representation.
EXAMPLES:
sage: E = EllipticCurve('11a1') sage: rho = E.galois_representation() sage: rho.elliptic_curve() == E True
>>> from sage.all import * >>> E = EllipticCurve('11a1') >>> rho = E.galois_representation() >>> rho.elliptic_curve() == E True
E = EllipticCurve('11a1') rho = E.galois_representation() rho.elliptic_curve() == E
- image_classes(p, bound=10000)[source]¶
This function returns, given the representation \(\rho\) a list of \(p\) values that add up to 1, representing the frequency of the conjugacy classes of the projective image of \(\rho\) in \(PGL_2(\GF{p})\).
Let \(M\) be a matrix in \(GL_2(\GF{p})\), then define \(u(M) = \text{tr}(M)^2/\det(M)\), which only depends on the conjugacy class of \(M\) in \(PGL_2(\GF{p})\). Hence this defines a map \(u: PGL_2(\GF{p}) \to \GF{p}\), which is almost a bijection between conjugacy classes of the source and \(\GF{p}\) (the elements of order \(p\) and the identity map to \(4\) and both classes of elements of order 2 map to 0).
This function returns the frequency with which the values of \(u\) appeared among the images of the Frobenius elements \(a_{\ell}`at `\ell\) for good primes \(\ell\neq p\) below a given
bound
.INPUT:
p
– a primebound
– a natural number (default: 10000)
OUTPUT: list of \(p\) real numbers in the interval \([0,1]\) adding up to 1
EXAMPLES:
sage: E = EllipticCurve('14a1') sage: rho = E.galois_representation() sage: rho.image_classes(5) [0.2095, 0.1516, 0.2445, 0.1728, 0.2217] sage: E = EllipticCurve('11a1') sage: rho = E.galois_representation() sage: rho.image_classes(5) [0.2467, 0.0000, 0.5049, 0.0000, 0.2484]
>>> from sage.all import * >>> E = EllipticCurve('14a1') >>> rho = E.galois_representation() >>> rho.image_classes(Integer(5)) [0.2095, 0.1516, 0.2445, 0.1728, 0.2217] >>> E = EllipticCurve('11a1') >>> rho = E.galois_representation() >>> rho.image_classes(Integer(5)) [0.2467, 0.0000, 0.5049, 0.0000, 0.2484]
E = EllipticCurve('14a1') rho = E.galois_representation() rho.image_classes(5) E = EllipticCurve('11a1') rho = E.galois_representation() rho.image_classes(5)
sage: EllipticCurve('27a1').galois_representation().image_classes(5) [0.5839, 0.1645, 0.0000, 0.1702, 0.08143] sage: EllipticCurve('30a1').galois_representation().image_classes(5) [0.1956, 0.1801, 0.2543, 0.1728, 0.1972] sage: EllipticCurve('32a1').galois_representation().image_classes(5) [0.6319, 0.0000, 0.2492, 0.0000, 0.1189] sage: EllipticCurve('900a1').galois_representation().image_classes(5) [0.5852, 0.1679, 0.0000, 0.1687, 0.07824] sage: EllipticCurve('441a1').galois_representation().image_classes(5) [0.5860, 0.1646, 0.0000, 0.1679, 0.08150] sage: EllipticCurve('648a1').galois_representation().image_classes(5) [0.3945, 0.3293, 0.2388, 0.0000, 0.03749]
>>> from sage.all import * >>> EllipticCurve('27a1').galois_representation().image_classes(Integer(5)) [0.5839, 0.1645, 0.0000, 0.1702, 0.08143] >>> EllipticCurve('30a1').galois_representation().image_classes(Integer(5)) [0.1956, 0.1801, 0.2543, 0.1728, 0.1972] >>> EllipticCurve('32a1').galois_representation().image_classes(Integer(5)) [0.6319, 0.0000, 0.2492, 0.0000, 0.1189] >>> EllipticCurve('900a1').galois_representation().image_classes(Integer(5)) [0.5852, 0.1679, 0.0000, 0.1687, 0.07824] >>> EllipticCurve('441a1').galois_representation().image_classes(Integer(5)) [0.5860, 0.1646, 0.0000, 0.1679, 0.08150] >>> EllipticCurve('648a1').galois_representation().image_classes(Integer(5)) [0.3945, 0.3293, 0.2388, 0.0000, 0.03749]
EllipticCurve('27a1').galois_representation().image_classes(5) EllipticCurve('30a1').galois_representation().image_classes(5) EllipticCurve('32a1').galois_representation().image_classes(5) EllipticCurve('900a1').galois_representation().image_classes(5) EllipticCurve('441a1').galois_representation().image_classes(5) EllipticCurve('648a1').galois_representation().image_classes(5)
>>> from sage.all import * >>> EllipticCurve('27a1').galois_representation().image_classes(Integer(5)) [0.5839, 0.1645, 0.0000, 0.1702, 0.08143] >>> EllipticCurve('30a1').galois_representation().image_classes(Integer(5)) [0.1956, 0.1801, 0.2543, 0.1728, 0.1972] >>> EllipticCurve('32a1').galois_representation().image_classes(Integer(5)) [0.6319, 0.0000, 0.2492, 0.0000, 0.1189] >>> EllipticCurve('900a1').galois_representation().image_classes(Integer(5)) [0.5852, 0.1679, 0.0000, 0.1687, 0.07824] >>> EllipticCurve('441a1').galois_representation().image_classes(Integer(5)) [0.5860, 0.1646, 0.0000, 0.1679, 0.08150] >>> EllipticCurve('648a1').galois_representation().image_classes(Integer(5)) [0.3945, 0.3293, 0.2388, 0.0000, 0.03749]
EllipticCurve('27a1').galois_representation().image_classes(5) EllipticCurve('30a1').galois_representation().image_classes(5) EllipticCurve('32a1').galois_representation().image_classes(5) EllipticCurve('900a1').galois_representation().image_classes(5) EllipticCurve('441a1').galois_representation().image_classes(5) EllipticCurve('648a1').galois_representation().image_classes(5)
sage: EllipticCurve('784h1').galois_representation().image_classes(7) [0.5049, 0.0000, 0.0000, 0.0000, 0.4951, 0.0000, 0.0000] sage: EllipticCurve('49a1').galois_representation().image_classes(7) [0.5045, 0.0000, 0.0000, 0.0000, 0.4955, 0.0000, 0.0000] sage: EllipticCurve('121c1').galois_representation().image_classes(11) [0.1001, 0.0000, 0.0000, 0.0000, 0.1017, 0.1953, 0.1993, 0.0000, 0.0000, 0.2010, 0.2026] sage: EllipticCurve('121d1').galois_representation().image_classes(11) [0.08869, 0.07974, 0.08706, 0.08137, 0.1001, 0.09439, 0.09764, 0.08218, 0.08625, 0.1017, 0.1009] sage: EllipticCurve('441f1').galois_representation().image_classes(13) [0.08232, 0.1663, 0.1663, 0.1663, 0.08232, 0.0000, 0.1549, 0.0000, 0.0000, 0.0000, 0.0000, 0.1817, 0.0000]
>>> from sage.all import * >>> EllipticCurve('784h1').galois_representation().image_classes(Integer(7)) [0.5049, 0.0000, 0.0000, 0.0000, 0.4951, 0.0000, 0.0000] >>> EllipticCurve('49a1').galois_representation().image_classes(Integer(7)) [0.5045, 0.0000, 0.0000, 0.0000, 0.4955, 0.0000, 0.0000] >>> EllipticCurve('121c1').galois_representation().image_classes(Integer(11)) [0.1001, 0.0000, 0.0000, 0.0000, 0.1017, 0.1953, 0.1993, 0.0000, 0.0000, 0.2010, 0.2026] >>> EllipticCurve('121d1').galois_representation().image_classes(Integer(11)) [0.08869, 0.07974, 0.08706, 0.08137, 0.1001, 0.09439, 0.09764, 0.08218, 0.08625, 0.1017, 0.1009] >>> EllipticCurve('441f1').galois_representation().image_classes(Integer(13)) [0.08232, 0.1663, 0.1663, 0.1663, 0.08232, 0.0000, 0.1549, 0.0000, 0.0000, 0.0000, 0.0000, 0.1817, 0.0000]
EllipticCurve('784h1').galois_representation().image_classes(7) EllipticCurve('49a1').galois_representation().image_classes(7) EllipticCurve('121c1').galois_representation().image_classes(11) EllipticCurve('121d1').galois_representation().image_classes(11) EllipticCurve('441f1').galois_representation().image_classes(13)
>>> from sage.all import * >>> EllipticCurve('784h1').galois_representation().image_classes(Integer(7)) [0.5049, 0.0000, 0.0000, 0.0000, 0.4951, 0.0000, 0.0000] >>> EllipticCurve('49a1').galois_representation().image_classes(Integer(7)) [0.5045, 0.0000, 0.0000, 0.0000, 0.4955, 0.0000, 0.0000] >>> EllipticCurve('121c1').galois_representation().image_classes(Integer(11)) [0.1001, 0.0000, 0.0000, 0.0000, 0.1017, 0.1953, 0.1993, 0.0000, 0.0000, 0.2010, 0.2026] >>> EllipticCurve('121d1').galois_representation().image_classes(Integer(11)) [0.08869, 0.07974, 0.08706, 0.08137, 0.1001, 0.09439, 0.09764, 0.08218, 0.08625, 0.1017, 0.1009] >>> EllipticCurve('441f1').galois_representation().image_classes(Integer(13)) [0.08232, 0.1663, 0.1663, 0.1663, 0.08232, 0.0000, 0.1549, 0.0000, 0.0000, 0.0000, 0.0000, 0.1817, 0.0000]
EllipticCurve('784h1').galois_representation().image_classes(7) EllipticCurve('49a1').galois_representation().image_classes(7) EllipticCurve('121c1').galois_representation().image_classes(11) EllipticCurve('121d1').galois_representation().image_classes(11) EllipticCurve('441f1').galois_representation().image_classes(13)
REMARKS:
Conjugacy classes of subgroups of \(PGL_2(\GF{5})\)
For the case \(p=5\), the order of an element determines almost the value of \(u\):
\(u\)
0
1
2
3
4
orders
2
3
4
6
1 or 5
Here we give here the full table of all conjugacy classes of subgroups with the values that
image_classes
should give (asbound
tends to \(\infty\)). Comparing with the output of the above examples, it is now easy to guess what the image is.subgroup
order
frequencies of values of \(u\)
trivial
1
[0.0000, 0.0000, 0.0000, 0.0000, 1.000]
cyclic
2
[0.5000, 0.0000, 0.0000, 0.0000, 0.5000]
cyclic
2
[0.5000, 0.0000, 0.0000, 0.0000, 0.5000]
cyclic
3
[0.0000, 0.6667, 0.0000, 0.0000, 0.3333]
Klein
4
[0.7500, 0.0000, 0.0000, 0.0000, 0.2500]
cyclic
4
[0.2500, 0.0000, 0.5000, 0.0000, 0.2500]
Klein
4
[0.7500, 0.0000, 0.0000, 0.0000, 0.2500]
cyclic
5
[0.0000, 0.0000, 0.0000, 0.0000, 1.000]
cyclic
6
[0.1667, 0.3333, 0.0000, 0.3333, 0.1667]
\(S_3\)
6
[0.5000, 0.3333, 0.0000, 0.0000, 0.1667]
\(S_3\)
6
[0.5000, 0.3333, 0.0000, 0.0000, 0.1667]
\(D_4\)
8
[0.6250, 0.0000, 0.2500, 0.0000, 0.1250]
\(D_5\)
10
[0.5000, 0.0000, 0.0000, 0.0000, 0.5000]
\(A_4\)
12
[0.2500, 0.6667, 0.0000, 0.0000, 0.08333]
\(D_6\)
12
[0.5833, 0.1667, 0.0000, 0.1667, 0.08333]
Borel
20
[0.2500, 0.0000, 0.5000, 0.0000, 0.2500]
\(S_4\)
24
[0.3750, 0.3333, 0.2500, 0.0000, 0.04167]
\(PSL_2\)
60
[0.2500, 0.3333, 0.0000, 0.0000, 0.4167]
\(PGL_2\)
120
[0.2083, 0.1667, 0.2500, 0.1667, 0.2083]
- image_type(p)[source]¶
Return a string describing the image of the mod-p representation. The result is provably correct, but only indicates what sort of an image we have. If one wishes to determine the exact group one needs to work a bit harder. The probabilistic method of image_classes or Sutherland’s galrep package can give a very good guess what the image should be.
INPUT:
p
– a prime number
OUTPUT: string
EXAMPLES:
sage: E = EllipticCurve('14a1') sage: rho = E.galois_representation() sage: rho.image_type(5) 'The image is all of GL_2(F_5).' sage: E = EllipticCurve('11a1') sage: rho = E.galois_representation() sage: rho.image_type(5) 'The image is meta-cyclic inside a Borel subgroup as there is a 5-torsion point on the curve.' sage: EllipticCurve('27a1').galois_representation().image_type(5) 'The image is contained in the normalizer of a non-split Cartan group. (cm)' sage: EllipticCurve('30a1').galois_representation().image_type(5) 'The image is all of GL_2(F_5).' sage: EllipticCurve("324b1").galois_representation().image_type(5) 'The image in PGL_2(F_5) is the exceptional group S_4.' sage: E = EllipticCurve([0,0,0,-56,4848]) sage: rho = E.galois_representation() sage: rho.image_type(5) 'The image is contained in the normalizer of a split Cartan group.' sage: EllipticCurve('49a1').galois_representation().image_type(7) 'The image is contained in a Borel subgroup as there is a 7-isogeny.' sage: EllipticCurve('121c1').galois_representation().image_type(11) 'The image is contained in a Borel subgroup as there is a 11-isogeny.' sage: EllipticCurve('121d1').galois_representation().image_type(11) 'The image is all of GL_2(F_11).' sage: EllipticCurve('441f1').galois_representation().image_type(13) 'The image is contained in a Borel subgroup as there is a 13-isogeny.' sage: EllipticCurve([1,-1,1,-5,2]).galois_representation().image_type(5) 'The image is contained in the normalizer of a non-split Cartan group.' sage: EllipticCurve([0,0,1,-25650,1570826]).galois_representation().image_type(5) 'The image is contained in the normalizer of a split Cartan group.' sage: EllipticCurve([1,-1,1,-2680,-50053]).galois_representation().image_type(7) # the dots (...) in the output fix #11937 (installed 'Kash' may give additional output); long time (2s on sage.math, 2014) 'The image is a... group of order 18.' sage: EllipticCurve([1,-1,0,-107,-379]).galois_representation().image_type(7) # the dots (...) in the output fix #11937 (installed 'Kash' may give additional output); long time (1s on sage.math, 2014) 'The image is a... group of order 36.' sage: EllipticCurve([0,0,1,2580,549326]).galois_representation().image_type(7) 'The image is contained in the normalizer of a split Cartan group.'
>>> from sage.all import * >>> E = EllipticCurve('14a1') >>> rho = E.galois_representation() >>> rho.image_type(Integer(5)) 'The image is all of GL_2(F_5).' >>> E = EllipticCurve('11a1') >>> rho = E.galois_representation() >>> rho.image_type(Integer(5)) 'The image is meta-cyclic inside a Borel subgroup as there is a 5-torsion point on the curve.' >>> EllipticCurve('27a1').galois_representation().image_type(Integer(5)) 'The image is contained in the normalizer of a non-split Cartan group. (cm)' >>> EllipticCurve('30a1').galois_representation().image_type(Integer(5)) 'The image is all of GL_2(F_5).' >>> EllipticCurve("324b1").galois_representation().image_type(Integer(5)) 'The image in PGL_2(F_5) is the exceptional group S_4.' >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),-Integer(56),Integer(4848)]) >>> rho = E.galois_representation() >>> rho.image_type(Integer(5)) 'The image is contained in the normalizer of a split Cartan group.' >>> EllipticCurve('49a1').galois_representation().image_type(Integer(7)) 'The image is contained in a Borel subgroup as there is a 7-isogeny.' >>> EllipticCurve('121c1').galois_representation().image_type(Integer(11)) 'The image is contained in a Borel subgroup as there is a 11-isogeny.' >>> EllipticCurve('121d1').galois_representation().image_type(Integer(11)) 'The image is all of GL_2(F_11).' >>> EllipticCurve('441f1').galois_representation().image_type(Integer(13)) 'The image is contained in a Borel subgroup as there is a 13-isogeny.' >>> EllipticCurve([Integer(1),-Integer(1),Integer(1),-Integer(5),Integer(2)]).galois_representation().image_type(Integer(5)) 'The image is contained in the normalizer of a non-split Cartan group.' >>> EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(25650),Integer(1570826)]).galois_representation().image_type(Integer(5)) 'The image is contained in the normalizer of a split Cartan group.' >>> EllipticCurve([Integer(1),-Integer(1),Integer(1),-Integer(2680),-Integer(50053)]).galois_representation().image_type(Integer(7)) # the dots (...) in the output fix #11937 (installed 'Kash' may give additional output); long time (2s on sage.math, 2014) 'The image is a... group of order 18.' >>> EllipticCurve([Integer(1),-Integer(1),Integer(0),-Integer(107),-Integer(379)]).galois_representation().image_type(Integer(7)) # the dots (...) in the output fix #11937 (installed 'Kash' may give additional output); long time (1s on sage.math, 2014) 'The image is a... group of order 36.' >>> EllipticCurve([Integer(0),Integer(0),Integer(1),Integer(2580),Integer(549326)]).galois_representation().image_type(Integer(7)) 'The image is contained in the normalizer of a split Cartan group.'
E = EllipticCurve('14a1') rho = E.galois_representation() rho.image_type(5) E = EllipticCurve('11a1') rho = E.galois_representation() rho.image_type(5) EllipticCurve('27a1').galois_representation().image_type(5) EllipticCurve('30a1').galois_representation().image_type(5) EllipticCurve("324b1").galois_representation().image_type(5) E = EllipticCurve([0,0,0,-56,4848]) rho = E.galois_representation() rho.image_type(5) EllipticCurve('49a1').galois_representation().image_type(7) EllipticCurve('121c1').galois_representation().image_type(11) EllipticCurve('121d1').galois_representation().image_type(11) EllipticCurve('441f1').galois_representation().image_type(13) EllipticCurve([1,-1,1,-5,2]).galois_representation().image_type(5) EllipticCurve([0,0,1,-25650,1570826]).galois_representation().image_type(5) EllipticCurve([1,-1,1,-2680,-50053]).galois_representation().image_type(7) # the dots (...) in the output fix #11937 (installed 'Kash' may give additional output); long time (2s on sage.math, 2014) EllipticCurve([1,-1,0,-107,-379]).galois_representation().image_type(7) # the dots (...) in the output fix #11937 (installed 'Kash' may give additional output); long time (1s on sage.math, 2014) EllipticCurve([0,0,1,2580,549326]).galois_representation().image_type(7)
Test Issue #14577:
sage: EllipticCurve([0, 1, 0, -4788, 109188]).galois_representation().image_type(13) 'The image in PGL_2(F_13) is the exceptional group S_4.'
>>> from sage.all import * >>> EllipticCurve([Integer(0), Integer(1), Integer(0), -Integer(4788), Integer(109188)]).galois_representation().image_type(Integer(13)) 'The image in PGL_2(F_13) is the exceptional group S_4.'
EllipticCurve([0, 1, 0, -4788, 109188]).galois_representation().image_type(13)
Test Issue #14752:
sage: EllipticCurve([0, 0, 0, -1129345880,-86028258620304]).galois_representation().image_type(11) 'The image is contained in the normalizer of a non-split Cartan group.'
>>> from sage.all import * >>> EllipticCurve([Integer(0), Integer(0), Integer(0), -Integer(1129345880),-Integer(86028258620304)]).galois_representation().image_type(Integer(11)) 'The image is contained in the normalizer of a non-split Cartan group.'
EllipticCurve([0, 0, 0, -1129345880,-86028258620304]).galois_representation().image_type(11)
For \(p=2\):
sage: E = EllipticCurve('11a1') sage: rho = E.galois_representation() sage: rho.image_type(2) 'The image is all of GL_2(F_2), i.e. a symmetric group of order 6.' sage: rho = EllipticCurve('14a1').galois_representation() sage: rho.image_type(2) 'The image is cyclic of order 2 as there is exactly one rational 2-torsion point.' sage: rho = EllipticCurve('15a1').galois_representation() sage: rho.image_type(2) 'The image is trivial as all 2-torsion points are rational.' sage: rho = EllipticCurve('196a1').galois_representation() sage: rho.image_type(2) 'The image is cyclic of order 3.'
>>> from sage.all import * >>> E = EllipticCurve('11a1') >>> rho = E.galois_representation() >>> rho.image_type(Integer(2)) 'The image is all of GL_2(F_2), i.e. a symmetric group of order 6.' >>> rho = EllipticCurve('14a1').galois_representation() >>> rho.image_type(Integer(2)) 'The image is cyclic of order 2 as there is exactly one rational 2-torsion point.' >>> rho = EllipticCurve('15a1').galois_representation() >>> rho.image_type(Integer(2)) 'The image is trivial as all 2-torsion points are rational.' >>> rho = EllipticCurve('196a1').galois_representation() >>> rho.image_type(Integer(2)) 'The image is cyclic of order 3.'
E = EllipticCurve('11a1') rho = E.galois_representation() rho.image_type(2) rho = EllipticCurve('14a1').galois_representation() rho.image_type(2) rho = EllipticCurve('15a1').galois_representation() rho.image_type(2) rho = EllipticCurve('196a1').galois_representation() rho.image_type(2)
\(p=3\):
sage: rho = EllipticCurve('33a1').galois_representation() sage: rho.image_type(3) 'The image is all of GL_2(F_3).' sage: rho = EllipticCurve('30a1').galois_representation() sage: rho.image_type(3) 'The image is meta-cyclic inside a Borel subgroup as there is a 3-torsion point on the curve.' sage: rho = EllipticCurve('50b1').galois_representation() sage: rho.image_type(3) 'The image is contained in a Borel subgroup as there is a 3-isogeny.' sage: rho = EllipticCurve('3840h1').galois_representation() sage: rho.image_type(3) 'The image is contained in a dihedral group of order 8.' sage: rho = EllipticCurve('32a1').galois_representation() sage: rho.image_type(3) 'The image is a semi-dihedral group of order 16, gap.SmallGroup([16,8]).'
>>> from sage.all import * >>> rho = EllipticCurve('33a1').galois_representation() >>> rho.image_type(Integer(3)) 'The image is all of GL_2(F_3).' >>> rho = EllipticCurve('30a1').galois_representation() >>> rho.image_type(Integer(3)) 'The image is meta-cyclic inside a Borel subgroup as there is a 3-torsion point on the curve.' >>> rho = EllipticCurve('50b1').galois_representation() >>> rho.image_type(Integer(3)) 'The image is contained in a Borel subgroup as there is a 3-isogeny.' >>> rho = EllipticCurve('3840h1').galois_representation() >>> rho.image_type(Integer(3)) 'The image is contained in a dihedral group of order 8.' >>> rho = EllipticCurve('32a1').galois_representation() >>> rho.image_type(Integer(3)) 'The image is a semi-dihedral group of order 16, gap.SmallGroup([16,8]).'
rho = EllipticCurve('33a1').galois_representation() rho.image_type(3) rho = EllipticCurve('30a1').galois_representation() rho.image_type(3) rho = EllipticCurve('50b1').galois_representation() rho.image_type(3) rho = EllipticCurve('3840h1').galois_representation() rho.image_type(3) rho = EllipticCurve('32a1').galois_representation() rho.image_type(3)
ALGORITHM: Mainly based on Serre’s paper.
- is_crystalline(p)[source]¶
Return true is the \(p\)-adic Galois representation to \(GL_2(\ZZ_p)\) is crystalline.
For an elliptic curve \(E\), this is to ask whether \(E\) has good reduction at \(p\).
INPUT:
p
– a prime
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('64a1').galois_representation() sage: rho.is_crystalline(5) True sage: rho.is_crystalline(2) False
>>> from sage.all import * >>> rho = EllipticCurve('64a1').galois_representation() >>> rho.is_crystalline(Integer(5)) True >>> rho.is_crystalline(Integer(2)) False
rho = EllipticCurve('64a1').galois_representation() rho.is_crystalline(5) rho.is_crystalline(2)
- is_irreducible(p)[source]¶
Return
True
if the mod p representation is irreducible.INPUT:
p
– a prime number
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('37b').galois_representation() sage: rho.is_irreducible(2) True sage: rho.is_irreducible(3) False sage: rho.is_reducible(2) False sage: rho.is_reducible(3) True
>>> from sage.all import * >>> rho = EllipticCurve('37b').galois_representation() >>> rho.is_irreducible(Integer(2)) True >>> rho.is_irreducible(Integer(3)) False >>> rho.is_reducible(Integer(2)) False >>> rho.is_reducible(Integer(3)) True
rho = EllipticCurve('37b').galois_representation() rho.is_irreducible(2) rho.is_irreducible(3) rho.is_reducible(2) rho.is_reducible(3)
- is_ordinary(p)[source]¶
Return true if the \(p\)-adic Galois representation to \(GL_2(\ZZ_p)\) is ordinary, i.e. if the image of the decomposition group in \(\text{Gal}(\bar\QQ/\QQ)\) above he prime \(p\) maps into a Borel subgroup.
For an elliptic curve \(E\), this is to ask whether \(E\) is ordinary at \(p\), i.e. good ordinary or multiplicative.
INPUT:
p
– a prime
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('11a3').galois_representation() sage: rho.is_ordinary(11) True sage: rho.is_ordinary(5) True sage: rho.is_ordinary(19) False
>>> from sage.all import * >>> rho = EllipticCurve('11a3').galois_representation() >>> rho.is_ordinary(Integer(11)) True >>> rho.is_ordinary(Integer(5)) True >>> rho.is_ordinary(Integer(19)) False
rho = EllipticCurve('11a3').galois_representation() rho.is_ordinary(11) rho.is_ordinary(5) rho.is_ordinary(19)
- is_potentially_crystalline(p)[source]¶
Return true is the \(p\)-adic Galois representation to \(GL_2(\ZZ_p)\) is potentially crystalline, i.e. if there is a finite extension \(K/\QQ_p\) such that the \(p\)-adic representation becomes crystalline.
For an elliptic curve \(E\), this is to ask whether \(E\) has potentially good reduction at \(p\).
INPUT:
p
– a prime
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('37b1').galois_representation() sage: rho.is_potentially_crystalline(37) False sage: rho.is_potentially_crystalline(7) True
>>> from sage.all import * >>> rho = EllipticCurve('37b1').galois_representation() >>> rho.is_potentially_crystalline(Integer(37)) False >>> rho.is_potentially_crystalline(Integer(7)) True
rho = EllipticCurve('37b1').galois_representation() rho.is_potentially_crystalline(37) rho.is_potentially_crystalline(7)
- is_potentially_semistable(p)[source]¶
Return true if the \(p\)-adic Galois representation to \(GL_2(\ZZ_p)\) is potentially semistable.
For an elliptic curve \(E\), this returns
True
alwaysINPUT:
p
– a prime
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('27a2').galois_representation() sage: rho.is_potentially_semistable(3) True
>>> from sage.all import * >>> rho = EllipticCurve('27a2').galois_representation() >>> rho.is_potentially_semistable(Integer(3)) True
rho = EllipticCurve('27a2').galois_representation() rho.is_potentially_semistable(3)
- is_quasi_unipotent(p, ell)[source]¶
Return true if the Galois representation to \(GL_2(\ZZ_p)\) is quasi-unipotent at \(\ell\neq p\), i.e. if there is a finite extension \(K/\QQ\) such that the inertia group at a place above \(\ell\) in \(\text{Gal}(\bar\QQ/K)\) maps into a Borel subgroup.
For a Galois representation attached to an elliptic curve \(E\), this returns always True.
INPUT:
p
– a primeell
– a different prime
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('11a3').galois_representation() sage: rho.is_quasi_unipotent(11,13) True
>>> from sage.all import * >>> rho = EllipticCurve('11a3').galois_representation() >>> rho.is_quasi_unipotent(Integer(11),Integer(13)) True
rho = EllipticCurve('11a3').galois_representation() rho.is_quasi_unipotent(11,13)
- is_reducible(p)[source]¶
Return
True
if the mod-p representation is reducible. This is equivalent to the existence of an isogeny defined over \(\QQ\) of degree \(p\) from the elliptic curve.INPUT:
p
– a prime number
OUTPUT: boolean
The answer is cached.
EXAMPLES:
sage: rho = EllipticCurve('121a').galois_representation() sage: rho.is_reducible(7) False sage: rho.is_reducible(11) True sage: EllipticCurve('11a').galois_representation().is_reducible(5) True sage: rho = EllipticCurve('11a2').galois_representation() sage: rho.is_reducible(5) True sage: EllipticCurve('11a2').torsion_order() 1
>>> from sage.all import * >>> rho = EllipticCurve('121a').galois_representation() >>> rho.is_reducible(Integer(7)) False >>> rho.is_reducible(Integer(11)) True >>> EllipticCurve('11a').galois_representation().is_reducible(Integer(5)) True >>> rho = EllipticCurve('11a2').galois_representation() >>> rho.is_reducible(Integer(5)) True >>> EllipticCurve('11a2').torsion_order() 1
rho = EllipticCurve('121a').galois_representation() rho.is_reducible(7) rho.is_reducible(11) EllipticCurve('11a').galois_representation().is_reducible(5) rho = EllipticCurve('11a2').galois_representation() rho.is_reducible(5) EllipticCurve('11a2').torsion_order()
- is_semistable(p)[source]¶
Return true if the \(p\)-adic Galois representation to \(GL_2(\ZZ_p)\) is semistable.
For an elliptic curve \(E\), this is to ask whether \(E\) has semistable reduction at \(p\).
INPUT:
p
– a prime
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('20a3').galois_representation() sage: rho.is_semistable(2) False sage: rho.is_semistable(3) True sage: rho.is_semistable(5) True
>>> from sage.all import * >>> rho = EllipticCurve('20a3').galois_representation() >>> rho.is_semistable(Integer(2)) False >>> rho.is_semistable(Integer(3)) True >>> rho.is_semistable(Integer(5)) True
rho = EllipticCurve('20a3').galois_representation() rho.is_semistable(2) rho.is_semistable(3) rho.is_semistable(5)
- is_surjective(p, A=1000)[source]¶
Return
True
if the mod-p representation is surjective onto \(Aut(E[p]) = GL_2(\GF{p})\).False
if it is not, orNone
if we were unable to determine whether it is or not.INPUT:
p
– integer; a prime numberA
– integer; a bound on the number of \(a_p\) to use
OUTPUT: boolean;
True
if the mod-p representation is surjective andFalse
if notThe answer is cached.
EXAMPLES:
sage: rho = EllipticCurve('37b').galois_representation() sage: rho.is_surjective(2) True sage: rho.is_surjective(3) False
>>> from sage.all import * >>> rho = EllipticCurve('37b').galois_representation() >>> rho.is_surjective(Integer(2)) True >>> rho.is_surjective(Integer(3)) False
rho = EllipticCurve('37b').galois_representation() rho.is_surjective(2) rho.is_surjective(3)
sage: rho = EllipticCurve('121a1').galois_representation() sage: rho.non_surjective() [11] sage: rho.is_surjective(5) True sage: rho.is_surjective(11) False sage: rho = EllipticCurve('121d1').galois_representation() sage: rho.is_surjective(5) False sage: rho.is_surjective(11) True
>>> from sage.all import * >>> rho = EllipticCurve('121a1').galois_representation() >>> rho.non_surjective() [11] >>> rho.is_surjective(Integer(5)) True >>> rho.is_surjective(Integer(11)) False >>> rho = EllipticCurve('121d1').galois_representation() >>> rho.is_surjective(Integer(5)) False >>> rho.is_surjective(Integer(11)) True
rho = EllipticCurve('121a1').galois_representation() rho.non_surjective() rho.is_surjective(5) rho.is_surjective(11) rho = EllipticCurve('121d1').galois_representation() rho.is_surjective(5) rho.is_surjective(11)
>>> from sage.all import * >>> rho = EllipticCurve('121a1').galois_representation() >>> rho.non_surjective() [11] >>> rho.is_surjective(Integer(5)) True >>> rho.is_surjective(Integer(11)) False >>> rho = EllipticCurve('121d1').galois_representation() >>> rho.is_surjective(Integer(5)) False >>> rho.is_surjective(Integer(11)) True
rho = EllipticCurve('121a1').galois_representation() rho.non_surjective() rho.is_surjective(5) rho.is_surjective(11) rho = EllipticCurve('121d1').galois_representation() rho.is_surjective(5) rho.is_surjective(11)
Here is a case, in which the algorithm does not return an answer:
sage: rho = EllipticCurve([0,0,1,2580,549326]).galois_representation() sage: rho.is_surjective(7)
>>> from sage.all import * >>> rho = EllipticCurve([Integer(0),Integer(0),Integer(1),Integer(2580),Integer(549326)]).galois_representation() >>> rho.is_surjective(Integer(7))
rho = EllipticCurve([0,0,1,2580,549326]).galois_representation() rho.is_surjective(7)
In these cases, one can use image_type to get more information about the image:
sage: rho.image_type(7) 'The image is contained in the normalizer of a split Cartan group.'
>>> from sage.all import * >>> rho.image_type(Integer(7)) 'The image is contained in the normalizer of a split Cartan group.'
rho.image_type(7)
REMARKS:
If \(p \geq 5\) then the mod-p representation is surjective if and only if the \(p\)-adic representation is surjective. When \(p = 2, 3\) there are counterexamples. See papers of Dokchitsers and Elkies for more details.
For the primes \(p=2\) and 3, this will always answer either
True
orFalse
. For larger primes it might giveNone
.
- is_unipotent(p, ell)[source]¶
Return true if the Galois representation to \(GL_2(\ZZ_p)\) is unipotent at \(\ell\neq p\), i.e. if the inertia group at a place above \(\ell\) in \(\text{Gal}(\bar\QQ/\QQ)\) maps into a Borel subgroup.
For a Galois representation attached to an elliptic curve \(E\), this returns
True
if \(E\) has semi-stable reduction at \(\ell\).INPUT:
p
– a primeell
– a different prime
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('120a1').galois_representation() sage: rho.is_unipotent(2,5) True sage: rho.is_unipotent(5,2) False sage: rho.is_unipotent(5,7) True sage: rho.is_unipotent(5,3) True sage: rho.is_unipotent(5,5) Traceback (most recent call last): ... ValueError: unipotent is not defined for l = p, use semistable instead.
>>> from sage.all import * >>> rho = EllipticCurve('120a1').galois_representation() >>> rho.is_unipotent(Integer(2),Integer(5)) True >>> rho.is_unipotent(Integer(5),Integer(2)) False >>> rho.is_unipotent(Integer(5),Integer(7)) True >>> rho.is_unipotent(Integer(5),Integer(3)) True >>> rho.is_unipotent(Integer(5),Integer(5)) Traceback (most recent call last): ... ValueError: unipotent is not defined for l = p, use semistable instead.
rho = EllipticCurve('120a1').galois_representation() rho.is_unipotent(2,5) rho.is_unipotent(5,2) rho.is_unipotent(5,7) rho.is_unipotent(5,3) rho.is_unipotent(5,5)
- is_unramified(p, ell)[source]¶
Return true if the Galois representation to \(GL_2(\ZZ_p)\) is unramified at \(\ell\), i.e. if the inertia group at a place above \(\ell\) in \(\text{Gal}(\bar\QQ/\QQ)\) has trivial image in \(GL_2(\ZZ_p)\).
For a Galois representation attached to an elliptic curve \(E\), this returns
True
if \(\ell\neq p\) and \(E\) has good reduction at \(\ell\).INPUT:
p
– a primeell
– another prime
OUTPUT: boolean
EXAMPLES:
sage: rho = EllipticCurve('20a3').galois_representation() sage: rho.is_unramified(5,7) True sage: rho.is_unramified(5,5) False sage: rho.is_unramified(7,5) False
>>> from sage.all import * >>> rho = EllipticCurve('20a3').galois_representation() >>> rho.is_unramified(Integer(5),Integer(7)) True >>> rho.is_unramified(Integer(5),Integer(5)) False >>> rho.is_unramified(Integer(7),Integer(5)) False
rho = EllipticCurve('20a3').galois_representation() rho.is_unramified(5,7) rho.is_unramified(5,5) rho.is_unramified(7,5)
This says that the 5-adic representation is unramified at 7, but the 7-adic representation is ramified at 5.
- non_surjective(A=1000)[source]¶
Return a list of primes p such that the mod-p representation might not be surjective. If \(p\) is not in the returned list, then the mod-p representation is provably surjective.
By a theorem of Serre, there are only finitely many primes in this list, except when the curve has complex multiplication.
If the curve has CM, we simply return the sequence [0] and do no further computation.
INPUT:
A
– integer (default: 1000); by increasing this parameter the resulting set might get smaller
OUTPUT:
list
– if the curve has CM, returns[0]
. Otherwise, returns a list of primes where mod-p representation is very likely not surjective. At any prime not in this list, the representation is definitely surjective.
EXAMPLES:
sage: E = EllipticCurve([0, 0, 1, -38, 90]) # 361A sage: E.galois_representation().non_surjective() # CM curve [0]
>>> from sage.all import * >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(38), Integer(90)]) # 361A >>> E.galois_representation().non_surjective() # CM curve [0]
E = EllipticCurve([0, 0, 1, -38, 90]) # 361A E.galois_representation().non_surjective() # CM curve
sage: E = EllipticCurve([0, -1, 1, 0, 0]) # X_1(11) sage: E.galois_representation().non_surjective() [5] sage: E = EllipticCurve([0, 0, 1, -1, 0]) # 37A sage: E.galois_representation().non_surjective() [] sage: E = EllipticCurve([0,-1,1,-2,-1]) # 141C sage: E.galois_representation().non_surjective() [13]
>>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), Integer(0), Integer(0)]) # X_1(11) >>> E.galois_representation().non_surjective() [5] >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(1), Integer(0)]) # 37A >>> E.galois_representation().non_surjective() [] >>> E = EllipticCurve([Integer(0),-Integer(1),Integer(1),-Integer(2),-Integer(1)]) # 141C >>> E.galois_representation().non_surjective() [13]
E = EllipticCurve([0, -1, 1, 0, 0]) # X_1(11) E.galois_representation().non_surjective() E = EllipticCurve([0, 0, 1, -1, 0]) # 37A E.galois_representation().non_surjective() E = EllipticCurve([0,-1,1,-2,-1]) # 141C E.galois_representation().non_surjective()
>>> from sage.all import * >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), Integer(0), Integer(0)]) # X_1(11) >>> E.galois_representation().non_surjective() [5] >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(1), Integer(0)]) # 37A >>> E.galois_representation().non_surjective() [] >>> E = EllipticCurve([Integer(0),-Integer(1),Integer(1),-Integer(2),-Integer(1)]) # 141C >>> E.galois_representation().non_surjective() [13]
E = EllipticCurve([0, -1, 1, 0, 0]) # X_1(11) E.galois_representation().non_surjective() E = EllipticCurve([0, 0, 1, -1, 0]) # 37A E.galois_representation().non_surjective() E = EllipticCurve([0,-1,1,-2,-1]) # 141C E.galois_representation().non_surjective()
sage: E = EllipticCurve([1,-1,1,-9965,385220]) # 9999a1 sage: rho = E.galois_representation() sage: rho.non_surjective() [2] sage: E = EllipticCurve('324b1') sage: rho = E.galois_representation() sage: rho.non_surjective() [3, 5]
>>> from sage.all import * >>> E = EllipticCurve([Integer(1),-Integer(1),Integer(1),-Integer(9965),Integer(385220)]) # 9999a1 >>> rho = E.galois_representation() >>> rho.non_surjective() [2] >>> E = EllipticCurve('324b1') >>> rho = E.galois_representation() >>> rho.non_surjective() [3, 5]
E = EllipticCurve([1,-1,1,-9965,385220]) # 9999a1 rho = E.galois_representation() rho.non_surjective() E = EllipticCurve('324b1') rho = E.galois_representation() rho.non_surjective()
>>> from sage.all import * >>> E = EllipticCurve([Integer(1),-Integer(1),Integer(1),-Integer(9965),Integer(385220)]) # 9999a1 >>> rho = E.galois_representation() >>> rho.non_surjective() [2] >>> E = EllipticCurve('324b1') >>> rho = E.galois_representation() >>> rho.non_surjective() [3, 5]
E = EllipticCurve([1,-1,1,-9965,385220]) # 9999a1 rho = E.galois_representation() rho.non_surjective() E = EllipticCurve('324b1') rho = E.galois_representation() rho.non_surjective()
ALGORITHM: We first find an upper bound \(B\) on the possible primes. If \(E\) is semi-stable, we can take \(B=11\) by a result of Mazur. There is a bound by Serre in the case that the \(j\)-invariant is not integral in terms of the smallest prime of good reduction. Finally there is an unconditional bound by Cojocaru, but which depends on the conductor of \(E\). For the prime below that bound we call
is_surjective
.
- reducible_primes()[source]¶
Return a list of the primes \(p\) such that the mod-\(p\) representation is reducible. For all other primes the representation is irreducible.
EXAMPLES:
sage: rho = EllipticCurve('225a').galois_representation() sage: rho.reducible_primes() [3]
>>> from sage.all import * >>> rho = EllipticCurve('225a').galois_representation() >>> rho.reducible_primes() [3]
rho = EllipticCurve('225a').galois_representation() rho.reducible_primes()