Constructor for hyperelliptic curves using the smooth model¶
Uses weighted projective space \(\mathbb{P}(1 : g + 1 : 1)\).
TODO:
We do not yet support the construction of hyperelliptic curves over rings
AUTHORS:
David Kohel (2006): initial version
Anna Somoza (2019-04): dynamic class creation
Sabrina Kunzweiler, Gareth Ma, Giacomo Pope (2024): adapt to smooth model
- sage.schemes.hyperelliptic_curves.constructor.HyperellipticCurve(f, h=0, names=['x', 'y'], check_squarefree=True, distinguished_point=None)[source]¶
Constructor function for creating a hyperelliptic curve with smooth model with polynomials \(f\), \(h\).
In Sage, a hyperelliptic curve of genus \(g\) is always specified by an (affine) equation in Weierstrass form
\[y^2 + h(x) y = f(x),\]for some polynomials \(h\) and \(f\). This defines a smooth model in weighted projective space \(\mathbb{P}(1 : g + 1 : 1)\)
\[Y^2 + H(X,Z) Y = F(X,Z),\]where \(H\) is the degree \(g + 1\) homogenization of \(h\), and \(F\) is the degree \(2 g + 2\) homogenization of \(f\).
INPUT:
f– polynomialh(default:0) – polynomialnames– (default:['x', 'y']) names for the coordinate functionscheck_squarefree(default:True) – test if the input defines a hyperelliptic curvedistinguished_point(default:None) – set a custompoint to be the distinguished point for arithmetic. One of points at infinity if one so exists.
EXAMPLES:
We create a hyperelliptic curve over the rationals:
sage: R.<x> = PolynomialRing(QQ) sage: H = HyperellipticCurve(x^8+1, x^4+1); H Hyperelliptic Curve over Rational Field defined by y^2 + (x^4 + 1)*y = x^8 + 1
>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(8)+Integer(1), x**Integer(4)+Integer(1)); H Hyperelliptic Curve over Rational Field defined by y^2 + (x^4 + 1)*y = x^8 + 1
This hyperelliptic curve has no points at infinity, i.e. \(H\) is inert:
sage: H.points_at_infinity() [] sage: H.is_inert() True
[Python]>>> from sage.all import * >>> H.points_at_infinity() [] >>> H.is_inert() True
We can extend the base field to obtain a hyperelliptic curve with two points at infinity:
sage: K.<alpha> = QQ.extension(x^2+x-1) sage: HK = H.change_ring(K) sage: HK.points_at_infinity() [(1 : alpha : 0), (1 : -alpha - 1 : 0)] sage: HK.is_split() True
>>> from sage.all import * >>> K = QQ.extension(x**Integer(2)+x-Integer(1), names=('alpha',)); (alpha,) = K._first_ngens(1) >>> HK = H.change_ring(K) >>> HK.points_at_infinity() [(1 : alpha : 0), (1 : -alpha - 1 : 0)] >>> HK.is_split() True
The construction of hyperelliptic curves is supported over different fields. The correct class is chosen automatically:
sage: F = FiniteField(13) sage: S.<x> = PolynomialRing(F) sage: HF = HyperellipticCurve(x^5 + x^4 + x^3 + x^2 + x + 1, x^3 + x); HF Hyperelliptic Curve over Finite Field of size 13 defined by y^2 + (x^3 + x)*y = x^5 + x^4 + x^3 + x^2 + x + 1 sage: type(HF) <class 'sage.schemes.hyperelliptic_curves.hyperelliptic_g2.HyperellipticCurve_g2_finite_field_with_category'> sage: Q5 = Qp(5,10) sage: T.<x> = Q5[] sage: H5 = HyperellipticCurve(x^7 + 1); H5 Hyperelliptic Curve over 5-adic Field with capped relative precision 10 defined by (1 + O(5^10))*y^2 = (1 + O(5^10))*x^7 + 1 + O(5^10) sage: type(H5) <class 'sage.schemes.hyperelliptic_curves.hyperelliptic_padic_field.HyperellipticCurve_padic_field_with_category'>
[Python]>>> from sage.all import * >>> F = FiniteField(Integer(13)) >>> S = PolynomialRing(F, names=('x',)); (x,) = S._first_ngens(1) >>> HF = HyperellipticCurve(x**Integer(5) + x**Integer(4) + x**Integer(3) + x**Integer(2) + x + Integer(1), x**Integer(3) + x); HF Hyperelliptic Curve over Finite Field of size 13 defined by y^2 + (x^3 + x)*y = x^5 + x^4 + x^3 + x^2 + x + 1 >>> type(HF) <class 'sage.schemes.hyperelliptic_curves.hyperelliptic_g2.HyperellipticCurve_g2_finite_field_with_category'> >>> Q5 = Qp(Integer(5),Integer(10)) >>> T = Q5['x']; (x,) = T._first_ngens(1) >>> H5 = HyperellipticCurve(x**Integer(7) + Integer(1)); H5 Hyperelliptic Curve over 5-adic Field with capped relative precision 10 defined by (1 + O(5^10))*y^2 = (1 + O(5^10))*x^7 + 1 + O(5^10) >>> type(H5) <class 'sage.schemes.hyperelliptic_curves.hyperelliptic_padic_field.HyperellipticCurve_padic_field_with_category'>
The input polynomials need not be monic:
sage: R.<x> = QQ[] sage: HyperellipticCurve(3*x^5+1) Hyperelliptic Curve over Rational Field defined by y^2 = 3*x^5 + 1
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> HyperellipticCurve(Integer(3)*x**Integer(5)+Integer(1)) Hyperelliptic Curve over Rational Field defined by y^2 = 3*x^5 + 1
The polynomials \(f\) and \(h\) need to define a smooth curve of genus at least one. In particular polynomials defining elliptic curves are allowed as input:
sage: E = HyperellipticCurve(x^3+1) sage: E.genus() 1 sage: HyperellipticCurve(x) Traceback (most recent call last): ... ValueError: arguments f = x and h = 0 must define a curve of genus at least one.
[Python]>>> from sage.all import * >>> E = HyperellipticCurve(x**Integer(3)+Integer(1)) >>> E.genus() 1 >>> HyperellipticCurve(x) Traceback (most recent call last): ... ValueError: arguments f = x and h = 0 must define a curve of genus at least one.
The following polynomials define a singular curve and are not allowed as input:
sage: C = HyperellipticCurve(x^6 + 2*x - 1, 2*x - 2) Traceback (most recent call last): ... ValueError: singularity in the provided affine patch
>>> from sage.all import * >>> C = HyperellipticCurve(x**Integer(6) + Integer(2)*x - Integer(1), Integer(2)*x - Integer(2)) Traceback (most recent call last): ... ValueError: singularity in the provided affine patch
The constructor accepts a distinguished point as an argument, allowing the user to pick which point at infinity is selected in the case there is more than one for the given curve model:
sage: C = HyperellipticCurve(x^5 + x + 2, distinguished_point=(1, -2)) sage: C.distinguished_point() (1 : -2 : 1)
[Python]>>> from sage.all import * >>> C = HyperellipticCurve(x**Integer(5) + x + Integer(2), distinguished_point=(Integer(1), -Integer(2))) >>> C.distinguished_point() (1 : -2 : 1)
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=['u','v']) # needs sage.rings.finite_rings Hyperelliptic Curve over Finite Field in a of size 3^2 defined by v^2 + (u + a)*v = u^3 + u + 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=['u','v']) # needs sage.rings.finite_rings Hyperelliptic Curve over Finite Field in a of size 3^2 defined by v^2 + (u + a)*v = u^3 + u + 2