Esempio n. 1
0
 def __init__(self, J):
     """
     """
     R = J.base_ring()
     PP = ProjectiveSpace(3, R, ["X0", "X1", "X2", "X3"])
     X0, X1, X2, X3 = PP.gens()
     C = J.curve()
     f, h = C.hyperelliptic_polynomials()
     a12 = f[0]
     a10 = f[1]
     a8 = f[2]
     a6 = f[3]
     a4 = f[4]
     a2 = f[5]
     a0 = f[6]
     if h != 0:
         c6 = h[0]
         c4 = h[1]
         c2 = h[2]
         c0 = h[3]
         a12, a10, a8, a6, a4, a2, a0 = \
              (4*a12 + c6**2,
               4*a10 + 2*c4*c6,
               4*a8 + 2*c2*c6 + c4**2,
               4*a6 + 2*c0*c6 + 2*c2*c4,
               4*a4 + 2*c0*c4 + c2**2,
               4*a2 + 2*c0*c2,
               4*a0 + c0**2)
     F = \
       (-4*a8*a12 + a10**2)*X0**4 + \
       -4*a6*a12*X0**3*X1 + \
       -2*a6*a10*X0**3*X2 + \
       -4*a12*X0**3*X3 + \
       -4*a4*a12*X0**2*X1**2 + \
       (4*a2*a12 - 4*a4*a10)*X0**2*X1*X2 + \
       -2*a10*X0**2*X1*X3 + \
       (-4*a0*a12 + 2*a2*a10 - 4*a4*a8 + a6**2)*X0**2*X2**2 + \
       -4*a8*X0**2*X2*X3 + \
       -4*a2*a12*X0*X1**3 + \
       (8*a0*a12 - 4*a2*a10)*X0*X1**2*X2 + \
       (4*a0*a10 - 4*a2*a8)*X0*X1*X2**2 + \
       -2*a6*X0*X1*X2*X3 + \
       -2*a2*a6*X0*X2**3 + \
       -4*a4*X0*X2**2*X3 + \
       -4*X0*X2*X3**2 + \
       -4*a0*a12*X1**4 + \
       -4*a0*a10*X1**3*X2 + \
       -4*a0*a8*X1**2*X2**2 + \
       X1**2*X3**2 + \
       -4*a0*a6*X1*X2**3 + \
       -2*a2*X1*X2**2*X3 + \
       (-4*a0*a4 + a2**2)*X2**4 + \
       -4*a0*X2**3*X3
     AlgebraicScheme_subscheme_projective.__init__(self, PP, F)
     X, Y, Z = C.ambient_space().gens()
     if a0 == 0:
         a0 = a2
     phi = Hom(C, self)([0, Z**2, X * Z, a0 * X**2], Schemes())
     C._kummer_morphism = phi
     J._kummer_surface = self
