Path: blob/master/src/sage/schemes/hyperelliptic_curves/constructor.py
8820 views
"""1Hyperelliptic curve constructor2"""34#*****************************************************************************5# Copyright (C) 2006 David Kohel <[email protected]>6# Distributed under the terms of the GNU General Public License (GPL)7# http://www.gnu.org/licenses/8#*****************************************************************************910from sage.schemes.projective.projective_space import ProjectiveSpace1112from hyperelliptic_generic import HyperellipticCurve_generic13from hyperelliptic_finite_field import HyperellipticCurve_finite_field14from hyperelliptic_rational_field import HyperellipticCurve_rational_field15from hyperelliptic_padic_field import HyperellipticCurve_padic_field16from hyperelliptic_g2_generic import HyperellipticCurve_g2_generic17from hyperelliptic_g2_finite_field import HyperellipticCurve_g2_finite_field18from hyperelliptic_g2_rational_field import HyperellipticCurve_g2_rational_field19from hyperelliptic_g2_padic_field import HyperellipticCurve_g2_padic_field2021from sage.rings.padics.all import is_pAdicField2223from sage.rings.rational_field import is_RationalField24from sage.rings.finite_rings.constructor import is_FiniteField25from sage.rings.polynomial.polynomial_element import is_Polynomial262728def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True):29r"""30Returns the hyperelliptic curve `y^2 + h y = f`, for31univariate polynomials `h` and `f`. If `h`32is not given, then it defaults to 0.3334INPUT:3536- ``f`` - univariate polynomial3738- ``h`` - optional univariate polynomial3940- ``names`` (default: ``["x","y"]``) - names for the41coordinate functions4243- ``check_squarefree`` (default: ``True``) - test if44the input defines a hyperelliptic curve when f is45homogenized to degree `2g+2` and h to degree46`g+1` for some g.4748.. WARNING::4950When setting ``check_squarefree=False`` or using a base ring that is51not a field, the output curves are not to be trusted. For example, the52output of ``is_singular`` is always ``False``, without this being53properly tested in that case.5455.. NOTE::5657The words "hyperelliptic curve" are normally only used for curves of58genus at least two, but this class allows more general smooth double59covers of the projective line (conics and elliptic curves), even though60the class is not meant for those and some outputs may be incorrect.6162EXAMPLES:6364Basic examples::6566sage: R.<x> = QQ[]67sage: HyperellipticCurve(x^5 + x + 1)68Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 169sage: HyperellipticCurve(x^19 + x + 1, x-2)70Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 17172sage: k.<a> = GF(9); R.<x> = k[]73sage: HyperellipticCurve(x^3 + x - 1, x+a)74Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + (x + a)*y = x^3 + x + 27576Characteristic two::7778sage: P.<x> = GF(8,'a')[]79sage: HyperellipticCurve(x^7+1, x)80Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + x*y = x^7 + 181sage: HyperellipticCurve(x^8+x^7+1, x^4+1)82Hyperelliptic Curve over Finite Field in a of size 2^3 defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 18384sage: HyperellipticCurve(x^8+1, x)85Traceback (most recent call last):86...87ValueError: Not a hyperelliptic curve: highly singular at infinity.8889sage: HyperellipticCurve(x^8+x^7+1, x^4)90Traceback (most recent call last):91...92ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.9394sage: F.<t> = PowerSeriesRing(FiniteField(2))95sage: P.<x> = PolynomialRing(FractionField(F))96sage: HyperellipticCurve(x^5+t, x)97Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2 defined by y^2 + x*y = x^5 + t9899We can change the names of the variables in the output::100101sage: k.<a> = GF(9); R.<x> = k[]102sage: HyperellipticCurve(x^3 + x - 1, x+a, names=['X','Y'])103Hyperelliptic Curve over Finite Field in a of size 3^2 defined by Y^2 + (X + a)*Y = X^3 + X + 2104105This class also allows curves of genus zero or one, which are strictly106speaking not hyperelliptic::107108sage: P.<x> = QQ[]109sage: HyperellipticCurve(x^2+1)110Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 1111sage: HyperellipticCurve(x^4-1)112Hyperelliptic Curve over Rational Field defined by y^2 = x^4 - 1113sage: HyperellipticCurve(x^3+2*x+2)114Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2115116Double roots::117118sage: P.<x> = GF(7)[]119sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1))120Traceback (most recent call last):121...122ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.123124sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False)125Hyperelliptic 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 + 3126127The input for a (smooth) hyperelliptic curve of genus `g` should not128contain polynomials of degree greater than `2g+2`. In the following129example, the hyperelliptic curve has genus 2 and there exists a model130`y^2 = F` of degree 6, so the model `y^2 + yh = f` of degree 200 is not131allowed.::132133sage: P.<x> = QQ[]134sage: h = x^100135sage: F = x^6+1136sage: f = F-h^2/4137sage: HyperellipticCurve(f, h)138Traceback (most recent call last):139...140ValueError: Not a hyperelliptic curve: highly singular at infinity.141142sage: HyperellipticCurve(F)143Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1144145An example with a singularity over an inseparable extension of the146base field::147148sage: F.<t> = GF(5)[]149sage: P.<x> = F[]150sage: HyperellipticCurve(x^5+t)151Traceback (most recent call last):152...153ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.154155Input with integer coefficients creates objects with the integers156as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`).157In other words, it is checked that the discriminant is non-zero, but it is158not checked whether the discriminant is a unit in `\ZZ^*`.::159160sage: P.<x> = ZZ[]161sage: HyperellipticCurve(3*x^7+6*x+6)162Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6163164TESTS:165166Check that `f` can be a constant (see :trac:`15516`)::167168sage: R.<u> = PolynomialRing(Rationals())169sage: HyperellipticCurve(-12, u^4 + 7)170Hyperelliptic Curve over Rational Field defined by y^2 + (x^4 + 7)*y = -12171172"""173# F is the discriminant; use this for the type check174# rather than f and h, one of which might be constant.175F = h**2 + 4*f176if not is_Polynomial(F):177raise TypeError("Arguments f (= %s) and h (= %s) must be polynomials" % (f, h))178P = F.parent()179f = P(f)180h = P(h)181df = f.degree()182dh_2 = 2*h.degree()183if dh_2 < df:184g = (df-1)//2185else:186g = (dh_2-1)//2187if check_squarefree:188# Assuming we are working over a field, this checks that after189# resolving the singularity at infinity, we get a smooth double cover190# of P^1.191if P(2) == 0:192# characteristic 2193if h == 0:194raise ValueError, \195"In characteristic 2, argument h (= %s) must be non-zero."%h196if h[g+1] == 0 and f[2*g+1]**2 == f[2*g+2]*h[g]**2:197raise ValueError, "Not a hyperelliptic curve: " \198"highly singular at infinity."199should_be_coprime = [h, f*h.derivative()**2+f.derivative()**2]200else:201# characteristic not 2202if not F.degree() in [2*g+1, 2*g+2]:203raise ValueError, "Not a hyperelliptic curve: " \204"highly singular at infinity."205should_be_coprime = [F, F.derivative()]206try:207smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree()==0208except (AttributeError, NotImplementedError, TypeError):209try:210smooth = should_be_coprime[0].resultant(should_be_coprime[1])!=0211except (AttributeError, NotImplementedError, TypeError):212raise NotImplementedError, "Cannot determine whether " \213"polynomials %s have a common root. Use " \214"check_squarefree=False to skip this check." % \215should_be_coprime216if not smooth:217raise ValueError, "Not a hyperelliptic curve: " \218"singularity in the provided affine patch."219R = P.base_ring()220PP = ProjectiveSpace(2, R)221if names is None:222names = ["x","y"]223if is_FiniteField(R):224if g == 2:225return HyperellipticCurve_g2_finite_field(PP, f, h, names=names, genus=g)226else:227return HyperellipticCurve_finite_field(PP, f, h, names=names, genus=g)228elif is_RationalField(R):229if g == 2:230return HyperellipticCurve_g2_rational_field(PP, f, h, names=names, genus=g)231else:232return HyperellipticCurve_rational_field(PP, f, h, names=names, genus=g)233elif is_pAdicField(R):234if g == 2:235return HyperellipticCurve_g2_padic_field(PP, f, h, names=names, genus=g)236else:237return HyperellipticCurve_padic_field(PP, f, h, names=names, genus=g)238else:239if g == 2:240return HyperellipticCurve_g2_generic(PP, f, h, names=names, genus=g)241else:242return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)243244245