Path: blob/master/src/sage/schemes/affine/affine_space.py
8820 views
"""1Affine `n` space over a ring2"""34#*****************************************************************************5# Copyright (C) 2006 William Stein <[email protected]>6#7# Distributed under the terms of the GNU General Public License (GPL)8#9# http://www.gnu.org/licenses/10#*****************************************************************************1112from sage.rings.all import (13PolynomialRing,14ZZ,15Integer)1617from sage.rings.ring import is_Ring18from sage.rings.rational_field import is_RationalField19from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing20from sage.rings.finite_rings.constructor import is_FiniteField2122from sage.categories.fields import Fields23_Fields = Fields()2425from sage.misc.all import latex26from sage.structure.parent_gens import normalize_names2728from sage.schemes.generic.scheme import AffineScheme29from sage.schemes.generic.ambient_space import AmbientSpace30from sage.schemes.affine.affine_homset import SchemeHomset_points_affine31from sage.schemes.affine.affine_morphism import (SchemeMorphism_polynomial_affine_space,32SchemeMorphism_polynomial_affine_space_field,33SchemeMorphism_polynomial_affine_space_finite_field)34from sage.schemes.affine.affine_point import (SchemeMorphism_point_affine,35SchemeMorphism_point_affine_field,36SchemeMorphism_point_affine_finite_field)37383940def is_AffineSpace(x):41r"""42Returns True if x is an affine space, i.e., an ambient space43`\mathbb{A}^n_R`, where `R` is a ring and44`n\geq 0` is an integer.4546EXAMPLES::4748sage: from sage.schemes.affine.affine_space import is_AffineSpace49sage: is_AffineSpace(AffineSpace(5, names='x'))50True51sage: is_AffineSpace(AffineSpace(5, GF(9,'alpha'), names='x'))52True53sage: is_AffineSpace(Spec(ZZ))54False55"""56return isinstance(x, AffineSpace_generic)5758def AffineSpace(n, R=None, names='x'):59r"""60Return affine space of dimension `n` over the ring `R`.6162EXAMPLES:6364The dimension and ring can be given in either order::6566sage: AffineSpace(3, QQ, 'x')67Affine Space of dimension 3 over Rational Field68sage: AffineSpace(5, QQ, 'x')69Affine Space of dimension 5 over Rational Field70sage: A = AffineSpace(2, QQ, names='XY'); A71Affine Space of dimension 2 over Rational Field72sage: A.coordinate_ring()73Multivariate Polynomial Ring in X, Y over Rational Field7475Use the divide operator for base extension::7677sage: AffineSpace(5, names='x')/GF(17)78Affine Space of dimension 5 over Finite Field of size 177980The default base ring is `\ZZ`::8182sage: AffineSpace(5, names='x')83Affine Space of dimension 5 over Integer Ring8485There is also an affine space associated to each polynomial ring::8687sage: R = GF(7)['x,y,z']88sage: A = AffineSpace(R); A89Affine Space of dimension 3 over Finite Field of size 790sage: A.coordinate_ring() is R91True92"""93if is_MPolynomialRing(n) and R is None:94R = n95A = AffineSpace(R.ngens(), R.base_ring(), R.variable_names())96A._coordinate_ring = R97return A98if isinstance(R, (int, long, Integer)):99n, R = R, n100if R is None:101R = ZZ # default is the integers102if names is None:103if n == 0:104names = ''105else:106raise TypeError("You must specify the variables names of the coordinate ring.")107if R in _Fields:108if is_FiniteField(R):109return AffineSpace_finite_field(n, R, names)110else:111return AffineSpace_field(n, R, names)112return AffineSpace_generic(n, R, names)113114115class AffineSpace_generic(AmbientSpace, AffineScheme):116"""117Affine space of dimension `n` over the ring `R`.118119EXAMPLES::120121sage: X.<x,y,z> = AffineSpace(3, QQ)122sage: X.base_scheme()123Spectrum of Rational Field124sage: X.base_ring()125Rational Field126sage: X.category()127Category of schemes over Rational Field128sage: X.structure_morphism()129Scheme morphism:130From: Affine Space of dimension 3 over Rational Field131To: Spectrum of Rational Field132Defn: Structure map133134Loading and saving::135136sage: loads(X.dumps()) == X137True138139We create several other examples of affine spaces::140141sage: AffineSpace(5, PolynomialRing(QQ, 'z'), 'Z')142Affine Space of dimension 5 over Univariate Polynomial Ring in z over Rational Field143144sage: AffineSpace(RealField(), 3, 'Z')145Affine Space of dimension 3 over Real Field with 53 bits of precision146147sage: AffineSpace(Qp(7), 2, 'x')148Affine Space of dimension 2 over 7-adic Field with capped relative precision 20149150Even 0-dimensional affine spaces are supported::151152sage: AffineSpace(0)153Affine Space of dimension 0 over Integer Ring154"""155def __init__(self, n, R, names):156"""157EXAMPLES::158159sage: AffineSpace(3, Zp(5), 'y')160Affine Space of dimension 3 over 5-adic Ring with capped relative precision 20161"""162names = normalize_names(n, names)163AmbientSpace.__init__(self, n, R)164self._assign_names(names)165166def __iter__(self):167"""168Return iterator over the elements of this affine space when defined169over a finite field.170171EXAMPLES::172173sage: FF = FiniteField(3)174sage: AA = AffineSpace(FF, 0)175sage: [ x for x in AA ]176[()]177sage: AA = AffineSpace(FF, 1, 'Z')178sage: [ x for x in AA ]179[(0), (1), (2)]180sage: AA.<z,w> = AffineSpace(FF, 2)181sage: [ x for x in AA ]182[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)]183184AUTHOR:185186- David Kohel187"""188n = self.dimension_relative()189R = self.base_ring()190zero = R(0)191P = [ zero for _ in range(n) ]192yield self(P)193iters = [ iter(R) for _ in range(n) ]194for x in iters: x.next() # put at zero195i = 0196while i < n:197try:198P[i] = iters[i].next()199yield self(P)200i = 0201except StopIteration:202iters[i] = iter(R) # reset203iters[i].next() # put at zero204P[i] = zero205i += 1206207def ngens(self):208"""209Return the number of generators of self, i.e. the number of210variables in the coordinate ring of self.211212EXAMPLES::213214sage: AffineSpace(3, QQ).ngens()2153216sage: AffineSpace(7, ZZ).ngens()2177218"""219return self.dimension_relative()220221def rational_points(self, F=None):222"""223Return the list of `F`-rational points on the affine space self,224where `F` is a given finite field, or the base ring of self.225226EXAMPLES::227228sage: A = AffineSpace(1, GF(3))229sage: A.rational_points()230[(0), (1), (2)]231sage: A.rational_points(GF(3^2, 'b'))232[(0), (b), (b + 1), (2*b + 1), (2), (2*b), (2*b + 2), (b + 2), (1)]233234sage: AffineSpace(2, ZZ).rational_points(GF(2))235[(0, 0), (1, 0), (0, 1), (1, 1)]236237TESTS::238239sage: AffineSpace(2, QQ).rational_points()240Traceback (most recent call last):241...242TypeError: Base ring (= Rational Field) must be a finite field.243sage: AffineSpace(1, GF(3)).rational_points(ZZ)244Traceback (most recent call last):245...246TypeError: Second argument (= Integer Ring) must be a finite field.247"""248if F == None:249if not is_FiniteField(self.base_ring()):250raise TypeError("Base ring (= %s) must be a finite field."%self.base_ring())251return [ P for P in self ]252elif not is_FiniteField(F):253raise TypeError("Second argument (= %s) must be a finite field."%F)254return [ P for P in self.base_extend(F) ]255256def __cmp__(self, right):257"""258Compare ``self`` with ``right``.259260EXAMPLES::261262sage: AffineSpace(QQ, 3, 'a') == AffineSpace(ZZ, 3, 'a')263False264sage: AffineSpace(ZZ,1, 'a') == AffineSpace(ZZ, 0, 'a')265False266sage: loads(AffineSpace(ZZ, 1, 'x').dumps()) == AffineSpace(ZZ, 1, 'x')267True268"""269if not isinstance(right, AffineSpace_generic):270return -1271return cmp([self.dimension_relative(), self.coordinate_ring()],272[right.dimension_relative(), right.coordinate_ring()])273274def _latex_(self):275r"""276Return a LaTeX representation of this affine space.277278EXAMPLES::279280sage: print latex(AffineSpace(1, ZZ, 'x'))281\mathbf{A}_{\Bold{Z}}^1282283TESTS::284285sage: AffineSpace(3, Zp(5), 'y')._latex_()286'\\mathbf{A}_{\\ZZ_{5}}^3'287"""288return "\\mathbf{A}_{%s}^%s"%(latex(self.base_ring()), self.dimension_relative())289290def _morphism(self, *args, **kwds):291"""292Construct a morphism determined by action on points of ``self``.293294INPUT:295296Same as for297:class:`~sage.schemes.affine.affine_morphism.SchemeMorphism_polynomial_affine_space`.298299OUPUT:300301A new instance of302:class:`~sage.schemes.affine.affine_morphism.SchemeMorphism_polynomial_affine_space`.303304EXAMPLES::305306sage: AA = AffineSpace(QQ, 3, 'a')307sage: AA.inject_variables()308Defining a0, a1, a2309sage: EndAA = AA.Hom(AA)310sage: AA._morphism(EndAA, [a0*a1, a1*a2, a0*a2])311Scheme endomorphism of Affine Space of dimension 3 over Rational Field312Defn: Defined on coordinates by sending (a0, a1, a2) to313(a0*a1, a1*a2, a0*a2)314"""315return SchemeMorphism_polynomial_affine_space(*args, **kwds)316317def _point_homset(self, *args, **kwds):318"""319Construct a Hom-set for ``self``.320321INPUT:322323Same as for324:class:`~sage.schemes.affine.affine_homset.SchemeHomset_points_affine`.325326OUPUT:327328A new instance of329:class:`~sage.schemes.affine.affine_homset.SchemeHomset_points_affine`.330331EXAMPLES::332333sage: AA = AffineSpace(QQ, 3, 'a')334sage: AA._point_homset(Spec(QQ), AA)335Set of rational points of Affine Space of dimension 3 over Rational Field336"""337return SchemeHomset_points_affine(*args, **kwds)338339def _point(self, *args, **kwds):340r"""341Construct a point of ``self``.342343INPUT:344345Same as for346:class:`~sage.schemes.affine.affine_point.SchemeMorphism_point_affine`.347348OUPUT:349350A new instance of351:class:`~sage.schemes.affine.affine_point.SchemeMorphism_point_affine`.352353TESTS::354355sage: AA = AffineSpace(QQ, 3, 'a')356sage: AA._point(AA.point_homset(), [0,1,2])357(0, 1, 2)358"""359return SchemeMorphism_point_affine(*args, **kwds)360361def _repr_(self):362"""363Return a string representation of this affine space.364365EXAMPLES::366367sage: AffineSpace(1, ZZ, 'x')368Affine Space of dimension 1 over Integer Ring369370TESTS::371372sage: AffineSpace(3, Zp(5), 'y')._repr_()373'Affine Space of dimension 3 over 5-adic Ring with capped relative precision 20'374"""375return "Affine Space of dimension %s over %s"%(self.dimension_relative(), self.base_ring())376377def _repr_generic_point(self, polys=None):378"""379Return a string representation of the generic point380corresponding to the list of polys on this affine space.381382If polys is None, the representation of the generic point of383the affine space is returned.384385EXAMPLES::386387sage: A.<x, y> = AffineSpace(2, ZZ)388sage: A._repr_generic_point([y-x^2])389'(-x^2 + y)'390sage: A._repr_generic_point()391'(x, y)'392"""393if polys is None:394polys = self.gens()395return '(%s)'%(", ".join([str(f) for f in polys]))396397def _latex_generic_point(self, v=None):398"""399Return a LaTeX representation of the generic point400corresponding to the list of polys on this affine space.401402If polys is None, the representation of the generic point of403the affine space is returned.404405EXAMPLES::406407sage: A.<x, y> = AffineSpace(2, ZZ)408sage: A._latex_generic_point([y-x^2])409'\\left(- x^{2} + y\\right)'410sage: A._latex_generic_point()411'\\left(x, y\\right)'412"""413if v is None:414v = self.gens()415return '\\left(%s\\right)'%(", ".join([str(latex(f)) for f in v]))416417def _check_satisfies_equations(self, v):418"""419Return True if `v` defines a point on the scheme self; raise a420TypeError otherwise.421422EXAMPLES::423424sage: A = AffineSpace(3, ZZ)425sage: A._check_satisfies_equations([1, 1, 0])426True427sage: A._check_satisfies_equations((0, 1, 0))428True429sage: A._check_satisfies_equations([0, 0, 0])430True431sage: A._check_satisfies_equations([1, 2, 3, 4, 5])432Traceback (most recent call last):433...434TypeError: The list v=[1, 2, 3, 4, 5] must have 3 components435sage: A._check_satisfies_equations([1/2, 1, 1])436Traceback (most recent call last):437...438TypeError: The components of v=[1/2, 1, 1] must be elements of Integer Ring439sage: A._check_satisfies_equations(5)440Traceback (most recent call last):441...442TypeError: The argument v=5 must be a list or tuple443"""444if not isinstance(v, (list, tuple)):445raise TypeError('The argument v=%s must be a list or tuple'%v)446n = self.ngens()447if not len(v) == n:448raise TypeError('The list v=%s must have %s components'%(v, n))449R = self.base_ring()450from sage.structure.sequence import Sequence451if not Sequence(v).universe() == R:452raise TypeError('The components of v=%s must be elements of %s'%(v, R))453return True454455def __pow__(self, m):456"""457Return the cartesian power of self.458459INPUT:460461- ``m`` -- integer462463OUTPUT:464465- affine ambient space466467EXAMPLES::468469sage: A = AffineSpace(1, QQ, 'x')470sage: A5 = A^5; A5471Affine Space of dimension 5 over Rational Field472sage: A5.variable_names()473('x0', 'x1', 'x2', 'x3', 'x4')474sage: A2 = AffineSpace(2, QQ, "x, y")475sage: A4 = A2^2; A4476Affine Space of dimension 4 over Rational Field477sage: A4.variable_names()478('x0', 'x1', 'x2', 'x3')479480As you see, custom variable names are not preserved by power operator,481since there is no natural way to make new ones in general.482"""483mm = int(m)484if mm != m:485raise ValueError("m must be an integer")486return AffineSpace(self.dimension_relative() * mm, self.base_ring())487488def change_ring(self, R):489r"""490Return an affine space over ring `R` and otherwise the same as self.491492INPUT:493494- ``R`` -- commutative ring495496OUTPUT:497498- affine space over ``R``499500.. NOTE::501502There is no need to have any relation between `R` and the base ring503of self, if you want to have such a relation, use504``self.base_extend(R)`` instead.505506EXAMPLES::507508sage: A.<x, y, z> = AffineSpace(3, ZZ)509sage: AQ = A.change_ring(QQ); AQ510Affine Space of dimension 3 over Rational Field511sage: AQ.change_ring(GF(5))512Affine Space of dimension 3 over Finite Field of size 5513"""514return AffineSpace(self.dimension_relative(), R, self.variable_names())515516def coordinate_ring(self):517"""518Return the coordinate ring of this scheme, if defined.519520EXAMPLES::521522sage: R = AffineSpace(2, GF(9,'alpha'), 'z').coordinate_ring(); R523Multivariate Polynomial Ring in z0, z1 over Finite Field in alpha of size 3^2524sage: AffineSpace(3, R, 'x').coordinate_ring()525Multivariate Polynomial Ring in x0, x1, x2 over Multivariate Polynomial Ring in z0, z1 over Finite Field in alpha of size 3^2526"""527try:528return self._coordinate_ring529except AttributeError:530self._coordinate_ring = PolynomialRing(self.base_ring(), self.dimension_relative(), names=self.variable_names())531return self._coordinate_ring532533def _validate(self, polynomials):534"""535If ``polynomials`` is a tuple of valid polynomial functions on self,536return ``polynomials``, otherwise raise TypeError.537538Since this is an affine space, all polynomials are valid.539540INPUT:541542- ``polynomials`` -- tuple of polynomials in the coordinate ring of543self544545OUTPUT:546547- tuple of polynomials in the coordinate ring of self548549EXAMPLES::550551sage: A.<x, y, z> = AffineSpace(3, ZZ)552sage: A._validate((x*y - z, 1))553(x*y - z, 1)554"""555return polynomials556557def projective_embedding(self, i=None, PP=None):558"""559Returns a morphism from this space into an ambient projective space560of the same dimension.561562INPUT:563564565- ``i`` - integer (default: dimension of self = last566coordinate) determines which projective embedding to compute. The567embedding is that which has a 1 in the i-th coordinate, numbered568from 0.569570- ``PP`` - (default: None) ambient projective space, i.e.,571codomain of morphism; this is constructed if it is not572given.573574EXAMPLES::575576sage: AA = AffineSpace(2, QQ, 'x')577sage: pi = AA.projective_embedding(0); pi578Scheme morphism:579From: Affine Space of dimension 2 over Rational Field580To: Projective Space of dimension 2 over Rational Field581Defn: Defined on coordinates by sending (x0, x1) to582(1 : x0 : x1)583sage: z = AA(3,4)584sage: pi(z)585(1/4 : 3/4 : 1)586sage: pi(AA(0,2))587(1/2 : 0 : 1)588sage: pi = AA.projective_embedding(1); pi589Scheme morphism:590From: Affine Space of dimension 2 over Rational Field591To: Projective Space of dimension 2 over Rational Field592Defn: Defined on coordinates by sending (x0, x1) to593(x0 : 1 : x1)594sage: pi(z)595(3/4 : 1/4 : 1)596sage: pi = AA.projective_embedding(2)597sage: pi(z)598(3 : 4 : 1)599"""600n = self.dimension_relative()601if i is None:602try:603i = self._default_embedding_index604except AttributeError:605i = int(n)606else:607i = int(i)608try:609return self.__projective_embedding[i]610except AttributeError:611self.__projective_embedding = {}612except KeyError:613pass614if PP is None:615from sage.schemes.projective.projective_space import ProjectiveSpace616PP = ProjectiveSpace(n, self.base_ring())617R = self.coordinate_ring()618v = list(R.gens())619if n < 0 or n >self.dimension_relative():620raise ValueError("Argument i (=%s) must be between 0 and %s, inclusive"%(i,n))621v.insert(i, R(1))622phi = self.hom(v, PP)623self.__projective_embedding[i] = phi624return phi625626def subscheme(self, X):627"""628Return the closed subscheme defined by X.629630INPUT:631632633- ``X`` - a list or tuple of equations634635636EXAMPLES::637638sage: A.<x,y> = AffineSpace(QQ, 2)639sage: X = A.subscheme([x, y^2, x*y^2]); X640Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:641x,642y^2,643x*y^2644645::646647sage: X.defining_polynomials ()648(x, y^2, x*y^2)649sage: I = X.defining_ideal(); I650Ideal (x, y^2, x*y^2) of Multivariate Polynomial Ring in x, y over Rational Field651sage: I.groebner_basis()652[y^2, x]653sage: X.dimension()6540655sage: X.base_ring()656Rational Field657sage: X.base_scheme()658Spectrum of Rational Field659sage: X.structure_morphism()660Scheme morphism:661From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:662x,663y^2,664x*y^2665To: Spectrum of Rational Field666Defn: Structure map667sage: X.dimension()6680669"""670from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme_affine671return AlgebraicScheme_subscheme_affine(self, X)672673def _an_element_(self):674r"""675Returns a (preferably typical) element of ``self``.676677This is used both for illustration and testing purposes.678679OUTPUT: a point in the affine space ``self``.680681EXAMPLES::682683sage: AffineSpace(ZZ,2,'x').an_element()684(5, 4)685686sage: AffineSpace(Qp(5),2,'x').an_element()687(5^2 + O(5^22), 4*5 + O(5^21))688"""689n = self.dimension_relative()690R = self.base_ring()691return self([(5 - i) * R.an_element() for i in range(n)])692693694class AffineSpace_field(AffineSpace_generic):695def _point(self, *args, **kwds):696"""697Construct a point.698699For internal use only. See :mod:`morphism` for details.700701TESTS::702703sage: P2.<x,y,z> = AffineSpace(3, GF(3))704sage: point_homset = P2._point_homset(Spec(GF(3)), P2)705sage: P2._point(point_homset, [1,2,3])706(1, 2, 0)707"""708return SchemeMorphism_point_affine_field(*args, **kwds)709710def _morphism(self, *args, **kwds):711"""712Construct a morphism.713714For internal use only. See :mod:`morphism` for details.715716TESTS::717718sage: P2.<x,y,z> = AffineSpace(3, GF(3))719sage: P2._morphism(P2.Hom(P2), [x,y,z])720Scheme endomorphism of Affine Space of dimension 3 over Finite Field of size 3721Defn: Defined on coordinates by sending (x, y, z) to722(x, y, z)723"""724return SchemeMorphism_polynomial_affine_space_field(*args, **kwds)725726class AffineSpace_finite_field(AffineSpace_field):727def _point(self, *args, **kwds):728"""729Construct a point.730731For internal use only. See :mod:`morphism` for details.732733TESTS::734735sage: P2.<x,y,z> = AffineSpace(3, GF(3))736sage: point_homset = P2._point_homset(Spec(GF(3)), P2)737sage: P2._point(point_homset, [1,2,3])738(1, 2, 0)739"""740return SchemeMorphism_point_affine_finite_field(*args, **kwds)741742def _morphism(self, *args, **kwds):743"""744Construct a morphism.745746For internal use only. See :mod:`morphism` for details.747748TESTS::749750sage: P2.<x,y,z> = AffineSpace(3, GF(3))751sage: P2._morphism(P2.Hom(P2), [x,y,z])752Scheme endomorphism of Affine Space of dimension 3 over Finite Field of size 3753Defn: Defined on coordinates by sending (x, y, z) to754(x, y, z)755"""756return SchemeMorphism_polynomial_affine_space_finite_field(*args, **kwds)757758#fix the pickles from moving affine_space.py759from sage.structure.sage_object import register_unpickle_override760register_unpickle_override('sage.schemes.generic.affine_space',761'AffineSpace_generic',762AffineSpace_generic)763764765