Jacobians of function fields

This module provides base classes for Jacobians of function fields.

Jacobian

Sage currently has five models for Jacobian arithmetic on function fields. We denote the genus of the function field by \(g\). Constructing each model requires either a base divisor or place \(B\), with varying requirements:

  • Unique Hess model (unique_hess). Requires that \(B\) is a degree 1 place.

  • Hess model (hess). Requires that \(B\) is a degree \(g\) divisor.

  • Khuri-Makdisi small model (km_small). Requires that \(B\) is an effective divisor with \(\deg(B) \geq 2g + 1\).

  • Khuri-Makdisi medium model (km_medium). Requires that \(B\) is an effective divisor with \(\deg(B) \geq 2g + 1\).

  • Khuri-Makdisi large model (km_large). Requires that \(B\) is an effective divisor with \(\deg(B) \geq g + 1\).

The unique_hess model is the only current model that computes with unique representatives of divisor classes, and so is the only model where Jacobian elements are hashable.

All models will attempt to find an appropriate \(B\) if one is not provided. The current implementation does this by finding a degree 1 place and scaling it appropriately. If the function field does not have a degree one place, then the unique_hess model cannot be used, and other models will fail unless the user supplies an appropriate base divisor \(B\). It is exceedingly rare for a global function field to not contain a degree one place, see [HLT2003] for a heuristic argument of this.

In order to allow for future optimizations, the way we choose the base place/divisor is considered to be an implementation detail. It is not guaranteed that the default base place/divisor is chosen deterministically, or that the default base place/divisor will be the same between Sage versions or Sage installations. If the user wants a specific base place/divisor to be used, then they should specify one.

The Jacobian of a function field is created by default in the hess model, with a base divisor of degree \(g\) the genus of the function field. The base divisor is automatically chosen if not given.

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: F = C.function_field()
sage: J = F.jacobian()
sage: J
Jacobian of Function field in z defined by z^3 + 23*y^2*z + 6 (Hess model)
sage: J.base_divisor().degree()
1

Explicitly specify a model if you want Jacobians in different models.

sage: J_km = F.jacobian(model='km_large')
sage: J_km
Jacobian of Function field in z defined by z^3 + 23*y^2*z + 6 (Khuri-Makdisi large model)

Group of rational points

The group of rational points of a Jacobian is created from the Jacobian. A point of the Jacobian group is determined by a divisor of degree zero. To represent the point, a divisor of the form \(D - B\) is selected where \(D\) is an effective divisor of the same degree with the base divisor \(B\). Hence the point is simply represented by the divisor \(D\).

sage: G = J.group()
sage: G.order()
30
sage: pl1 = C([1,8,1]).place()
sage: pl2 = C([2,10,1]).place()
sage: p1 = G.point(pl1 - pl2)
sage: p1
[Place (y + 1, z + 6)]
sage: p2 = G.point(pl2 - pl1)
sage: p2
[Place (y + 28, z + 6)]
sage: p1 + p2 == G.zero()
True
sage: p1.order()
5

We can get the corresponding point in the Jacobian in a different model.

sage: p1km = J_km(p1)
sage: p1km.order()
5
sage: p1km
Point of Jacobian determined by
[ 1  0  0  0  0  0 11  0  0]
[ 0  1  0  0  0  0 18  0  0]
[ 0  0  1  0  0  0 11  0  0]
[ 0  0  0  1  0  0 18  1  0]
[ 0  0  0  0  1  0 25  0 19]
[ 0  0  0  0  0  1  8  8  0]

AUTHORS:

  • Kwankyu Lee (2022-01-24): initial version

  • Vincent Macri (2025-10-10): updates for unique_hess model

class sage.rings.function_field.jacobian_base.JacobianGroupFunctor(base_field, field)[source]

Bases: ConstructionFunctor

A construction functor for Jacobian groups.

EXAMPLES:

sage: k = GF(7)
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: J = C.jacobian(model='hess')
sage: G = J.group()
sage: F, obj = G.construction()
sage: F
JacobianGroupFunctor
merge(other)[source]

Return the functor merging self and other.

INPUT:

  • other – a functor

EXAMPLES:

