def create_key_and_extra_args(self, X, Y, category=None, base=ZZ, check=True): """ Create a key that uniquely determines the Hom-set. INPUT: - ``X`` -- a scheme. The domain of the morphisms. - ``Y`` -- a scheme. The codomain of the morphisms. - ``category`` -- a category for the Hom-sets (default: schemes over given base). - ``base`` -- a scheme or a ring. The base scheme of domain and codomain schemes. If a ring is specified, the spectrum of that ring will be used as base scheme. - ``check`` -- boolean (default: ``True``). EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A3 = AffineSpace(QQ,3) sage: A3.Hom(A2) # indirect doctest Set of morphisms From: Affine Space of dimension 3 over Rational Field To: Affine Space of dimension 2 over Rational Field sage: from sage.schemes.generic.homset import SchemeHomsetFactory sage: SHOMfactory = SchemeHomsetFactory('test') sage: key, extra = SHOMfactory.create_key_and_extra_args(A3,A2,check=False) sage: key (..., ..., Category of schemes over Integer Ring) sage: extra {'Y': Affine Space of dimension 2 over Rational Field, 'X': Affine Space of dimension 3 over Rational Field, 'base_ring': Integer Ring, 'check': False} """ if not is_Scheme(X) and is_CommutativeRing(X): X = Spec(X) if not is_Scheme(Y) and is_CommutativeRing(Y): Y = Spec(Y) if is_Spec(base): base_spec = base base_ring = base.coordinate_ring() elif is_CommutativeRing(base): base_spec = Spec(base) base_ring = base else: raise ValueError( 'The base must be a commutative ring or its spectrum.') if not category: from sage.categories.schemes import Schemes category = Schemes(base_spec) key = tuple([id(X), id(Y), category]) extra = {'X':X, 'Y':Y, 'base_ring':base_ring, 'check':check} return key, extra
def __init__(self, A): """ EXAMPLES:: sage: CommutativeAlgebraIdeals(ZZ['x']) Category of commutative algebra ideals in Univariate Polynomial Ring in x over Integer Ring sage: CommutativeAlgebraIdeals(ZZ) Traceback (most recent call last): ... TypeError: A (=Integer Ring) must be a commutative algebra sage: CommutativeAlgebraIdeals(IntegerModRing(4)) Traceback (most recent call last): ... TypeError: A (=Ring of integers modulo 4) must be a commutative algebra sage: CommutativeAlgebraIdeals(Partitions(4)) Traceback (most recent call last): ... TypeError: A (=Partitions of the integer 4) must be a commutative algebra TESTS:: sage: TestSuite(CommutativeAlgebraIdeals(QQ[x])).run() """ # TODO: replace by ``A in CommutativeAlgebras(*)`` once a # suitable mantra has been implemented for this. from sage.algebras.algebra import is_Algebra from sage.rings.commutative_ring import is_CommutativeRing if not (is_Algebra(A) and is_CommutativeRing(A)): raise TypeError("A (=%s) must be a commutative algebra"%A) Category_in_ambient.__init__(self, A)
def __init__(self, A): """ EXAMPLES:: sage: CommutativeAlgebraIdeals(ZZ['x']) Category of commutative algebra ideals in Univariate Polynomial Ring in x over Integer Ring sage: CommutativeAlgebraIdeals(ZZ) Traceback (most recent call last): ... TypeError: A (=Integer Ring) must be a commutative algebra sage: CommutativeAlgebraIdeals(IntegerModRing(4)) Traceback (most recent call last): ... TypeError: A (=Ring of integers modulo 4) must be a commutative algebra sage: CommutativeAlgebraIdeals(Partitions(4)) Traceback (most recent call last): ... TypeError: A (=Partitions of the integer 4) must be a commutative algebra TESTS:: sage: TestSuite(CommutativeAlgebraIdeals(QQ[x])).run() """ # TODO: replace by ``A in CommutativeAlgebras(*)`` once a # suitable mantra has been implemented for this. from sage.algebras.algebra import is_Algebra from sage.rings.commutative_ring import is_CommutativeRing if not (is_Algebra(A) and is_CommutativeRing(A)): raise TypeError, "A (=%s) must be a commutative algebra"%A Category_in_ambient.__init__(self, A)
def base_extend(self, R): """ Extend the base ring/scheme. INPUT: - ``R`` -- an affine scheme or a commutative ring. EXAMPLES:: sage: Spec_ZZ = Spec(ZZ); Spec_ZZ Spectrum of Integer Ring sage: Spec_ZZ.base_extend(QQ) Spectrum of Rational Field """ if is_CommutativeRing(R): return Spec(self.coordinate_ring().base_extend(R), self.base_ring()) if not self.base_scheme() == R.base_scheme(): raise ValueError( 'The new base scheme must be a scheme over the old base scheme.' ) return Spec( self.coordinate_ring().base_extend(new_base.coordinate_ring()), self.base_ring())
def __init__(self, R, S=None, check=True): """ EXAMPLES:: sage: Spec(ZZ) Spectrum of Integer Ring """ if not is_CommutativeRing(R): raise TypeError, "R (=%s) must be a commutative ring"%R self.__R = R if not S is None: if not is_CommutativeRing(S): raise TypeError, "S (=%s) must be a commutative ring"%S try: S.hom(R) except TypeError: raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) self._base_ring = S
def __init__(self, R, S=None, check=True): """ EXAMPLES:: sage: Spec(ZZ) Spectrum of Integer Ring """ if not is_CommutativeRing(R): raise TypeError, "R (=%s) must be a commutative ring" % R self.__R = R if not S is None: if not is_CommutativeRing(S): raise TypeError, "S (=%s) must be a commutative ring" % S try: S.hom(R) except TypeError: raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s" % ( S, R) self._base_ring = S
def canonical_parameters(group, weight, sign, base_ring): """ Return the canonically normalized parameters associated to a choice of group, weight, sign, and base_ring. That is, normalize each of these to be of the correct type, perform all appropriate type checking, etc. EXAMPLES:: sage: p1 = sage.modular.modsym.modsym.canonical_parameters(5,int(2),1,QQ) ; p1 (Congruence Subgroup Gamma0(5), 2, 1, Rational Field) sage: p2 = sage.modular.modsym.modsym.canonical_parameters(Gamma0(5),2,1,QQ) ; p2 (Congruence Subgroup Gamma0(5), 2, 1, Rational Field) sage: p1 == p2 True sage: type(p1[1]) <type 'sage.rings.integer.Integer'> """ sign = rings.Integer(sign) if not (sign in [-1, 0, 1]): raise ValueError("sign must be -1, 0, or 1") weight = rings.Integer(weight) if weight <= 1: raise ValueError("the weight must be at least 2") if isinstance(group, (int, rings.Integer)): group = arithgroup.Gamma0(group) elif isinstance(group, dirichlet.DirichletCharacter): try: eps = group.minimize_base_ring() except NotImplementedError: # TODO -- implement minimize_base_ring over finite fields eps = group G = eps.parent() if eps.is_trivial(): group = arithgroup.Gamma0(eps.modulus()) else: group = (eps, G) if base_ring is None: base_ring = eps.base_ring() if base_ring is None: base_ring = rational_field.RationalField() if not is_CommutativeRing(base_ring): raise TypeError("base_ring (=%s) must be a commutative ring" % base_ring) if not base_ring.is_field(): raise TypeError("(currently) base_ring (=%s) must be a field" % base_ring) return group, weight, sign, base_ring
def __init__(self, R, S=None): """ Construct the spectrum of the ring ``R``. See :class:`Spec` for details. EXAMPLES:: sage: Spec(ZZ) Spectrum of Integer Ring """ if not is_CommutativeRing(R): raise TypeError, "R (=%s) must be a commutative ring"%R self.__R = R if not S is None: if not is_CommutativeRing(S): raise TypeError, "S (=%s) must be a commutative ring"%S try: S.hom(R) except TypeError: raise ValueError, "There must be a natural map S --> R, but S = %s and R = %s"%(S,R) AffineScheme.__init__(self, S)
def __init__(self, R, S=None): """ Construct the spectrum of the ring ``R``. See :class:`Spec` for details. EXAMPLES:: sage: Spec(ZZ) Spectrum of Integer Ring """ if not is_CommutativeRing(R): raise TypeError("R (=%s) must be a commutative ring"%R) self.__R = R if not S is None: if not is_CommutativeRing(S): raise TypeError("S (=%s) must be a commutative ring"%S) try: S.hom(R) except TypeError: raise ValueError("There must be a natural map S --> R, but S = %s and R = %s"%(S,R)) AffineScheme.__init__(self, S)
def canonical_parameters(group, weight, sign, base_ring): """ Return the canonically normalized parameters associated to a choice of group, weight, sign, and base_ring. That is, normalize each of these to be of the correct type, perform all appropriate type checking, etc. EXAMPLES:: sage: p1 = sage.modular.modsym.modsym.canonical_parameters(5,int(2),1,QQ) ; p1 (Congruence Subgroup Gamma0(5), 2, 1, Rational Field) sage: p2 = sage.modular.modsym.modsym.canonical_parameters(Gamma0(5),2,1,QQ) ; p2 (Congruence Subgroup Gamma0(5), 2, 1, Rational Field) sage: p1 == p2 True sage: type(p1[1]) <type 'sage.rings.integer.Integer'> """ sign = rings.Integer(sign) if not (sign in [-1,0,1]): raise ValueError, "sign must be -1, 0, or 1" weight = rings.Integer(weight) if weight <= 1: raise ValueError, "the weight must be at least 2" if isinstance(group, (int, rings.Integer)): group = arithgroup.Gamma0(group) elif isinstance(group, dirichlet.DirichletCharacter): try: eps = group.minimize_base_ring() except NotImplementedError: # TODO -- implement minimize_base_ring over finite fields eps = group G = eps.parent() if eps.is_trivial(): group = arithgroup.Gamma0(eps.modulus()) else: group = (eps, G) if base_ring is None: base_ring = eps.base_ring() if base_ring is None: base_ring = rational_field.RationalField() if not is_CommutativeRing(base_ring): raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring if not base_ring.is_field(): raise TypeError, "(currently) base_ring (=%s) must be a field"%base_ring return group, weight, sign, base_ring
def __call__(self, x): """ Call syntax for Spec. INPUT/OUTPUT: The argument ``x`` must be one of the following: - a prime ideal of the coordinate ring; the output will be the corresponding point of X - an element (or list of elements) of the coordinate ring which generates a prime ideal; the output will be the corresponding point of X - a ring or a scheme S; the output will be the set X(S) of S-valued points on X EXAMPLES:: sage: S = Spec(ZZ) sage: P = S(3); P Point on Spectrum of Integer Ring defined by the Principal ideal (3) of Integer Ring sage: type(P) <class 'sage.schemes.generic.point.SchemeTopologicalPoint_prime_ideal'> sage: S(ZZ.ideal(next_prime(1000000))) Point on Spectrum of Integer Ring defined by the Principal ideal (1000003) of Integer Ring sage: R.<x, y, z> = QQ[] sage: S = Spec(R) sage: P = S(R.ideal(x, y, z)); P Point on Spectrum of Multivariate Polynomial Ring in x, y, z over Rational Field defined by the Ideal (x, y, z) of Multivariate Polynomial Ring in x, y, z over Rational Field This indicates the fix of :trac:`12734`:: sage: S = Spec(ZZ) sage: S(ZZ) Set of rational points of Spectrum of Integer Ring sage: S(S) Set of rational points of Spectrum of Integer Ring """ if is_CommutativeRing(x): return self.point_homset(x) from sage.schemes.all import is_Scheme if is_Scheme(x): return x.Hom(self) return SchemeTopologicalPoint_prime_ideal(self, x)
def __init__(self, N, R=QQ, names=None): r""" The Python constructor INPUT: - ``N`` - a list or tuple of positive integers - ``R`` - a ring - ``names`` - a tuple or list of strings. This must either be a single variable name or the complete list of variables. EXAMPLES:: sage: T.<x,y,z,u,v,w> = ProductProjectiveSpaces([2,2],QQ) sage: T Product of projective spaces P^2 x P^2 over Rational Field sage: T.coordinate_ring() Multivariate Polynomial Ring in x, y, z, u, v, w over Rational Field sage: T[1].coordinate_ring() Multivariate Polynomial Ring in u, v, w over Rational Field :: sage: ProductProjectiveSpaces([1,1,1],ZZ, ['x','y','z','u','v','w']) Product of projective spaces P^1 x P^1 x P^1 over Integer Ring :: sage: T = ProductProjectiveSpaces([1,1],QQ,'z') sage: T.coordinate_ring() Multivariate Polynomial Ring in z0, z1, z2, z3 over Rational Field """ assert isinstance(N, (tuple, list)) assert all(x.parent() is ZZ for x in N) assert is_CommutativeRing(R) if len(N) < 2: raise ValueError("Must be at least two components for a product") AmbientSpace.__init__(self, sum(N), R) self._dims = N start = 0 self._components = [] for i in range(len(N)): self._components.append( ProjectiveSpace(N[i], R, names[start:start + N[i] + 1])) start += N[i] + 1 #Note that the coordinate ring should really be the tensor product of the component #coordinate rings. But we just deal with them as multihomogeneous polynomial rings self._coordinate_ring = PolynomialRing(R, sum(N) + len(N), names)
def __init__(self, N, R = QQ, names = None): r""" The Python constructor INPUT: - ``N`` - a list or tuple of positive integers - ``R`` - a ring - ``names`` - a tuple or list of strings. This must either be a single variable name or the complete list of variables. EXAMPLES:: sage: T.<x,y,z,u,v,w> = ProductProjectiveSpaces([2,2],QQ) sage: T Product of projective spaces P^2 x P^2 over Rational Field sage: T.coordinate_ring() Multivariate Polynomial Ring in x, y, z, u, v, w over Rational Field sage: T[1].coordinate_ring() Multivariate Polynomial Ring in u, v, w over Rational Field :: sage: ProductProjectiveSpaces([1,1,1],ZZ, ['x','y','z','u','v','w']) Product of projective spaces P^1 x P^1 x P^1 over Integer Ring :: sage: T = ProductProjectiveSpaces([1,1],QQ,'z') sage: T.coordinate_ring() Multivariate Polynomial Ring in z0, z1, z2, z3 over Rational Field """ assert isinstance(N, (tuple, list)) N = [Integer(n) for n in N] assert is_CommutativeRing(R) if len(N) < 2: raise ValueError("Must be at least two components for a product") AmbientSpace.__init__(self, sum(N), R) self._dims = N start = 0 self._components = [] for i in range(len(N)): self._components.append(ProjectiveSpace(N[i],R,names[start:start+N[i]+1])) start += N[i]+1 #Note that the coordinate ring should really be the tensor product of the component #coordinate rings. But we just deal with them as multihomogeneous polynomial rings self._coordinate_ring = PolynomialRing(R,sum(N)+ len(N),names)
def __init__(self, X=None, category=None): """ Construct a scheme. TESTS:: sage: R.<x, y> = QQ[] sage: I = (x^2 - y^2)*R sage: RmodI = R.quotient(I) sage: X = Spec(RmodI) sage: TestSuite(X).run(skip = ["_test_an_element", "_test_elements", ... "_test_some_elements", "_test_category"]) # See #7946 """ from sage.schemes.generic.spec import is_Spec from sage.schemes.generic.morphism import is_SchemeMorphism if X is None: try: from sage.schemes.generic.spec import SpecZ self._base_scheme = SpecZ except ImportError: # we are currently constructing SpecZ self._base_ring = ZZ elif is_Scheme(X): self._base_scheme = X elif is_SchemeMorphism(X): self._base_morphism = X elif is_CommutativeRing(X): self._base_ring = X elif is_RingHomomorphism(X): self._base_ring = X.codomain() else: raise ValueError("The base must be define by a scheme, " "scheme morphism, or commutative ring.") from sage.categories.schemes import Schemes if not X: default_category = Schemes() else: default_category = Schemes(self.base_scheme()) if category is None: category = default_category else: assert category.is_subcategory(default_category), "%s is not a subcategory of %s" % ( category, default_category, ) Parent.__init__(self, self.base_ring(), category=category)
def __init__(self, n, R=ZZ): """ TEST:: sage: from sage.schemes.generic.ambient_space import AmbientSpace sage: A = AmbientSpace(5, ZZ) sage: TestSuite(A).run() # not tested (abstract scheme with no elements?) """ if not is_CommutativeRing(R): raise TypeError("R (=%s) must be a commutative ring" % R) n = Integer(n) if n < 0: raise ValueError("n (=%s) must be nonnegative" % n) self._dimension_relative = n Scheme.__init__(self, R)
def __init__(self, n, R=ZZ): """ TEST:: sage: from sage.schemes.generic.ambient_space import AmbientSpace sage: A = AmbientSpace(5, ZZ) sage: TestSuite(A).run() # not tested (abstract scheme with no elements?) """ if not is_CommutativeRing(R): raise TypeError("R (=%s) must be a commutative ring"%R) n = Integer(n) if n < 0: raise ValueError("n (=%s) must be nonnegative"%n) self._dimension_relative = n Scheme.__init__(self, R)
def __init__(self, X=None, category=None): """ Construct a scheme. TESTS:: sage: R.<x, y> = QQ[] sage: I = (x^2 - y^2)*R sage: RmodI = R.quotient(I) sage: X = Spec(RmodI) sage: TestSuite(X).run(skip = ["_test_an_element", "_test_elements", ... "_test_some_elements", "_test_category"]) # See #7946 """ from sage.schemes.generic.spec import is_Spec from sage.schemes.generic.morphism import is_SchemeMorphism if X is None: try: from sage.schemes.generic.spec import SpecZ self._base_scheme = SpecZ except ImportError: # we are currently constructing SpecZ self._base_ring = ZZ elif is_Scheme(X): self._base_scheme = X elif is_SchemeMorphism(X): self._base_morphism = X elif is_CommutativeRing(X): self._base_ring = X elif is_RingHomomorphism(X): self._base_ring = X.codomain() else: raise ValueError('The base must be define by a scheme, ' 'scheme morphism, or commutative ring.') from sage.categories.schemes import Schemes if not X: default_category = Schemes() else: default_category = Schemes(self.base_scheme()) if category is None: category = default_category else: assert category.is_subcategory(default_category), \ "%s is not a subcategory of %s"%(category, default_category) Parent.__init__(self, self.base_ring(), category=category)
def __init__(self, X=None, category=None): """ Construct a scheme. TESTS: The full test suite works since :trac:`7946`:: sage: R.<x, y> = QQ[] sage: I = (x^2 - y^2)*R sage: RmodI = R.quotient(I) sage: X = Spec(RmodI) sage: TestSuite(X).run() """ from sage.schemes.generic.morphism import is_SchemeMorphism if X is None: self._base_ring = ZZ elif is_Scheme(X): self._base_scheme = X elif is_SchemeMorphism(X): self._base_morphism = X elif is_CommutativeRing(X): self._base_ring = X elif is_RingHomomorphism(X): self._base_ring = X.codomain() else: raise ValueError('The base must be define by a scheme, ' 'scheme morphism, or commutative ring.') from sage.categories.schemes import Schemes if X is None: default_category = Schemes() else: default_category = Schemes(self.base_scheme()) if category is None: category = default_category else: assert category.is_subcategory(default_category), \ "%s is not a subcategory of %s"%(category, default_category) Parent.__init__(self, self.base_ring(), category = category)
def __init__(self, X=None, category=None): """ Construct a scheme. TESTS: The full test suite works since :trac:`7946`:: sage: R.<x, y> = QQ[] sage: I = (x^2 - y^2)*R sage: RmodI = R.quotient(I) sage: X = Spec(RmodI) sage: TestSuite(X).run() """ from sage.schemes.generic.morphism import is_SchemeMorphism if X is None: self._base_ring = ZZ elif is_Scheme(X): self._base_scheme = X elif is_SchemeMorphism(X): self._base_morphism = X elif is_CommutativeRing(X): self._base_ring = X elif is_RingHomomorphism(X): self._base_ring = X.codomain() else: raise ValueError('The base must be define by a scheme, ' 'scheme morphism, or commutative ring.') from sage.categories.schemes import Schemes if X is None: default_category = Schemes() else: default_category = Schemes(self.base_scheme()) if category is None: category = default_category else: assert category.is_subcategory(default_category), \ "%s is not a subcategory of %s"%(category, default_category) Parent.__init__(self, self.base_ring(), category=category)
def base_extend(self, R): """ Extend the base ring/scheme. INPUT: - ``R`` -- an affine scheme or a commutative ring. EXAMPLES:: sage: Spec_ZZ = Spec(ZZ); Spec_ZZ Spectrum of Integer Ring sage: Spec_ZZ.base_extend(QQ) Spectrum of Rational Field """ if is_CommutativeRing(R): return Spec(self.coordinate_ring().base_extend(R), self.base_ring()) if not self.base_scheme() == R.base_scheme(): raise ValueError("The new base scheme must be a scheme over the old base scheme.") return Spec(self.coordinate_ring().base_extend(new_base.coordinate_ring()), self.base_ring())
def base_extend(self, R): """ Return the natural extension of ``self`` over ``R``. INPUT: - ``R`` -- a commutative ring, such that there is a natural map from the base ring of self to ``R``. OUTPUT: - an ambient space over ``R`` of the same structure as ``self``. .. NOTE:: A ``ValueError`` is raised if there is no such natural map. If you need to drop this condition, use ``self.change_ring(R)``. EXAMPLES:: sage: P.<x, y, z> = ProjectiveSpace(2, ZZ) sage: PQ = P.base_extend(QQ); PQ Projective Space of dimension 2 over Rational Field sage: PQ.base_extend(GF(5)) Traceback (most recent call last): ... ValueError: no natural map from the base ring (=Rational Field) to R (=Finite Field of size 5)! """ if is_CommutativeRing(R): if self.base_ring() == R: return self if not R.has_coerce_map_from(self.base_ring()): raise ValueError( "no natural map from the base ring (=%s) to R (=%s)!" % (self.base_ring(), R)) return self.change_ring(R) else: raise NotImplementedError( "extension of spaces over %s to %s is not implemented!" % (self.base_ring(), R))
def __init__(self, abvar, base): """ This is an abstract base class, so it is called implicitly in the following examples. EXAMPLES:: sage: H = J0(43).integral_homology() sage: type(H) <class 'sage.modular.abvar.homology.IntegralHomology_with_category'> TESTS:: sage: H = J0(43).integral_homology() sage: loads(dumps(H)) == H True """ if not is_CommutativeRing(base): raise TypeError, "base ring must be a commutative ring" HeckeModule_free_module.__init__(self, base, abvar.level(), weight=2) self.__abvar = abvar
def __init__(self, abvar, base): """ This is an abstract base class, so it is called implicitly in the following examples. EXAMPLES:: sage: H = J0(43).integral_homology() sage: type(H) <class 'sage.modular.abvar.homology.IntegralHomology_with_category'> TESTS:: sage: H = J0(43).integral_homology() sage: loads(dumps(H)) == H True """ if not is_CommutativeRing(base): raise TypeError, "base ring must be a commutative ring" HeckeModule_free_module.__init__( self, base, abvar.level(), weight=2) self.__abvar = abvar
def _is_valid_homomorphism_(self, codomain, im_gens): """ Replacement for method of PowerSeriesRing_generic. To be valid, a homomorphism must send generators to elements of positive valuation or to nilpotent elements. Note that the method is_nilpotent doesn't (as of sage 4.4) seem to be defined for obvious examples (matrices, quotients of polynomial rings). EXAMPLES:: sage: R.<a,b,c> = PowerSeriesRing(Zmod(8)); R Multivariate Power Series Ring in a, b, c over Ring of integers modulo 8 sage: M = PowerSeriesRing(ZZ,3,'x,y,z'); sage: M._is_valid_homomorphism_(R,[a,c,b]) True sage: M._is_valid_homomorphism_(R,[0,c,b]) True 2 is nilpotent in `ZZ/8`, but 3 is not:: sage: M._is_valid_homomorphism_(R,[2,c,b]) True sage: M._is_valid_homomorphism_(R,[3,c,b]) False Over `ZZ`, 2 is not nilpotent:: sage: S = R.change_ring(ZZ); S Multivariate Power Series Ring in a, b, c over Integer Ring sage: M._is_valid_homomorphism_(S,[a,c,b]) True sage: M._is_valid_homomorphism_(S,[0,c,b]) True sage: M._is_valid_homomorphism_(S,[2,c,b]) False sage: g = [S.random_element(10)*v for v in S.gens()] sage: M._is_valid_homomorphism_(S,g) True """ try: im_gens = [codomain(v) for v in im_gens] except TypeError: raise TypeError( "The given generator images do not coerce to codomain.") if len(im_gens) is not self.ngens(): raise ValueError("You must specify the image of each generator.") if all(v == 0 for v in im_gens): return True if is_MPowerSeriesRing(codomain) or is_PowerSeriesRing(codomain): try: B = all(v.valuation() > 0 or v.is_nilpotent() for v in im_gens) except NotImplementedError: B = all(v.valuation() > 0 for v in im_gens) return B if is_CommutativeRing(codomain): return all(v.is_nilpotent() for v in im_gens)
def __call__(self, *args): """ Call syntax for schemes. INPUT/OUTPUT: The arguments must be one of the following: - a ring or a scheme `S`. Output will be the set `X(S)` of `S`-valued points on `X`. - If `S` is a list or tuple or just the coordinates, return a point in `X(T)`, where `T` is the base scheme of self. EXAMPLES:: sage: A = AffineSpace(2, QQ) We create some point sets:: sage: A(QQ) Set of rational points of Affine Space of dimension 2 over Rational Field sage: A(RR) Set of rational points of Affine Space of dimension 2 over Real Field with 53 bits of precision Space of dimension 2 over Rational Field:: sage: R.<x> = PolynomialRing(QQ) sage: A(NumberField(x^2+1, 'a')) Set of rational points of Affine Space of dimension 2 over Number Field in a with defining polynomial x^2 + 1 sage: A(GF(7)) Traceback (most recent call last): ... ValueError: There must be a natural map S --> R, but S = Rational Field and R = Finite Field of size 7 We create some points:: sage: A(QQ)([1,0]) (1, 0) We create the same point by giving the coordinates of the point directly:: sage: A( 1,0 ) (1, 0) """ if len(args) == 0: raise TypeError('You need to specify at least one argument.') S = args[0] if is_CommutativeRing(S): return self.point_homset(S) if is_Scheme(S): return S.Hom(self) from sage.schemes.generic.morphism import SchemeMorphism_point if isinstance(S, (list, tuple)): args = S elif isinstance(S, SchemeMorphism_point): if S.codomain() == self: return S else: # TODO: fix circular import resulting from non-multiple inheritance from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field if isinstance(S, EllipticCurvePoint_field): if S.codomain() == self: return S else: return self.point(S) return self.point(args)
def _call_(self, x): """ Construct a scheme from the data in ``x`` EXAMPLES: Let us first construct the category of schemes:: sage: S = Schemes(); S Category of schemes We create a scheme from a ring:: sage: X = S(ZZ); X # indirect doctest Spectrum of Integer Ring We create a scheme from a scheme (do nothing):: sage: S(X) Spectrum of Integer Ring We create a scheme morphism from a ring homomorphism.x:: sage: phi = ZZ.hom(QQ); phi Ring Coercion morphism: From: Integer Ring To: Rational Field sage: f = S(phi); f # indirect doctest Affine Scheme morphism: From: Spectrum of Rational Field To: Spectrum of Integer Ring Defn: Ring Coercion morphism: From: Integer Ring To: Rational Field sage: f.domain() Spectrum of Rational Field sage: f.codomain() Spectrum of Integer Ring sage: S(f) # indirect doctest Affine Scheme morphism: From: Spectrum of Rational Field To: Spectrum of Integer Ring Defn: Ring Coercion morphism: From: Integer Ring To: Rational Field """ from sage.schemes.generic.scheme import is_Scheme if is_Scheme(x): return x from sage.schemes.generic.morphism import is_SchemeMorphism if is_SchemeMorphism(x): return x from sage.rings.morphism import is_RingHomomorphism from sage.rings.commutative_ring import is_CommutativeRing from sage.schemes.generic.spec import Spec if is_CommutativeRing(x): return Spec(x) elif is_RingHomomorphism(x): A = Spec(x.codomain()) return A.hom(x) else: raise TypeError( "No way to create an object or morphism in %s from %s" % (self, x))
def _is_valid_homomorphism_(self, codomain, im_gens): """ Replacement for method of PowerSeriesRing_generic. To be valid, a homomorphism must send generators to elements of positive valuation or to nilpotent elements. Note that the method is_nilpotent doesn't (as of sage 4.4) seem to be defined for obvious examples (matrices, quotients of polynomial rings). EXAMPLES:: sage: R.<a,b,c> = PowerSeriesRing(Zmod(8)); R Multivariate Power Series Ring in a, b, c over Ring of integers modulo 8 sage: M = PowerSeriesRing(ZZ,3,'x,y,z'); sage: M._is_valid_homomorphism_(R,[a,c,b]) True sage: M._is_valid_homomorphism_(R,[0,c,b]) True 2 is nilpotent in `ZZ/8`, but 3 is not:: sage: M._is_valid_homomorphism_(R,[2,c,b]) True sage: M._is_valid_homomorphism_(R,[3,c,b]) False Over `ZZ`, 2 is not nilpotent:: sage: S = R.change_ring(ZZ); S Multivariate Power Series Ring in a, b, c over Integer Ring sage: M._is_valid_homomorphism_(S,[a,c,b]) True sage: M._is_valid_homomorphism_(S,[0,c,b]) True sage: M._is_valid_homomorphism_(S,[2,c,b]) False sage: g = [S.random_element(10)*v for v in S.gens()] sage: M._is_valid_homomorphism_(S,g) True """ try: im_gens = [codomain(v) for v in im_gens] except TypeError: raise TypeError("The given generator images do not coerce to codomain.") if len(im_gens) is not self.ngens(): raise ValueError("You must specify the image of each generator.") if all(v == 0 for v in im_gens): return True if is_MPowerSeriesRing(codomain) or is_PowerSeriesRing(codomain): try: B = all(v.valuation() > 0 or v.is_nilpotent() for v in im_gens) except NotImplementedError: B = all(v.valuation() > 0 for v in im_gens) return B if is_CommutativeRing(codomain): return all(v.is_nilpotent() for v in im_gens)
def _get_action_(self, other, op, self_is_left): """ Register actions with the coercion model. The monoid actions are Minkowski sum and cartesian product. In addition, we want multiplication by a scalar to be dilation and addition by a vector to be translation. This is implemented as an action in the coercion model. INPUT: - ``other`` -- a scalar or a vector. - ``op`` -- the operator. - ``self_is_left`` -- boolean. Whether ``self`` is on the left of the operator. OUTPUT: An action that is used by the coercion model. EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(ZZ,2).get_action(ZZ) # indirect doctest Right action by Integer Ring on Polyhedra in ZZ^2 sage: Polyhedra(ZZ,2).get_action(QQ) Right action by Rational Field on Polyhedra in QQ^2 with precomposition on left by Conversion map: From: Polyhedra in ZZ^2 To: Polyhedra in QQ^2 with precomposition on right by Identity endomorphism of Rational Field sage: Polyhedra(QQ,2).get_action(ZZ) Right action by Integer Ring on Polyhedra in QQ^2 sage: Polyhedra(QQ,2).get_action(QQ) Right action by Rational Field on Polyhedra in QQ^2 sage: Polyhedra(ZZ,2).an_element() * 2 A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: Polyhedra(ZZ,2).an_element() * (2/3) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: Polyhedra(QQ,2).an_element() * 2 A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: Polyhedra(QQ,2).an_element() * (2/3) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: 2 * Polyhedra(ZZ,2).an_element() A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: (2/3) * Polyhedra(ZZ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: 2 * Polyhedra(QQ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: (2/3) * Polyhedra(QQ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(ZZ,2).get_action( ZZ^2, op=operator.add) Right action by Ambient free module of rank 2 over the principal ideal domain Integer Ring on Polyhedra in ZZ^2 with precomposition on left by Identity endomorphism of Polyhedra in ZZ^2 with precomposition on right by Generic endomorphism of Ambient free module of rank 2 over the principal ideal domain Integer Ring """ import operator from sage.structure.coerce_actions import ActedUponAction from sage.categories.action import PrecomposedAction if op is operator.add and is_FreeModule(other): base_ring = self._coerce_base_ring(other) extended_self = self.base_extend(base_ring) extended_other = other.base_extend(base_ring) action = ActedUponAction(extended_other, extended_self, not self_is_left) if self_is_left: action = PrecomposedAction( action, extended_self._internal_coerce_map_from(self).__copy__(), extended_other._internal_coerce_map_from(other).__copy__(), ) else: action = PrecomposedAction( action, extended_other._internal_coerce_map_from(other).__copy__(), extended_self._internal_coerce_map_from(self).__copy__(), ) return action if op is operator.mul and is_CommutativeRing(other): ring = self._coerce_base_ring(other) if ring is self.base_ring(): return ActedUponAction(other, self, not self_is_left) extended = self.base_extend(ring) action = ActedUponAction(ring, extended, not self_is_left) if self_is_left: action = PrecomposedAction( action, extended._internal_coerce_map_from(self).__copy__(), ring._internal_coerce_map_from(other).__copy__(), ) else: action = PrecomposedAction( action, ring._internal_coerce_map_from(other).__copy__(), extended._internal_coerce_map_from(self).__copy__(), ) return action
def canonical_parameters(group, level, weight, base_ring): """ Given a group, level, weight, and base_ring as input by the user, return a canonicalized version of them, where level is a Sage integer, group really is a group, weight is a Sage integer, and base_ring a Sage ring. Note that we can't just get the level from the group, because we have the convention that the character for Gamma1(N) is None (which makes good sense). INPUT: - ``group`` - int, long, Sage integer, group, dirichlet character, or - ``level`` - int, long, Sage integer, or group - ``weight`` - coercible to Sage integer - ``base_ring`` - commutative Sage ring OUTPUT: - ``level`` - Sage integer - ``group`` - congruence subgroup - ``weight`` - Sage integer - ``ring`` - commutative Sage ring EXAMPLES:: sage: from sage.modular.modform.constructor import canonical_parameters sage: v = canonical_parameters(5, 5, int(7), ZZ); v (5, Congruence Subgroup Gamma0(5), 7, Integer Ring) sage: type(v[0]), type(v[1]), type(v[2]), type(v[3]) (<type 'sage.rings.integer.Integer'>, <class 'sage.modular.arithgroup.congroup_gamma0.Gamma0_class_with_category'>, <type 'sage.rings.integer.Integer'>, <type 'sage.rings.integer_ring.IntegerRing_class'>) sage: canonical_parameters( 5, 7, 7, ZZ ) Traceback (most recent call last): ... ValueError: group and level do not match. """ weight = rings.Integer(weight) if weight <= 0: raise NotImplementedError, "weight must be at least 1" if isinstance(group, dirichlet.DirichletCharacter): if ( group.level() != rings.Integer(level) ): raise ValueError, "group.level() and level do not match." group = group.minimize_base_ring() level = rings.Integer(level) elif arithgroup.is_CongruenceSubgroup(group): if ( rings.Integer(level) != group.level() ): raise ValueError, "group.level() and level do not match." # normalize the case of SL2Z if arithgroup.is_SL2Z(group) or \ arithgroup.is_Gamma1(group) and group.level() == rings.Integer(1): group = arithgroup.Gamma0(rings.Integer(1)) elif group is None: pass else: try: m = rings.Integer(group) except TypeError: raise TypeError, "group of unknown type." level = rings.Integer(level) if ( m != level ): raise ValueError, "group and level do not match." group = arithgroup.Gamma0(m) if not is_CommutativeRing(base_ring): raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring # it is *very* important to include the level as part of the data # that defines the key, since dirichlet characters of different # levels can compare equal, but define much different modular # forms spaces. return level, group, weight, base_ring
def __call__(self, *args): """ Call syntax for schemes. INPUT/OUTPUT: The arguments must be one of the following: - a ring or a scheme `S`. Output will be the set `X(S)` of `S`-valued points on `X`. - If `S` is a list or tuple or just the coordinates, return a point in `X(T)`, where `T` is the base scheme of self. EXAMPLES:: sage: A = AffineSpace(2, QQ) We create some point sets:: sage: A(QQ) Set of rational points of Affine Space of dimension 2 over Rational Field sage: A(RR) Set of rational points of Affine Space of dimension 2 over Real Field with 53 bits of precision Space of dimension 2 over Rational Field:: sage: R.<x> = PolynomialRing(QQ) sage: A(NumberField(x^2+1, 'a')) Set of rational points of Affine Space of dimension 2 over Number Field in a with defining polynomial x^2 + 1 sage: A(GF(7)) Traceback (most recent call last): ... ValueError: There must be a natural map S --> R, but S = Rational Field and R = Finite Field of size 7 We create some points:: sage: A(QQ)([1, 0]) (1, 0) We create the same point by giving the coordinates of the point directly:: sage: A(1, 0) (1, 0) Check that :trac:`16832` is fixed:: sage: P.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: X=P.subscheme(x^2 - y^2) sage: X(P([4, 4, 1])) (4 : 4 : 1) """ if len(args) == 1: from sage.schemes.generic.morphism import SchemeMorphism_point S = args[0] if is_CommutativeRing(S): return self.point_homset(S) elif is_Scheme(S): return S.Hom(self) elif isinstance(S, (list, tuple)): args = S elif isinstance(S, SchemeMorphism_point): if S.codomain() is self: return S args = S return self.point(args)
def _get_action_(self, other, op, self_is_left): """ Register actions with the coercion model. The monoid actions are Minkowski sum and Cartesian product. In addition, we want multiplication by a scalar to be dilation and addition by a vector to be translation. This is implemented as an action in the coercion model. INPUT: - ``other`` -- a scalar or a vector. - ``op`` -- the operator. - ``self_is_left`` -- boolean. Whether ``self`` is on the left of the operator. OUTPUT: An action that is used by the coercion model. EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra sage: PZZ2 = Polyhedra(ZZ, 2) sage: PZZ2.get_action(ZZ) # indirect doctest Right action by Integer Ring on Polyhedra in ZZ^2 sage: PZZ2.get_action(QQ) Right action by Rational Field on Polyhedra in QQ^2 with precomposition on left by Conversion map: From: Polyhedra in ZZ^2 To: Polyhedra in QQ^2 with precomposition on right by Identity endomorphism of Rational Field sage: PQQ2 = Polyhedra(QQ, 2) sage: PQQ2.get_action(ZZ) Right action by Integer Ring on Polyhedra in QQ^2 sage: PQQ2.get_action(QQ) Right action by Rational Field on Polyhedra in QQ^2 sage: Polyhedra(ZZ,2).an_element() * 2 A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: Polyhedra(ZZ,2).an_element() * (2/3) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: Polyhedra(QQ,2).an_element() * 2 A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: Polyhedra(QQ,2).an_element() * (2/3) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: 2 * Polyhedra(ZZ,2).an_element() A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: (2/3) * Polyhedra(ZZ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: 2 * Polyhedra(QQ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: (2/3) * Polyhedra(QQ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: from sage.geometry.polyhedron.parent import Polyhedra sage: PZZ2.get_action(ZZ^2, op=operator.add) Right action by Ambient free module of rank 2 over the principal ideal domain Integer Ring on Polyhedra in ZZ^2 with precomposition on left by Identity endomorphism of Polyhedra in ZZ^2 with precomposition on right by Generic endomorphism of Ambient free module of rank 2 over the principal ideal domain Integer Ring """ import operator from sage.structure.coerce_actions import ActedUponAction from sage.categories.action import PrecomposedAction if op is operator.add and is_FreeModule(other): base_ring = self._coerce_base_ring(other) extended_self = self.base_extend(base_ring) extended_other = other.base_extend(base_ring) action = ActedUponAction(extended_other, extended_self, not self_is_left) if self_is_left: action = PrecomposedAction( action, extended_self._internal_coerce_map_from(self).__copy__(), extended_other._internal_coerce_map_from(other).__copy__()) else: action = PrecomposedAction( action, extended_other._internal_coerce_map_from(other).__copy__(), extended_self._internal_coerce_map_from(self).__copy__()) return action if op is operator.mul and is_CommutativeRing(other): ring = self._coerce_base_ring(other) if ring is self.base_ring(): return ActedUponAction(other, self, not self_is_left) extended = self.base_extend(ring) action = ActedUponAction(ring, extended, not self_is_left) if self_is_left: action = PrecomposedAction( action, extended._internal_coerce_map_from(self).__copy__(), ring._internal_coerce_map_from(other).__copy__()) else: action = PrecomposedAction( action, ring._internal_coerce_map_from(other).__copy__(), extended._internal_coerce_map_from(self).__copy__()) return action
def ProjectiveSpace(n, R=None, names='x'): r""" Return projective space of dimension `n` over the ring `R`. EXAMPLES: The dimension and ring can be given in either order. :: sage: ProjectiveSpace(3, QQ) Projective Space of dimension 3 over Rational Field sage: ProjectiveSpace(5, QQ) Projective Space of dimension 5 over Rational Field sage: P = ProjectiveSpace(2, QQ, names='XYZ'); P Projective Space of dimension 2 over Rational Field sage: P.coordinate_ring() Multivariate Polynomial Ring in X, Y, Z over Rational Field The divide operator does base extension. :: sage: ProjectiveSpace(5)/GF(17) Projective Space of dimension 5 over Finite Field of size 17 The default base ring is `\ZZ`. :: sage: ProjectiveSpace(5) Projective Space of dimension 5 over Integer Ring There is also an projective space associated each polynomial ring. :: sage: R = GF(7)['x,y,z'] sage: P = ProjectiveSpace(R); P Projective Space of dimension 2 over Finite Field of size 7 sage: P.coordinate_ring() Multivariate Polynomial Ring in x, y, z over Finite Field of size 7 sage: P.coordinate_ring() is R True :: sage: ProjectiveSpace(3, Zp(5), 'y') Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20 :: sage: ProjectiveSpace(2,QQ,'x,y,z') Projective Space of dimension 2 over Rational Field :: sage: PS.<x,y>=ProjectiveSpace(1,CC) sage: PS Projective Space of dimension 1 over Complex Field with 53 bits of precision Projective spaces are not cached, i.e., there can be several with the same base ring and dimension (to facilitate gluing constructions). """ if is_MPolynomialRing(n) and R is None: A = ProjectiveSpace(n.ngens() - 1, n.base_ring()) A._coordinate_ring = n return A if isinstance(R, (int, long, Integer)): n, R = R, n if R is None: R = ZZ # default is the integers if R in _Fields: if is_FiniteField(R): return ProjectiveSpace_finite_field(n, R, names) if is_RationalField(R): return ProjectiveSpace_rational_field(n, R, names) else: return ProjectiveSpace_field(n, R, names) elif is_CommutativeRing(R): return ProjectiveSpace_ring(n, R, names) else: raise TypeError("R (=%s) must be a commutative ring" % R)
def ProductProjectiveSpaces(n, R=None, names='x'): r""" Returns the Cartesian product of projective spaces. Can input either a list of projective spaces over the same base ring or the list of dimensions, the base ring, and the variable names. INPUT: - ``n`` -- a list of integers or a list of projective spaces - ``R`` -- a ring - ``names`` -- a string or list of strings EXAMPLES:: sage: P1 = ProjectiveSpace(QQ,2,'x') sage: P2 = ProjectiveSpace(QQ,3,'y') sage: ProductProjectiveSpaces([P1,P2]) Product of projective spaces P^2 x P^3 over Rational Field :: sage: ProductProjectiveSpaces([2,2],GF(7),'y') Product of projective spaces P^2 x P^2 over Finite Field of size 7 :: sage: P1 = ProjectiveSpace(ZZ,2,'x') sage: P2 = ProjectiveSpace(QQ,3,'y') sage: ProductProjectiveSpaces([P1,P2]) Traceback (most recent call last): ... AttributeError: Components must be over the same base ring """ if isinstance(R, (list, tuple)): n, R = R, n if not isinstance(n, (tuple, list)): raise TypeError("Must be a list of dimensions") if R is None: R = QQ # default is the rationals if isinstance(n[0], ProjectiveSpace_ring): #this should be a list of projective spaces names = [] N = [] R = None for PS in n: if not isinstance(PS,ProjectiveSpace_ring): raise TypeError("Must be a list of Projective Spaces or (dimensions,base ring,names)") if R is None: R = PS.base_ring() elif R != PS.base_ring(): raise AttributeError("Components must be over the same base ring") N.append(PS.dimension_relative()) names += PS.variable_names() X = ProductProjectiveSpaces_ring(N, R, names) X._components = n else: if isinstance(R, (list,tuple)): n, R = R, n if not isinstance(n,(list,tuple)): raise ValueError("Need list or tuple of dimensions") if not is_CommutativeRing(R): raise ValueError("Must be a commutative ring") from sage.structure.category_object import normalize_names n_vars=sum(d+1 for d in n) if isinstance(names, six.string_types): names = normalize_names(n_vars, names) else: name_list = list(names) if len(name_list) == len(n): names = [] for name, dim in zip(name_list, n): names += normalize_names(dim+1, name) else: n_vars = sum(1+d for d in n) names = normalize_names(n_vars, name_list) X = ProductProjectiveSpaces_ring(n, R, names) return(X)
def _call_(self, x): """ Construct a scheme from the data in ``x`` EXAMPLES: Let us first construct the category of schemes:: sage: S = Schemes(); S Category of schemes We create a scheme from a ring:: sage: X = S(ZZ); X # indirect doctest Spectrum of Integer Ring We create a scheme from a scheme (do nothing):: sage: S(X) Spectrum of Integer Ring We create a scheme morphism from a ring homomorphism.x:: sage: phi = ZZ.hom(QQ); phi Ring Coercion morphism: From: Integer Ring To: Rational Field sage: f = S(phi); f # indirect doctest Affine Scheme morphism: From: Spectrum of Rational Field To: Spectrum of Integer Ring Defn: Ring Coercion morphism: From: Integer Ring To: Rational Field sage: f.domain() Spectrum of Rational Field sage: f.codomain() Spectrum of Integer Ring sage: S(f) # indirect doctest Affine Scheme morphism: From: Spectrum of Rational Field To: Spectrum of Integer Ring Defn: Ring Coercion morphism: From: Integer Ring To: Rational Field """ from sage.schemes.generic.scheme import is_Scheme if is_Scheme(x): return x from sage.schemes.generic.morphism import is_SchemeMorphism if is_SchemeMorphism(x): return x from sage.rings.morphism import is_RingHomomorphism from sage.rings.commutative_ring import is_CommutativeRing from sage.schemes.generic.spec import Spec if is_CommutativeRing(x): return Spec(x) elif is_RingHomomorphism(x): A = Spec(x.codomain()) return A.hom(x) else: raise TypeError("No way to create an object or morphism in %s from %s"%(self, x))
def ProjectiveSpace(n, R=None, names='x'): r""" Return projective space of dimension `n` over the ring `R`. EXAMPLES: The dimension and ring can be given in either order. :: sage: ProjectiveSpace(3, QQ) Projective Space of dimension 3 over Rational Field sage: ProjectiveSpace(5, QQ) Projective Space of dimension 5 over Rational Field sage: P = ProjectiveSpace(2, QQ, names='XYZ'); P Projective Space of dimension 2 over Rational Field sage: P.coordinate_ring() Multivariate Polynomial Ring in X, Y, Z over Rational Field The divide operator does base extension. :: sage: ProjectiveSpace(5)/GF(17) Projective Space of dimension 5 over Finite Field of size 17 The default base ring is `\ZZ`. :: sage: ProjectiveSpace(5) Projective Space of dimension 5 over Integer Ring There is also an projective space associated each polynomial ring. :: sage: R = GF(7)['x,y,z'] sage: P = ProjectiveSpace(R); P Projective Space of dimension 2 over Finite Field of size 7 sage: P.coordinate_ring() Multivariate Polynomial Ring in x, y, z over Finite Field of size 7 sage: P.coordinate_ring() is R True :: sage: ProjectiveSpace(3, Zp(5), 'y') Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20 :: sage: ProjectiveSpace(2,QQ,'x,y,z') Projective Space of dimension 2 over Rational Field :: sage: PS.<x,y>=ProjectiveSpace(1,CC) sage: PS Projective Space of dimension 1 over Complex Field with 53 bits of precision Projective spaces are not cached, i.e., there can be several with the same base ring and dimension (to facilitate gluing constructions). """ if is_MPolynomialRing(n) and R is None: A = ProjectiveSpace(n.ngens()-1, n.base_ring()) A._coordinate_ring = n return A if isinstance(R, (int, long, Integer)): n, R = R, n if R is None: R = ZZ # default is the integers if R in _Fields: if is_FiniteField(R): return ProjectiveSpace_finite_field(n, R, names) if is_RationalField(R): return ProjectiveSpace_rational_field(n, R, names) else: return ProjectiveSpace_field(n, R, names) elif is_CommutativeRing(R): return ProjectiveSpace_ring(n, R, names) else: raise TypeError("R (=%s) must be a commutative ring"%R)