Esempio n. 2
0
 def __init__(self,J):
     """
     """
     R = J.base_ring()
     PP = ProjectiveSpace(3,R,["X0","X1","X2","X3"])
     X0, X1, X2, X3 = PP.gens()
     C = J.curve()
     f, h = C.hyperelliptic_polynomials()
     a12 = f[0]; a10 = f[1]; a8 = f[2];
     a6 = f[3]; a4 = f[4]; a2 = f[5]; a0 = f[6]
     if h != 0:
         c6 = h[0]; c4 = h[1]; c2 = h[2]; c0 = h[3]
         a12, a10, a8, a6, a4, a2, a0 = \
              (4*a12 + c6**2,
               4*a10 + 2*c4*c6,
               4*a8 + 2*c2*c6 + c4**2,
               4*a6 + 2*c0*c6 + 2*c2*c4,
               4*a4 + 2*c0*c4 + c2**2,
               4*a2 + 2*c0*c2,
               4*a0 + c0**2)
     F = \
       (-4*a8*a12 + a10**2)*X0**4 + \
       -4*a6*a12*X0**3*X1 + \
       -2*a6*a10*X0**3*X2 + \
       -4*a12*X0**3*X3 + \
       -4*a4*a12*X0**2*X1**2 + \
       (4*a2*a12 - 4*a4*a10)*X0**2*X1*X2 + \
       -2*a10*X0**2*X1*X3 + \
       (-4*a0*a12 + 2*a2*a10 - 4*a4*a8 + a6**2)*X0**2*X2**2 + \
       -4*a8*X0**2*X2*X3 + \
       -4*a2*a12*X0*X1**3 + \
       (8*a0*a12 - 4*a2*a10)*X0*X1**2*X2 + \
       (4*a0*a10 - 4*a2*a8)*X0*X1*X2**2 + \
       -2*a6*X0*X1*X2*X3 + \
       -2*a2*a6*X0*X2**3 + \
       -4*a4*X0*X2**2*X3 + \
       -4*X0*X2*X3**2 + \
       -4*a0*a12*X1**4 + \
       -4*a0*a10*X1**3*X2 + \
       -4*a0*a8*X1**2*X2**2 + \
       X1**2*X3**2 + \
       -4*a0*a6*X1*X2**3 + \
       -2*a2*X1*X2**2*X3 + \
       (-4*a0*a4 + a2**2)*X2**4 + \
       -4*a0*X2**3*X3
     AlgebraicScheme_subscheme_projective.__init__(self, PP, F)
     X, Y, Z = C.ambient_space().gens()
     if a0 ==0:
         a0 = a2
     phi = Hom(C,self)([0,Z**2,X*Z,a0*X**2],Schemes())
     C._kummer_morphism = phi
     J._kummer_surface = self
Esempio n. 3
0
def QuarticCurve(F, PP=None, check=False):
    """
    Returns the quartic curve defined by F.
    """
    if not PP is None:
        if not is_ProjectiveSpace(PP) and PP.dimension == 2:
            raise TypeError, "Argument PP (=%s) must be a projective plane" % PP
    elif not is_MPolynomial(F):
        raise TypeError, \
              "Argument F (=%s) must be a homogeneous multivariate polynomial"%F
    else:
        if not F.is_homogeneous():
            "Argument F (=%s) must be a homogeneous polynomial" % F
        P = F.parent()
        if P.ngens() != 3:
            "Argument F (=%s) must be a homogeneous multivariate polynomial in 3 variables" % F
        PP = ProjectiveSpace(P)
    if check:
        raise TypeError, "Argument checking (for nonsingularity) is not implemented."
    return QuarticCurve_generic(PP, F)