sage: k = GF(7)
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: J = C.jacobian(model='hess')
sage: K2 = k.extension(2)
sage: G2 = J.group(K2)
sage: K3 = k.extension(3)
sage: G3 = J.group(K3)
sage: sage.categories.pushout.pushout(G2, G3)  # indirect doctest
Group of rational points of Jacobian over Finite Field in z6 of size 7^6 (Hess model)
rank = 20
class sage.rings.function_field.jacobian_base.JacobianGroup_base(parent, function_field: FunctionField, base_div: FunctionFieldDivisor)[source]

Bases: Parent

Groups of rational points of Jacobians.

INPUT:

  • parent – a Jacobian

  • function_field – a function field

  • base_div – an effective divisor of the function field

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: J = C.jacobian(model='hess')
sage: J.group()
Group of rational points of Jacobian over Finite Field of size 7 (Hess model)
base_divisor()[source]

Return the base divisor that is used to represent points of this group.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: J = C.jacobian(model='hess', base_div=b)
sage: G = J.group()
sage: G.base_divisor()
Place (1/y, 1/y*z)
sage: _ == 1*b
True

The base divisor is the denominator (negative part) of the divisor of degree zero that represents a point.

sage: p = C([-1,2,1]).place()
sage: G.point(p - b).divisor()
- Place (1/y, 1/y*z)
 + Place (y + 2, z + 1)
construction()[source]

Return the data for a functorial construction of this Jacobian group.

EXAMPLES:

sage: k = GF(7)
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: J = C.jacobian(model='hess')
sage: K2 = k.extension(2)
sage: G2 = J.group(K2)
sage: K3= k.extension(3)
sage: G3 = J.group(K3)
sage: p1, p2 = G2.get_points(2)
sage: q1, q2 = G3.get_points(2)
sage: (p1 + q1).parent() is (p2 + q2).parent()
True
function_field()[source]

Return the function field to which this Jacobian group attached.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: J = C.jacobian(model='hess')
sage: G = J.group()
sage: G.function_field()
Function field in z defined by z^3 + 4*y^2*z + 3
parent()[source]

Return the Jacobian to which this Jacobian group belongs.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: J = C.jacobian(model='hess')
sage: G = J.group()
sage: G.parent()
Jacobian of Projective Plane Curve over Finite Field of size 7
 defined by x^3 - y^2*z - 2*z^3 (Hess model)
class sage.rings.function_field.jacobian_base.JacobianGroup_finite_field_base(parent, function_field: FunctionField, base_div: FunctionFieldDivisor)[source]

Bases: JacobianGroup_base

Jacobian groups of function fields over finite fields.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: J = C.jacobian(model='hess', base_div=b)
sage: J.group()
Group of rational points of Jacobian over Finite Field of size 7 (Hess model)
get_points(n)[source]

Return \(n\) points of the Jacobian group.

If \(n\) is greater than the order of the group, then returns all points of the group.

INPUT:

  • n – integer

EXAMPLES:

sage: k = GF(7)
sage: A.<x,y> = AffineSpace(k,2)
sage: C = Curve(y^2 + x^3 + 2*x + 1).projective_closure()
sage: J = C.jacobian(model='hess')
sage: G = J.group()
sage: pts = G.get_points(G.order())
sage: len(pts)
11
order(algorithm='numeric')[source]

Return the order of the Jacobian group.

INPUT:

  • algorithm'numeric' (default) or 'algebraic'

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: J = C.jacobian(model='hess', base_div=b)
sage: G = J.group()
sage: G.order()
7
some_elements()[source]
class sage.rings.function_field.jacobian_base.JacobianPoint_base[source]

Bases: AdditiveGroupElement

Abstract base class of points of Jacobian groups.

addflip(other)[source]

Return the addflip of this and other point. This naive implementation simply returns -(self + other). The Khuri-Makdisi implement this operation more efficiently than naively adding and negating. This naive implementation of addflip is to provide compatibility with the Khuri-Makdisi models for the models which do not implement addflip separately.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: G = C.jacobian(model='hess', base_div=b).group()
sage: pl1 = C([-1,2,1]).place()
sage: pl2 = C([2,19,1]).place()
sage: p1 = G.point(pl1 - b)
sage: p2 = G.point(pl2 - b)
sage: p1.addflip(p2)
[Place (y + 8, z + 27)]
sage: _ == -(p1 + p2)
True
divisor()[source]

