Jacobian of a general hyperelliptic curve

class sage.schemes.hyperelliptic_curves.jacobian_generic.HyperellipticJacobian_generic(C, category=None)[source]

Bases: Jacobian_generic

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: FF = FiniteField(2003)
sage: R.<x> = PolynomialRing(FF)
sage: f = x**5 + 1184*x**3 + 1846*x**2 + 956*x + 560
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: a = x**2 + 376*x + 245; b = 1015*x + 1368
sage: X = J(FF)
sage: D = X([a,b])
sage: D
(x^2 + 376*x + 245, y + 988*x + 635)
sage: J(0)
(1)
sage: D == J([a,b])
True
sage: D == D + J(0)
True
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> FF = FiniteField(Integer(2003))
>>> R = PolynomialRing(FF, names=('x',)); (x,) = R._first_ngens(1)
>>> f = x**Integer(5) + Integer(1184)*x**Integer(3) + Integer(1846)*x**Integer(2) + Integer(956)*x + Integer(560)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> a = x**Integer(2) + Integer(376)*x + Integer(245); b = Integer(1015)*x + Integer(1368)
>>> X = J(FF)
>>> D = X([a,b])
>>> D
(x^2 + 376*x + 245, y + 988*x + 635)
>>> J(Integer(0))
(1)
>>> D == J([a,b])
True
>>> D == D + J(Integer(0))
True
# needs sage.rings.finite_rings
FF = FiniteField(2003)
R.<x> = PolynomialRing(FF)
f = x**5 + 1184*x**3 + 1846*x**2 + 956*x + 560
C = HyperellipticCurve(f)
J = C.jacobian()
a = x**2 + 376*x + 245; b = 1015*x + 1368
X = J(FF)
D = X([a,b])
D
J(0)
D == J([a,b])
D == D + J(0)

A more extended example, demonstrating arithmetic in J(QQ) and J(K) for a number field K/QQ.

sage: P.<x> = PolynomialRing(QQ)
sage: f = x^5 - x + 1; h = x
sage: C = HyperellipticCurve(f,h,'u,v'); C
Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1
sage: PP = C.ambient_space(); PP
Projective Space of dimension 2 over Rational Field
sage: C.defining_polynomial()
-x0^5 + x0*x1*x2^3 + x1^2*x2^3 + x0*x2^4 - x2^5
sage: C(QQ)
Set of rational points of Hyperelliptic Curve over Rational Field
 defined by v^2 + u*v = u^5 - u + 1
sage: K.<t> = NumberField(x^2 - 2)                                              # needs sage.rings.number_field
sage: C(K)                                                                      # needs sage.rings.number_field
Set of rational points of Hyperelliptic Curve
 over Number Field in t with defining polynomial x^2 - 2
 defined by v^2 + u*v = u^5 - u + 1
sage: P = C(QQ)(0,1,1); P
(0 : 1 : 1)
sage: P == C(0,1,1)
True
sage: C(0,1,1).parent()
Set of rational points of Hyperelliptic Curve over Rational Field
 defined by v^2 + u*v = u^5 - u + 1

sage: # needs sage.rings.number_field
sage: P1 = C(K)(P)
sage: P2 = C(K)([2, 4*t - 1, 1])
sage: P3 = C(K)([-1/2, 1/8*(7*t+2), 1])
sage: P1, P2, P3
((0 : 1 : 1), (2 : 4*t - 1 : 1), (-1/2 : 7/8*t + 1/4 : 1))

sage: J = C.jacobian(); J
Jacobian of Hyperelliptic Curve over Rational Field
defined by v^2 + u*v = u^5 - u + 1
sage: Q = J(QQ)(P); Q
(u, v - 1)
sage: for i in range(6): Q*i
(1)
(u, v - 1)
(u^2, v + u - 1)
(u^2, v + 1)
(u, v + 1)
(1)