Esempio n. 4
0
def Conic(base_field, F=None, names=None, unique=True):
    r"""
    Return the plane projective conic curve defined by ``F``
    over ``base_field``.
    
    The input form ``Conic(F, names=None)`` is also accepted,
    in which case the fraction field of the base ring of ``F``
    is used as base field.

    INPUT:
    
    - ``base_field`` -- The base field of the conic.
    
    - ``names`` -- a list, tuple, or comma separated string
      of three variable names specifying the names
      of the coordinate functions of the ambient
      space `\Bold{P}^3`. If not specified or read
      off from ``F``, then this defaults to ``'x,y,z'``.

    - ``F`` -- a polynomial, list, matrix, ternary quadratic form,
      or list or tuple of 5 points in the plane.
                   
                   If ``F`` is a polynomial or quadratic form,
                   then the output is the curve in the projective plane
                   defined by ``F = 0``.

                   If ``F`` is a polynomial, then it must be a polynomial
                   of degree at most 2 in 2 variables, or a homogeneous
                   polynomial in of degree 2 in 3 variables.
                   
                   If ``F`` is a matrix, then the output is the zero locus
                   of `(x,y,z) F (x,y,z)^t`.
    
                   If ``F`` is a list of coefficients, then it has
                   length 3 or 6 and gives the coefficients of
                   the monomials `x^2, y^2, z^2` or all 6 monomials
                   `x^2, xy, xz, y^2, yz, z^2` in lexicographic order.

                   If ``F`` is a list of 5 points in the plane, then the output
                   is a conic through those points.
      
    - ``unique`` -- Used only if ``F`` is a list of points in the plane.
      If the conic through the points is not unique, then
      raise ``ValueError`` if and only if ``unique`` is True
                    
    OUTPUT:
    
    A plane projective conic curve defined by ``F`` over a field.
    
    EXAMPLES:
    
    Conic curves given by polynomials ::

        sage: X,Y,Z = QQ['X,Y,Z'].gens()
        sage: Conic(X^2 - X*Y + Y^2 - Z^2)
        Projective Conic Curve over Rational Field defined by X^2 - X*Y + Y^2 - Z^2
        sage: x,y = GF(7)['x,y'].gens()
        sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W')
        Projective Conic Curve over Finite Field of size 7 defined by U^2 + 2*V^2 - U*W - 3*W^2

    Conic curves given by matrices ::

        sage: Conic(matrix(QQ, [[1, 2, 0], [4, 0, 0], [7, 0, 9]]), 'x,y,z')
        Projective Conic Curve over Rational Field defined by x^2 + 6*x*y + 7*x*z + 9*z^2

        sage: x,y,z = GF(11)['x,y,z'].gens()
        sage: C = Conic(x^2+y^2-2*z^2); C
        Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2
        sage: Conic(C.symmetric_matrix(), 'x,y,z')
        Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2

    Conics given by coefficients ::
    
        sage: Conic(QQ, [1,2,3])
        Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + 3*z^2
        sage: Conic(GF(7), [1,2,3,4,5,6], 'X')
        Projective Conic Curve over Finite Field of size 7 defined by X0^2 + 2*X0*X1 - 3*X1^2 + 3*X0*X2 - 2*X1*X2 - X2^2
    
    The conic through a set of points ::

        sage: C = Conic(QQ, [[10,2],[3,4],[-7,6],[7,8],[9,10]]); C
        Projective Conic Curve over Rational Field defined by x^2 + 13/4*x*y - 17/4*y^2 - 35/2*x*z + 91/4*y*z - 37/2*z^2
        sage: C.rational_point()
        (10 : 2 : 1)
        sage: C.point([3,4])
        (3 : 4 : 1)

        sage: a=AffineSpace(GF(13),2)
        sage: Conic([a([x,x^2]) for x in range(5)])
        Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z
    """
    if not (is_IntegralDomain(base_field) or base_field == None):
        if names is None:
            names = F
        F = base_field
        base_field = None
    if isinstance(F, (list,tuple)):
        if len(F) == 1:
            return Conic(base_field, F[0], names)
        if names == None:
            names = 'x,y,z'
        if len(F) == 5:
            L=[]
            for f in F:
                if isinstance(f, SchemeMorphism_point_affine):
                    C = Sequence(f, universe = base_field)
                    if len(C) != 2:
                        raise TypeError, "points in F (=%s) must be planar"%F
                    C.append(1)
                elif isinstance(f, SchemeMorphism_point_projective_field):
                    C = Sequence(f, universe = base_field)
                elif isinstance(f, (list, tuple)):
                    C = Sequence(f, universe = base_field)
                    if len(C) == 2:
                        C.append(1)
                else:
                    raise TypeError, "F (=%s) must be a sequence of planar " \
                                      "points" % F
                if len(C) != 3:
                    raise TypeError, "points in F (=%s) must be planar" % F
                P = C.universe()
                if not is_IntegralDomain(P):
                    raise TypeError, "coordinates of points in F (=%s) must " \
                                     "be in an integral domain" % F
                L.append(Sequence([C[0]**2, C[0]*C[1], C[0]*C[2], C[1]**2,
                                   C[1]*C[2], C[2]**2], P.fraction_field()))
            M=Matrix(L)
            if unique and M.rank() != 5:
                raise ValueError, "points in F (=%s) do not define a unique " \
                                   "conic" % F
            con = Conic(base_field, Sequence(M.right_kernel().gen()), names)
            con.point(F[0])
            return con
        F = Sequence(F, universe = base_field)
        base_field = F.universe().fraction_field()
        temp_ring = PolynomialRing(base_field, 3, names)
        (x,y,z) = temp_ring.gens()
        if len(F) == 3:
            return Conic(F[0]*x**2 + F[1]*y**2 + F[2]*z**2)
        if len(F) == 6:
            return Conic(F[0]*x**2 + F[1]*x*y + F[2]*x*z + F[3]*y**2 + \
                         F[4]*y*z + F[5]*z**2)
        raise TypeError, "F (=%s) must be a sequence of 3 or 6" \
                         "coefficients" % F
    if is_QuadraticForm(F):
        F = F.matrix()
    if is_Matrix(F) and F.is_square() and F.ncols() == 3:
        if names == None:
            names = 'x,y,z'
        temp_ring = PolynomialRing(F.base_ring(), 3, names)
        F = vector(temp_ring.gens()) * F * vector(temp_ring.gens())

    if not is_MPolynomial(F):
        raise TypeError, "F (=%s) must be a three-variable polynomial or " \
                         "a sequence of points or coefficients" % F

    if F.total_degree() != 2:
        raise TypeError, "F (=%s) must have degree 2" % F

    if base_field == None:
        base_field = F.base_ring()
    if not is_IntegralDomain(base_field):
        raise ValueError, "Base field (=%s) must be a field" % base_field
    base_field = base_field.fraction_field()
    if names == None:
        names = F.parent().variable_names()
    pol_ring = PolynomialRing(base_field, 3, names)

    if F.parent().ngens() == 2:
        (x,y,z) = pol_ring.gens()
        F = pol_ring(F(x/z,y/z)*z**2)    

    if F == 0:
        raise ValueError, "F must be nonzero over base field %s" % base_field

    if F.total_degree() != 2:
        raise TypeError, "F (=%s) must have degree 2 over base field %s" % \
                          (F, base_field)

    if F.parent().ngens() == 3:
        P2 = ProjectiveSpace(2, base_field, names)
        if is_PrimeFiniteField(base_field):
            return ProjectiveConic_prime_finite_field(P2, F)
        if is_FiniteField(base_field):
            return ProjectiveConic_finite_field(P2, F)
        if is_RationalField(base_field):
            return ProjectiveConic_rational_field(P2, F)
        if is_NumberField(base_field):
            return ProjectiveConic_number_field(P2, F)
        return ProjectiveConic_field(P2, F)

    raise TypeError, "Number of variables of F (=%s) must be 2 or 3" % F
