Jacobian of a general hyperelliptic curve¶
AUTHORS:
David Kohel (2006): initial version
Sabrina Kunzweiler, Gareth Ma, Giacomo Pope (2024): adapt to smooth model
- class sage.schemes.hyperelliptic_curves.jacobian_generic.HyperellipticJacobian_generic(C, category=None)[source]¶
Bases:
Jacobian_genericThis is the base class for Jacobians of hyperelliptic curves.
We represent elements of the Jacobian by tuples of the form \((u, v : n)\), where
\((u,v)\) is the Mumford representative of a divisor \(P_1 + ... + P_r\),
\(n\) is a non-negative integer
This tuple represents the equivalence class
\[[P_1 + ... + P_r + n \cdot \infty_+ + m\cdot \infty_- - D_\infty],\]where \(m = g - \deg(u) - n\), and \(\infty_+\), \(\infty_-\) are the points at infinity of the hyperelliptic curve,
\[D_\infty = \lceil g/2 \rceil \infty_+ + \lfloor g/2 \rfloor \infty_-.\]Here, \(\infty_- = \infty_+\), if the hyperelliptic curve is ramified.
Such a representation exists and is unique, unless the genus \(g\) is odd and the curve is inert.
If the hyperelliptic curve is ramified or inert, then \(n\) can be deduced from \(\deg(u)\) and \(g\). In these cases, \(n\) is omitted in the description.
- abelian_group(*args, **kwds)[source]¶
Return the group of rational points on this Jacobian as an
AdditiveAbelianGroupWrapperobject.EXAMPLES:
sage: x = polygen(GF(11^4)) sage: C = HyperellipticCurve(x^5 + x + 1) sage: J = C.jacobian() sage: J.abelian_group() Additive abelian group isomorphic to Z/1677896 + Z/8 + Z/4 + Z/4 embedded in Abelian group of points over Finite Field in z4 of size 11^4 on Jacobian of Hyperelliptic Curve over Finite Field in z4 of size 11^4 defined by y^2 = x^5 + x + 1
>>> from sage.all import * >>> x = polygen(GF(Integer(11)**Integer(4))) >>> C = HyperellipticCurve(x**Integer(5) + x + Integer(1)) >>> J = C.jacobian() >>> J.abelian_group() Additive abelian group isomorphic to Z/1677896 + Z/8 + Z/4 + Z/4 embedded in Abelian group of points over Finite Field in z4 of size 11^4 on Jacobian of Hyperelliptic Curve over Finite Field in z4 of size 11^4 defined by y^2 = x^5 + x + 1
See also
sage.schemes.hyperelliptic_curves.jacobian_homset_generic.abelian_group().
- count_points(*args, **kwds)[source]¶
Compute the number of points on this Jacobian, possibly also over extension fields.
EXAMPLES:
sage: R.<x> = GF(3663031)[] sage: J = HyperellipticCurve(x^5 + 1758294*x^4 + 1908793*x^3 + 3033920*x^2 + 3445698*x + 3020661).jacobian() sage: J.count_points() == J.order() True sage: J.count_points(3) [13403849798842, 180037321758127724648694244, 2415703144684957707144219559418205805522]
>>> from sage.all import * >>> R = GF(Integer(3663031))['x']; (x,) = R._first_ngens(1) >>> J = HyperellipticCurve(x**Integer(5) + Integer(1758294)*x**Integer(4) + Integer(1908793)*x**Integer(3) + Integer(3033920)*x**Integer(2) + Integer(3445698)*x + Integer(3020661)).jacobian() >>> J.count_points() == J.order() True >>> J.count_points(Integer(3)) [13403849798842, 180037321758127724648694244, 2415703144684957707144219559418205805522]
See also
sage.schemes.hyperelliptic_curves.jacobian_homset_generic.count_points().
- dimension()[source]¶
Return the dimension of this Jacobian.
EXAMPLES:
sage: R.<x> = QQ[] sage: H = HyperellipticCurve(x^2, x^4+1); H Hyperelliptic Curve over Rational Field defined by y^2 + (x^4 + 1)*y = x^2 sage: J = Jacobian(H) sage: J.dimension() 3
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(2), x**Integer(4)+Integer(1)); H Hyperelliptic Curve over Rational Field defined by y^2 + (x^4 + 1)*y = x^2 >>> J = Jacobian(H) >>> J.dimension() 3
- 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 returnsFalse, then strictly speaking this has not been proven to beFalseuntil one has exhibited a non-trivial endomorphism, which these methods are not designed to carry out. If one is convinced that this method should returnTrue, but it is returningFalse, 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
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
[Python]>>> 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
- geometric_endomorphism_ring_is_ZZ(B=200, proof=False)[source]¶
Return whether the geometric endomorphism ring of
selfis 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 returnsFalse, then strictly speaking this has not been proven to beFalseuntil 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 returnTrue, but it is returningFalse, 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
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
[Python]>>> 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
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
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
[Python]>>> 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
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
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
[Python]>>> from sage.all import * >>> f = x**Integer(5) - Integer(1) >>> C = HyperellipticCurve(f) >>> J = C.jacobian() >>> J.geometric_endomorphism_ring_is_ZZ() False
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
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
[Python]>>> 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
- lift_u(*args, **kwds)[source]¶
Return one or all points with given \(u\)-coordinate.
See also
sage.schemes.hyperelliptic_curves.jacobian_homset_generic.lift_u().
- order()[source]¶
Compute the order of the Jacobian.
EXAMPLES:
sage: R.<x> = GF(3663031)[] sage: HyperellipticCurve(x^5 + 1758294*x^4 + 1908793*x^3 + 3033920*x^2 + 3445698*x + 3020661).jacobian().cardinality() 13403849798842
>>> from sage.all import * >>> R = GF(Integer(3663031))['x']; (x,) = R._first_ngens(1) >>> HyperellipticCurve(x**Integer(5) + Integer(1758294)*x**Integer(4) + Integer(1908793)*x**Integer(3) + Integer(3033920)*x**Integer(2) + Integer(3445698)*x + Integer(3020661)).jacobian().cardinality() 13403849798842
See also
sage.schemes.hyperelliptic_curves.jacobian_homset_generic.order().
- point(check, *mumford, **kwargs)[source]¶
Return a point on the Jacobian, given:
No arguments or the integer \(0\); return \(0 \in J\);
A point \(P\) on \(J = Jac(C)\), return \(P\);
A point \(P\) on the curve \(H\) such that \(J = Jac(H)\); return \([P - P_0]\), where \(P_0\) is the distinguished point of \(H\). By default, \(P_0 = \infty\);
Two points \(P, Q\) on the curve \(H\) such that \(J = Jac(H)\); return \([P - Q]\);
Polynomials \((u, v)\) such that \(v^2 + hv - f \equiv 0 \pmod u\); return \([(u(x), y - v(x))]\).
EXAMPLES:
sage: x = polygen(GF(101)) sage: C = HyperellipticCurve(x^5 + x) sage: J = C.jacobian() sage: J.point(0) (1, 0) sage: J.point(C(-5, 1)) (x + 5, 1) sage: J.point(C(-5, 1), C(0, 0)) (x^2 + 5*x, 20*x) sage: J.point(C(-5, 1), C(0, 0)) - J.point(C(0, 0)) (x + 5, 1) sage: J.point(x, 0) (x, 0)
>>> from sage.all import * >>> x = polygen(GF(Integer(101))) >>> C = HyperellipticCurve(x**Integer(5) + x) >>> J = C.jacobian() >>> J.point(Integer(0)) (1, 0) >>> J.point(C(-Integer(5), Integer(1))) (x + 5, 1) >>> J.point(C(-Integer(5), Integer(1)), C(Integer(0), Integer(0))) (x^2 + 5*x, 20*x) >>> J.point(C(-Integer(5), Integer(1)), C(Integer(0), Integer(0))) - J.point(C(Integer(0), Integer(0))) (x + 5, 1) >>> J.point(x, Integer(0)) (x, 0)
- points(*args, **kwds)[source]¶
Return all rational points on the Jacobian.
EXAMPLES:
sage: x = polygen(GF(11)) sage: C = HyperellipticCurve(x^5 + x + 1) sage: J = C.jacobian() sage: pts = J.points() sage: sorted(pts) [(1, 0), (x, 1), (x, 10), (x + 2, 0), (x + 8, 4), ..., (x^2 + 10*x + 6, 3*x), (x^2 + 10*x + 6, 8*x), (x^2 + 10*x + 7, 5*x + 6), (x^2 + 10*x + 7, 6*x + 5)] sage: len(pts) == J.order() True
>>> from sage.all import * >>> x = polygen(GF(Integer(11))) >>> C = HyperellipticCurve(x**Integer(5) + x + Integer(1)) >>> J = C.jacobian() >>> pts = J.points() >>> sorted(pts) [(1, 0), (x, 1), (x, 10), (x + 2, 0), (x + 8, 4), ..., (x^2 + 10*x + 6, 3*x), (x^2 + 10*x + 6, 8*x), (x^2 + 10*x + 7, 5*x + 6), (x^2 + 10*x + 7, 6*x + 5)] >>> len(pts) == J.order() True
See also
sage.schemes.hyperelliptic_curves.jacobian_homset_generic.points().
- random_element(*args, **kwds)[source]¶
Return a random element of the Jacobian.
EXAMPLES:
sage: x = polygen(GF(11)) sage: J = HyperellipticCurve(x^5 + x + 1).jacobian() sage: elt = J.random_element(); elt # random (x^2 + 3*x + 10, 1) sage: elt in J True
>>> from sage.all import * >>> x = polygen(GF(Integer(11))) >>> J = HyperellipticCurve(x**Integer(5) + x + Integer(1)).jacobian() >>> elt = J.random_element(); elt # random (x^2 + 3*x + 10, 1) >>> elt in J True
See also
sage.schemes.hyperelliptic_curves.jacobian_homset_generic.random_element().
- some_elements()[source]¶
Return some rational points on the Jacobian.
EXAMPLES:
sage: x = polygen(GF(11)) sage: J = HyperellipticCurve(x^5 + x + 1).jacobian() sage: elts = J.some_elements(); elts # random [(1, 0), (x^2 + 7*x + 3, 10*x + 7), (x^2 + 10*x, 5*x + 1), (x^2 + 8*x + 10, 1)] sage: all(elt in J for elt in elts) True
>>> from sage.all import * >>> x = polygen(GF(Integer(11))) >>> J = HyperellipticCurve(x**Integer(5) + x + Integer(1)).jacobian() >>> elts = J.some_elements(); elts # random [(1, 0), (x^2 + 7*x + 3, 10*x + 7), (x^2 + 10*x, 5*x + 1), (x^2 + 8*x + 10, 1)] >>> all(elt in J for elt in elts) True