sage: # needs sage.rings.number_field
sage: Q1 = J(K)(P1); print("%s -> %s"%( P1, Q1 ))
(0 : 1 : 1) -> (u, v - 1)
sage: Q2 = J(K)(P2); print("%s -> %s"%( P2, Q2 ))
(2 : 4*t - 1 : 1) -> (u - 2, v - 4*t + 1)
sage: Q3 = J(K)(P3); print("%s -> %s"%( P3, Q3 ))
(-1/2 : 7/8*t + 1/4 : 1) -> (u + 1/2, v - 7/8*t - 1/4)
sage: R.<x> = PolynomialRing(K)
sage: Q4 = J(K)([x^2 - t, R(1)])
sage: for i in range(4): Q4*i
(1)
(u^2 - t, v - 1)
(u^2 + (-3/4*t - 9/16)*u + 1/2*t + 1/4, v + (-1/32*t - 57/64)*u + 1/2*t + 9/16)
(u^2 + (1352416/247009*t - 1636930/247009)*u - 1156544/247009*t + 1900544/247009,
 v + (-2326345442/122763473*t + 3233153137/122763473)*u
                              + 2439343104/122763473*t - 3350862929/122763473)
sage: R2 = Q2*5; R2
(u^2 - 3789465233/116983808*u - 267915823/58491904,
 v + (-233827256513849/1789384327168*t + 1/2)*u - 15782925357447/894692163584*t)
sage: R3 = Q3*5; R3
(u^2 + 5663300808399913890623/14426454798950909645952*u
     - 26531814176395676231273/28852909597901819291904,
 v + (253155440321645614070860868199103/2450498420175733688903836378159104*t + 1/2)*u
   + 2427708505064902611513563431764311/4900996840351467377807672756318208*t)
sage: R4 = Q4*5; R4
(u^2 - 3789465233/116983808*u - 267915823/58491904,
 v + (233827256513849/1789384327168*t + 1/2)*u + 15782925357447/894692163584*t)
>>> from sage.all import *
>>> P = PolynomialRing(QQ, names=('x',)); (x,) = P._first_ngens(1)
>>> f = x**Integer(5) - x + Integer(1); h = x
>>> C = HyperellipticCurve(f,h,'u,v'); C
Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1
>>> PP = C.ambient_space(); PP
Projective Space of dimension 2 over Rational Field
>>> C.defining_polynomial()
-x0^5 + x0*x1*x2^3 + x1^2*x2^3 + x0*x2^4 - x2^5
>>> C(QQ)
Set of rational points of Hyperelliptic Curve over Rational Field
 defined by v^2 + u*v = u^5 - u + 1
>>> K = NumberField(x**Integer(2) - Integer(2), names=('t',)); (t,) = K._first_ngens(1)# needs sage.rings.number_field
>>> C(K)                                                                      # needs sage.rings.number_field
Set of rational points of Hyperelliptic Curve
 over Number Field in t with defining polynomial x^2 - 2
 defined by v^2 + u*v = u^5 - u + 1
>>> P = C(QQ)(Integer(0),Integer(1),Integer(1)); P
(0 : 1 : 1)
>>> P == C(Integer(0),Integer(1),Integer(1))
True
>>> C(Integer(0),Integer(1),Integer(1)).parent()
Set of rational points of Hyperelliptic Curve over Rational Field
 defined by v^2 + u*v = u^5 - u + 1

>>> # needs sage.rings.number_field
>>> P1 = C(K)(P)
>>> P2 = C(K)([Integer(2), Integer(4)*t - Integer(1), Integer(1)])
>>> P3 = C(K)([-Integer(1)/Integer(2), Integer(1)/Integer(8)*(Integer(7)*t+Integer(2)), Integer(1)])
>>> P1, P2, P3
((0 : 1 : 1), (2 : 4*t - 1 : 1), (-1/2 : 7/8*t + 1/4 : 1))

>>> J = C.jacobian(); J
Jacobian of Hyperelliptic Curve over Rational Field
defined by v^2 + u*v = u^5 - u + 1
>>> Q = J(QQ)(P); Q
(u, v - 1)
>>> for i in range(Integer(6)): Q*i
(1)
(u, v - 1)
(u^2, v + u - 1)
(u^2, v + 1)
(u, v + 1)
(1)