Esempio n. 5
0
def HyperellipticCurve(f,h=None,names=None,PP=None):
    r"""
    Returns 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
    
    
    EXAMPLES: A curve with and without the h term::
    
        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
    
    A curve over a non-prime finite field::
    
        sage: k.<a> = GF(9); R.<x> = k[]
        sage: HyperellipticCurve(x^3 + x - 1, x+a)
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + (x + a)*y = x^3 + x + 2
    
    Here's one where we change the names of the vars in the homogeneous
    polynomial::
    
        sage: k.<a> = GF(9); R.<x> = k[]    
        sage: HyperellipticCurve(x^3 + x - 1, x+a, names=['X','Y'])
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by Y^2 + (X + a)*Y = X^3 + X + 2
    """
    if not is_Polynomial(f):
        raise TypeError, "Arguments f (=%s) and h (= %s) must be polynomials"%(f,h)
    P = f.parent()
    if h is None:
        h = P(0)
        g = (f.degree()-1)%2
    try:
        h = P(h)
    except TypeError:
        raise TypeError, \
              "Arguments f (=%s) and h (= %s) must be polynomials in the same ring"%(f,h)
    df = f.degree()
    dh_2 = 2*h.degree()
    if dh_2 < df:
        g = (df-1)//2
    elif df < dh_2:
        g = (dh_2-1)//2
    else:
        a0 = f.leading_coefficient()
        b0 = h.leading_coefficient()
        A0 = 4*a0 + b0^2
        if A0 != 0:
            g = (df-1)//2
        else:
            if P(2) == 0:
                raise TypeError, "Arguments define a curve with finite singularity."
            f0 = 4*f + h^2
            d0 = f0.degree()
            g = (d0-1)//2
    R = P.base_ring()
    PP = ProjectiveSpace(2, R)
    if names is None:
        names = ["x","y"]
    if is_FiniteField(R):
        if g == 2:
            return HyperellipticCurve_g2_finite_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_finite_field(PP, f, h, names=names, genus=g)
    elif is_RationalField(R):
        if g == 2:
            return HyperellipticCurve_g2_rational_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_rational_field(PP, f, h, names=names, genus=g)
    elif is_pAdicField(R):
        if g == 2:
            return HyperellipticCurve_g2_padic_field(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_padic_field(PP, f, h, names=names, genus=g)
    else:
        if g == 2:
            return HyperellipticCurve_g2_generic(PP, f, h, names=names, genus=g)
        else:
            return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)
