Hyperelliptic curves over a general ring#
EXAMPLES:
sage: P.<x> = GF(5)[]
sage: f = x^5 - 3*x^4 - 2*x^3 + 6*x^2 + 3*x - 1
sage: C = HyperellipticCurve(f); C
Hyperelliptic Curve over Finite Field of size 5
defined by y^2 = x^5 + 2*x^4 + 3*x^3 + x^2 + 3*x + 4
>>> from sage.all import *
>>> P = GF(Integer(5))['x']; (x,) = P._first_ngens(1)
>>> f = x**Integer(5) - Integer(3)*x**Integer(4) - Integer(2)*x**Integer(3) + Integer(6)*x**Integer(2) + Integer(3)*x - Integer(1)
>>> C = HyperellipticCurve(f); C
Hyperelliptic Curve over Finite Field of size 5
defined by y^2 = x^5 + 2*x^4 + 3*x^3 + x^2 + 3*x + 4
sage: P.<x> = QQ[]
sage: f = 4*x^5 - 30*x^3 + 45*x - 22
sage: C = HyperellipticCurve(f); C
Hyperelliptic Curve over Rational Field defined by y^2 = 4*x^5 - 30*x^3 + 45*x - 22
sage: C.genus()
2
sage: D = C.affine_patch(0)
sage: D.defining_polynomials()[0].parent()
Multivariate Polynomial Ring in x1, x2 over Rational Field
>>> from sage.all import *
>>> P = QQ['x']; (x,) = P._first_ngens(1)
>>> f = Integer(4)*x**Integer(5) - Integer(30)*x**Integer(3) + Integer(45)*x - Integer(22)
>>> C = HyperellipticCurve(f); C
Hyperelliptic Curve over Rational Field defined by y^2 = 4*x^5 - 30*x^3 + 45*x - 22
>>> C.genus()
2
>>> D = C.affine_patch(Integer(0))
>>> D.defining_polynomials()[Integer(0)].parent()
Multivariate Polynomial Ring in x1, x2 over Rational Field
- class sage.schemes.hyperelliptic_curves.hyperelliptic_generic.HyperellipticCurve_generic(PP, f, h=None, names=None, genus=None)[source]#
Bases:
ProjectivePlaneCurve
- base_extend(R)[source]#
Returns this HyperellipticCurve over a new base ring
R
.EXAMPLES:
sage: # needs sage.rings.padics sage: R.<x> = QQ[] sage: H = HyperellipticCurve(x^5 - 10*x + 9) sage: K = Qp(3, 5) sage: L.<a> = K.extension(x^30 - 3) sage: HK = H.change_ring(K) sage: HL = HK.change_ring(L); HL Hyperelliptic Curve over 3-adic Eisenstein Extension Field in a defined by x^30 - 3 defined by (1 + O(a^150))*y^2 = (1 + O(a^150))*x^5 + (2 + 2*a^30 + a^60 + 2*a^90 + 2*a^120 + O(a^150))*x + a^60 + O(a^210) sage: R.<x> = FiniteField(7)[] sage: H = HyperellipticCurve(x^8 + x + 5) sage: H.base_extend(FiniteField(7^2, 'a')) # needs sage.rings.finite_rings Hyperelliptic Curve over Finite Field in a of size 7^2 defined by y^2 = x^8 + x + 5
>>> from sage.all import * >>> # needs sage.rings.padics >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(5) - Integer(10)*x + Integer(9)) >>> K = Qp(Integer(3), Integer(5)) >>> L = K.extension(x**Integer(30) - Integer(3), names=('a',)); (a,) = L._first_ngens(1) >>> HK = H.change_ring(K) >>> HL = HK.change_ring(L); HL Hyperelliptic Curve over 3-adic Eisenstein Extension Field in a defined by x^30 - 3 defined by (1 + O(a^150))*y^2 = (1 + O(a^150))*x^5 + (2 + 2*a^30 + a^60 + 2*a^90 + 2*a^120 + O(a^150))*x + a^60 + O(a^210) >>> R = FiniteField(Integer(7))['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(8) + x + Integer(5)) >>> H.base_extend(FiniteField(Integer(7)**Integer(2), 'a')) # needs sage.rings.finite_rings Hyperelliptic Curve over Finite Field in a of size 7^2 defined by y^2 = x^8 + x + 5
- change_ring(R)[source]#
Returns this HyperellipticCurve over a new base ring
R
.EXAMPLES:
sage: # needs sage.rings.padics sage: R.<x> = QQ[] sage: H = HyperellipticCurve(x^5 - 10*x + 9) sage: K = Qp(3, 5) sage: L.<a> = K.extension(x^30 - 3) sage: HK = H.change_ring(K) sage: HL = HK.change_ring(L); HL Hyperelliptic Curve over 3-adic Eisenstein Extension Field in a defined by x^30 - 3 defined by (1 + O(a^150))*y^2 = (1 + O(a^150))*x^5 + (2 + 2*a^30 + a^60 + 2*a^90 + 2*a^120 + O(a^150))*x + a^60 + O(a^210) sage: R.<x> = FiniteField(7)[] sage: H = HyperellipticCurve(x^8 + x + 5) sage: H.base_extend(FiniteField(7^2, 'a')) # needs sage.rings.finite_rings Hyperelliptic Curve over Finite Field in a of size 7^2 defined by y^2 = x^8 + x + 5
>>> from sage.all import * >>> # needs sage.rings.padics >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(5) - Integer(10)*x + Integer(9)) >>> K = Qp(Integer(3), Integer(5)) >>> L = K.extension(x**Integer(30) - Integer(3), names=('a',)); (a,) = L._first_ngens(1) >>> HK = H.change_ring(K) >>> HL = HK.change_ring(L); HL Hyperelliptic Curve over 3-adic Eisenstein Extension Field in a defined by x^30 - 3 defined by (1 + O(a^150))*y^2 = (1 + O(a^150))*x^5 + (2 + 2*a^30 + a^60 + 2*a^90 + 2*a^120 + O(a^150))*x + a^60 + O(a^210) >>> R = FiniteField(Integer(7))['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(8) + x + Integer(5)) >>> H.base_extend(FiniteField(Integer(7)**Integer(2), 'a')) # needs sage.rings.finite_rings Hyperelliptic Curve over Finite Field in a of size 7^2 defined by y^2 = x^8 + x + 5
- has_odd_degree_model()[source]#
Return True if an odd degree model of self exists over the field of definition; False otherwise.
Use
odd_degree_model
to calculate an odd degree model.EXAMPLES:
sage: x = QQ['x'].0 sage: HyperellipticCurve(x^5 + x).has_odd_degree_model() True sage: HyperellipticCurve(x^6 + x).has_odd_degree_model() True sage: HyperellipticCurve(x^6 + x + 1).has_odd_degree_model() False
>>> from sage.all import * >>> x = QQ['x'].gen(0) >>> HyperellipticCurve(x**Integer(5) + x).has_odd_degree_model() True >>> HyperellipticCurve(x**Integer(6) + x).has_odd_degree_model() True >>> HyperellipticCurve(x**Integer(6) + x + Integer(1)).has_odd_degree_model() False
- hyperelliptic_polynomials(K=None, var='x')[source]#
EXAMPLES:
sage: R.<x> = QQ[]; C = HyperellipticCurve(x^3 + x - 1, x^3/5); C Hyperelliptic Curve over Rational Field defined by y^2 + 1/5*x^3*y = x^3 + x - 1 sage: C.hyperelliptic_polynomials() (x^3 + x - 1, 1/5*x^3)
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1); C = HyperellipticCurve(x**Integer(3) + x - Integer(1), x**Integer(3)/Integer(5)); C Hyperelliptic Curve over Rational Field defined by y^2 + 1/5*x^3*y = x^3 + x - 1 >>> C.hyperelliptic_polynomials() (x^3 + x - 1, 1/5*x^3)
- invariant_differential()[source]#
Returns \(dx/2y\), as an element of the Monsky-Washnitzer cohomology of self
EXAMPLES:
sage: R.<x> = QQ['x'] sage: C = HyperellipticCurve(x^5 - 4*x + 4) sage: C.invariant_differential() 1 dx/2y
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> C = HyperellipticCurve(x**Integer(5) - Integer(4)*x + Integer(4)) >>> C.invariant_differential() 1 dx/2y
- is_singular()[source]#
Returns False, because hyperelliptic curves are smooth projective curves, as checked on construction.
EXAMPLES:
sage: R.<x> = QQ[] sage: H = HyperellipticCurve(x^5 + 1) sage: H.is_singular() False
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(5) + Integer(1)) >>> H.is_singular() False
A hyperelliptic curve with genus at least 2 always has a singularity at infinity when viewed as a plane projective curve. This can be seen in the following example.:
sage: R.<x> = QQ[] sage: H = HyperellipticCurve(x^5 + 2) sage: from sage.misc.verbose import set_verbose sage: set_verbose(-1) sage: H.is_singular() False sage: from sage.schemes.curves.projective_curve import ProjectivePlaneCurve sage: ProjectivePlaneCurve.is_singular(H) True
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(5) + Integer(2)) >>> from sage.misc.verbose import set_verbose >>> set_verbose(-Integer(1)) >>> H.is_singular() False >>> from sage.schemes.curves.projective_curve import ProjectivePlaneCurve >>> ProjectivePlaneCurve.is_singular(H) True
- is_smooth()[source]#
Returns True, because hyperelliptic curves are smooth projective curves, as checked on construction.
EXAMPLES:
sage: R.<x> = GF(13)[] sage: H = HyperellipticCurve(x^8 + 1) sage: H.is_smooth() True
>>> from sage.all import * >>> R = GF(Integer(13))['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(8) + Integer(1)) >>> H.is_smooth() True
A hyperelliptic curve with genus at least 2 always has a singularity at infinity when viewed as a plane projective curve. This can be seen in the following example.:
sage: # needs sage.rings.finite_rings sage: R.<x> = GF(27, 'a')[] sage: H = HyperellipticCurve(x^10 + 2) sage: from sage.misc.verbose import set_verbose sage: set_verbose(-1) sage: H.is_smooth() True sage: from sage.schemes.curves.projective_curve import ProjectivePlaneCurve sage: ProjectivePlaneCurve.is_smooth(H) False
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> R = GF(Integer(27), 'a')['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(10) + Integer(2)) >>> from sage.misc.verbose import set_verbose >>> set_verbose(-Integer(1)) >>> H.is_smooth() True >>> from sage.schemes.curves.projective_curve import ProjectivePlaneCurve >>> ProjectivePlaneCurve.is_smooth(H) False
- is_x_coord(x)[source]#
Return True if
x
is the \(x\)-coordinate of a point on this curve.See also
See also
lift_x()
to find the point(s) with a given \(x\)-coordinate. This function may be useful in cases where testing an element of the base field for being a square is faster than finding its square root.INPUT:
x
– an element of the base ring of the curve
OUTPUT:
A bool stating whether or not \(x\) is a x-coordinate of a point on the curve
EXAMPLES:
When \(x\) is the \(x\)-coordinate of a rational point on the curve, we can request these:
sage: R.<x> = PolynomialRing(QQ) sage: f = x^5 + x^3 + 1 sage: H = HyperellipticCurve(f) sage: H.is_x_coord(0) True
>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(5) + x**Integer(3) + Integer(1) >>> H = HyperellipticCurve(f) >>> H.is_x_coord(Integer(0)) True
There are no rational points with \(x\)-coordinate 3:
sage: H.is_x_coord(3) False
>>> from sage.all import * >>> H.is_x_coord(Integer(3)) False
The function also handles the case when \(h(x)\) is not zero:
sage: R.<x> = PolynomialRing(QQ) sage: f = x^5 + x^3 + 1 sage: h = x + 1 sage: H = HyperellipticCurve(f, h) sage: H.is_x_coord(1) True
>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(5) + x**Integer(3) + Integer(1) >>> h = x + Integer(1) >>> H = HyperellipticCurve(f, h) >>> H.is_x_coord(Integer(1)) True
We can perform these operations over finite fields too:
sage: # needs sage.rings.finite_rings sage: R.<x> = PolynomialRing(GF(163)) sage: f = x^7 + x + 1 sage: H = HyperellipticCurve(f) sage: H.is_x_coord(13) True
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> R = PolynomialRing(GF(Integer(163)), names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(7) + x + Integer(1) >>> H = HyperellipticCurve(f) >>> H.is_x_coord(Integer(13)) True
Including the case of characteristic two:
sage: # needs sage.rings.finite_rings sage: F.<z4> = GF(2^4) sage: R.<x> = PolynomialRing(F) sage: f = x^7 + x^3 + 1 sage: h = x + 1 sage: H = HyperellipticCurve(f, h) sage: H.is_x_coord(z4^3 + z4^2 + z4) True
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(2)**Integer(4), names=('z4',)); (z4,) = F._first_ngens(1) >>> R = PolynomialRing(F, names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(7) + x**Integer(3) + Integer(1) >>> h = x + Integer(1) >>> H = HyperellipticCurve(f, h) >>> H.is_x_coord(z4**Integer(3) + z4**Integer(2) + z4) True
AUTHORS:
Giacomo Pope (2024): adapted from
lift_x()
- lift_x(x, all=False)[source]#
Return one or all points with given \(x\)-coordinate.
This method is deterministic: It returns the same data each time when called again with the same \(x\).
INPUT:
x
– an element of the base ring of the curveall
(bool, defaultFalse
) – ifTrue
, return a (possibly empty) list of all points; ifFalse
, return just one point, or raise aValueError
if there are none.
OUTPUT:
A point or list of up to two points on this curve.
See also
AUTHORS:
Giacomo Pope (2024): Allowed for the case of characteristic two
EXAMPLES:
When \(x\) is the \(x\)-coordinate of a rational point on the curve, we can request these:
sage: R.<x> = PolynomialRing(QQ) sage: f = x^5 + x^3 + 1 sage: H = HyperellipticCurve(f) sage: H.lift_x(0) (0 : -1 : 1) sage: H.lift_x(4, all=True) [(4 : -33 : 1), (4 : 33 : 1)]
>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(5) + x**Integer(3) + Integer(1) >>> H = HyperellipticCurve(f) >>> H.lift_x(Integer(0)) (0 : -1 : 1) >>> H.lift_x(Integer(4), all=True) [(4 : -33 : 1), (4 : 33 : 1)]
There are no rational points with \(x\)-coordinate 3:
sage: H.lift_x(3) Traceback (most recent call last): ... ValueError: No point with x-coordinate 3 on Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x^3 + 1
>>> from sage.all import * >>> H.lift_x(Integer(3)) Traceback (most recent call last): ... ValueError: No point with x-coordinate 3 on Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x^3 + 1
An empty list is returned when there are no points and
all=True
:sage: H.lift_x(3, all=True) []
>>> from sage.all import * >>> H.lift_x(Integer(3), all=True) []
The function also handles the case when \(h(x)\) is not zero:
sage: R.<x> = PolynomialRing(QQ) sage: f = x^5 + x^3 + 1 sage: h = x + 1 sage: H = HyperellipticCurve(f, h) sage: H.lift_x(1) (1 : -3 : 1)
>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(5) + x**Integer(3) + Integer(1) >>> h = x + Integer(1) >>> H = HyperellipticCurve(f, h) >>> H.lift_x(Integer(1)) (1 : -3 : 1)
We can perform these operations over finite fields too:
sage: # needs sage.rings.finite_rings sage: R.<x> = PolynomialRing(GF(163)) sage: f = x^7 + x + 1 sage: H = HyperellipticCurve(f) sage: H.lift_x(13) (13 : 41 : 1)
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> R = PolynomialRing(GF(Integer(163)), names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(7) + x + Integer(1) >>> H = HyperellipticCurve(f) >>> H.lift_x(Integer(13)) (13 : 41 : 1)
Including the case of characteristic two:
sage: # needs sage.rings.finite_rings sage: F.<z4> = GF(2^4) sage: R.<x> = PolynomialRing(F) sage: f = x^7 + x^3 + 1 sage: h = x + 1 sage: H = HyperellipticCurve(f, h) sage: H.lift_x(z4^3 + z4^2 + z4, all=True) [(z4^3 + z4^2 + z4 : z4^2 + z4 + 1 : 1), (z4^3 + z4^2 + z4 : z4^3 : 1)]
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(2)**Integer(4), names=('z4',)); (z4,) = F._first_ngens(1) >>> R = PolynomialRing(F, names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(7) + x**Integer(3) + Integer(1) >>> h = x + Integer(1) >>> H = HyperellipticCurve(f, h) >>> H.lift_x(z4**Integer(3) + z4**Integer(2) + z4, all=True) [(z4^3 + z4^2 + z4 : z4^2 + z4 + 1 : 1), (z4^3 + z4^2 + z4 : z4^3 : 1)]
- local_coord(P, prec=20, name='t')[source]#
Calls the appropriate local_coordinates function
INPUT:
P
– a point on selfprec
– desired precision of the local coordinatesname
– generator of the power series ring (default:t
)
OUTPUT:
\((x(t),y(t))\) such that \(y(t)^2 = f(x(t))\), where \(t\) is the local parameter at \(P\)
EXAMPLES:
sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x) sage: H.local_coord(H(1 ,6), prec=5) (1 + t + O(t^5), 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5)) sage: H.local_coord(H(4, 0), prec=7) (4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7), t + O(t^7)) sage: H.local_coord(H(0, 1, 0), prec=5) (t^-2 + 23*t^2 - 18*t^4 - 569*t^6 + O(t^7), t^-5 + 46*t^-1 - 36*t - 609*t^3 + 1656*t^5 + O(t^6))
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(5) - Integer(23)*x**Integer(3) + Integer(18)*x**Integer(2) + Integer(40)*x) >>> H.local_coord(H(Integer(1) ,Integer(6)), prec=Integer(5)) (1 + t + O(t^5), 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5)) >>> H.local_coord(H(Integer(4), Integer(0)), prec=Integer(7)) (4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7), t + O(t^7)) >>> H.local_coord(H(Integer(0), Integer(1), Integer(0)), prec=Integer(5)) (t^-2 + 23*t^2 - 18*t^4 - 569*t^6 + O(t^7), t^-5 + 46*t^-1 - 36*t - 609*t^3 + 1656*t^5 + O(t^6))
AUTHOR:
Jennifer Balakrishnan (2007-12)
- local_coordinates_at_infinity(prec=20, name='t')[source]#
For the genus \(g\) hyperelliptic curve \(y^2 = f(x)\), return \((x(t), y(t))\) such that \((y(t))^2 = f(x(t))\), where \(t = x^g/y\) is the local parameter at infinity
INPUT:
prec
– desired precision of the local coordinatesname
– generator of the power series ring (default:t
)
OUTPUT:
\((x(t),y(t))\) such that \(y(t)^2 = f(x(t))\) and \(t = x^g/y\) is the local parameter at infinity
EXAMPLES:
sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5 - 5*x^2 + 1) sage: x, y = H.local_coordinates_at_infinity(10) sage: x t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12) sage: y t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12)
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(5) - Integer(5)*x**Integer(2) + Integer(1)) >>> x, y = H.local_coordinates_at_infinity(Integer(10)) >>> x t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12) >>> y t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12)
sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^3 - x + 1) sage: x, y = H.local_coordinates_at_infinity(10) sage: x t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12) sage: y t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12)
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(3) - x + Integer(1)) >>> x, y = H.local_coordinates_at_infinity(Integer(10)) >>> x t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12) >>> y t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12)
AUTHOR:
Jennifer Balakrishnan (2007-12)
- local_coordinates_at_nonweierstrass(P, prec=20, name='t')[source]#
For a non-Weierstrass point \(P = (a,b)\) on the hyperelliptic curve \(y^2 = f(x)\), return \((x(t), y(t))\) such that \((y(t))^2 = f(x(t))\), where \(t = x - a\) is the local parameter.
INPUT:
P = (a, b)
– a non-Weierstrass point on selfprec
– desired precision of the local coordinatesname
– gen of the power series ring (default:t
)
OUTPUT:
\((x(t),y(t))\) such that \(y(t)^2 = f(x(t))\) and \(t = x - a\) is the local parameter at \(P\)
EXAMPLES:
sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x) sage: P = H(1, 6) sage: x, y = H.local_coordinates_at_nonweierstrass(P, prec=5) sage: x 1 + t + O(t^5) sage: y 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5) sage: Q = H(-2, 12) sage: x, y = H.local_coordinates_at_nonweierstrass(Q, prec=5) sage: x -2 + t + O(t^5) sage: y 12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5)
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(5) - Integer(23)*x**Integer(3) + Integer(18)*x**Integer(2) + Integer(40)*x) >>> P = H(Integer(1), Integer(6)) >>> x, y = H.local_coordinates_at_nonweierstrass(P, prec=Integer(5)) >>> x 1 + t + O(t^5) >>> y 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5) >>> Q = H(-Integer(2), Integer(12)) >>> x, y = H.local_coordinates_at_nonweierstrass(Q, prec=Integer(5)) >>> x -2 + t + O(t^5) >>> y 12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5)
AUTHOR:
Jennifer Balakrishnan (2007-12)
- local_coordinates_at_weierstrass(P, prec=20, name='t')[source]#
For a finite Weierstrass point on the hyperelliptic curve \(y^2 = f(x)\), returns \((x(t), y(t))\) such that \((y(t))^2 = f(x(t))\), where \(t = y\) is the local parameter.
INPUT:
P
– a finite Weierstrass point on selfprec
– desired precision of the local coordinatesname
– gen of the power series ring (default: \(t\))
OUTPUT:
\((x(t),y(t))\) such that \(y(t)^2 = f(x(t))\) and \(t = y\) is the local parameter at \(P\)
EXAMPLES:
sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x) sage: A = H(4, 0) sage: x, y = H.local_coordinates_at_weierstrass(A, prec=7) sage: x 4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7) sage: y t + O(t^7) sage: B = H(-5, 0) sage: x, y = H.local_coordinates_at_weierstrass(B, prec=5) sage: x -5 + 1/1260*t^2 + 887/2000376000*t^4 + O(t^5) sage: y t + O(t^5)
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> H = HyperellipticCurve(x**Integer(5) - Integer(23)*x**Integer(3) + Integer(18)*x**Integer(2) + Integer(40)*x) >>> A = H(Integer(4), Integer(0)) >>> x, y = H.local_coordinates_at_weierstrass(A, prec=Integer(7)) >>> x 4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7) >>> y t + O(t^7) >>> B = H(-Integer(5), Integer(0)) >>> x, y = H.local_coordinates_at_weierstrass(B, prec=Integer(5)) >>> x -5 + 1/1260*t^2 + 887/2000376000*t^4 + O(t^5) >>> y t + O(t^5)
- AUTHOR:
Jennifer Balakrishnan (2007-12)
Francis Clarke (2012-08-26)
- odd_degree_model()[source]#
Return an odd degree model of self, or raise ValueError if one does not exist over the field of definition.
EXAMPLES:
sage: x = QQ['x'].gen() sage: H = HyperellipticCurve((x^2 + 2)*(x^2 + 3)*(x^2 + 5)); H Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 10*x^4 + 31*x^2 + 30 sage: H.odd_degree_model() Traceback (most recent call last): ... ValueError: No odd degree model exists over field of definition sage: K2 = QuadraticField(-2, 'a') # needs sage.rings.number_field sage: Hp2 = H.change_ring(K2).odd_degree_model(); Hp2 # needs sage.rings.number_field Hyperelliptic Curve over Number Field in a with defining polynomial x^2 + 2 with a = 1.414213562373095?*I defined by y^2 = 6*a*x^5 - 29*x^4 - 20*x^2 + 6*a*x + 1 sage: K3 = QuadraticField(-3, 'b') # needs sage.rings.number_field sage: Hp3 = H.change_ring(QuadraticField(-3, 'b')).odd_degree_model(); Hp3 # needs sage.rings.number_field Hyperelliptic Curve over Number Field in b with defining polynomial x^2 + 3 with b = 1.732050807568878?*I defined by y^2 = -4*b*x^5 - 14*x^4 - 20*b*x^3 - 35*x^2 + 6*b*x + 1 Of course, ``Hp2`` and ``Hp3`` are isomorphic over the composite extension. One consequence of this is that odd degree models reduced over "different" fields should have the same number of points on their reductions. 43 and 67 split completely in the compositum, so when we reduce we find: sage: # needs sage.rings.number_field sage: P2 = K2.factor(43)[0][0] sage: P3 = K3.factor(43)[0][0] sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial() x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial() x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 sage: H.change_ring(GF(43)).odd_degree_model().frobenius_polynomial() # needs sage.rings.finite_rings x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 sage: # needs sage.rings.number_field sage: P2 = K2.factor(67)[0][0] sage: P3 = K3.factor(67)[0][0] sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial() x^4 - 8*x^3 + 150*x^2 - 536*x + 4489 sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial() x^4 - 8*x^3 + 150*x^2 - 536*x + 4489 sage: H.change_ring(GF(67)).odd_degree_model().frobenius_polynomial() # needs sage.rings.finite_rings x^4 - 8*x^3 + 150*x^2 - 536*x + 4489
>>> from sage.all import * >>> x = QQ['x'].gen() >>> H = HyperellipticCurve((x**Integer(2) + Integer(2))*(x**Integer(2) + Integer(3))*(x**Integer(2) + Integer(5))); H Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 10*x^4 + 31*x^2 + 30 >>> H.odd_degree_model() Traceback (most recent call last): ... ValueError: No odd degree model exists over field of definition >>> K2 = QuadraticField(-Integer(2), 'a') # needs sage.rings.number_field >>> Hp2 = H.change_ring(K2).odd_degree_model(); Hp2 # needs sage.rings.number_field Hyperelliptic Curve over Number Field in a with defining polynomial x^2 + 2 with a = 1.414213562373095?*I defined by y^2 = 6*a*x^5 - 29*x^4 - 20*x^2 + 6*a*x + 1 >>> K3 = QuadraticField(-Integer(3), 'b') # needs sage.rings.number_field >>> Hp3 = H.change_ring(QuadraticField(-Integer(3), 'b')).odd_degree_model(); Hp3 # needs sage.rings.number_field Hyperelliptic Curve over Number Field in b with defining polynomial x^2 + 3 with b = 1.732050807568878?*I defined by y^2 = -4*b*x^5 - 14*x^4 - 20*b*x^3 - 35*x^2 + 6*b*x + 1 Of course, ``Hp2`` and ``Hp3`` are isomorphic over the composite extension. One consequence of this is that odd degree models reduced over "different" fields should have the same number of points on their reductions. 43 and 67 split completely in the compositum, so when we reduce we find: >>> # needs sage.rings.number_field >>> P2 = K2.factor(Integer(43))[Integer(0)][Integer(0)] >>> P3 = K3.factor(Integer(43))[Integer(0)][Integer(0)] >>> Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial() x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 >>> Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial() x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 >>> H.change_ring(GF(Integer(43))).odd_degree_model().frobenius_polynomial() # needs sage.rings.finite_rings x^4 - 16*x^3 + 134*x^2 - 688*x + 1849 >>> # needs sage.rings.number_field >>> P2 = K2.factor(Integer(67))[Integer(0)][Integer(0)] >>> P3 = K3.factor(Integer(67))[Integer(0)][Integer(0)] >>> Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial() x^4 - 8*x^3 + 150*x^2 - 536*x + 4489 >>> Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial() x^4 - 8*x^3 + 150*x^2 - 536*x + 4489 >>> H.change_ring(GF(Integer(67))).odd_degree_model().frobenius_polynomial() # needs sage.rings.finite_rings x^4 - 8*x^3 + 150*x^2 - 536*x + 4489
- rational_points(**kwds)[source]#
Find rational points on the hyperelliptic curve, all arguments are passed on to
sage.schemes.generic.algebraic_scheme.rational_points()
.EXAMPLES:
For the LMFDB genus 2 curve 932.a.3728.1:
sage: R.<x> = PolynomialRing(QQ) sage: C = HyperellipticCurve(R([0, -1, 1, 0, 1, -2, 1]), R([1])) sage: C.rational_points(bound=8) [(-1 : -3 : 1), (-1 : 2 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 0), (1/2 : -5/8 : 1), (1/2 : -3/8 : 1), (1 : -1 : 1), (1 : 0 : 1)]
>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> C = HyperellipticCurve(R([Integer(0), -Integer(1), Integer(1), Integer(0), Integer(1), -Integer(2), Integer(1)]), R([Integer(1)])) >>> C.rational_points(bound=Integer(8)) [(-1 : -3 : 1), (-1 : 2 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 0), (1/2 : -5/8 : 1), (1/2 : -3/8 : 1), (1 : -1 : 1), (1 : 0 : 1)]
Check that Issue #29509 is fixed for the LMFDB genus 2 curve 169.a.169.1:
sage: C = HyperellipticCurve(R([0, 0, 0, 0, 1, 1]), R([1, 1, 0, 1])) sage: C.rational_points(bound=10) [(-1 : 0 : 1), (-1 : 1 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 0)]
>>> from sage.all import * >>> C = HyperellipticCurve(R([Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1)]), R([Integer(1), Integer(1), Integer(0), Integer(1)])) >>> C.rational_points(bound=Integer(10)) [(-1 : 0 : 1), (-1 : 1 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 0)]
An example over a number field:
sage: R.<x> = PolynomialRing(QuadraticField(2)) # needs sage.rings.number_field sage: C = HyperellipticCurve(R([1, 0, 0, 0, 0, 1])) # needs sage.rings.number_field sage: C.rational_points(bound=2) # needs sage.rings.number_field [(-1 : 0 : 1), (0 : -1 : 1), (0 : 1 : 0), (0 : 1 : 1), (1 : -a : 1), (1 : a : 1)]
>>> from sage.all import * >>> R = PolynomialRing(QuadraticField(Integer(2)), names=('x',)); (x,) = R._first_ngens(1)# needs sage.rings.number_field >>> C = HyperellipticCurve(R([Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1)])) # needs sage.rings.number_field >>> C.rational_points(bound=Integer(2)) # needs sage.rings.number_field [(-1 : 0 : 1), (0 : -1 : 1), (0 : 1 : 0), (0 : 1 : 1), (1 : -a : 1), (1 : a : 1)]
- sage.schemes.hyperelliptic_curves.hyperelliptic_generic.is_HyperellipticCurve(C)[source]#
EXAMPLES:
sage: from sage.schemes.hyperelliptic_curves.hyperelliptic_generic import is_HyperellipticCurve sage: R.<x> = QQ[]; C = HyperellipticCurve(x^3 + x - 1); C Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + x - 1 sage: is_HyperellipticCurve(C) doctest:warning... DeprecationWarning: The function is_HyperellipticCurve is deprecated; use 'isinstance(..., HyperellipticCurve_generic)' instead. See https://github.com/sagemath/sage/issues/38022 for details. True
>>> from sage.all import * >>> from sage.schemes.hyperelliptic_curves.hyperelliptic_generic import is_HyperellipticCurve >>> R = QQ['x']; (x,) = R._first_ngens(1); C = HyperellipticCurve(x**Integer(3) + x - Integer(1)); C Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + x - 1 >>> is_HyperellipticCurve(C) doctest:warning... DeprecationWarning: The function is_HyperellipticCurve is deprecated; use 'isinstance(..., HyperellipticCurve_generic)' instead. See https://github.com/sagemath/sage/issues/38022 for details. True