>>> # needs sage.rings.number_field
>>> Q1 = J(K)(P1); print("%s -> %s"%( P1, Q1 ))
(0 : 1 : 1) -> (u, v - 1)
>>> Q2 = J(K)(P2); print("%s -> %s"%( P2, Q2 ))
(2 : 4*t - 1 : 1) -> (u - 2, v - 4*t + 1)
>>> Q3 = J(K)(P3); print("%s -> %s"%( P3, Q3 ))
(-1/2 : 7/8*t + 1/4 : 1) -> (u + 1/2, v - 7/8*t - 1/4)
>>> R = PolynomialRing(K, names=('x',)); (x,) = R._first_ngens(1)
>>> Q4 = J(K)([x**Integer(2) - t, R(Integer(1))])
>>> for i in range(Integer(4)): Q4*i
(1)
(u^2 - t, v - 1)
(u^2 + (-3/4*t - 9/16)*u + 1/2*t + 1/4, v + (-1/32*t - 57/64)*u + 1/2*t + 9/16)
(u^2 + (1352416/247009*t - 1636930/247009)*u - 1156544/247009*t + 1900544/247009,
 v + (-2326345442/122763473*t + 3233153137/122763473)*u
                              + 2439343104/122763473*t - 3350862929/122763473)
>>> R2 = Q2*Integer(5); R2
(u^2 - 3789465233/116983808*u - 267915823/58491904,
 v + (-233827256513849/1789384327168*t + 1/2)*u - 15782925357447/894692163584*t)
>>> R3 = Q3*Integer(5); R3
(u^2 + 5663300808399913890623/14426454798950909645952*u
     - 26531814176395676231273/28852909597901819291904,
 v + (253155440321645614070860868199103/2450498420175733688903836378159104*t + 1/2)*u
   + 2427708505064902611513563431764311/4900996840351467377807672756318208*t)
>>> R4 = Q4*Integer(5); R4
(u^2 - 3789465233/116983808*u - 267915823/58491904,
 v + (233827256513849/1789384327168*t + 1/2)*u + 15782925357447/894692163584*t)
P.<x> = PolynomialRing(QQ)
f = x^5 - x + 1; h = x
C = HyperellipticCurve(f,h,'u,v'); C
PP = C.ambient_space(); PP
C.defining_polynomial()
C(QQ)
K.<t> = NumberField(x^2 - 2)                                              # needs sage.rings.number_field
C(K)                                                                      # needs sage.rings.number_field
P = C(QQ)(0,1,1); P
P == C(0,1,1)
C(0,1,1).parent()
# needs sage.rings.number_field
P1 = C(K)(P)
P2 = C(K)([2, 4*t - 1, 1])
P3 = C(K)([-1/2, 1/8*(7*t+2), 1])
P1, P2, P3
J = C.jacobian(); J
Q = J(QQ)(P); Q
for i in range(6): Q*i
# needs sage.rings.number_field
Q1 = J(K)(P1); print("%s -> %s"%( P1, Q1 ))
Q2 = J(K)(P2); print("%s -> %s"%( P2, Q2 ))
Q3 = J(K)(P3); print("%s -> %s"%( P3, Q3 ))
R.<x> = PolynomialRing(K)
Q4 = J(K)([x^2 - t, R(1)])
for i in range(4): Q4*i
R2 = Q2*5; R2
R3 = Q3*5; R3
R4 = Q4*5; R4

Thus we find the following identity:

sage: 5*Q2 + 5*Q4                                                               # needs sage.rings.number_field
(1)
>>> from sage.all import *
>>> Integer(5)*Q2 + Integer(5)*Q4                                                               # needs sage.rings.number_field
(1)
5*Q2 + 5*Q4                                                               # needs sage.rings.number_field

Moreover the following relation holds in the 5-torsion subgroup:

sage: Q2 + Q4 == 2*Q1                                                           # needs sage.rings.number_field
True
>>> from sage.all import *
>>> Q2 + Q4 == Integer(2)*Q1                                                           # needs sage.rings.number_field
True
Q2 + Q4 == 2*Q1                                                           # needs sage.rings.number_field
dimension()[source]

Return the dimension of this Jacobian.

