Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Subschemes of projective space
AUTHORS:
- David Kohel (2005): initial version. - William Stein (2005): initial version. - Volker Braun (2010-12-24): documentation of schemes and refactoring. Added coordinate neighborhoods and is_smooth() - Ben Hutz (2013) refactoring """
#***************************************************************************** # Copyright (C) 2005 William Stein <wstein@gmail.com> # Copyright (C) 2013 Ben Hutz <bn4941@gmail.com>
# # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
from sage.arith.misc import binomial from sage.categories.fields import Fields from sage.categories.homset import Hom from sage.matrix.constructor import matrix from sage.rings.all import ZZ from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import is_RationalField from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme
class AlgebraicScheme_subscheme_projective(AlgebraicScheme_subscheme): r""" Construct an algebraic subscheme of projective space.
.. WARNING::
You should not create objects of this class directly. The preferred method to construct such subschemes is to use :meth:`~sage.schemes.projective.projective_space.ProjectiveSpace_field.subscheme` method of :class:`projective space <sage.schemes.projective.projective_space.ProjectiveSpace_field>`.
INPUT:
- ``A`` -- ambient :class:`projective space <sage.schemes.projective.projective_space.ProjectiveSpace_field>`.
- ``polynomials`` -- single polynomial, ideal or iterable of defining homogeneous polynomials.
EXAMPLES::
sage: P.<x, y, z> = ProjectiveSpace(2, QQ) sage: P.subscheme([x^2-y*z]) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^2 - y*z
TESTS::
sage: from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective sage: AlgebraicScheme_subscheme_projective(P, [x^2-y*z]) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^2 - y*z """
def point(self, v, check=True): """ Create a point on this projective subscheme.
INPUT:
- ``v`` -- anything that defines a point
- ``check`` -- boolean (optional, default: ``True``); whether to check the defining data for consistency
OUTPUT: A point of the subscheme.
EXAMPLES::
sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: X = P2.subscheme([x-y,y-z]) sage: X.point([1,1,1]) (1 : 1 : 1)
::
sage: P2.<x,y> = ProjectiveSpace(QQ, 1) sage: X = P2.subscheme([y]) sage: X.point(infinity) (1 : 0)
::
sage: P.<x,y> = ProjectiveSpace(QQ, 1) sage: X = P.subscheme(x^2+2*y^2) sage: X.point(infinity) Traceback (most recent call last): ... TypeError: Coordinates [1, 0] do not define a point on Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: x^2 + 2*y^2 """ (isinstance(v, (list,tuple)) and len(v) == 1 and v[0] is infinity): raise ValueError("%s not well defined in dimension > 1"%v) # todo: update elliptic curve stuff to take point_homset as argument
def _morphism(self, *args, **kwds): r""" Construct a morphism determined by action on points of ``self``.
For internal use only.
INPUT:
- same as for :class:`~sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space`.
OUTPUT:
- :class:`~sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space`.
TESTS::
sage: P1.<x,y> = ProjectiveSpace(1,QQ) sage: P2 = ProjectiveSpace(2,QQ) sage: H12 = P1.Hom(P2) sage: H12([x^2,x*y, y^2]) # indirect doctest Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y) to (x^2 : x*y : y^2) sage: P1._morphism(H12, [x^2,x*y, y^2]) Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y) to (x^2 : x*y : y^2) """
def dimension(self): """ Return the dimension of the projective algebraic subscheme.
OUTPUT:
Integer.
EXAMPLES::
sage: P2.<x,y,z> = ProjectiveSpace(2, QQ) sage: P2.subscheme([]).dimension() 2 sage: P2.subscheme([x]).dimension() 1 sage: P2.subscheme([x^5]).dimension() 1 sage: P2.subscheme([x^2 + y^2 - z^2]).dimension() 1 sage: P2.subscheme([x*(x-z), y*(y-z)]).dimension() 0
Something less obvious::
sage: P3.<x,y,z,w,t> = ProjectiveSpace(4, QQ) sage: X = P3.subscheme([x^2, x^2*y^2 + z^2*t^2, z^2 - w^2, 10*x^2 + w^2 - z^2]) sage: X Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: x^2, x^2*y^2 + z^2*t^2, z^2 - w^2, 10*x^2 - z^2 + w^2 sage: X.dimension() 1 """
def affine_patch(self, i, AA = None): r""" Return the `i^{th}` affine patch of this projective scheme. This is the intersection with this `i^{th}` affine patch of its ambient space.
INPUT:
- ``i`` -- integer between 0 and dimension of self, inclusive.
- ``AA`` -- (default: None) ambient affine space, this is constructed if it is not given.
OUTPUT:
An affine algebraic scheme with fixed :meth:`embedding_morphism` equal to the default :meth:`projective_embedding` map`.
EXAMPLES::
sage: PP = ProjectiveSpace(2, QQ, names='X,Y,Z') sage: X,Y,Z = PP.gens() sage: C = PP.subscheme(X^3*Y + Y^3*Z + Z^3*X) sage: U = C.affine_patch(0) sage: U Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x0^3*x1 + x1^3 + x0 sage: U.embedding_morphism() Scheme morphism: From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x0^3*x1 + x1^3 + x0 To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: X^3*Y + Y^3*Z + X*Z^3 Defn: Defined on coordinates by sending (x0, x1) to (1 : x0 : x1) sage: U.projective_embedding() is U.embedding_morphism() True
::
sage: A.<x,y,z> = AffineSpace(QQ,3) sage: X = A.subscheme([x-y*z]) sage: Y = X.projective_embedding(1).codomain() sage: Y.affine_patch(1,A).ambient_space() == A True
::
sage: P.<u,v,w> = ProjectiveSpace(2,ZZ) sage: S = P.subscheme([u^2-v*w]) sage: A.<x, y> = AffineSpace(2, ZZ) sage: S.affine_patch(1, A) Closed subscheme of Affine Space of dimension 2 over Integer Ring defined by: x^2 - y """ raise ValueError("Argument i (= %s) must be between 0 and %s."%(i, n)) #assume that if you've passed in a new ambient affine space #you want to override the existing patch raise ValueError("Affine Space must be of the dimension %s"%(n))
def _best_affine_patch(self, point): r""" Return the best affine patch of the ambient projective space.
The "best" affine patch is where you end up dividing by the homogeneous coordinate with the largest absolutue value. Division by small numbers is numerically unstable.
INPUT:
- ``point`` -- a point of the algebraic subscheme.
OUTPUT:
Integer. The index of the patch. See :meth:`affine_patch`.
EXAMPLES::
sage: P.<x,y,z>= ProjectiveSpace(QQ,2) sage: S = P.subscheme(x+2*y+3*z) sage: S._best_affine_patch(P.point([0,-3,2])) 1 sage: S._best_affine_patch([0,-3,2]) 1
TESTS::
sage: F = GF(3) sage: P.<x,y,z>= ProjectiveSpace(F,2) sage: S._best_affine_patch([0,1,2]) 2 """ except ArithmeticError: # our base ring does not know abs abs_point = point # find best patch
def neighborhood(self, point): r""" Return an affine algebraic subscheme isomorphic to a neighborhood of the ``point``.
INPUT:
- ``point`` -- a point of the projective subscheme.
OUTPUT:
An affine algebraic scheme (polynomial equations in affine space) ``result`` such that
* :meth:`embedding_morphism <AlgebraicScheme.embedding_morphism>` is an isomorphism to a neighborhood of ``point``
* :meth:`embedding_center <AlgebraicScheme.embedding_center>` is mapped to ``point``.
EXAMPLES::
sage: P.<x,y,z>= ProjectiveSpace(QQ,2) sage: S = P.subscheme(x+2*y+3*z) sage: s = S.point([0,-3,2]); s (0 : -3/2 : 1) sage: patch = S.neighborhood(s); patch Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x0 + 3*x1 sage: patch.embedding_morphism() Scheme morphism: From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: x0 + 3*x1 To: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x + 2*y + 3*z Defn: Defined on coordinates by sending (x0, x1) to (x0 : -3/2 : x1 + 1) sage: patch.embedding_center() (0, 0) sage: patch.embedding_morphism()([0,0]) (0 : -3/2 : 1) sage: patch.embedding_morphism()(patch.embedding_center()) (0 : -3/2 : 1) """
def is_smooth(self, point=None): r""" Test whether the algebraic subscheme is smooth.
INPUT:
- ``point`` -- A point or ``None`` (default). The point to test smoothness at.
OUTPUT:
Boolean. If no point was specified, returns whether the algebraic subscheme is smooth everywhere. Otherwise, smoothness at the specified point is tested.
EXAMPLES::
sage: P2.<x,y,z> = ProjectiveSpace(2,QQ) sage: cuspidal_curve = P2.subscheme([y^2*z-x^3]) sage: cuspidal_curve Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: -x^3 + y^2*z sage: cuspidal_curve.is_smooth([1,1,1]) True sage: cuspidal_curve.is_smooth([0,0,1]) False sage: cuspidal_curve.is_smooth() False sage: P2.subscheme([y^2*z-x^3+z^3+1/10*x*y*z]).is_smooth() True
TESTS::
sage: H = P2.subscheme(x) sage: H.is_smooth() # one of the few cases where the cone over the subvariety is smooth True """
# testing smoothness everywhere tends to be expensive # We really test the affine cone here; the origin is always a # singular point:
def orbit(self, f, N): r""" Returns the orbit of this scheme by ``f``.
If `N` is an integer it returns `[self,f(self),\ldots,f^N(self)]`. If `N` is a list or tuple `N=[m,k]` it returns `[f^m(self),\ldots,f^k(self)`].
INPUT:
- ``f`` -- a :class:`DynamicalSystem_projective` with ``self`` in ``f.domain()``
- ``N`` -- a non-negative integer or list or tuple of two non-negative integers
OUTPUT:
- a list of projective subschemes
EXAMPLES::
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3) sage: f = DynamicalSystem_projective([(x-2*y)^2,(x-2*z)^2,(x-2*w)^2,x^2]) sage: f.orbit(P.subscheme([x]),5) [Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: x, Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: w, Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: z - w, Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: y - z, Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: x - y, Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: x - w]
::
sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: P1.<u,v> = ProjectiveSpace(QQ, 1) sage: H = Hom(PS, P1) sage: f = H([x^2, y^2]) sage: X = PS.subscheme([x-y]) sage: X.orbit(f,2) Traceback (most recent call last): ... TypeError: map must be a dynamical system for iteration
::
sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) sage: X = PS.subscheme([x-y]) sage: X.orbit(f,[-1,2]) Traceback (most recent call last): ... TypeError: orbit bounds must be non-negative """ N = [0,N] if N[0] > N[1]: return([])
Q = self for i in range(1, N[0]+1): Q = f(Q) Orb = [Q]
for i in range(N[0]+1, N[1]+1): Q = f(Q) Orb.append(Q) return(Orb)
def nth_iterate(self, f, n): r""" The nth forward image of this scheme by the map ``f``.
INPUT:
- ``f`` -- a :class:`DynamicalSystem_projective` with ``self`` in ``f.domain()``
- ``n`` -- a positive integer.
OUTPUT:
- A subscheme in ``f.codomain()``
EXAMPLES::
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3) sage: f = DynamicalSystem_projective([y^2, z^2, x^2, w^2]) sage: f.nth_iterate(P.subscheme([x-w,y-z]), 3) Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: y - z, x - w
::
sage: PS.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) sage: X = PS.subscheme([x-y]) sage: X.nth_iterate(f,-2) Traceback (most recent call last): ... TypeError: must be a forward orbit
::
sage: PS.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: P2.<u,v,w>=ProjectiveSpace(QQ, 2) sage: H = Hom(PS, P2) sage: f = H([x^2, y^2, z^2]) sage: X = PS.subscheme([x-y]) sage: X.nth_iterate(f,2) Traceback (most recent call last): ... TypeError: map must be a dynamical system for iteration
::
sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) sage: X = PS.subscheme([x-y]) sage: X.nth_iterate(f,2.5) Traceback (most recent call last): ... TypeError: Attempt to coerce non-integral RealNumber to Integer """
def _forward_image(self, f, check = True): """ Compute the forward image of this subscheme by the morphism ``f``.
The forward image is computed through elimination and ``f`` must be a morphism for this to be well defined. In particular, let $X = V(h_1,\ldots, h_t)$ and define the ideal $I = (h_1,\ldots,h_t,y_0-f_0(\bar{x}), \ldots, y_n-f_n(\bar{x}))$. Then the elimination ideal $I_{n+1} = I \cap K[y_0,\ldots,y_n]$ is a homogeneous ideal and $self(X) = V(I_{n+1})$.
INPUT:
- ``f`` -- a map whose domain contains ``self``
- ``check`` -- Boolean, if `False` no input checking is done
OUTPUT:
- a subscheme in the codomain of ``f``.
EXAMPLES::
sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: H = End(PS) sage: f = H([x^2, y^2-2*z^2, z^2]) sage: X = PS.subscheme(y-2*z) sage: X._forward_image(f) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: y - 2*z
::
sage: set_verbose(None) sage: PS.<x,y,z,w> = ProjectiveSpace(ZZ, 3) sage: H = End(PS) sage: f = H([y^2, x^2, w^2, z^2]) sage: X = PS.subscheme([z^2+y*w, x-w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Integer Ring defined by: y - z, x*z - w^2
::
sage: PS.<x,y,z,w> = ProjectiveSpace(CC, 3) sage: H = End(PS) sage: f = H([x^2 + y^2, y^2, z^2-y^2, w^2]) sage: X = PS.subscheme([z-2*w]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Complex Field with 53 bits of precision defined by: y + z + (-4.00000000000000)*w
::
sage: R.<t> = PolynomialRing(QQ) sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2) sage: H = End(P) sage: f = H([x^2 + 2*y*z, t^2*y^2, z^2]) sage: f([t^2*y-z]) Closed subscheme of Projective Space of dimension 2 over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by: y + (-1/t^2)*z
::
sage: set_verbose(-1) sage: PS.<x,y,z> = ProjectiveSpace(Qp(3), 2) sage: H = End(PS) sage: f = H([x^2,2*y^2,z^2]) sage: X = PS.subscheme([2*x-y,z]) sage: f(X) Closed subscheme of Projective Space of dimension 2 over 3-adic Field with capped relative precision 20 defined by: z, x + (1 + 3^2 + 3^4 + 3^6 + 3^8 + 3^10 + 3^12 + 3^14 + 3^16 + 3^18 + O(3^20))*y
::
sage: R.<y0,y1,y2,y3> = PolynomialRing(QQ) sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2) sage: H = End(P) sage: f = H([y0*x^2+y1*z^2, y2*y^2+y3*z^2, z^2]) sage: X = P.subscheme(x*z) sage: X._forward_image(f) Closed subscheme of Projective Space of dimension 2 over Fraction Field of Multivariate Polynomial Ring in y0, y1, y2, y3 over Rational Field defined by: x*z + (-y1)*z^2
::
sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: P5.<z0,z1,z2,z3,z4,z5> = ProjectiveSpace(QQ, 5) sage: H = Hom(P2, P5) sage: f = H([x^2,x*y,x*z,y^2,y*z,z^2]) #Veronese map sage: X = P2.subscheme([]) sage: f(X) Closed subscheme of Projective Space of dimension 5 over Rational Field defined by: -z4^2 + z3*z5, -z2*z4 + z1*z5, -z2*z3 + z1*z4, -z2^2 + z0*z5, -z1*z2 + z0*z4, -z1^2 + z0*z3
::
sage: P2.<x,y,z>=ProjectiveSpace(QQ, 2) sage: P3.<u,v,w,t>=ProjectiveSpace(QQ, 3) sage: H = Hom(P2, P3) sage: X = P2.subscheme([x-y,x-z]) sage: f = H([x^2,y^2,z^2,x*y]) sage: f(X) Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: w - t, v - t, u - t
::
sage: P1.<u,v> = ProjectiveSpace(QQ, 1) sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: H = Hom(P2,P1) sage: f = H([x^2,y*z]) sage: X = P2.subscheme([x-y]) sage: f(X) Traceback (most recent call last): ... TypeError: map must be a morphism
::
sage: PS.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: H = End(PS) sage: f = H([x^3, x*y^2, x*z^2]) sage: X = PS.subscheme([x-y]) sage: X._forward_image(f) Traceback (most recent call last): ... TypeError: map must be a morphism
::
sage: PS.<x,y,z> = ProjectiveSpace(QQ, 2) sage: P1.<u,v> = ProjectiveSpace(QQ, 1) sage: Y = P1.subscheme([u-v]) sage: H = End(PS) sage: f = H([x^2, y^2, z^2]) sage: Y._forward_image(f) Traceback (most recent call last): ... TypeError: subscheme must be in ambient space of domain of map """ #can't call eliminate if the base ring is polynomial so we do it ourselves #with a lex ordering #set up ideal #get only the elimination ideal portion
def preimage(self, f, k=1, check=True): r""" The subscheme that maps to this scheme by the map `f^k`.
In particular, `f^{-k}(V(h_1,\ldots,h_t)) = V(h_1 \circ f^k, \ldots, h_t \circ f^k)`. Map must be a morphism and also must be an endomorphism for `k > 1`.
INPUT:
- ``f`` - a map whose codomain contains this scheme
- ``k`` - a positive integer
- ``check`` -- Boolean, if ``False`` no input checking is done
OUTPUT:
- a subscheme in the domain of ``f``.
Examples::
sage: PS.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: H = End(PS) sage: f = H([y^2, x^2, z^2]) sage: X = PS.subscheme([x-y]) sage: X.preimage(f) Closed subscheme of Projective Space of dimension 2 over Integer Ring defined by: -x^2 + y^2
::
sage: P.<x,y,z,w,t> = ProjectiveSpace(QQ, 4) sage: H = End(P) sage: f = H([x^2-y^2, y^2, z^2, w^2, t^2+w^2]) sage: f.rational_preimages(P.subscheme([x-z, t^2, w-t])) Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: x^2 - y^2 - z^2, w^4 + 2*w^2*t^2 + t^4, -t^2
::
sage: P1.<x,y> = ProjectiveSpace(QQ, 1) sage: P3.<u,v,w,t> = ProjectiveSpace(QQ, 3) sage: H = Hom(P1, P3) sage: X = P3.subscheme([u-v, 2*u-w, u+t]) sage: f = H([x^2,y^2, x^2+y^2, x*y]) sage: X.preimage(f) Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: x^2 - y^2, x^2 - y^2, x^2 + x*y
::
sage: P1.<x,y> = ProjectiveSpace(QQ, 1) sage: P3.<u,v,w,t> = ProjectiveSpace(QQ, 3) sage: H = Hom(P3, P1) sage: X = P1.subscheme([x-y]) sage: f = H([u^2, v^2]) sage: X.preimage(f) Traceback (most recent call last): ... TypeError: map must be a morphism
::
sage: PS.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: H = End(PS) sage: f = H([x^2, x^2, x^2]) sage: X = PS.subscheme([x-y]) sage: X.preimage(f) Traceback (most recent call last): ... TypeError: map must be a morphism
::
sage: PS.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: P1.<u,v> = ProjectiveSpace(ZZ, 1) sage: Y = P1.subscheme([u^2-v^2]) sage: H = End(PS) sage: f = H([x^2, y^2, z^2]) sage: Y.preimage(f) Traceback (most recent call last): ... TypeError: subscheme must be in ambient space of codomain
::
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2) sage: Y = P.subscheme([x-y]) sage: H = End(P) sage: f = H([x^2, y^2, z^2]) sage: Y.preimage(f, k=2) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: x^4 - y^4 """ raise ValueError("k (=%s) must be a positive integer"%(k)) raise TypeError("map must be an endomorphism") else:
def dual(self): r""" Return the projective dual of the given subscheme of projective space.
INPUT:
- ``X`` -- A subscheme of projective space. At present, ``X`` is required to be an irreducible and reduced hypersurface defined over `\QQ` or a finite field.
OUTPUT:
- The dual of ``X`` as a subscheme of the dual projective space.
EXAMPLES:
The dual of a smooth conic in the plane is also a smooth conic::
sage: R.<x, y, z> = QQ[] sage: P.<x, y, z> = ProjectiveSpace(2, QQ) sage: I = R.ideal(x^2 + y^2 + z^2) sage: X = P.subscheme(I) sage: X.dual() Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: y0^2 + y1^2 + y2^2
The dual of the twisted cubic curve in projective 3-space is a singular quartic surface. In the following example, we compute the dual of this surface, which by double duality is equal to the twisted cubic itself. The output is the twisted cubic as an intersection of three quadrics::
sage: R.<x, y, z, w> = QQ[] sage: P.<x, y, z, w> = ProjectiveSpace(3, QQ) sage: I = R.ideal(y^2*z^2 - 4*x*z^3 - 4*y^3*w + 18*x*y*z*w - 27*x^2*w^2) sage: X = P.subscheme(I) sage: X.dual() Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: y2^2 - y1*y3, y1*y2 - y0*y3, y1^2 - y0*y2
The singular locus of the quartic surface in the last example is itself supported on a twisted cubic::
sage: X.Jacobian().radical() Ideal (z^2 - 3*y*w, y*z - 9*x*w, y^2 - 3*x*z) of Multivariate Polynomial Ring in x, y, z, w over Rational Field
An example over a finite field::
sage: R = PolynomialRing(GF(61), 'a,b,c') sage: P.<a, b, c> = ProjectiveSpace(2, R.base_ring()) sage: X = P.subscheme(R.ideal(a*a+2*b*b+3*c*c)) sage: X.dual() Closed subscheme of Projective Space of dimension 2 over Finite Field of size 61 defined by: y0^2 - 30*y1^2 - 20*y2^2
TESTS::
sage: R = PolynomialRing(Qp(3), 'a,b,c') sage: P.<a, b, c> = ProjectiveSpace(2, R.base_ring()) sage: X = P.subscheme(R.ideal(a*a+2*b*b+3*c*c)) sage: X.dual() Traceback (most recent call last): ... NotImplementedError: base ring must be QQ or a finite field """
or I.is_trivial() or not I.is_prime()): raise NotImplementedError("At the present, the method is only" " implemented for irreducible and" " reduced hypersurfaces and the given" " list of generators for the ideal must" " have exactly one element.") T = PolynomialRing(K, 'w', n + 1) I_S = (I.change_ring(T)).change_ring(S) else:
def Chow_form(self): r""" Returns the Chow form associated to this subscheme.
For a `k`-dimensional subvariety of `\mathbb{P}^N` of degree `D`. The `(N-k-1)`-dimensional projective linear subspaces of `\mathbb{P}^N` meeting `X` form a hypersurface in the Grassmannian `G(N-k-1,N)`. The homogeneous form of degree `D` defining this hypersurface in Plucker coordinates is called the Chow form of `X`.
The base ring needs to be a number field, finite field, or `\QQbar`.
ALGORITHM:
For a `k`-dimension subscheme `X` consider the `k+1` linear forms `l_i = u_{i0}x_0 + \cdots + u_{in}x_n`. Let `J` be the ideal in the polynomial ring `K[x_i,u_{ij}]` defined by the equations of `X` and the `l_i`. Let `J'` be the saturation of `J` with respect to the irrelevant ideal of the ambient projective space of `X`. The elimination ideal `I = J' \cap K[u_{ij}]` is a principal ideal, let `R` be its generator. The Chow form is obtained by writing `R` as a polynomial in Plucker coordinates (i.e. bracket polynomials). [DalbecSturmfels]_.
OUTPUT: a homogeneous polynomial.
REFERENCES:
.. [DalbecSturmfels] J. Dalbec and B. Sturmfels. Invariant methods in discrete and computational geometry, chapter Introduction to Chow forms, pages 37-58. Springer Netherlands, 1994.
EXAMPLES::
sage: P.<x0,x1,x2,x3> = ProjectiveSpace(GF(17), 3) sage: X = P.subscheme([x3+x1,x2-x0,x2-x3]) sage: X.Chow_form() t0 - t1 + t2 + t3
::
sage: P.<x0,x1,x2,x3> = ProjectiveSpace(QQ,3) sage: X = P.subscheme([x3^2 -101*x1^2 - 3*x2*x0]) sage: X.Chow_form() t0^2 - 101*t2^2 - 3*t1*t3
::
sage: P.<x0,x1,x2,x3>=ProjectiveSpace(QQ,3) sage: X = P.subscheme([x0*x2-x1^2, x0*x3-x1*x2, x1*x3-x2^2]) sage: Ch = X.Chow_form(); Ch t2^3 + 2*t2^2*t3 + t2*t3^2 - 3*t1*t2*t4 - t1*t3*t4 + t0*t4^2 + t1^2*t5 sage: Y = P.subscheme_from_Chow_form(Ch, 1); Y Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: x2^2*x3 - x1*x3^2, -x2^3 + x0*x3^2, -x2^2*x3 + x1*x3^2, x1*x2*x3 - x0*x3^2, 3*x1*x2^2 - 3*x0*x2*x3, -2*x1^2*x3 + 2*x0*x2*x3, -3*x1^2*x2 + 3*x0*x1*x3, x1^3 - x0^2*x3, x2^3 - x1*x2*x3, -3*x1*x2^2 + 2*x1^2*x3 + x0*x2*x3, 2*x0*x2^2 - 2*x0*x1*x3, 3*x1^2*x2 - 2*x0*x2^2 - x0*x1*x3, -x0*x1*x2 + x0^2*x3, -x0*x1^2 + x0^2*x2, -x1^3 + x0*x1*x2, x0*x1^2 - x0^2*x2 sage: I = Y.defining_ideal() sage: I.saturation(I.ring().ideal(list(I.ring().gens())))[0] Ideal (x2^2 - x1*x3, x1*x2 - x0*x3, x1^2 - x0*x2) of Multivariate Polynomial Ring in x0, x1, x2, x3 over Rational Field """ #create the ring for the generic linear hyperplanes # u0x0 + u1x1 + ... #map the generators of the subscheme into the ring with the hyperplane variables #create the dim(X)+1 linear hyperplanes #intersect the hyperplanes with X #saturate the ideal with respect to the irrelevant ideal #elimante the original variables to be left with the hyperplane coefficients 'u' #create the plucker coordinates #create the ideal that we can use for eliminating to get a polynomial #in the plucker coordinates (brackets) #create a mapping into a polynomial ring over the plucker coordinates #and the hyperplane coefficients #eliminate the hyperplane coefficients #CH should be a principal ideal, but because of the relations among #the plucker coordinates, the elimination will probably have several generators
#get the relations among the plucker coordinates #reduce CH with respect to the relations #find the principal generator
#polynomial ring in just the plucker coordinates #get the degrees of the reduced generators of CH #need the smallest degree form that did not reduce to 0 #check that it is correct (i.e., it is a principal generator for CH + the relations)
def degree(self): r""" Return the degree of this projective subscheme.
If `P(t) = a_{m}t^m + \ldots + a_{0}` is the Hilbert polynomial of this subscheme, then the degree is `a_{m} m!`.
OUTPUT: Integer.
EXAMPLES::
sage: P.<x,y,z,w,t,u> = ProjectiveSpace(QQ, 5) sage: X = P.subscheme([x^7 + x*y*z*t^4 - u^7]) sage: X.degree() 7
sage: P.<x,y,z,w> = ProjectiveSpace(GF(13), 3) sage: X = P.subscheme([y^3 - w^3, x + 7*z]) sage: X.degree() 3
sage: P.<x,y,z,w,u> = ProjectiveSpace(QQ, 4) sage: C = P.curve([x^7 - y*z^3*w^2*u, w*x^2 - y*u^2, z^3 + y^3]) sage: C.degree() 63 """
def intersection_multiplicity(self, X, P): r""" Return the intersection multiplicity of this subscheme and the subscheme ``X`` at the point ``P``.
This uses the intersection_multiplicity function for affine subschemes on affine patches of this subscheme and ``X`` that contain ``P``.
INPUT:
- ``X`` -- subscheme in the same ambient space as this subscheme.
- ``P`` -- a point in the intersection of this subscheme with ``X``.
OUTPUT: An integer.
EXAMPLES::
sage: P.<x,y,z> = ProjectiveSpace(GF(5), 2) sage: C = Curve([x^4 - z^2*y^2], P) sage: D = Curve([y^4*z - x^5 - x^3*z^2], P) sage: Q1 = P([0,1,0]) sage: C.intersection_multiplicity(D, Q1) 4 sage: Q2 = P([0,0,1]) sage: C.intersection_multiplicity(D, Q2) 6
::
sage: R.<a> = QQ[] sage: K.<b> = NumberField(a^4 + 1) sage: P.<x,y,z,w> = ProjectiveSpace(K, 3) sage: X = P.subscheme([x^2 + y^2 - z*w]) sage: Y = P.subscheme([y*z - x*w, z - w]) sage: Q1 = P([b^2,1,0,0]) sage: X.intersection_multiplicity(Y, Q1) 1 sage: Q2 = P([1/2*b^3-1/2*b,1/2*b^3-1/2*b,1,1]) sage: X.intersection_multiplicity(Y, Q2) 1
::
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3) sage: X = P.subscheme([x^2 - z^2, y^3 - w*x^2]) sage: Y = P.subscheme([w^2 - 2*x*y + z^2, y^2 - w^2]) sage: Q = P([1,1,-1,1]) sage: X.intersection_multiplicity(Y, Q) Traceback (most recent call last): ... TypeError: the intersection of this subscheme and (=Closed subscheme of Affine Space of dimension 3 over Rational Field defined by: x1^2 + x2^2 - 2*x0, x0^2 - x2^2) must be proper and finite """ except TypeError: raise TypeError("(=%s) must be a point in the ambient space of this subscheme and (=%s)"%(P,X)) # find an affine chart of the ambient space of this curve that contains P
def multiplicity(self, P): r""" Return the multiplicity of ``P`` on this subscheme.
This is computed as the multiplicity of the corresponding point on an affine patch of this subscheme that contains ``P``. This subscheme must be defined over a field. An error is returned if ``P`` not a point on this subscheme.
INPUT:
- ``P`` -- a point on this subscheme.
OUTPUT:
An integer.
EXAMPLES::
sage: P.<x,y,z,w,t> = ProjectiveSpace(QQ, 4) sage: X = P.subscheme([y^2 - x*t, w^7 - t*w*x^5 - z^7]) sage: Q1 = P([0,0,1,1,1]) sage: X.multiplicity(Q1) 1 sage: Q2 = P([1,0,0,0,0]) sage: X.multiplicity(Q2) 3 sage: Q3 = P([0,0,0,0,1]) sage: X.multiplicity(Q3) 7
::
sage: P.<x,y,z,w> = ProjectiveSpace(CC, 3) sage: X = P.subscheme([z^5*x^2*w - y^8]) sage: Q = P([2,0,0,1]) sage: X.multiplicity(Q) 5
::
sage: P.<x,y,z,w> = ProjectiveSpace(GF(29), 3) sage: C = Curve([y^17 - x^5*w^4*z^8, x*y - z^2], P) sage: Q = P([3,0,0,1]) sage: C.multiplicity(Q) 8 """ raise TypeError("subscheme must be defined over a field")
# Check whether P is a point on this subscheme except TypeError: raise TypeError("(=%s) is not a point on (=%s)"%(P,self))
# Find an affine chart of the ambient space of self that contains P
def veronese_embedding(self, d, CS=None, order='lex'): r""" Return the degree ``d`` Veronese embedding of this projective subscheme.
INPUT:
- ``d`` -- a positive integer.
- ``CS`` -- a projective ambient space to embed into. If the projective ambient space of this subscheme is of dimension `N`, the dimension of ``CS`` must be `\binom{N + d}{d} - 1`. This is constructed if not specified. Default: ``None``.
- ``order`` -- a monomial order to use to arrange the monomials defining the embedding. The monomials will be arranged from greatest to least with respect to this order. Default: ``'lex'``.
OUTPUT:
- a scheme morphism from this subscheme to its image by the degree ``d`` Veronese embedding.
EXAMPLES::
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2) sage: L = P.subscheme([y - x]) sage: v = L.veronese_embedding(2) sage: v Scheme morphism: From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: -x + y To: Closed subscheme of Projective Space of dimension 5 over Rational Field defined by: -x4^2 + x3*x5, x2 - x4, x1 - x3, x0 - x3 Defn: Defined on coordinates by sending (x : y : z) to (x^2 : x*y : x*z : y^2 : y*z : z^2) sage: v.codomain().degree() 2 sage: C = P.subscheme([y*z - x^2]) sage: C.veronese_embedding(2).codomain().degree() 4
twisted cubic::
sage: P.<x,y> = ProjectiveSpace(QQ, 1) sage: Q.<u,v,s,t> = ProjectiveSpace(QQ, 3) sage: P.subscheme([]).veronese_embedding(3, Q) Scheme morphism: From: Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: (no polynomials) To: Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: -s^2 + v*t, -v*s + u*t, -v^2 + u*s Defn: Defined on coordinates by sending (x : y) to (x^3 : x^2*y : x*y^2 : y^3) """ # construct map between projective spaces # return this map restricted to self and its image |