diff --git a/src/sage/schemes/affine/affine_space.py b/src/sage/schemes/affine/affine_space.py index 1b98542ebf7..516d15e63ef 100644 --- a/src/sage/schemes/affine/affine_space.py +++ b/src/sage/schemes/affine/affine_space.py @@ -859,6 +859,24 @@ def weil_restriction(self): self.__weil_restriction = X return X + def curve(self,F): + r""" + Return a curve defined by ``F`` in this affine space. + + INPUT: + + - ``F`` -- a polynomial, or a list or tuple of polynomials in the coorinate ring + of this affine space. + + EXAMPLES:: + + sage: A. = AffineSpace(QQ, 3) + sage: A.curve([y - x^4, z - y^5]) + Affine Space Curve over Rational Field defined by -x^4 + y, -y^5 + z + """ + from sage.schemes.plane_curves.constructor import Curve + return Curve(F, self) + class AffineSpace_finite_field(AffineSpace_field): def _point(self, *args, **kwds): """ diff --git a/src/sage/schemes/plane_curves/affine_curve.py b/src/sage/schemes/plane_curves/affine_curve.py index 564a220ec1a..64e89a96663 100644 --- a/src/sage/schemes/plane_curves/affine_curve.py +++ b/src/sage/schemes/plane_curves/affine_curve.py @@ -93,7 +93,6 @@ def projective_closure(self, i=0): class AffineCurve_generic(AffineSpaceCurve_generic): def __init__(self, A, f): - P = f.parent() if not (is_AffineSpace(A) and A.dimension != 2): raise TypeError("Argument A (= %s) must be an affine plane."%A) Curve_generic.__init__(self, A, [f]) diff --git a/src/sage/schemes/plane_curves/constructor.py b/src/sage/schemes/plane_curves/constructor.py index 43f1dca2fe4..7ce6d958955 100644 --- a/src/sage/schemes/plane_curves/constructor.py +++ b/src/sage/schemes/plane_curves/constructor.py @@ -29,8 +29,10 @@ from sage.structure.all import Sequence +from sage.schemes.affine.affine_space import is_AffineSpace from sage.schemes.generic.ambient_space import is_AmbientSpace from sage.schemes.generic.algebraic_scheme import is_AlgebraicScheme +from sage.schemes.projective.projective_space import is_ProjectiveSpace from sage.schemes.affine.all import AffineSpace @@ -49,15 +51,26 @@ from sage.schemes.plane_conics.constructor import Conic -def Curve(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 + 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. + 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 @@ -164,9 +177,53 @@ def Curve(F): Traceback (most recent call last): ... ValueError: defining polynomial of curve must be nonzero + + :: + + sage: A. = 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 AffineSpaceCurve_generic(A, F) + k = A.base_ring() + if is_FiniteField(k): + if k.is_prime_field(): + return AffineCurve_prime_finite_field(A, F[0]) + return AffineCurve_finite_field(A, F[0]) + return AffineCurve_generic(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 ProjectiveSpaceCurve_generic(A, F) + k = A.base_ring() + if is_FiniteField(k): + if k.is_prime_field(): + return ProjectiveCurve_prime_finite_field(A, F[0]) + return ProjectiveCurve_finite_field(A, F[0]) + return ProjectiveCurve_generic(A, F[0]) + if is_AlgebraicScheme(F): - return Curve(F.defining_polynomials()) + return Curve(F.defining_polynomials(), F.ambient_space()) if isinstance(F, (list, tuple)): if len(F) == 1: diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index a3468077b9c..b10c24e7477 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1167,6 +1167,24 @@ def point_transformation_matrix(self, points_source, points_target): w = v.rational_points() return matrix(r, n+1, n+1, list(w[0])) + def curve(self,F): + r""" + Return a curve defined by ``F`` in this projective space. + + INPUT: + + - ``F`` -- a polynomial, or a list or tuple of polynomials in the coorinate ring + of this projective space. + + EXAMPLES:: + + sage: P. = ProjectiveSpace(QQ, 2) + sage: P.curve([y^2 - x*z]) + Projective Curve over Rational Field defined by y^2 - x*z + """ + from sage.schemes.plane_curves.constructor import Curve + return Curve(F, self) + class ProjectiveSpace_finite_field(ProjectiveSpace_field): def _point(self, *args, **kwds): """