OUTPUT: integer

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(9); R.<x> = k[]
sage: HyperellipticCurve(x^3 + x - 1, x + a).jacobian().dimension()
1
sage: g = HyperellipticCurve(x^6 + x - 1, x + a).jacobian().dimension(); g
2
sage: type(g)
<... 'sage.rings.integer.Integer'>
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> k = GF(Integer(9), names=('a',)); (a,) = k._first_ngens(1); R = k['x']; (x,) = R._first_ngens(1)
>>> HyperellipticCurve(x**Integer(3) + x - Integer(1), x + a).jacobian().dimension()
1
>>> g = HyperellipticCurve(x**Integer(6) + x - Integer(1), x + a).jacobian().dimension(); g
2
>>> type(g)
<... 'sage.rings.integer.Integer'>
# needs sage.rings.finite_rings
k.<a> = GF(9); R.<x> = k[]
HyperellipticCurve(x^3 + x - 1, x + a).jacobian().dimension()
g = HyperellipticCurve(x^6 + x - 1, x + a).jacobian().dimension(); g
type(g)
geometric_endomorphism_algebra_is_field(B=200, proof=False)[source]

Return whether the geometric endomorphism algebra is a field.

This implies that the Jacobian of the curve is geometrically simple. It is based on Algorithm 4.10 from [Lom2019]

INPUT:

  • B – (default: 200) the bound which appears in the statement of the algorithm from [Lom2019]

  • proof – boolean (default: False); whether or not to insist on a provably correct answer. This is related to the warning in the docstring of this module: if this function returns False, then strictly speaking this has not been proven to be False until one has exhibited a non-trivial endomorphism, which these methods are not designed to carry out. If one is convinced that this method should return True, but it is returning False, then this can be exhibited by increasing \(B\).

OUTPUT:

Boolean indicating whether or not the geometric endomorphism algebra is a field.

EXAMPLES:

This is LMFDB curve 262144.d.524288.2 which has QM. Although its Jacobian is geometrically simple, the geometric endomorphism algebra is not a field:

sage: R.<x> = QQ[]
sage: f = x^5 + x^4 + 4*x^3 + 8*x^2 + 5*x + 1
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_algebra_is_field()
False
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> f = x**Integer(5) + x**Integer(4) + Integer(4)*x**Integer(3) + Integer(8)*x**Integer(2) + Integer(5)*x + Integer(1)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_algebra_is_field()
False
R.<x> = QQ[]
f = x^5 + x^4 + 4*x^3 + 8*x^2 + 5*x + 1
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_algebra_is_field()

This is LMFDB curve 50000.a.200000.1:

sage: f = 8*x^5 + 1
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_algebra_is_field()
True
>>> from sage.all import *
>>> f = Integer(8)*x**Integer(5) + Integer(1)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_algebra_is_field()
True
f = 8*x^5 + 1
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_algebra_is_field()
geometric_endomorphism_ring_is_ZZ(B=200, proof=False)[source]

Return whether the geometric endomorphism ring of self is the integer ring \(\ZZ\).

INPUT:

  • B – (default: 200) the bound which appears in the statement of the algorithm from [Lom2019]

  • proof – boolean (default: False); whether or not to insist on a provably correct answer. This is related to the warning in the module docstring of \(jacobian_endomorphisms.py\): if this function returns False, then strictly speaking this has not been proven to be False until one has exhibited a non-trivial endomorphism, which the methods in that module are not designed to carry out. If one is convinced that this method should return True, but it is returning False, then this can be exhibited by increasing \(B\).

OUTPUT:

Boolean indicating whether or not the geometric endomorphism ring is isomorphic to the integer ring.

EXAMPLES:

This is LMFDB curve 603.a.603.2:

sage: R.<x> = QQ[]
sage: f = 4*x^5 + x^4 - 4*x^3 + 2*x^2 + 4*x + 1
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_ring_is_ZZ()
True
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> f = Integer(4)*x**Integer(5) + x**Integer(4) - Integer(4)*x**Integer(3) + Integer(2)*x**Integer(2) + Integer(4)*x + Integer(1)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_ring_is_ZZ()
True
R.<x> = QQ[]
f = 4*x^5 + x^4 - 4*x^3 + 2*x^2 + 4*x + 1
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_ring_is_ZZ()

This is LMFDB curve 1152.a.147456.1 whose geometric endomorphism ring is isomorphic to the group of 2x2 matrices over \(\QQ\):

