Skip to content

Commit

Permalink
Many fixes related with genus
Browse files Browse the repository at this point in the history
  • Loading branch information
kwankyu committed Mar 4, 2024
1 parent 4ac7152 commit 2339e7b
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 47 deletions.
23 changes: 21 additions & 2 deletions src/sage/rings/function_field/function_field_polymod.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@
from sage.rings.integer import Integer
from sage.categories.homset import Hom
from sage.categories.function_fields import FunctionFields
from sage.categories.number_fields import NumberFields

from .element import FunctionFieldElement
from .element_polymod import FunctionFieldElement_polymod
from .function_field import FunctionField
from .function_field_rational import RationalFunctionField

_FunctionFields = FunctionFields()
_NumberFields = NumberFields()


class FunctionField_polymod(FunctionField):
"""
Expand Down Expand Up @@ -160,7 +164,7 @@ def __init__(self, polynomial, names, category=None):
self._polynomial = polynomial

FunctionField.__init__(self, base_field, names=names,
category=FunctionFields().or_subcategory(category))
category=_FunctionFields.or_subcategory(category))

from .place_polymod import FunctionFieldPlace_polymod
self._place_class = FunctionFieldPlace_polymod
Expand Down Expand Up @@ -1842,11 +1846,26 @@ def genus(self):
sage: L.genus()
6
sage: # needs sage.rings.number_fields
sage: R.<T> = QQ[]
sage: N.<a> = NumberField(T^2 + 1)
sage: K.<x> = FunctionField(N); K
sage: K.genus()
0
sage: S.<t> = PolynomialRing(K)
sage: L.<y> = K.extension(t^2 - x^3 + x)
sage: L.genus()
1
The genus is computed by the Hurwitz genus formula.
"""
k, _ = self.exact_constant_field()
if k in _NumberFields:
k_degree = k.relative_degree()
else:
k_degree = k.degree()
different_degree = self.different().degree() # must be even
return Integer(different_degree // 2 - self.degree() / k.degree()) + 1
return Integer(different_degree // 2 - self.degree() / k_degree) + 1

def residue_field(self, place, name=None):
"""
Expand Down
15 changes: 11 additions & 4 deletions src/sage/schemes/curves/affine_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -2065,13 +2065,20 @@ def _genus(self):
sage: C = Curve(x^5 + y^5 + x*y + 1)
sage: C.genus() # indirect doctest
1
"""
k = self.base_ring()
TESTS::
sage: R.<T> = QQ[]
sage: N.<a> = NumberField(T^2 + 1)
sage: A2.<x,y> = AffineSpace(N, 2)
sage: C = Curve(y^2 - x^3 + x, A2)
sage: C.genus()
1
"""
# Singular's genus command is usually much faster than the genus method
# of function fields in Sage. But unfortunately Singular's genus
# command does not yet work over non-prime finite fields.
if k.is_finite() and k.degree() > 1:
# command does not work over extension fields.
if self.base_ring().degree() > 1:
return self._function_field.genus()

# call Singular's genus command
Expand Down
70 changes: 48 additions & 22 deletions src/sage/schemes/curves/constructor.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,20 @@
# ********************************************************************

from sage.categories.fields import Fields
from sage.categories.number_fields import NumberFields

from sage.rings.polynomial.multi_polynomial import MPolynomial
from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing
from sage.rings.finite_rings.finite_field_base import FiniteField

from sage.rings.rational_field import QQ

from sage.structure.all import Sequence

from sage.schemes.affine.affine_space import is_AffineSpace
from sage.schemes.generic.ambient_space import is_AmbientSpace
from sage.schemes.generic.algebraic_scheme import is_AlgebraicScheme
from sage.schemes.projective.projective_space import is_ProjectiveSpace

from sage.schemes.affine.affine_space import AffineSpace

from sage.schemes.projective.projective_space import ProjectiveSpace

from sage.schemes.affine.affine_space import AffineSpace, is_AffineSpace
from sage.schemes.projective.projective_space import ProjectiveSpace, is_ProjectiveSpace
from sage.schemes.plane_conics.constructor import Conic

from .projective_curve import (ProjectiveCurve,
ProjectivePlaneCurve,
Expand All @@ -76,8 +72,8 @@
IntegralAffinePlaneCurve,
IntegralAffinePlaneCurve_finite_field)


from sage.schemes.plane_conics.constructor import Conic
_Fields = Fields()
_NumberFields = NumberFields()


def _is_irreducible_and_reduced(F) -> bool:
Expand Down Expand Up @@ -113,11 +109,13 @@ def Curve(F, A=None):
INPUT:
- ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme.
- ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme
- ``A`` -- (default: None) an ambient space in which to create the curve
- ``A`` -- (default: None) an ambient space in which to create the curve.
EXAMPLES:
EXAMPLES: A projective plane curve. ::
A projective plane curve::
sage: x,y,z = QQ['x,y,z'].gens()
sage: C = Curve(x^3 + y^3 + z^3); C
Expand Down Expand Up @@ -215,7 +213,7 @@ def Curve(F, A=None):
sage: Curve(P1)
Projective Line over Finite Field of size 5
::
An affine line::
sage: A1.<x> = AffineSpace(1, QQ)
sage: R = A1.coordinate_ring()
Expand All @@ -224,6 +222,18 @@ def Curve(F, A=None):
sage: Curve(A1)
Affine Line over Rational Field
A projective line::
sage: R.<x> = QQ[]
sage: N.<a> = NumberField(x^2 + 1)
sage: P1.<x,y> = ProjectiveSpace(N, 1)
sage: C = Curve(P1)
sage: C
Projective Line over Number Field in a with defining polynomial x^2 + 1
sage: C.geometric_genus()
0
sage: C.arithmetic_genus()
0
"""
if A is None:
if is_AmbientSpace(F) and F.dimension() == 1:
Expand Down Expand Up @@ -298,12 +308,20 @@ def Curve(F, A=None):
k = A.base_ring()

if is_AffineSpace(A):
if n == 1:
if A.coordinate_ring().ideal(F).is_zero():
if isinstance(k, FiniteField):
return IntegralAffineCurve_finite_field(A, F)
if k in _Fields:
return IntegralAffineCurve(A, F)
return AffineCurve(A, F)
raise TypeError(f"{F} does not define a curve in one-dimensional affine space")
if n != 2:
if isinstance(k, FiniteField):
if A.coordinate_ring().ideal(F).is_prime():
return IntegralAffineCurve_finite_field(A, F)
if k in Fields():
if k == QQ and A.coordinate_ring().ideal(F).is_prime():
if k in _Fields:
if (k == QQ or k in _NumberFields) and A.coordinate_ring().ideal(F).is_prime():
return IntegralAffineCurve(A, F)
return AffineCurve_field(A, F)
return AffineCurve(A, F)
Expand All @@ -316,21 +334,29 @@ def Curve(F, A=None):
if _is_irreducible_and_reduced(F):
return IntegralAffinePlaneCurve_finite_field(A, F)
return AffinePlaneCurve_finite_field(A, F)
if k in Fields():
if k == QQ and _is_irreducible_and_reduced(F):
if k in _Fields:
if (k == QQ or k in _NumberFields) and _is_irreducible_and_reduced(F):
return IntegralAffinePlaneCurve(A, F)
return AffinePlaneCurve_field(A, F)
return AffinePlaneCurve(A, F)

elif is_ProjectiveSpace(A):
if n == 1:
if A.coordinate_ring().ideal(F).is_zero():
if isinstance(k, FiniteField):
return IntegralProjectiveCurve_finite_field(A, F)
if k in _Fields:
return IntegralProjectiveCurve(A, F)
return ProjectiveCurve(A, F)
raise TypeError(f"{F} does not define a curve in one-dimensional projective space")
if n != 2:
if not all(f.is_homogeneous() for f in F):
raise TypeError("polynomials defining a curve in a projective space must be homogeneous")
if isinstance(k, FiniteField):
if A.coordinate_ring().ideal(F).is_prime():
return IntegralProjectiveCurve_finite_field(A, F)
if k in Fields():
if k == QQ and A.coordinate_ring().ideal(F).is_prime():
if k in _Fields:
if (k == QQ or k in _NumberFields) and A.coordinate_ring().ideal(F).is_prime():
return IntegralProjectiveCurve(A, F)
return ProjectiveCurve_field(A, F)
return ProjectiveCurve(A, F)
Expand All @@ -348,8 +374,8 @@ def Curve(F, A=None):
if _is_irreducible_and_reduced(F):
return IntegralProjectivePlaneCurve_finite_field(A, F)
return ProjectivePlaneCurve_finite_field(A, F)
if k in Fields():
if k == QQ and _is_irreducible_and_reduced(F):
if k in _Fields:
if (k == QQ or k in _NumberFields) and _is_irreducible_and_reduced(F):
return IntegralProjectivePlaneCurve(A, F)
return ProjectivePlaneCurve_field(A, F)
return ProjectivePlaneCurve(A, F)
Expand Down
26 changes: 14 additions & 12 deletions src/sage/schemes/curves/curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,17 +209,9 @@ 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 @@ -233,7 +225,7 @@ def geometric_genus(self):
sage: C.geometric_genus()
3
Examples of affine curves. ::
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 @@ -246,12 +238,22 @@ def geometric_genus(self):
sage: C.geometric_genus()
3
Note that the geometric genus is only defined for `geometrically
irreducible curve <https://stacks.math.columbia.edu/tag/0BYE>`_. This
method does not check the condition. Be warned that you may get a
nonsensical result if the curve is not geometrically irreducible.
A geometrically reducible curve::
sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = Curve(x^2 + y^2, P2)
sage: C.geometric_genus() # nonsense!
-1
"""
try:
return self._genus
except AttributeError:
self._genus = self.defining_ideal().genus()
return self._genus
raise NotImplementedError

def union(self, other):
"""
Expand Down
12 changes: 5 additions & 7 deletions src/sage/schemes/curves/projective_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -1599,9 +1599,9 @@ def arithmetic_genus(self):
r"""
Return the arithmetic genus of this projective curve.
This is the arithmetic genus `g_a(C)` as defined in [Har1977]_. If `P` is the
This is the arithmetic genus `p_a(C)` as defined in [Har1977]_. If `P` is the
Hilbert polynomial of the defining ideal of this curve, then the arithmetic genus
of this curve is `1 - P(0)`. This curve must be irreducible.
of this curve is `1 - P(0)`.
EXAMPLES::
Expand All @@ -1617,8 +1617,6 @@ def arithmetic_genus(self):
sage: C.arithmetic_genus()
10
"""
if not self.is_irreducible():
raise TypeError("this curve must be irreducible")
return 1 - self.defining_ideal().hilbert_polynomial()(0)

def is_complete_intersection(self):
Expand Down Expand Up @@ -2290,9 +2288,9 @@ def _genus(self):
EXAMPLES::
sage: P.<x,y,z> = ProjectiveSpace(GF(4), 2) # needs sage.rings.finite_rings
sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) # needs sage.rings.finite_rings
sage: C.genus() # indirect doctest # needs sage.rings.finite_rings
sage: P.<x,y,z> = ProjectiveSpace(GF(4), 2)
sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5)
sage: C.genus() # indirect doctest
1
"""
return self._open_affine.genus()
Expand Down

0 comments on commit 2339e7b

Please sign in to comment.