Hyperelliptic curve constructor

AUTHORS:

  • David Kohel (2006): initial version

  • Anna Somoza (2019-04): dynamic class creation

sage.schemes.hyperelliptic_curves.constructor.HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True)[source]

Return the hyperelliptic curve \(y^2 + h y = f\), for univariate polynomials \(h\) and \(f\). If \(h\) is not given, then it defaults to 0.

INPUT:

  • f – univariate polynomial

  • h – (optional) univariate polynomial

  • names – (default: ["x","y"]) names for the coordinate functions

  • check_squarefree – boolean (default: True); test if the input defines a hyperelliptic curve when f is homogenized to degree \(2g+2\) and h to degree \(g+1\) for some \(g\)

Warning

When setting check_squarefree=False or using a base ring that is not a field, the output curves are not to be trusted. For example, the output of is_singular is always False, without this being properly tested in that case.

Note

The words “hyperelliptic curve” are normally only used for curves of genus at least two, but this class allows more general smooth double covers of the projective line (conics and elliptic curves), even though the class is not meant for those and some outputs may be incorrect.

EXAMPLES:

Basic examples:

sage: R.<x> = QQ[]
sage: HyperellipticCurve(x^5 + x + 1)
Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
sage: HyperellipticCurve(x^19 + x + 1, x - 2)
Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1

sage: k.<a> = GF(9); R.<x> = k[]                                                # needs sage.rings.finite_rings
sage: HyperellipticCurve(x^3 + x - 1, x+a)                                      # needs sage.rings.finite_rings
Hyperelliptic Curve over Finite Field in a of size 3^2
 defined by y^2 + (x + a)*y = x^3 + x + 2
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> HyperellipticCurve(x**Integer(5) + x + Integer(1))
Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
>>> HyperellipticCurve(x**Integer(19) + x + Integer(1), x - Integer(2))
Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1

>>> k = GF(Integer(9), names=('a',)); (a,) = k._first_ngens(1); R = k['x']; (x,) = R._first_ngens(1)# needs sage.rings.finite_rings
>>> HyperellipticCurve(x**Integer(3) + x - Integer(1), x+a)                                      # needs sage.rings.finite_rings
Hyperelliptic Curve over Finite Field in a of size 3^2
 defined by y^2 + (x + a)*y = x^3 + x + 2
R.<x> = QQ[]
HyperellipticCurve(x^5 + x + 1)
HyperellipticCurve(x^19 + x + 1, x - 2)
k.<a> = GF(9); R.<x> = k[]                                                # needs sage.rings.finite_rings
HyperellipticCurve(x^3 + x - 1, x+a)                                      # needs sage.rings.finite_rings

Characteristic two:

sage: # needs sage.rings.finite_rings
sage: P.<x> = GF(8, 'a')[]
sage: HyperellipticCurve(x^7 + 1, x)
Hyperelliptic Curve over Finite Field in a of size 2^3
 defined by y^2 + x*y = x^7 + 1
sage: HyperellipticCurve(x^8 + x^7 + 1, x^4 + 1)
Hyperelliptic Curve over Finite Field in a of size 2^3
 defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 1
sage: HyperellipticCurve(x^8 + 1, x)
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: highly singular at infinity
sage: HyperellipticCurve(x^8 + x^7 + 1, x^4)
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: singularity in the provided affine patch

sage: F.<t> = PowerSeriesRing(FiniteField(2))
sage: P.<x> = PolynomialRing(FractionField(F))
sage: HyperellipticCurve(x^5 + t, x)
Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2
 defined by y^2 + x*y = x^5 + t
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> P = GF(Integer(8), 'a')['x']; (x,) = P._first_ngens(1)
>>> HyperellipticCurve(x**Integer(7) + Integer(1), x)
Hyperelliptic Curve over Finite Field in a of size 2^3
 defined by y^2 + x*y = x^7 + 1
>>> HyperellipticCurve(x**Integer(8) + x**Integer(7) + Integer(1), x**Integer(4) + Integer(1))
Hyperelliptic Curve over Finite Field in a of size 2^3
 defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 1
>>> HyperellipticCurve(x**Integer(8) + Integer(1), x)
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: highly singular at infinity
>>> HyperellipticCurve(x**Integer(8) + x**Integer(7) + Integer(1), x**Integer(4))
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: singularity in the provided affine patch

>>> F = PowerSeriesRing(FiniteField(Integer(2)), names=('t',)); (t,) = F._first_ngens(1)
>>> P = PolynomialRing(FractionField(F), names=('x',)); (x,) = P._first_ngens(1)
>>> HyperellipticCurve(x**Integer(5) + t, x)
Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2
 defined by y^2 + x*y = x^5 + t
# needs sage.rings.finite_rings
P.<x> = GF(8, 'a')[]
HyperellipticCurve(x^7 + 1, x)
HyperellipticCurve(x^8 + x^7 + 1, x^4 + 1)
HyperellipticCurve(x^8 + 1, x)
HyperellipticCurve(x^8 + x^7 + 1, x^4)
F.<t> = PowerSeriesRing(FiniteField(2))
P.<x> = PolynomialRing(FractionField(F))
HyperellipticCurve(x^5 + t, x)

We can change the names of the variables in the output:

sage: k.<a> = GF(9); R.<x> = k[]                                                # needs sage.rings.finite_rings
sage: HyperellipticCurve(x^3 + x - 1, x + a, names=['X','Y'])                   # needs sage.rings.finite_rings
Hyperelliptic Curve over Finite Field in a of size 3^2
 defined by Y^2 + (X + a)*Y = X^3 + X + 2