Esempio n. 6
0
def Curve(F):
    """
    Return the plane or space curve defined by `F`, where
    `F` can be either a multivariate polynomial, a list or
    tuple of polynomials, or an algebraic scheme.

    If `F` is in two variables the curve is affine, and if it
    is homogenous in `3` variables, then the curve is
    projective.

    EXAMPLE: A projective plane curve

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3); C
        Projective Curve over Rational Field defined by x^3 + y^3 + z^3
        sage: C.genus()
        1

    EXAMPLE: Affine plane curves

    ::

        sage: x,y = GF(7)['x,y'].gens()
        sage: C = Curve(y^2 + x^3 + x^10); C
        Affine Curve over Finite Field of size 7 defined by x^10 + x^3 + y^2
        sage: C.genus()
        0
        sage: x, y = QQ['x,y'].gens()
        sage: Curve(x^3 + y^3 + 1)
        Affine Curve over Rational Field defined by x^3 + y^3 + 1

    EXAMPLE: A projective space curve

    ::

        sage: x,y,z,w = QQ['x,y,z,w'].gens()
        sage: C = Curve([x^3 + y^3 - z^3 - w^3, x^5 - y*z^4]); C
        Projective Space Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4
        sage: C.genus()
        13

    EXAMPLE: An affine space curve

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve([y^2 + x^3 + x^10 + z^7,  x^2 + y^2]); C
        Affine Space Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2
        sage: C.genus()
        47

    EXAMPLE: We can also make non-reduced non-irreducible curves.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve((x-y)*(x+y))
        Projective Conic Curve over Rational Field defined by x^2 - y^2
        sage: Curve((x-y)^2*(x+y)^2)
        Projective Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4

    EXAMPLE: A union of curves is a curve.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3)
        sage: D = Curve(x^4 + y^4 + z^4)
        sage: C.union(D)
        Projective Curve over Rational Field defined by
        x^7 + x^4*y^3 + x^3*y^4 + y^7 + x^4*z^3 + y^4*z^3 + x^3*z^4 + y^3*z^4 + z^7

    The intersection is not a curve, though it is a scheme.

    ::

        sage: X = C.intersection(D); X
        Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
         x^3 + y^3 + z^3,
         x^4 + y^4 + z^4

    Note that the intersection has dimension `0`.

    ::

        sage: X.dimension()
        0
        sage: I = X.defining_ideal(); I
        Ideal (x^3 + y^3 + z^3, x^4 + y^4 + z^4) of Multivariate Polynomial Ring in x, y, z over Rational Field

    EXAMPLE: In three variables, the defining equation must be
    homogeneous.

    If the parent polynomial ring is in three variables, then the
    defining ideal must be homogeneous.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve(x^2+y^2)
        Projective Conic Curve over Rational Field defined by x^2 + y^2
        sage: Curve(x^2+y^2+z)
        Traceback (most recent call last):
        ...
        TypeError: x^2 + y^2 + z is not a homogeneous polynomial!

    The defining polynomial must always be nonzero::

        sage: P1.<x,y> = ProjectiveSpace(1,GF(5))
        sage: Curve(0*x)
        Traceback (most recent call last):
        ...
        ValueError: defining polynomial of curve must be nonzero
    """
    if is_AlgebraicScheme(F):
        return Curve(F.defining_polynomials())

    if isinstance(F, (list, tuple)):
        if len(F) == 1:
            return Curve(F[0])
        F = Sequence(F)
        P = F.universe()
        if not is_MPolynomialRing(P):
            raise TypeError, "universe of F must be a multivariate polynomial ring"

        for f in F:
            if not f.is_homogeneous():
                A = AffineSpace(P.ngens(), P.base_ring())
                A._coordinate_ring = P
                return AffineSpaceCurve_generic(A, F)

        A = ProjectiveSpace(P.ngens()-1, P.base_ring())
        A._coordinate_ring = P
        return ProjectiveSpaceCurve_generic(A, F)

    if not is_MPolynomial(F):
        raise TypeError, "F (=%s) must be a multivariate polynomial"%F

    P = F.parent()
    k = F.base_ring()
    if F.parent().ngens() == 2:
        if F == 0:
            raise ValueError, "defining polynomial of curve must be nonzero"
        A2 = AffineSpace(2, P.base_ring())
        A2._coordinate_ring = P

        if is_FiniteField(k):
            if k.is_prime_field():
                return AffineCurve_prime_finite_field(A2, F)
            else:
                return AffineCurve_finite_field(A2, F)
        else:
            return AffineCurve_generic(A2, F)

    elif F.parent().ngens() == 3:
        if F == 0:
            raise ValueError, "defining polynomial of curve must be nonzero"
        P2 = ProjectiveSpace(2, P.base_ring())
        P2._coordinate_ring = P

        if F.total_degree() == 2 and k.is_field():
            return Conic(F)

        if is_FiniteField(k):
            if k.is_prime_field():
                return ProjectiveCurve_prime_finite_field(P2, F)
            else:
                return ProjectiveCurve_finite_field(P2, F)
        else:
            return ProjectiveCurve_generic(P2, F)


    else:

        raise TypeError, "Number of variables of F (=%s) must be 2 or 3"%F
