Skip to content

Commit

Permalink
Add Jacobian to function fields and curves
Browse files Browse the repository at this point in the history
  • Loading branch information
kwankyu committed Mar 8, 2024
1 parent cb8e15b commit 1bad7be
Show file tree
Hide file tree
Showing 14 changed files with 3,942 additions and 65 deletions.
25 changes: 19 additions & 6 deletions src/doc/en/reference/curves/index.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
Plane and Space Curves
======================

Sage enables computations with curves in affine and projective ambient spaces,
curves over `\CC` as Riemann surfaces, and Jacobians of projective curves.

Curves
======
------

.. toctree::
:maxdepth: 1
Expand All @@ -12,10 +18,8 @@ Curves
sage/schemes/curves/closed_point
sage/schemes/curves/zariski_vankampen

sage/schemes/jacobians/abstract_jacobian

Plane conics
============
------------

.. toctree::
:maxdepth: 1
Expand All @@ -28,7 +32,7 @@ Plane conics
sage/schemes/plane_conics/con_rational_function_field

Plane quartics
=========================
--------------

.. toctree::
:maxdepth: 1
Expand All @@ -37,11 +41,20 @@ Plane quartics
sage/schemes/plane_quartics/quartic_generic

Riemann surfaces
================
----------------

.. toctree::
:maxdepth: 1

sage/schemes/riemann_surfaces/riemann_surface

Jacobians
---------

.. toctree::
:maxdepth: 1

sage/schemes/jacobians/abstract_jacobian
sage/schemes/jacobians/khuri_makdisi

.. include:: ../footer.txt
12 changes: 12 additions & 0 deletions src/doc/en/reference/function_fields/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ algebraic closure of `\QQ`.

A basic reference for the theory of algebraic function fields is [Stich2009]_.

Jacobians of function fields
----------------------------

Arithmetic in Jacobians of function fields are available in two flavors.

.. toctree::
:maxdepth: 1

sage/rings/function_field/jacobian_base
sage/rings/function_field/jacobian_hess
sage/rings/function_field/jacobian_khuri_makdisi

A Support Module
----------------

Expand Down
6 changes: 6 additions & 0 deletions src/doc/en/reference/references/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3155,6 +3155,9 @@ REFERENCES:
Cryptanalysis* ; 2002' available at
http://www.engr.mun.ca/~howard/PAPERS/ldc_tutorial.pdf
.. [Hes2004] Florian Hess, "Computing relations in divisor class groups of
algebraic curves over finite fields," Preprint, 2004.
.. [Hes2002] Florian Hess, "Computing Riemann-Roch spaces in algebraic
function fields and related topics," J. Symbolic
Comput. 33 (2002), no. 4, 425--445.
Expand Down Expand Up @@ -3750,6 +3753,9 @@ REFERENCES:
block cipher*, Lightweight Cryptography Workshop, 2016.
https://www.nist.gov/sites/default/files/documents/2016/10/18/karpman-paper-lwc2016.pdf
.. [Khu2004] \K. Khuri-Makdisi. *Linear algebra algorithms for divisors on an algebraic curve*,
Mathematics of Computation 73, no. 245 (2004) pp. 333-357.
.. [Kin1992] Nancy G. Kinnersley, *The vertex separation number of a graph
equals its path-width*, Information Processing Letters
42(6):345-350, 1992. :doi:`10.1016/0020-0190(92)90234-M`.
Expand Down
90 changes: 90 additions & 0 deletions src/sage/rings/function_field/function_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -1245,3 +1245,93 @@ def extension_constant_field(self, k):
"""
from .extensions import ConstantFieldExtension
return ConstantFieldExtension(self, k)

@cached_method
def jacobian(self, model=None, base_div=None, **kwds):
"""
Return the Jacobian of the function field.
INPUT:
- ``model`` -- (default: ``'hess'``) model to use for arithmetic
- ``base_div`` -- an effective divisor
The degree of the base divisor should satisfy certain degree condition
corresponding to the model used. The following table lists these
conditions. Let `g` be the genus of the function field.
- ``hess``: ideal-based arithmetic; requires base divisor of degree `g`
- ``km_large``: Khuri-Makdisi's large model; requires base divisor of
degree at least `2g + 1`
- ``km_medium``: Khuri-Makdisi's medium model; requires base divisor of
degree at least `2g + 1`
- ``km_small``: Khuri-Makdisi's small model requires base divisor of
degree at least `g + 1`
We assume the function field has a rational place. If a base divisor is
not given, one is constructed using an arbitrary rational place.
EXAMPLES::
sage: A.<x,y> = AffineSpace(GF(5), 2)
sage: C = Curve(y^2*(x^3 - 1) - (x^3 - 2))
sage: F = C.function_field()
sage: F.jacobian()
Jacobian of Function field in y defined by (x^3 + 4)*y^2 + 4*x^3 + 2 over Finite Field of size 5 (Hess model)
"""
from .place import FunctionFieldPlace

if model is None:
model = 'hess'

if base_div is None:
try:
base_place = self.get_place(1)
except AttributeError:
raise ValueError('failed to obtain a rational place; provide a base divisor')
if base_place is None:
raise ValueError('the function field has no rational place')
# appropriate base divisor is constructed below.
else:
if isinstance(base_div, FunctionFieldPlace):
base_div = base_div.divisor()

g = self.genus()
curve = kwds.get('curve')

if model.startswith('km'):
from .jacobian_khuri_makdisi import Jacobian
if model == 'km' or model.endswith('large'):
if base_div is None:
base_div = (2*g + 1) * base_place
if not base_div.degree() >= 2*g + 1:
raise ValueError("Khuri-Makdisi large model requires base divisor of degree "
"at least 2*g + 1 for genus g")
return Jacobian(self, base_div, model='large', curve=curve)
elif model.endswith('medium'):
if base_div is None:
base_div = (2*g + 1) * base_place
if not base_div.degree() >= 2*g + 1:
raise ValueError("Khuri-Makdisi medium model requires base divisor of degree "
"at least 2*g + 1 for genus g")
return Jacobian(self, base_div, model='medium', curve=curve)
elif model.endswith('small'):
if base_div is None:
base_div = (g + 1) * base_place
if not base_div.degree() >= g + 1:
raise ValueError("Khuri-Makdisi small model requires base divisor of degree "
"at least g + 1 for genus g")
return Jacobian(self, base_div, model='small', curve=curve)
elif model == 'hess':
from .jacobian_hess import Jacobian
if base_div is None:
base_div = g * base_place
if base_div.degree() != g:
raise ValueError("Hess model requires base divisor of degree g for genus g")
return Jacobian(self, base_div, curve=curve)

raise ValueError("unknown model")
88 changes: 44 additions & 44 deletions src/sage/rings/function_field/function_field_polymod.py
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,50 @@ def residue_field(self, place, name=None):
"""
return place.residue_field(name=name)

