# Jacobians of function fields#

This module provides base classes for Jacobians of function fields.

## Jacobian#

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

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(29)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> F = C.function_field()
>>> J = F.jacobian()
>>> J
Jacobian of Function field in z defined by z^3 + 23*y^2*z + 6 (Hess model)
>>> 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)

>>> from sage.all import *
>>> J_km = F.jacobian(model='km_large')
>>> 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

>>> from sage.all import *
>>> G = J.group()
>>> G.order()
30
>>> pl1 = C([Integer(1),Integer(8),Integer(1)]).place()
>>> pl2 = C([Integer(2),Integer(10),Integer(1)]).place()
>>> p1 = G.point(pl1 - pl2)
>>> p1
[Place (y + 1, z + 6)]
>>> p2 = G.point(pl2 - pl1)
>>> p2
[Place (y + 28, z + 6)]
>>> p1 + p2 == G.zero()
True
>>> 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]

>>> from sage.all import *
>>> p1km = J_km(p1)
>>> p1km.order()
5
>>> 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

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

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

>>> from sage.all import *
>>> k = GF(Integer(7))
>>> P2 = ProjectiveSpace(k, Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> J = C.jacobian(model='hess')
>>> G = J.group()
>>> F, obj = G.construction()
>>> 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)

>>> from sage.all import *
>>> k = GF(Integer(7))
>>> P2 = ProjectiveSpace(k, Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> J = C.jacobian(model='hess')
>>> K2 = k.extension(Integer(2))
>>> G2 = J.group(K2)
>>> K3 = k.extension(Integer(3))
>>> G3 = J.group(K3)
>>> 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, base_div)[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)

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(7)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> J = C.jacobian(model='hess')
>>> 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

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(7)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> J = C.jacobian(model='hess', base_div=b)
>>> G = J.group()
>>> G.base_divisor()
Place (1/y, 1/y*z)
>>> _ == Integer(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)

>>> from sage.all import *
>>> p = C([-Integer(1),Integer(2),Integer(1)]).place()
>>> 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

>>> from sage.all import *
>>> k = GF(Integer(7))
>>> P2 = ProjectiveSpace(k, Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> J = C.jacobian(model='hess')
>>> K2 = k.extension(Integer(2))
>>> G2 = J.group(K2)
>>> K3= k.extension(Integer(3))
>>> G3 = J.group(K3)
>>> p1, p2 = G2.get_points(Integer(2))
>>> q1, q2 = G3.get_points(Integer(2))
>>> (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

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(7)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> J = C.jacobian(model='hess')
>>> G = J.group()
>>> 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)

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(7)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> J = C.jacobian(model='hess')
>>> G = J.group()
>>> 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, base_div)[source]#

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)

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(7)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> J = C.jacobian(model='hess', base_div=b)
>>> 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 – an 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

>>> from sage.all import *
>>> k = GF(Integer(7))
>>> A = AffineSpace(k,Integer(2), names=('x', 'y',)); (x, y,) = A._first_ngens(2)
>>> C = Curve(y**Integer(2) + x**Integer(3) + Integer(2)*x + Integer(1)).projective_closure()
>>> J = C.jacobian(model='hess')
>>> G = J.group()
>>> pts = G.get_points(G.order())
>>> 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

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(7)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> J = C.jacobian(model='hess', base_div=b)
>>> G = J.group()
>>> G.order()
7

class sage.rings.function_field.jacobian_base.JacobianPoint_base[source]#

Bases: ModuleElement

Abstract base class of points of Jacobian groups.

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

Points of Jacobians over finite fields.

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

>>> from sage.all import *
>>> k = GF(Integer(7))
>>> A = AffineSpace(k,Integer(2), names=('x', 'y',)); (x, y,) = A._first_ngens(2)
>>> C = Curve(y**Integer(2) + x**Integer(3) + Integer(2)*x + Integer(1)).projective_closure()
>>> J = C.jacobian(model='hess')
>>> G1 = J.group()
>>> G1.order()
11
>>> K = k.extension(Integer(3))
>>> G3 = J.group(K)
>>> pts1 = G1.get_points(Integer(11))
>>> pts3 = G3.get_points(Integer(12))
>>> pt = next(pt for pt in pts3 if pt not in pts1)
>>> pt.frobenius() == pt
False
>>> pt.frobenius().frobenius().frobenius() == pt
True

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

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


ALGORITHM: Shanks’ Baby Step Giant Step

class sage.rings.function_field.jacobian_base.Jacobian_base(function_field, base_div, **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)

>>> from sage.all import *
>>> K = FunctionField(GF(Integer(2)), names=('x',)); (x,) = K._first_ngens(1); _ = K['Y']; (Y,) = _._first_ngens(1)
>>> F = K.extension(Y**Integer(2) + Y + x + Integer(1)/x, names=('y',)); (y,) = F._first_ngens(1)
>>> 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

>>> from sage.all import *
>>> K = FunctionField(GF(Integer(2)), names=('x',)); (x,) = K._first_ngens(1); _ = K['Y']; (Y,) = _._first_ngens(1)
>>> F = K.extension(Y**Integer(2) + Y + x + Integer(1)/x, names=('y',)); (y,) = F._first_ngens(1)
>>> J = F.jacobian()
>>> 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

>>> from sage.all import *
>>> K = FunctionField(GF(Integer(2)), names=('x',)); (x,) = K._first_ngens(1); _ = K['Y']; (Y,) = _._first_ngens(1)
>>> F = K.extension(Y**Integer(2) + Y + x + Integer(1)/x, names=('y',)); (y,) = F._first_ngens(1)
>>> b = F.get_place(Integer(1))
>>> J = F.jacobian(base_div=b)
>>> 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()

>>> from sage.all import *
>>> K = FunctionField(GF(Integer(2)), names=('x',)); (x,) = K._first_ngens(1); _ = K['Y']; (Y,) = _._first_ngens(1)
>>> F = K.extension(Y**Integer(2) + Y + x + Integer(1)/x, names=('y',)); (y,) = F._first_ngens(1)
>>> J = F.jacobian()
>>> J.curve()


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()
[Group of rational points of Jacobian over Finite Field of size 2 (Hess model)]

>>> from sage.all import *
>>> K = FunctionField(GF(Integer(2)), names=('x',)); (x,) = K._first_ngens(1); _ = K['Y']; (Y,) = _._first_ngens(1)
>>> F = K.extension(Y**Integer(2) + Y + x + Integer(1)/x, names=('y',)); (y,) = F._first_ngens(1)
>>> J = F.jacobian()
[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)

>>> from sage.all import *
>>> K = FunctionField(GF(Integer(2)), names=('x',)); (x,) = K._first_ngens(1); _ = K['Y']; (Y,) = _._first_ngens(1)
>>> F = K.extension(Y**Integer(2) + Y + x + Integer(1)/x, names=('y',)); (y,) = F._first_ngens(1)
>>> b = F.get_place(Integer(1))
>>> J = F.jacobian(base_div=b)
>>> 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

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