Esempio n. 7
0
def Curve(F):
    """
    Return the plane or space curve defined by `F`, where
    `F` can be either a multivariate polynomial, a list or
    tuple of polynomials, or an algebraic scheme.
    
    If `F` is in two variables the curve is affine, and if it
    is homogenous in `3` variables, then the curve is
    projective.
    
    EXAMPLE: A projective plane curve
    
    ::
    
        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3); C
        Projective Curve over Rational Field defined by x^3 + y^3 + z^3
        sage: C.genus()
        1
    
    EXAMPLE: Affine plane curves
    
    ::
    
        sage: x,y = GF(7)['x,y'].gens()
        sage: C = Curve(y^2 + x^3 + x^10); C
        Affine Curve over Finite Field of size 7 defined by x^10 + x^3 + y^2
        sage: C.genus()
        0
        sage: x, y = QQ['x,y'].gens()
        sage: Curve(x^3 + y^3 + 1)
        Affine Curve over Rational Field defined by x^3 + y^3 + 1
    
    EXAMPLE: A projective space curve
    
    ::
    
        sage: x,y,z,w = QQ['x,y,z,w'].gens()
        sage: C = Curve([x^3 + y^3 - z^3 - w^3, x^5 - y*z^4]); C
        Projective Space Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4
        sage: C.genus()
        13
    
    EXAMPLE: An affine space curve
    
    ::
    
        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve([y^2 + x^3 + x^10 + z^7,  x^2 + y^2]); C
        Affine Space Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2
        sage: C.genus()
        47
    
    EXAMPLE: We can also make non-reduced non-irreducible curves.
    
    ::
    
        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve((x-y)*(x+y))
        Projective Conic Curve over Rational Field defined by x^2 - y^2
        sage: Curve((x-y)^2*(x+y)^2)
        Projective Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4
    
    EXAMPLE: A union of curves is a curve.
    
    ::
    
        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3)
        sage: D = Curve(x^4 + y^4 + z^4)
        sage: C.union(D)
        Projective Curve over Rational Field defined by
        x^7 + x^4*y^3 + x^3*y^4 + y^7 + x^4*z^3 + y^4*z^3 + x^3*z^4 + y^3*z^4 + z^7
    
    The intersection is not a curve, though it is a scheme.
    
    ::
    
        sage: X = C.intersection(D); X
        Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
         x^3 + y^3 + z^3,
         x^4 + y^4 + z^4
    
    Note that the intersection has dimension `0`.
    
    ::
    
        sage: X.dimension()
        0
        sage: I = X.defining_ideal(); I
        Ideal (x^3 + y^3 + z^3, x^4 + y^4 + z^4) of Multivariate Polynomial Ring in x, y, z over Rational Field
    
    EXAMPLE: In three variables, the defining equation must be
    homogeneous.
    
    If the parent polynomial ring is in three variables, then the
    defining ideal must be homogeneous.
    
    ::
    
        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve(x^2+y^2)
        Projective Conic Curve over Rational Field defined by x^2 + y^2
        sage: Curve(x^2+y^2+z)
        Traceback (most recent call last):
        ...
        TypeError: x^2 + y^2 + z is not a homogeneous polynomial!
    
    The defining polynomial must always be nonzero::
    
        sage: P1.<x,y> = ProjectiveSpace(1,GF(5))
        sage: Curve(0*x)
        Traceback (most recent call last):
        ...
        ValueError: defining polynomial of curve must be nonzero
    """
    if is_AlgebraicScheme(F):
        return Curve(F.defining_polynomials())

    if isinstance(F, (list, tuple)):
        if len(F) == 1:
            return Curve(F[0])
        F = Sequence(F)
        P = F.universe()
        if not is_MPolynomialRing(P):
            raise TypeError, "universe of F must be a multivariate polynomial ring"

        for f in F:
            if not f.is_homogeneous():
                A = AffineSpace(P.ngens(), P.base_ring())
                A._coordinate_ring = P
                return AffineSpaceCurve_generic(A, F)

        A = ProjectiveSpace(P.ngens() - 1, P.base_ring())
        A._coordinate_ring = P
        return ProjectiveSpaceCurve_generic(A, F)

    if not is_MPolynomial(F):
        raise TypeError, "F (=%s) must be a multivariate polynomial" % F

    P = F.parent()
    k = F.base_ring()
    if F.parent().ngens() == 2:
        if F == 0:
            raise ValueError, "defining polynomial of curve must be nonzero"
        A2 = AffineSpace(2, P.base_ring())
        A2._coordinate_ring = P

        if is_FiniteField(k):
            if k.is_prime_field():
                return AffineCurve_prime_finite_field(A2, F)
            else:
                return AffineCurve_finite_field(A2, F)
        else:
            return AffineCurve_generic(A2, F)

    elif F.parent().ngens() == 3:
        if F == 0:
            raise ValueError, "defining polynomial of curve must be nonzero"
        P2 = ProjectiveSpace(2, P.base_ring())
        P2._coordinate_ring = P

        if F.total_degree() == 2 and k.is_field():
            return Conic(F)

        if is_FiniteField(k):
            if k.is_prime_field():
                return ProjectiveCurve_prime_finite_field(P2, F)
            else:
                return ProjectiveCurve_finite_field(P2, F)
        else:
            return ProjectiveCurve_generic(P2, F)

    else:

        raise TypeError, "Number of variables of F (=%s) must be 2 or 3" % F