Return a function field divisor in the divisor class of this Jacobian element.

class sage.rings.function_field.jacobian_base.JacobianPoint_finite_field_base[source]

Bases: JacobianPoint_base

Points of Jacobians over finite fields.

additive_order()[source]

Return the order of this point.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: F = C.function_field()
sage: h = C.function(y/x).divisor_of_poles()
sage: J = C.jacobian(model='km_large', base_div=h)
sage: G = J.group()
sage: b = F.get_place(1)
sage: pl = C([-1,2,1]).place()
sage: p = G.point(pl - b)
sage: p.order()
15

sage: b = C([0,1,0]).place()
sage: G = C.jacobian(model='hess', base_div=b).group()
sage: p = C([-1,2,1]).place()
sage: pt = G.point(p - b)
sage: pt.order()
30

ALGORITHM: Shanks’ Baby Step Giant Step

frobenius()[source]

Return the image of the point acted by the Frobenius automorphism.

EXAMPLES:

sage: k = GF(7)
sage: A.<x,y> = AffineSpace(k,2)
sage: C = Curve(y^2 + x^3 + 2*x + 1).projective_closure()
sage: J = C.jacobian(model='hess')
sage: G1 = J.group()
sage: G1.order()
11
sage: K = k.extension(3)
sage: G3 = J.group(K)
sage: pts1 = G1.get_points(11)
sage: pts3 = G3.get_points(12)
sage: pt = next(pt for pt in pts3 if pt not in pts1)
sage: pt.frobenius() == pt
False
sage: pt.frobenius().frobenius().frobenius() == pt
True
class sage.rings.function_field.jacobian_base.Jacobian_base(function_field: FunctionField, base_div: FunctionFieldDivisor | FunctionFieldPlace, **kwds)[source]

Bases: Parent

Jacobians of function fields.

EXAMPLES:

sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
sage: F.jacobian()
Jacobian of Function field in y defined by y^2 + y + (x^2 + 1)/x (Hess model)
base_curve()[source]

Return the base curve or the function field that abstractly defines a curve.

EXAMPLES:

sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
sage: J = F.jacobian()
sage: J.base_curve()
Function field in y defined by y^2 + y + (x^2 + 1)/x
base_divisor()[source]

Return the base divisor used to construct the Jacobian.

EXAMPLES:

sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
sage: b = F.get_place(1)
sage: J = F.jacobian(base_div=b)
sage: J.base_divisor() == b
True
curve()[source]

Return the projective curve to which this Jacobian is attached.

If the Jacobian was constructed from a function field, then returns nothing.

EXAMPLES:

sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
sage: J = F.jacobian()
sage: J.curve()
facade_for()[source]

Return the system of groups that this Jacobian is a facade for.

The Jacobian can be seen as a facade for all groups of rational points over field extensions of the base constant field of the function field. This method returns only the internally constructed system of such groups.

EXAMPLES:

sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
sage: J = F.jacobian()
sage: J.facade_for()
[Group of rational points of Jacobian over Finite Field of size 2 (Hess model)]
group(k_ext=None)[source]

Return the group of rational points of the Jacobian.

EXAMPLES:

sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
sage: b = F.get_place(1)
sage: J = F.jacobian(base_div=b)
sage: J.group()
Group of rational points of Jacobian over Finite Field of size 2 (Hess model)
set_base_place(place)[source]

Set place as the base place.

INPUT:

  • place – a rational place of the function field

The base place \(B\) is used to map a rational place \(P\) of the function field to the point of the Jacobian defined by the divisor \(P - B\).

EXAMPLES:

sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
sage: J = F.jacobian()
sage: B = F.get_place(1)
sage: J.set_base_place(B)
sage: Q = F.places()[-1]
sage: J(Q)
[Place (x + 1, x*y + 1)]
sage: J(Q).parent()
Group of rational points of Jacobian over Finite Field of size 2 (Hess model)
sage: J(B)
[Place (x, x*y)]
sage: J(B).is_zero()
True