Skip to content

Commit

Permalink
bugfix in the genus code (addresses #28336
Browse files Browse the repository at this point in the history
)
  • Loading branch information
katie committed Jan 26, 2025
1 parent 5188024 commit 98b29b9
Showing 1 changed file with 86 additions and 28 deletions.
114 changes: 86 additions & 28 deletions src/sage/schemes/curves/curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
AUTHORS:
- William Stein (2005)
- Katie Ahrens (2024): fixed #28336
"""
# ****************************************************************************
# Copyright (C) 2005 William Stein <[email protected]>
Expand All @@ -38,8 +40,10 @@
from sage.schemes.generic.divisor_group import DivisorGroup
from sage.schemes.generic.divisor import Divisor_curve

from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
from sage.rings.integer import Integer

from sage.rings.rational_field import is_RationalField
from sage.rings.qqbar import QQbar

class Curve_generic(AlgebraicScheme_subscheme):
r"""
Expand Down Expand Up @@ -153,8 +157,8 @@ def divisor_group(self, base_ring=None):
INPUT:
- ``base_ring`` -- the base ring of the divisor group; usually, this is
`\ZZ` (default) or `\QQ`
- ``base_ring`` -- the base ring of the divisor group. Usually, this is
`\ZZ` (default) or `\QQ`.
OUTPUT: the divisor group of the curve
Expand Down Expand Up @@ -201,16 +205,52 @@ def genus(self):
sage: C = Curve(y^2*z - x^3 - 17*x*z^2 + y*z^2)
sage: C.genus()
1
Throw an error if the curve is not geometrically irreducible. Addresses issue #28336.
sage: x,y = PolynomialRing(QQ, 2, names='x,y').gens()
sage: C = Curve(x^2+y^2)
sage: C.genus()
Traceback (most recent call last):
...
NotImplementedError: Curve is not geometrically irreducible
sage: FF.<y> =QQ[]
sage: R.<x> = FF[]
sage: K = QQ[y, x]
sage: poly2 = K(x^2 - y^4)
sage: C2 = Curve(poly2)
sage: C2.genus()
Traceback (most recent call last):
...
NotImplementedError: Curve is not irreducible over the ground field
Geometric irreducibility is also checked for finite fields.
sage: x,y = PolynomialRing(GF(5), 2, names='x,y').gens()
sage: C = Curve(x^2+2)
sage: C.genus()
Traceback (most recent call last):
...
NotImplementedError: Curve is not geometrically irreducible
"""

return self.geometric_genus()

def geometric_genus(self):
r"""
Return the geometric genus of the curve.
This is by definition the genus of the normalization of the projective
closure of the curve over the algebraic closure of the base field; the
base field must be a prime field.
.. NOTE::
This calls Singular's genus command.
EXAMPLES:
Examples of projective curves::
Examples of projective curves. ::
sage: P2 = ProjectiveSpace(2, GF(5), names=['x','y','z'])
sage: x, y, z = P2.coordinate_ring().gens()
Expand All @@ -224,7 +264,14 @@ def geometric_genus(self):
sage: C.geometric_genus()
3
Examples of affine curves::
Addressing issue #28336
sage: C = Curve(x^2+y^2)
sage: C.geometric_genus()
Traceback (most recent call last):
...
NotImplementedError: Curve is not irreducible over the ground field
Examples of affine curves. ::
sage: x, y = PolynomialRing(GF(5), 2, 'xy').gens()
sage: C = Curve(y^2 - x^3 - 17*x + y)
Expand All @@ -237,22 +284,31 @@ def geometric_genus(self):
sage: C.geometric_genus()
3
.. WARNING::
Geometric genus is only defined for `geometrically irreducible curve
<https://stacks.math.columbia.edu/tag/0BYE>`_. This method does not
check the condition. You may get a nonsensical result if the curve is
not geometrically irreducible::
sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = Curve(x^2 + y^2, P2)
sage: C.geometric_genus() # nonsense!
-1
"""
k=self.base_ring()

#handle the rational case
if is_RationalField(k):
curve_over_closure = self.change_ring(QQbar)
if len(curve_over_closure.defining_polynomial().factor()) > 1:
if self.is_irreducible():
raise NotImplementedError("Curve is not geometrically irreducible")
else:
raise NotImplementedError("Curve is not irreducible over the ground field")

#handle the finite field case
if k.is_finite():
if len(self.change_ring(GF(k.characteristic()**self.defining_polynomial().degree())).defining_polynomial().factor()) > 1:
if self.is_irreducible():
raise NotImplementedError("Curve is not geometrically irreducible")
else:
raise NotImplementedError("Curve is not irreducible over the ground field")

try:
return self._genus
except AttributeError:
raise NotImplementedError
self._genus = self.defining_ideal().genus()
return self._genus

def union(self, other):
"""
Expand All @@ -275,7 +331,9 @@ def singular_subscheme(self):
r"""
Return the subscheme of singular points of this curve.
OUTPUT: a subscheme in the ambient space of this curve
OUTPUT:
- a subscheme in the ambient space of this curve.
EXAMPLES::
Expand Down Expand Up @@ -313,10 +371,10 @@ def singular_points(self, F=None):
INPUT:
- ``F`` -- (default: ``None``) field over which to find the singular
- ``F`` -- (default: None) field over which to find the singular
points; if not given, the base ring of this curve is used
OUTPUT: list of points in the ambient space of this curve
OUTPUT: a list of points in the ambient space of this curve
EXAMPLES::
Expand Down Expand Up @@ -360,13 +418,13 @@ def is_singular(self, P=None):
INPUT:
- ``P`` -- (default: ``None``) a point on this curve
- ``P`` -- (default: None) a point on this curve
OUTPUT:
boolean; if a point ``P`` is provided, and if ``P`` lies on this
curve, returns ``True`` if ``P`` is a singular point of this curve, and
``False`` otherwise. If no point is provided, returns ``True`` or False
A boolean. If a point ``P`` is provided, and if ``P`` lies on this
curve, returns True if ``P`` is a singular point of this curve, and
False otherwise. If no point is provided, returns True or False
depending on whether this curve is or is not singular, respectively.
EXAMPLES::
Expand All @@ -393,9 +451,9 @@ def intersects_at(self, C, P):
INPUT:
- ``C`` -- a curve in the same ambient space as this curve
- ``C`` -- a curve in the same ambient space as this curve.
- ``P`` -- a point in the ambient space of this curve
- ``P`` -- a point in the ambient space of this curve.
EXAMPLES::
Expand Down Expand Up @@ -448,11 +506,11 @@ def intersection_points(self, C, F=None):
- ``C`` -- a curve in the same ambient space as this curve
- ``F`` -- (default: ``None``) field over which to compute the
- ``F`` -- (default: None); field over which to compute the
intersection points; if not specified, the base ring of this curve is
used
OUTPUT: list of points in the ambient space of this curve
OUTPUT: a list of points in the ambient space of this curve
EXAMPLES::
Expand Down

0 comments on commit 98b29b9

Please sign in to comment.