forked from sagemath/sage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sagemathgh-35467: Attach Jacobians to function fields and curves
<!-- Please provide a concise, informative and self-explanatory title. --> <!-- Don't put issue numbers in the title. Put it in the Description below. --> <!-- For example, instead of "Fixes sagemath#12345", use "Add a new method to multiply two integers" --> ### 📚 Description We attach Jacobians to function fields and curves, enabling arithmetic with the points of the Jacobian. Fixes sagemath#34232. A point of Jacobian is represented by an effective divisor `D` such that the point is the divisor class of `D - B` (of degree 0) with a fixed base divisor `B`. There are two models for Jacobian arithmetic: - Hess model: `D` is internally represented by a pair of certain ideals and arithmetic relies on divisor reduction using Riemann-Roch space computation by Hess' algorithm. - Khuri-Makdisi model: `D` is internally represented by a linear subspace `W_D` of a linear space `V` and arithmetic uses Khuri-Makdisi's linear algebra algorithms. For implementation, sagemath#15113 was referenced. An example with non-hyperelliptic genus 3 curve: ```sage sage: A2.<x,y> = AffineSpace(QQ, 2) sage: f = y^3 + x^4 - 5*x^2*y + 2*x*y - x^2 - 5*y - 4*x + 1 sage: C = Curve(f, A2) sage: X = C.projective_closure() sage: X.genus() 3 sage: X.rational_points(bound=5) [(0 : 0 : 1), (1/3 : 1/3 : 1)] sage: Q = X(0,0,1).place() sage: P = X(1,1,3).place() sage: D = P - Q sage: D.degree() 0 sage: J = X.jacobian(model='hess', base_div=3*Q) sage: G = J.group() sage: p = G.point(D) sage: 2*p + 3*p == 5*p True ``` An example with elliptic curve: ```sage sage: k.<a> = GF((5,2)) sage: E = EllipticCurve(k,[1,0]); E Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size 5^2 sage: E.order() 32 sage: P = E([a, 2*a + 4]) sage: P (a : 2*a + 4 : 1) sage: P.order() 8 sage: p = P.point_of_jacobian_of_curve() sage: p [Place (x + 4*a, y + 3*a + 1)] sage: p.order() 8 sage: Q = 3*P sage: q = Q.point_of_jacobian_of_curve() sage: q == 3*p True sage: G = p.parent() sage: G.order() 32 sage: G Group of rational points of Jacobian over Finite Field in a of size 5^2 (Hess model) sage: J = G.parent(); J Jacobian of Projective Plane Curve over Finite Field in a of size 5^2 defined by x^2*y + y^3 - x*z^2 (Hess model) sage: J.curve() == E.affine_patch(2).projective_closure() True ``` An example with hyperelliptic curve: ```sage sage: R.<x> = PolynomialRing(GF(11)) sage: f = x^6 + x + 1 sage: H = HyperellipticCurve(f) sage: J = H.jacobian() sage: D = J(H.lift_x(1)) sage: D # divisor in Mumford representation (x + 10, y + 6) sage: jacobian_order = sum(H.frobenius_polynomial()) sage: jacobian_order 234 sage: p = D.point_of_jacobian_of_curve(); p sage: p # Jacobian point represented by an effective divisor [Place (1/x0, 1/x0^3*x1 + 1) + Place (x0 + 10, x1 + 6)] sage: p.order() 39 sage: 234*p == 0 True sage: G = p.parent() sage: G Group of rational points of Jacobian over Finite Field of size 11 (Hess model) sage: J = G.parent() sage: J Jacobian of Projective Plane Curve over Finite Field of size 11 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2 (Hess model) sage: C = J.curve() sage: C Projective Plane Curve over Finite Field of size 11 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2 sage: C.affine_patch(0) == H.affine_patch(2) True ``` [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2 /gh/kwankyu/sage/p/35467/add-jacobian-groups-notebook-binder) prepared with sagemath#36245 <!-- Describe your changes here in detail. --> <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes sagemath#12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x ]`. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - sagemath#12345: short description why this is a dependency - sagemath#34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: sagemath#35467 Reported by: Kwankyu Lee Reviewer(s): Kwankyu Lee, Matthias Köppe
- Loading branch information
Showing
18 changed files
with
4,284 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,18 @@ | ||
r""" | ||
Schemes | ||
""" | ||
|
||
# **************************************************************************** | ||
# Copyright (C) 2005 David Kohel <[email protected]> | ||
# Copyright (C) 2005 David Kohel <[email protected]> | ||
# William Stein <[email protected]> | ||
# 2008-2012 Nicolas M. Thiery <nthiery at users.sf.net> | ||
# 2008-2012 Nicolas M. Thiery <nthiery@users.sf.net> | ||
# | ||
# Distributed under the terms of the GNU General Public License (GPL) | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 2 of the License, or | ||
# (at your option) any later version. | ||
# https://www.gnu.org/licenses/ | ||
# ***************************************************************************** | ||
# **************************************************************************** | ||
|
||
from sage.categories.category import Category | ||
from sage.categories.category_types import Category_over_base | ||
|
@@ -18,6 +22,7 @@ | |
from sage.categories.rings import Rings | ||
from sage.categories.fields import Fields | ||
from sage.categories.homsets import HomsetsCategory | ||
from sage.misc.abstract_method import abstract_method | ||
|
||
|
||
class Schemes(Category): | ||
|
@@ -55,7 +60,6 @@ class Schemes(Category): | |
sage: Schemes().Homsets().super_categories() | ||
[Category of homsets] | ||
""" | ||
|
||
@staticmethod | ||
def __classcall_private__(cls, X=None): | ||
""" | ||
|
@@ -73,8 +77,7 @@ def __classcall_private__(cls, X=None): | |
Category of schemes over Integer Ring | ||
""" | ||
if X is not None: | ||
from sage.schemes.generic.scheme import is_Scheme | ||
if not is_Scheme(X): | ||
if X not in Schemes(): | ||
X = Schemes()(X) | ||
return Schemes_over_base(X) | ||
return super().__classcall__(cls) | ||
|
@@ -155,9 +158,6 @@ def _call_(self, x): | |
raise TypeError("No way to create an object or morphism in %s from %s" % (self, x)) | ||
|
||
|
||
############################################################# | ||
# Schemes over a given base scheme. | ||
############################################################# | ||
class Schemes_over_base(Category_over_base): | ||
""" | ||
The category of schemes over a given base scheme. | ||
|
@@ -172,7 +172,6 @@ class Schemes_over_base(Category_over_base): | |
sage: C = Schemes(ZZ) | ||
sage: TestSuite(C).run() | ||
""" | ||
|
||
def base_scheme(self): | ||
""" | ||
EXAMPLES:: | ||
|
@@ -198,12 +197,12 @@ def _repr_object_names(self): | |
sage: Schemes(Spec(ZZ)) # indirect doctest | ||
Category of schemes over Integer Ring | ||
""" | ||
# To work around the name of the class (schemes_over_base) | ||
from sage.schemes.generic.scheme import is_AffineScheme | ||
if is_AffineScheme(self.base_scheme()): | ||
return "schemes over %s" % self.base_scheme().coordinate_ring() | ||
else: | ||
return "schemes over %s" % self.base_scheme() | ||
base = self.base() | ||
if is_AffineScheme(base): | ||
base = base.coordinate_ring() | ||
return f"schemes over {base}" | ||
|
||
|
||
class AbelianVarieties(Schemes_over_base): | ||
r""" | ||
|
@@ -236,6 +235,18 @@ def __init__(self, base): | |
raise ValueError('category of abelian varieties is only defined over fields') | ||
super().__init__(base) | ||
|
||
def base_scheme(self): | ||
""" | ||
EXAMPLES:: | ||
sage: Schemes(Spec(ZZ)).base_scheme() | ||
Spectrum of Integer Ring | ||
""" | ||
base = self.base() | ||
if base not in Schemes(): | ||
base = Schemes()(base) | ||
return base | ||
|
||
def super_categories(self): | ||
""" | ||
EXAMPLES:: | ||
|
@@ -253,7 +264,7 @@ def _repr_object_names(self): | |
sage: AbelianVarieties(Spec(QQ)) # indirect doctest | ||
Category of abelian varieties over Rational Field | ||
""" | ||
return "abelian varieties over %s" % self.base_scheme() | ||
return "abelian varieties over %s" % self.base() | ||
|
||
class Homsets(HomsetsCategory): | ||
r""" | ||
|
@@ -294,3 +305,87 @@ def extra_super_categories(self): | |
True | ||
""" | ||
return [Rings()] | ||
|
||
|
||
class Jacobians(Schemes_over_base): | ||
""" | ||
The category of Jacobians attached to curves or function fields. | ||
EXAMPLES:: | ||
sage: Jacobians(QQ) | ||
Category of Jacobians over Rational Field | ||
TESTS:: | ||
sage: TestSuite(Jacobians(QQ)).run() | ||
""" | ||
def __init__(self, base): | ||
r""" | ||
Constructor of this category. | ||
EXAMPLES:: | ||
sage: Jacobians(QQ) | ||
Category of Jacobians over Rational Field | ||
sage: Jacobians(Spec(QQ)) | ||
Category of Jacobians over Rational Field | ||
""" | ||
from sage.schemes.generic.scheme import is_AffineScheme | ||
if is_AffineScheme(base): | ||
base = base.coordinate_ring() | ||
if base not in Fields(): | ||
raise ValueError('category of Jacobians is only defined over fields') | ||
super().__init__(base) | ||
|
||
def base_scheme(self): | ||
""" | ||
Return the base scheme of this Jacobians category. | ||
EXAMPLES:: | ||
sage: Jacobians(QQ).base_scheme() | ||
Spectrum of Rational Field | ||
""" | ||
base = self.base() | ||
if base not in Schemes(): | ||
base = Schemes()(base) | ||
return base | ||
|
||
def super_categories(self): | ||
""" | ||
Return the super categories of this Jacobians category. | ||
EXAMPLES:: | ||
sage: Jacobians(QQ).super_categories() | ||
[Category of abelian varieties over Rational Field] | ||
""" | ||
return [AbelianVarieties(self.base_scheme())] | ||
|
||
def _repr_object_names(self): | ||
""" | ||
Return the string representation of this category. | ||
EXAMPLES:: | ||
sage: Jacobians(Spec(QQ)) # indirect doctest | ||
Category of Jacobians over Rational Field | ||
""" | ||
return "Jacobians over %s" % self.base() | ||
|
||
class ParentMethods: | ||
|
||
@abstract_method | ||
def base_curve(self): | ||
""" | ||
Return the curve to which this Jacobian is attached. | ||
EXAMPLES:: | ||
sage: # needs sage.rings.function_field | ||
sage: K.<x> = FunctionField(GF(2)) | ||
sage: J = K.jacobian() | ||
sage: J.base_curve() | ||
Rational function field in x over Finite Field of size 2 | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.