>>> from sage.all import *
>>> k = GF(Integer(9), names=('a',)); (a,) = k._first_ngens(1); R = k['x']; (x,) = R._first_ngens(1)# needs sage.rings.finite_rings
>>> HyperellipticCurve(x**Integer(3) + x - Integer(1), x + a, names=['X','Y'])                   # needs sage.rings.finite_rings
Hyperelliptic Curve over Finite Field in a of size 3^2
 defined by Y^2 + (X + a)*Y = X^3 + X + 2
k.<a> = GF(9); R.<x> = k[]                                                # needs sage.rings.finite_rings
HyperellipticCurve(x^3 + x - 1, x + a, names=['X','Y'])                   # needs sage.rings.finite_rings

This class also allows curves of genus zero or one, which are strictly speaking not hyperelliptic:

sage: P.<x> = QQ[]
sage: HyperellipticCurve(x^2 + 1)
Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 1
sage: HyperellipticCurve(x^4 - 1)
Hyperelliptic Curve over Rational Field defined by y^2 = x^4 - 1
sage: HyperellipticCurve(x^3 + 2*x + 2)
Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2
>>> from sage.all import *
>>> P = QQ['x']; (x,) = P._first_ngens(1)
>>> HyperellipticCurve(x**Integer(2) + Integer(1))
Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 1
>>> HyperellipticCurve(x**Integer(4) - Integer(1))
Hyperelliptic Curve over Rational Field defined by y^2 = x^4 - 1
>>> HyperellipticCurve(x**Integer(3) + Integer(2)*x + Integer(2))
Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2
P.<x> = QQ[]
HyperellipticCurve(x^2 + 1)
HyperellipticCurve(x^4 - 1)
HyperellipticCurve(x^3 + 2*x + 2)

Double roots:

sage: P.<x> = GF(7)[]
sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1))
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: singularity in the provided affine patch

sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False)
Hyperelliptic Curve over Finite Field of size 7 defined by
 y^2 = x^12 + 5*x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^6 + 2*x^4 + 3*x^3 + 6*x^2 + 4*x + 3
>>> from sage.all import *
>>> P = GF(Integer(7))['x']; (x,) = P._first_ngens(1)
>>> HyperellipticCurve((x**Integer(3)-x+Integer(2))**Integer(2)*(x**Integer(6)-Integer(1)))
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: singularity in the provided affine patch

>>> HyperellipticCurve((x**Integer(3)-x+Integer(2))**Integer(2)*(x**Integer(6)-Integer(1)), check_squarefree=False)
Hyperelliptic Curve over Finite Field of size 7 defined by
 y^2 = x^12 + 5*x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^6 + 2*x^4 + 3*x^3 + 6*x^2 + 4*x + 3
P.<x> = GF(7)[]
HyperellipticCurve((x^3-x+2)^2*(x^6-1))
HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False)

The input for a (smooth) hyperelliptic curve of genus \(g\) should not contain polynomials of degree greater than \(2g+2\). In the following example, the hyperelliptic curve has genus 2 and there exists a model \(y^2 = F\) of degree 6, so the model \(y^2 + yh = f\) of degree 200 is not allowed.:

sage: P.<x> = QQ[]
sage: h = x^100
sage: F = x^6 + 1
sage: f = F - h^2/4
sage: HyperellipticCurve(f, h)
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: highly singular at infinity

sage: HyperellipticCurve(F)
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1
>>> from sage.all import *
>>> P = QQ['x']; (x,) = P._first_ngens(1)
>>> h = x**Integer(100)
>>> F = x**Integer(6) + Integer(1)
>>> f = F - h**Integer(2)/Integer(4)
>>> HyperellipticCurve(f, h)
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: highly singular at infinity

>>> HyperellipticCurve(F)
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1
P.<x> = QQ[]
h = x^100
F = x^6 + 1
f = F - h^2/4
HyperellipticCurve(f, h)
HyperellipticCurve(F)

An example with a singularity over an inseparable extension of the base field:

sage: F.<t> = GF(5)[]
sage: P.<x> = F[]
sage: HyperellipticCurve(x^5 + t)
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: singularity in the provided affine patch
>>> from sage.all import *
>>> F = GF(Integer(5))['t']; (t,) = F._first_ngens(1)
>>> P = F['x']; (x,) = P._first_ngens(1)
>>> HyperellipticCurve(x**Integer(5) + t)
Traceback (most recent call last):
...
ValueError: not a hyperelliptic curve: singularity in the provided affine patch
F.<t> = GF(5)[]
P.<x> = F[]
HyperellipticCurve(x^5 + t)

Input with integer coefficients creates objects with the integers as base ring, but only checks smoothness over \(\QQ\), not over Spec(\(\ZZ\)). In other words, it is checked that the discriminant is nonzero, but it is not checked whether the discriminant is a unit in \(\ZZ^*\).:

sage: P.<x> = ZZ[]
sage: HyperellipticCurve(3*x^7 + 6*x + 6)
Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6
>>> from sage.all import *
>>> P = ZZ['x']; (x,) = P._first_ngens(1)
>>> HyperellipticCurve(Integer(3)*x**Integer(7) + Integer(6)*x + Integer(6))
Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6
P.<x> = ZZ[]
HyperellipticCurve(3*x^7 + 6*x + 6)