def QuarticCurve(F, PP=None, check=False): """ Returns the quartic curve defined by the polynomial F. INPUT: - F -- a polynomial in three variables, homogeneous of degree 4 - PP -- a projective plane (default:None) - check -- whether to check for smoothness or not (default:False) EXAMPLES:: sage: x,y,z=PolynomialRing(QQ,['x','y','z']).gens() sage: QuarticCurve(x**4+y**4+z**4) Quartic Curve over Rational Field defined by x^4 + y^4 + z^4 TESTS:: sage: QuarticCurve(x**3+y**3) Traceback (most recent call last): ... ValueError: Argument F (=x^3 + y^3) must be a homogeneous polynomial of degree 4 sage: QuarticCurve(x**4+y**4+z**3) Traceback (most recent call last): ... ValueError: Argument F (=x^4 + y^4 + z^3) must be a homogeneous polynomial of degree 4 sage: x,y=PolynomialRing(QQ,['x','y']).gens() sage: QuarticCurve(x**4+y**4) Traceback (most recent call last): ... ValueError: Argument F (=x^4 + y^4) must be a polynomial in 3 variables """ if not is_MPolynomial(F): raise ValueError("Argument F (=%s) must be a multivariate polynomial"%F) P = F.parent() if not P.ngens() == 3: raise ValueError("Argument F (=%s) must be a polynomial in 3 variables"%F) if not(F.is_homogeneous() and F.degree()==4): raise ValueError("Argument F (=%s) must be a homogeneous polynomial of degree 4"%F) if not PP is None: if not is_ProjectiveSpace(PP) and PP.dimension == 2: raise ValueError("Argument PP (=%s) must be a projective plane"%PP) else: PP = ProjectiveSpace(P) if check: raise NotImplementedError("Argument checking (for nonsingularity) is not implemented.") return QuarticCurve_generic(PP, F)
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)
def Curve(F, A=None): """ 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 no ambient space is passed in for ``A``, and if ``F`` is not an algebraic scheme, a new ambient space is constructed. Also not specifying an ambient space will cause the curve to be defined in either affine or projective space based on properties of ``F``. In particular, if ``F`` contains a nonhomogenous polynomial, the curve is affine, and if ``F`` consists of homogenous polynomials, then the curve is projective. INPUT: - ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme. - ``A`` -- (default: None) an ambient space in which to create the curve. EXAMPLES: A projective plane curve :: sage: x,y,z = QQ['x,y,z'].gens() sage: C = Curve(x^3 + y^3 + z^3); C Projective Plane Curve over Rational Field defined by x^3 + y^3 + z^3 sage: C.genus() 1 EXAMPLES: Affine plane curves :: sage: x,y = GF(7)['x,y'].gens() sage: C = Curve(y^2 + x^3 + x^10); C Affine Plane 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 Plane Curve over Rational Field defined by x^3 + y^3 + 1 EXAMPLES: 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 Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4 sage: C.genus() 13 EXAMPLES: 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 Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2 sage: C.genus() 47 EXAMPLES: 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 Plane Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4 EXAMPLES: 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 Plane 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 EXAMPLES: 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 :: sage: A.<x,y,z> = AffineSpace(QQ, 3) sage: C = Curve([y - x^2, z - x^3], A) sage: A == C.ambient_space() True """ if not A is None: if not isinstance(F, (list, tuple)): return Curve([F], A) if not is_AmbientSpace(A): raise TypeError("A (=%s) must be either an affine or projective space"%A) if not all([f.parent() == A.coordinate_ring() for f in F]): raise TypeError("F (=%s) must be a list or tuple of polynomials of the coordinate ring of " \ "A (=%s)"%(F, A)) n = A.dimension_relative() if n < 2: raise TypeError("A (=%s) must be either an affine or projective space of dimension > 1"%A) # there is no dimension check when initializing a plane curve, so check here that F consists # of a single nonconstant polynomial if n == 2: if len(F) != 1 or F[0] == 0 or not is_MPolynomial(F[0]): raise TypeError("F (=%s) must consist of a single nonconstant polynomial to define a plane curve"%(F,)) if is_AffineSpace(A): if n > 2: return AffineCurve(A, F) k = A.base_ring() if is_FiniteField(k): if k.is_prime_field(): return AffinePlaneCurve_prime_finite_field(A, F[0]) return AffinePlaneCurve_finite_field(A, F[0]) return AffinePlaneCurve(A, F[0]) elif is_ProjectiveSpace(A): if not all([f.is_homogeneous() for f in F]): raise TypeError("polynomials defining a curve in a projective space must be homogeneous") if n > 2: return ProjectiveCurve(A, F) k = A.base_ring() if is_FiniteField(k): if k.is_prime_field(): return ProjectivePlaneCurve_prime_finite_field(A, F[0]) return ProjectivePlaneCurve_finite_field(A, F[0]) return ProjectivePlaneCurve(A, F[0]) if is_AlgebraicScheme(F): return Curve(F.defining_polynomials(), F.ambient_space()) 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 AffineCurve(A, F) A = ProjectiveSpace(P.ngens()-1, P.base_ring()) A._coordinate_ring = P return ProjectiveCurve(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 AffinePlaneCurve_prime_finite_field(A2, F) else: return AffinePlaneCurve_finite_field(A2, F) else: return AffinePlaneCurve(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 ProjectivePlaneCurve_prime_finite_field(P2, F) else: return ProjectivePlaneCurve_finite_field(P2, F) else: return ProjectivePlaneCurve(P2, F) else: raise TypeError("Number of variables of F (=%s) must be 2 or 3"%F)
def Curve(F, A=None): """ 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 no ambient space is passed in for ``A``, and if ``F`` is not an algebraic scheme, a new ambient space is constructed. Also not specifying an ambient space will cause the curve to be defined in either affine or projective space based on properties of ``F``. In particular, if ``F`` contains a nonhomogenous polynomial, the curve is affine, and if ``F`` consists of homogenous polynomials, then the curve is projective. INPUT: - ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme. - ``A`` -- (default: None) an ambient space in which to create the curve. EXAMPLES: A projective plane curve. :: sage: x,y,z = QQ['x,y,z'].gens() sage: C = Curve(x^3 + y^3 + z^3); C Projective Plane Curve over Rational Field defined by x^3 + y^3 + z^3 sage: C.genus() 1 Affine plane curves. :: sage: x,y = GF(7)['x,y'].gens() sage: C = Curve(y^2 + x^3 + x^10); C Affine Plane 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 Plane Curve over Rational Field defined by x^3 + y^3 + 1 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 Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4 sage: C.genus() 13 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 Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2 sage: C.genus() 47 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 Plane Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4 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 Plane 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 If only a polynomial in three variables is given, then it must be homogeneous such that a projective curve is constructed. :: 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 An ambient space can be specified to construct a space curve in an affine or a projective space. :: sage: A.<x,y,z> = AffineSpace(QQ, 3) sage: C = Curve([y - x^2, z - x^3], A) sage: C Affine Curve over Rational Field defined by -x^2 + y, -x^3 + z sage: A == C.ambient_space() True The defining polynomial must be nonzero unless the ambient space itself is of dimension 1. :: sage: P1.<x,y> = ProjectiveSpace(1,GF(5)) sage: S = P1.coordinate_ring() sage: Curve(S(0), P1) Projective Line over Finite Field of size 5 sage: Curve(P1) Projective Line over Finite Field of size 5 :: sage: A1.<x> = AffineSpace(1, QQ) sage: R = A1.coordinate_ring() sage: Curve(R(0), A1) Affine Line over Rational Field sage: Curve(A1) Affine Line over Rational Field """ if A is None: if is_AmbientSpace(F) and F.dimension() == 1: return Curve(F.coordinate_ring().zero(), F) if is_AlgebraicScheme(F): return Curve(F.defining_polynomials(), F.ambient_space()) if isinstance(F, (list, tuple)): P = Sequence(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(), names=P.variable_names()) A._coordinate_ring = P break else: A = ProjectiveSpace(P.ngens()-1, P.base_ring(), names=P.variable_names()) A._coordinate_ring = P elif is_MPolynomial(F): # define a plane curve P = F.parent() k = F.base_ring() if not k.is_field(): if k.is_integral_domain(): # upgrade to a field P = P.change_ring(k.fraction_field()) F = P(F) k = F.base_ring() else: raise TypeError("not a multivariate polynomial over a field or an integral domain") if F.parent().ngens() == 2: if F == 0: raise ValueError("defining polynomial of curve must be nonzero") A = AffineSpace(2, P.base_ring(), names=P.variable_names()) A._coordinate_ring = P elif F.parent().ngens() == 3: if F == 0: raise ValueError("defining polynomial of curve must be nonzero") # special case: construct a conic curve if F.total_degree() == 2 and k.is_field(): return Conic(k, F) A = ProjectiveSpace(2, P.base_ring(), names=P.variable_names()) A._coordinate_ring = P elif F.parent().ngens() == 1: if not F.is_zero(): raise ValueError("defining polynomial of curve must be zero " "if the ambient space is of dimension 1") A = AffineSpace(1, P.base_ring(), names=P.variable_names()) A._coordinate_ring = P else: raise TypeError("number of variables of F (={}) must be 2 or 3".format(F)) F = [F] else: raise TypeError("F (={}) must be a multivariate polynomial".format(F)) else: if not is_AmbientSpace(A): raise TypeError("ambient space must be either an affine or projective space") if not isinstance(F, (list, tuple)): F = [F] if not all(f.parent() == A.coordinate_ring() for f in F): raise TypeError("need a list of polynomials of the coordinate ring of {}".format(A)) n = A.dimension_relative() if n < 1: raise TypeError("ambient space should be an affine or projective space of positive dimension") k = A.base_ring() if is_AffineSpace(A): if n != 2: if is_FiniteField(k): if A.coordinate_ring().ideal(F).is_prime(): return IntegralAffineCurve_finite_field(A, F) if k in Fields(): if k == QQ and A.coordinate_ring().ideal(F).is_prime(): return IntegralAffineCurve(A, F) return AffineCurve_field(A, F) return AffineCurve(A, F) if not (len(F) == 1 and F[0] != 0 and F[0].degree() > 0): raise TypeError("need a single nonconstant polynomial to define a plane curve") F = F[0] if is_FiniteField(k): if _is_irreducible_and_reduced(F): return IntegralAffinePlaneCurve_finite_field(A, F) return AffinePlaneCurve_finite_field(A, F) if k in Fields(): if k == QQ and _is_irreducible_and_reduced(F): return IntegralAffinePlaneCurve(A, F) return AffinePlaneCurve_field(A, F) return AffinePlaneCurve(A, F) elif is_ProjectiveSpace(A): if n != 2: if not all(f.is_homogeneous() for f in F): raise TypeError("polynomials defining a curve in a projective space must be homogeneous") if is_FiniteField(k): if A.coordinate_ring().ideal(F).is_prime(): return IntegralProjectiveCurve_finite_field(A, F) if k in Fields(): if k == QQ and A.coordinate_ring().ideal(F).is_prime(): return IntegralProjectiveCurve(A, F) return ProjectiveCurve_field(A, F) return ProjectiveCurve(A, F) # There is no dimension check when initializing a plane curve, so check # here that F consists of a single nonconstant polynomial. if not (len(F) == 1 and F[0] != 0 and F[0].degree() > 0): raise TypeError("need a single nonconstant polynomial to define a plane curve") F = F[0] if not F.is_homogeneous(): raise TypeError("{} is not a homogeneous polynomial".format(F)) if is_FiniteField(k): if _is_irreducible_and_reduced(F): return IntegralProjectivePlaneCurve_finite_field(A, F) return ProjectivePlaneCurve_finite_field(A, F) if k in Fields(): if k == QQ and _is_irreducible_and_reduced(F): return IntegralProjectivePlaneCurve(A, F) return ProjectivePlaneCurve_field(A, F) return ProjectivePlaneCurve(A, F) else: raise TypeError('ambient space neither affine nor projective')
def Curve(F, A=None): """ 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 no ambient space is passed in for ``A``, and if ``F`` is not an algebraic scheme, a new ambient space is constructed. Also not specifying an ambient space will cause the curve to be defined in either affine or projective space based on properties of ``F``. In particular, if ``F`` contains a nonhomogenous polynomial, the curve is affine, and if ``F`` consists of homogenous polynomials, then the curve is projective. INPUT: - ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme. - ``A`` -- (default: None) an ambient space in which to create the curve. 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 Plane 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 Plane 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 Plane 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 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 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 Plane 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 Plane 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 :: sage: A.<x,y,z> = AffineSpace(QQ, 3) sage: C = Curve([y - x^2, z - x^3], A) sage: A == C.ambient_space() True """ if not A is None: if not isinstance(F, (list, tuple)): return Curve([F], A) if not is_AmbientSpace(A): raise TypeError( "A (=%s) must be either an affine or projective space" % A) if not all([f.parent() == A.coordinate_ring() for f in F]): raise TypeError("F (=%s) must be a list or tuple of polynomials of the coordinate ring of " \ "A (=%s)"%(F, A)) n = A.dimension_relative() if n < 2: raise TypeError( "A (=%s) must be either an affine or projective space of dimension > 1" % A) # there is no dimension check when initializing a plane curve, so check here that F consists # of a single nonconstant polynomial if n == 2: if len(F) != 1 or F[0] == 0 or not is_MPolynomial(F[0]): raise TypeError( "F (=%s) must consist of a single nonconstant polynomial to define a plane curve" % (F, )) if is_AffineSpace(A): if n > 2: return AffineCurve(A, F) k = A.base_ring() if is_FiniteField(k): if k.is_prime_field(): return AffinePlaneCurve_prime_finite_field(A, F[0]) return AffinePlaneCurve_finite_field(A, F[0]) return AffinePlaneCurve(A, F[0]) elif is_ProjectiveSpace(A): if not all([f.is_homogeneous() for f in F]): raise TypeError( "polynomials defining a curve in a projective space must be homogeneous" ) if n > 2: return ProjectiveCurve(A, F) k = A.base_ring() if is_FiniteField(k): if k.is_prime_field(): return ProjectivePlaneCurve_prime_finite_field(A, F[0]) return ProjectivePlaneCurve_finite_field(A, F[0]) return ProjectivePlaneCurve(A, F[0]) if is_AlgebraicScheme(F): return Curve(F.defining_polynomials(), F.ambient_space()) 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 AffineCurve(A, F) A = ProjectiveSpace(P.ngens() - 1, P.base_ring()) A._coordinate_ring = P return ProjectiveCurve(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 AffinePlaneCurve_prime_finite_field(A2, F) else: return AffinePlaneCurve_finite_field(A2, F) else: return AffinePlaneCurve(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 ProjectivePlaneCurve_prime_finite_field(P2, F) else: return ProjectivePlaneCurve_finite_field(P2, F) else: return ProjectivePlaneCurve(P2, F) else: raise TypeError("Number of variables of F (=%s) must be 2 or 3" % F)
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