sage: f = x^6 - 2*x^4 + 2*x^2 - 1
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_ring_is_ZZ()
False
>>> from sage.all import *
>>> f = x**Integer(6) - Integer(2)*x**Integer(4) + Integer(2)*x**Integer(2) - Integer(1)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_ring_is_ZZ()
False
f = x^6 - 2*x^4 + 2*x^2 - 1
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_ring_is_ZZ()

This is LMFDB curve 20736.k.373248.1 whose geometric endomorphism ring is isomorphic to the group of 2x2 matrices over a CM field:

sage: f = x^6 + 8
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_ring_is_ZZ()
False
>>> from sage.all import *
>>> f = x**Integer(6) + Integer(8)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_ring_is_ZZ()
False
f = x^6 + 8
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_ring_is_ZZ()

This is LMFDB curve 708.a.181248.1:

sage: R.<x> = QQ[]
sage: f = -3*x^6 - 16*x^5 + 36*x^4 + 194*x^3 - 164*x^2 - 392*x - 143
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_ring_is_ZZ()
True
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> f = -Integer(3)*x**Integer(6) - Integer(16)*x**Integer(5) + Integer(36)*x**Integer(4) + Integer(194)*x**Integer(3) - Integer(164)*x**Integer(2) - Integer(392)*x - Integer(143)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_ring_is_ZZ()
True
R.<x> = QQ[]
f = -3*x^6 - 16*x^5 + 36*x^4 + 194*x^3 - 164*x^2 - 392*x - 143
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_ring_is_ZZ()

This is LMFDB curve 10609.a.10609.1 whose geometric endomorphism ring is an order in a real quadratic field:

sage: f = x^6 + 2*x^4 + 2*x^3 + 5*x^2 + 6*x + 1
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_ring_is_ZZ()
False
>>> from sage.all import *
>>> f = x**Integer(6) + Integer(2)*x**Integer(4) + Integer(2)*x**Integer(3) + Integer(5)*x**Integer(2) + Integer(6)*x + Integer(1)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_ring_is_ZZ()
False
f = x^6 + 2*x^4 + 2*x^3 + 5*x^2 + 6*x + 1
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_ring_is_ZZ()

This is LMFDB curve 160000.c.800000.1 whose geometric endomorphism ring is an order in a CM field:

sage: f = x^5 - 1
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_ring_is_ZZ()
False
>>> from sage.all import *
>>> f = x**Integer(5) - Integer(1)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_ring_is_ZZ()
False
f = x^5 - 1
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_ring_is_ZZ()

This is LMFDB curve 262144.d.524288.2 whose geometric endomorphism ring is an order in a quaternion algebra:

sage: f = x^5 + x^4 + 4*x^3 + 8*x^2 + 5*x + 1
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_ring_is_ZZ()
False
>>> from sage.all import *
>>> f = x**Integer(5) + x**Integer(4) + Integer(4)*x**Integer(3) + Integer(8)*x**Integer(2) + Integer(5)*x + Integer(1)
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_ring_is_ZZ()
False
f = x^5 + x^4 + 4*x^3 + 8*x^2 + 5*x + 1
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_ring_is_ZZ()

This is LMFDB curve 578.a.2312.1 whose geometric endomorphism ring is \(\QQ \times \QQ\):

sage: f = 4*x^5 - 7*x^4 + 10*x^3 - 7*x^2 + 4*x
sage: C = HyperellipticCurve(f)
sage: J = C.jacobian()
sage: J.geometric_endomorphism_ring_is_ZZ()
False
>>> from sage.all import *
>>> f = Integer(4)*x**Integer(5) - Integer(7)*x**Integer(4) + Integer(10)*x**Integer(3) - Integer(7)*x**Integer(2) + Integer(4)*x
>>> C = HyperellipticCurve(f)
>>> J = C.jacobian()
>>> J.geometric_endomorphism_ring_is_ZZ()
False
f = 4*x^5 - 7*x^4 + 10*x^3 - 7*x^2 + 4*x
C = HyperellipticCurve(f)
J = C.jacobian()
J.geometric_endomorphism_ring_is_ZZ()
point(mumford, check=True)[source]