def places_infinite(self, degree=1):
"""
Return a list of the infinite places with ``degree``.
INPUT:
- ``degree`` -- positive integer (default: `1`)
EXAMPLES::
sage: # needs sage.rings.finite_rings
sage: F.<a> = GF(2)
sage: K.<x> = FunctionField(F)
sage: R.<t> = PolynomialRing(K)
sage: L.<y> = K.extension(t^4 + t - x^5)
sage: L.places_infinite(1)
[Place (1/x, 1/x^4*y^3)]
"""
return list(self._places_infinite(degree))

def _places_infinite(self, degree):
"""
Return a generator of *infinite* places with ``degree``.
INPUT:
- ``degree`` -- positive integer
EXAMPLES::
sage: # needs sage.rings.finite_rings
sage: F.<a> = GF(2)
sage: K.<x> = FunctionField(F)
sage: R.<t> = PolynomialRing(K)
sage: L.<y> = K.extension(t^4 + t - x^5)
sage: L._places_infinite(1)
<generator object ...>
"""
Oinf = self.maximal_order_infinite()
for prime, _, _ in Oinf.decomposition():
place = prime.place()
if place.degree() == degree:
yield place


class FunctionField_char_zero(FunctionField_simple):
"""
Expand Down Expand Up @@ -2129,50 +2173,6 @@ def _places_finite(self, degree):
if place.degree() == degree:
yield place

def places_infinite(self, degree=1):
"""
Return a list of the infinite places with ``degree``.
INPUT:
- ``degree`` -- positive integer (default: `1`)
EXAMPLES::
sage: # needs sage.rings.finite_rings
sage: F.<a> = GF(2)
sage: K.<x> = FunctionField(F)
sage: R.<t> = PolynomialRing(K)
sage: L.<y> = K.extension(t^4 + t - x^5)
sage: L.places_infinite(1)
[Place (1/x, 1/x^4*y^3)]
"""
return list(self._places_infinite(degree))

def _places_infinite(self, degree):
"""
Return a generator of *infinite* places with ``degree``.
INPUT:
- ``degree`` -- positive integer
EXAMPLES::
sage: # needs sage.rings.finite_rings
sage: F.<a> = GF(2)
sage: K.<x> = FunctionField(F)
sage: R.<t> = PolynomialRing(K)
sage: L.<y> = K.extension(t^4 + t - x^5)
sage: L._places_infinite(1)
<generator object ...>
"""
Oinf = self.maximal_order_infinite()
for prime, _, _ in Oinf.decomposition():
place = prime.place()
if place.degree() == degree:
yield place

def gaps(self):
"""
Return the gaps of the function field.
Expand Down
Loading

0 comments on commit 1bad7be

Please sign in to comment.