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 polynomialh
– (optional) univariate polynomialnames
– (default:["x","y"]
) names for the coordinate functionscheck_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 ofis_singular
is alwaysFalse
, 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)