Esempio n. 8
0
def HyperellipticCurve(f, h=None, names=None, PP=None, check_squarefree=True):
    r"""
    Returns 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`` (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[]
        sage: HyperellipticCurve(x^3 + x - 1, x+a)
        Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + (x + a)*y = x^3 + x + 2

    Characteristic two::

        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

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

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

    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

    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

    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

    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.

    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 non-zero, 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
    """
    if (not is_Polynomial(f)) or f == 0:
        raise TypeError, "Arguments f (=%s) and h (= %s) must be polynomials " \
                         "and f must be non-zero" % (f,h)
    P = f.parent()
    if h is None:
        h = P(0)
    try:
        h = P(h)
    except TypeError:
        raise TypeError, \
              "Arguments f (=%s) and h (= %s) must be polynomials in the same ring"%(f,h)
    df = f.degree()
    dh_2 = 2 * h.degree()
    if dh_2 < df:
        g = (df - 1) // 2
    else:
        g = (dh_2 - 1) // 2
    if check_squarefree:
        # Assuming we are working over a field, this checks that after
        # resolving the singularity at infinity, we get a smooth double cover
        # of P^1.
        if P(2) == 0:
            # characteristic 2
            if h == 0:
                raise ValueError, \
                   "In characteristic 2, argument h (= %s) must be non-zero."%h
            if h[g + 1] == 0 and f[2 * g + 1]**2 == f[2 * g + 2] * h[g]**2:
                raise ValueError, "Not a hyperelliptic curve: " \
                                  "highly singular at infinity."
            should_be_coprime = [h, f * h.derivative()**2 + f.derivative()**2]
        else:
            # characteristic not 2
            F = f + h**2 / 4
            if not F.degree() in [2 * g + 1, 2 * g + 2]:
                raise ValueError, "Not a hyperelliptic curve: " \
                                  "highly singular at infinity."
            should_be_coprime = [F, F.derivative()]
        try:
            smooth = should_be_coprime[0].gcd(
                should_be_coprime[1]).degree() == 0
        except (AttributeError, NotImplementedError, TypeError):
            try:
                smooth = should_be_coprime[0].resultant(
                    should_be_coprime[1]) != 0
            except (AttributeError, NotImplementedError, TypeError):
                raise NotImplementedError, "Cannot determine whether " \
                      "polynomials %s have a common root. Use " \
                      "check_squarefree=False to skip this check." % \
                      should_be_coprime
        if not smooth:
            raise ValueError, "Not a hyperelliptic curve: " \
                              "singularity in the provided affine patch."
    R = P.base_ring()
    PP = ProjectiveSpace(2, R)
    if names is None:
        names = ["x", "y"]
    if is_FiniteField(R):
        if g == 2:
            return HyperellipticCurve_g2_finite_field(PP,
                                                      f,
                                                      h,
                                                      names=names,
                                                      genus=g)
        else:
            return HyperellipticCurve_finite_field(PP,
                                                   f,
                                                   h,
                                                   names=names,
                                                   genus=g)
    elif is_RationalField(R):
        if g == 2:
            return HyperellipticCurve_g2_rational_field(PP,
                                                        f,
                                                        h,
                                                        names=names,
                                                        genus=g)
        else:
            return HyperellipticCurve_rational_field(PP,
                                                     f,
                                                     h,
                                                     names=names,
                                                     genus=g)
    elif is_pAdicField(R):
        if g == 2:
            return HyperellipticCurve_g2_padic_field(PP,
                                                     f,
                                                     h,
                                                     names=names,
                                                     genus=g)
        else:
            return HyperellipticCurve_padic_field(PP,
                                                  f,
                                                  h,
                                                  names=names,
                                                  genus=g)
    else:
        if g == 2:
            return HyperellipticCurve_g2_generic(PP,
                                                 f,
                                                 h,
                                                 names=names,
                                                 genus=g)
        else:
            return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)