# Ticket #11599: trac_11599_toric_morphisms.patch

File trac_11599_toric_morphisms.patch, 33.0 KB (added by vbraun, 10 years ago)

Rebased patch

• ## doc/en/reference/schemes.rst

# HG changeset patch
# User Volker Braun <vbraun@stp.dias.ie>
# Date 1324030523 0
# Node ID e7ba730205c8583ed16ec3b31c56971757fa7f09
# Parent  e916c959ea369542d797bfee73b133cabf13d60c
Trac #11599: Toric morphisms

Implement the toric morphism classes and conversion from a fan morphism
to a morphism defined by homogeneous polynomials.

diff --git a/doc/en/reference/schemes.rst b/doc/en/reference/schemes.rst
 a sage/schemes/generic/ambient_space sage/schemes/generic/affine_space sage/schemes/generic/projective_space sage/schemes/generic/toric_variety sage/schemes/generic/toric_variety sage/schemes/generic/fano_toric_variety sage/schemes/generic/toric_variety_library sage/schemes/generic/toric_divisor sage/schemes/generic/toric_chow_group sage/schemes/generic/toric_ideal sage/schemes/generic/toric_morphism sage/schemes/generic/algebraic_scheme sage/schemes/generic/hypersurface sage/schemes/generic/homset sage/schemes/generic/morphism sage/schemes/generic/toric_morphism sage/schemes/generic/divisor sage/schemes/generic/rational_point
• ## sage/geometry/fan_morphism.py

diff --git a/sage/geometry/fan_morphism.py b/sage/geometry/fan_morphism.py
 a "domain fan is not contained in a single " "cone of the codomain fan!" % n) def codomain_fan(self): def codomain_fan(self, dim=None, codim=None): r""" Return the codomain fan of self. INPUT: - dim -- dimension of the requested cones; - codim -- codimension of the requested cones. OUTPUT: - a :class:fan . - :class:rational polyhedral fan  if no parameters were given, :class:tuple of :class:cones  otherwise. EXAMPLES:: sage: fm.codomain_fan() is quadrant True """ return self._codomain_fan return self._codomain_fan(dim=dim, codim=codim) def domain_fan(self): def domain_fan(self, dim=None, codim=None): r""" Return the codomain fan of self. INPUT: - dim -- dimension of the requested cones; - codim -- codimension of the requested cones. OUTPUT: - a :class:fan . - :class:rational polyhedral fan  if no parameters were given, :class:tuple of :class:cones  otherwise. EXAMPLES:: sage: fm.domain_fan() is quadrant_bl True """ return self._domain_fan return self._domain_fan(dim=dim, codim=codim) def image_cone(self, cone): r"""
• ## sage/schemes/generic/scheme.py

diff --git a/sage/schemes/generic/scheme.py b/sage/schemes/generic/scheme.py
 a #                  http://www.gnu.org/licenses/ #******************************************************************************* from sage.misc.all import cached_method from sage.structure.parent import Parent from sage.misc.all import cached_method from sage.rings.all import (IntegerRing, is_CommutativeRing,
• ## new file sage/schemes/generic/toric_homset.py

diff --git a/sage/schemes/generic/toric_homset.py b/sage/schemes/generic/toric_homset.py
new file mode 100644
 - r""" Set of homomorphisms between two toric varieties. For schemes X and Y, this module implements the set of morphisms Hom(X,Y). This is done by :class:SchemeHomset_generic. As a special case, the hom sets can also represent the points of a scheme. Recall that the K-rational points of a scheme X over k can be identified with the set of morphisms Spec(K) \to X. In Sage, the rational points are implemented by such scheme morphisms. This is done by :class:SchemeHomset_points and its subclasses. .. note:: You should not create the homsets manually. Instead, use the :meth:~sage.structure.parent.Hom method that is inherited by all schemes. """ from sage.rings.all import ZZ, is_RingHomomorphism from sage.matrix.matrix import is_Matrix from sage.matrix.matrix_space import MatrixSpace from sage.geometry.fan_morphism import FanMorphism from sage.schemes.generic.homset import SchemeHomset_generic class SchemeHomset_toric_variety(SchemeHomset_generic): """ Set of homomorphisms between two toric varieties. EXAMPLES:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() sage: hom_set = P1xP1.Hom(P1);  hom_set Set of morphisms From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   1-d CPR-Fano toric variety covered by 2 affine patches sage: type(hom_set) sage: hom_set(matrix([[1],[0]])) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   1-d CPR-Fano toric variety covered by 2 affine patches Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 1-d lattice N. """ def __init__(self, X, Y, category=None, check=True, base=ZZ): SchemeHomset_generic.__init__(self, X, Y, category=category, check=check, base=base) self.register_conversion(MatrixSpace(ZZ, X.fan().dim(), Y.fan().dim())) def _element_constructor_(self, x, check=True): """ Construct a scheme morphism. INPUT: - x -- anything that defines a morphism of toric varieties. A matrix, fan morphism, or a list or tuple of homogeneous polynomials that define a morphism. - check -- boolean (default: True) passed onto functions called by this to be more careful about input argument type checking OUTPUT: The morphism of toric varieties determined by x. EXAMPLES: First, construct from fan morphism:: sage: dP8. = toric_varieties.dP8() sage: P2. = toric_varieties.P2() sage: Hom = dP8.Hom(P2) sage: fm = FanMorphism(identity_matrix(2), dP8.fan(), P2.fan()) sage: Hom(fm) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 2-d lattice N. A matrix will automatically be converted to a fan morphism:: sage: Hom(identity_matrix(2)) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 2-d lattice N. Alternatively, one can use homogeneous polynomials to define morphisms:: sage: P2.inject_variables() Defining y0, y1, y2 sage: dP8.inject_variables() Defining t, x0, x1, x2 sage: Hom([x0,x1,x2]) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined on coordinates by sending [t : x0 : x1 : x2] to [x0 : x1 : x2] A morphism of the coordinate ring will also work:: sage: ring_hom = P2.coordinate_ring().hom([x0,x1,x2], dP8.coordinate_ring()) sage: ring_hom Ring morphism: From: Multivariate Polynomial Ring in y0, y1, y2 over Rational Field To:   Multivariate Polynomial Ring in t, x0, x1, x2 over Rational Field Defn: y0 |--> x0 y1 |--> x1 y2 |--> x2 sage: Hom(ring_hom) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined on coordinates by sending [t : x0 : x1 : x2] to [x0 : x1 : x2] """ from sage.schemes.generic.toric_morphism import SchemeMorphism_polynomial_toric_variety if isinstance(x, (list, tuple)): return SchemeMorphism_polynomial_toric_variety(self, x, check=check) if is_RingHomomorphism(x): assert x.domain() is self.codomain().coordinate_ring() assert x.codomain() is self.domain().coordinate_ring() return SchemeMorphism_polynomial_toric_variety(self, x.im_gens(), check=check) from sage.schemes.generic.toric_morphism import SchemeMorphism_fan_toric_variety if isinstance(x, FanMorphism): return SchemeMorphism_fan_toric_variety(self, x, check=check) if is_Matrix(x): fm = FanMorphism(x, self.domain().fan(), self.codomain().fan()) return SchemeMorphism_fan_toric_variety(self, fm, check=check) raise TypeError, "x must be a fan morphism or a list/tuple of polynomials"
• ## sage/schemes/generic/toric_morphism.py

diff --git a/sage/schemes/generic/toric_morphism.py b/sage/schemes/generic/toric_morphism.py
 a """ r""" Morphisms of Toric Varieties There are three "obvious" ways to map toric varieties to toric varieties: 1. Polynomial maps in local coordinates, the usual morphisms in algebraic geometry. 2. Polynomial maps in the (global) homogeneous coordinates. 3. Toric morphisms, that is, algebraic morphisms equivariant with respect to the torus action on the toric variety. Both 2 and 3 are special cases of 1, which is just to say that we always remain within the realm of algebraic geometry. But apart from that, none is included in one of the other cases. In the examples below, we will explore some algebraic maps that can or can not be written as a toric morphism. Often a toric morphism can be written with polynomial maps in homogeneous coordinates, but sometimes it cannot. The toric morphisms are perhaps the most mysterious at the beginning. Let us quickly review their definition (See Definition 3.3.3 of [CLS]_). Let \Sigma_1 a fan in N_{1,\RR} and \Sigma_2 a fan in N_{2,\RR}. A morphism \phi: X_{\Sigma_1} \to X_{\Sigma_2} of the associated toric varieties is toric if \phi maps the maximal torus T_{N_1} \subseteq X_{\Sigma_1} into T_{N_2} \subseteq X_{\Sigma_2} and \phi|_{T_N} is a group homomorphism. The data defining a toric morphism is precisely what defines a fan morphism (see :mod:~sage.geometry.fan_morphism), extending the more familiar dictionary between toric varieties and fans. Toric geometry is a functor from the category of fans and fan morphisms to the category of toric varieties and toric morphisms. .. note:: Do not create the toric morphisms (or any morphism of schemes) directly from the the SchemeMorphism... classes. Instead, use the :meth:~sage.schemes.generic.scheme.hom method common to all algebraic schemes to create new homomorphisms. EXAMPLES: First, consider the following embedding of \mathbb{P}^1 into \mathbb{P}^2 :: sage: P2. = toric_varieties.P2() sage: P1. = toric_varieties.P1() sage: P1.hom([0,u^2+v^2,u*v], P2) Scheme morphism: From: 1-d CPR-Fano toric variety covered by 2 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined on coordinates by sending [u : v] to [0 : u^2 + v^2 : u*v] This is a well-defined morphism of algebraic varieties because homogeneously rescaled points of \mathbb{P}^1 map to the same point in \mathbb{P}^2 up to its homogeneous rescalings. It is not equivariant with respect to the torus actions .. math:: \CC^\times \times \mathbb{P}^1, (\mu,[u:v]) \mapsto [u:\mu v] ,\quad \CC^\times \times \mathbb{P}^2, (\alpha,\beta,[x:y:z]) \mapsto [x:\alpha y:\beta z] , though. Hence it is not a toric morphism. Clearly, the problem is that the map in homogeneous coordinates contains summands that transform differently under the torus action. However, this is not the only difficulty. For example, consider :: sage: phi = P1.hom([0,u,v], P2);  phi Scheme morphism: From: 1-d CPR-Fano toric variety covered by 2 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined on coordinates by sending [u : v] to [0 : u : v] This map is actually the embedding of the :meth:~sage.schemes.generic.toric_variety.ToricVariety_field.orbit_closure associated to one of the rays of the fan of \mathbb{P}^2. Now the morphism is equivariant with respect to **some** map \CC^\times \to (\CC^\times)^2 of the maximal tori of \mathbb{P}^1 and \mathbb{P}^2. But this map of the maximal tori cannot be the same as phi defined above. Indeed, the image of phi completely misses the maximal torus T_{\mathbb{P}^2} = \{ [x:y:z] | x\not=0, y\not=0, z\not=0 \} of \mathbb{P}^2. Consider instead the following morphism of fans:: sage: fm = FanMorphism( matrix(ZZ,[[1,0]]), P1.fan(), P2.fan() );  fm Fan morphism defined by the matrix [1 0] Domain fan: Rational polyhedral fan in 1-d lattice N Codomain fan: Rational polyhedral fan in 2-d lattice N which also defines a morphism of toric varieties:: sage: P1.hom(fm, P2) Scheme morphism: From: 1-d CPR-Fano toric variety covered by 2 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined by sending the Rational polyhedral fan in 1-d lattice N to Rational polyhedral fan in 2-d lattice N. The fan morphism map is equivalent to the polynomial map:: sage: _.as_polynomial_map() Scheme morphism: From: 1-d CPR-Fano toric variety covered by 2 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined on coordinates by sending [u : v] to [u : v : v] Finally, here is an example of a fan morphism that cannot be written with homogeneous polynomials. Consider the blowup O_{\mathbb{P}^1}(2) \to \CC^2/\ZZ_2. In terms of toric data, this blowup is:: sage: A2_Z2 = toric_varieties.A2_Z2() sage: A2_Z2.fan().rays() (N(1, 0), N(1, 2)) sage: O2_P1 = A2_Z2.resolve(new_rays=[(1,1)]) sage: blowup = O2_P1.hom(identity_matrix(2), A2_Z2) sage: blowup.as_polynomial_map() Traceback (most recent call last): ... TypeError: The fan morphism cannot be written in homogeneous polynomials. If we denote the homogeneous coordinates of O_{\mathbb{P}^1}(2) by x, t, y corresponding to the rays (1,2), (1,1), and (1,0) then the blow-up map is [BB]_: .. math:: f: O_{\mathbb{P}^1}(2) \to \CC^2/\ZZ_2, \quad (x,t,y) \mapsto \left( x\sqrt{t}, y\sqrt{t} \right) which requires square roots. REFERENCES: .. [BB] Gavin Brown, Jaroslaw Buczynski: Maps of toric varieties in Cox coordinates, http://arxiv.org/abs/1004.4924 """ #***************************************************************************** #  Copyright (C) 2010 Volker Braun #  Copyright (C) 2011 Volker Braun #  Copyright (C) 2010 Andrey Novoseltsev #  Copyright (C) 2006 William Stein #  Distributed under the terms of the GNU General Public License (GPL) #***************************************************************************** from sage.structure.sequence  import Sequence from sage.rings.all import ZZ import scheme from sage.schemes.generic.scheme import is_Scheme from sage.schemes.generic.morphism import ( is_SchemeMorphism, SchemeMorphism_point, SchemeMorphism_polynomial SchemeMorphism, SchemeMorphism_point, SchemeMorphism_polynomial ) ############################################################################ # A points on a toric variety determined by homogeneous coordinates. class SchemeMorphism_point_toric_field(SchemeMorphism_point): """ Construct a morphism determined by giving coordinates in a field. A point of a toric variety determined by homogeneous coordinates in a field. .. WARNING:: You should not create objects of this class directly. You should not create objects of this class directly. Use the :meth:~sage.schemes.generic.scheme.hom method of :class:toric varieties  instead. INPUT: - X -- subscheme of a toric variety. - X -- toric variety or subscheme of a toric variety. - coordinates -- list of coordinates in the base field of X. OUTPUT: - :class:SchemeMorphism_point_toric_field. A :class:SchemeMorphism_point_toric_field. TESTS:: [1 : 2 : 3 : 4] """ # Convert scheme to its set of points over the base ring if scheme.is_Scheme(X): if is_Scheme(X): X = X(X.base_ring()) super(SchemeMorphism_point_toric_field, self).__init__(X) if check: ############################################################################ # A morphism of toric varieties determined by homogeneous polynomials. class SchemeMorphism_polynomial_toric_variety(SchemeMorphism_polynomial): """ Construct a morphism determined by homogeneous polynomials. A morphism determined by homogeneous polynomials. .. WARNING:: You should not create objects of this class directly. You should not create objects of this class directly. Use the :meth:~sage.schemes.generic.scheme.hom method of :class:toric varieties  instead. INPUT: - same as for :class:~sage.schemes.generic.morphism.SchemeMorphism_polynomial. Same as for :class:~sage.schemes.generic.morphism.SchemeMorphism_polynomial. OUPUT: - :class:~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety. A :class:~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety. TESTS:: for p in self.defining_polynomials(): if not self.domain().ambient_space().is_homogeneous(p): raise ValueError("%s is not homogeneous!" % p) def as_fan_morphism(self): """ Express the morphism as a map defined by a fan morphism. OUTPUT: A :class:SchemeMorphism_polynomial_toric_variety. Raises a TypeError if the morphism cannot be written in terms of homogeneous polynomials. EXAMPLES:: sage: A1. = toric_varieties.A1() sage: P1 = toric_varieties.P1() sage: patch = A1.hom([1,z], P1) sage: patch.as_fan_morphism() Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError ############################################################################ # A morphism of toric varieties determined by a fan morphism class SchemeMorphism_fan_toric_variety(SchemeMorphism): """ Construct a morphism determined by a fan morphism .. WARNING:: You should not create objects of this class directly. Use the :meth:~sage.schemes.generic.scheme.hom method of :class:toric varieties  instead. INPUT: - parent -- homset whose domain and codomain are toric varieties. - fan_morphism -- A morphism of fans whose domain and codomain fans equal the fans of the domain and codomain in the parent homset. - check -- boolean (optional, default:True). Whether to check the input for consistency. OUPUT: A :class:~sage.schemes.generic.morphism.SchemeMorphism_fan_toric_variety. EXAMPLES:: sage: P2 = toric_varieties.P2() sage: dP8 = toric_varieties.dP8() sage: f = dP8.hom(identity_matrix(2), P2);  f Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   2-d CPR-Fano toric variety covered by 3 affine patches Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 2-d lattice N. sage: type(f) Slightly more explicit construction:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() sage: hom_set = P1xP1.Hom(P1) sage: fm = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() ) sage: hom_set(fm) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   1-d CPR-Fano toric variety covered by 2 affine patches Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 1-d lattice N. sage: P1xP1.hom(fm, P1) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   1-d CPR-Fano toric variety covered by 2 affine patches Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 1-d lattice N. """ def __init__(self, parent, fan_morphism, check=True): r""" See :class:SchemeMorphism_polynomial_toric_variety for documentation. TESTS:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() sage: hom_set = P1xP1.Hom(P1) sage: fan_morphism = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() ) sage: from sage.schemes.generic.toric_morphism import SchemeMorphism_fan_toric_variety sage: SchemeMorphism_fan_toric_variety(hom_set, fan_morphism) Scheme morphism: From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   1-d CPR-Fano toric variety covered by 2 affine patches Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 1-d lattice N. """ SchemeMorphism.__init__(self, parent) if check and self.domain().fan()!=fan_morphism.domain_fan(): raise ValueError('The fan morphism domain must be the fan of the domain.') if check and self.codomain().fan()!=fan_morphism.codomain_fan(): raise ValueError('The fan morphism codomain must be the fan of the codomain.') self._fan_morphism = fan_morphism def _repr_defn(self): """ Return a string representation of the definition of self. OUTPUT: String. EXAMPLES:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() sage: f = P1xP1.hom(matrix([[1],[0]]), P1) sage: f._repr_defn() 'Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 1-d lattice N.' """ s  = 'Defined by sending the ' s += str(self.domain().fan()) s += ' to ' s += str(self.codomain().fan()) s += '.' return s def fan_morphism(self): """ Return the defining fan morphism. OUTPUT: A :class:~sage.geometry.fan_morphism.FanMorphism. EXAMPLES:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() sage: f = P1xP1.hom(matrix([[1],[0]]), P1) sage: f.fan_morphism() Fan morphism defined by the matrix [1] [0] Domain fan: Rational polyhedral fan in 2-d lattice N Codomain fan: Rational polyhedral fan in 1-d lattice N """ return self._fan_morphism def as_polynomial_map(self): """ Express the morphism via homogeneous polynomials. OUTPUT: A :class:SchemeMorphism_polynomial_toric_variety. Raises a TypeError if the morphism cannot be written in terms of homogeneous polynomials. EXAMPLES:: sage: A1 = toric_varieties.A1() sage: square = A1.hom(matrix([[2]]), A1) sage: square.as_polynomial_map() Scheme endomorphism of 1-d affine toric variety Defn: Defined on coordinates by sending [z] to [z^2] sage: P1 = toric_varieties.P1() sage: patch = A1.hom(matrix([[1]]), P1) sage: patch.as_polynomial_map() Scheme morphism: From: 1-d affine toric variety To:   1-d CPR-Fano toric variety covered by 2 affine patches Defn: Defined on coordinates by sending [z] to [z : 1] """ R = self.domain().coordinate_ring() phi = self.fan_morphism() polys = [R.one()] * phi.codomain_fan().nrays() for rho, x in zip(phi.domain_fan(1), R.gens()): ray = rho.ray(0) sigma = phi.image_cone(rho) degrees = sigma.ray_matrix().solve_right(phi(ray)) for i, d in zip(sigma.ambient_ray_indices(), degrees): try: d = ZZ(d) except TypeError: raise TypeError('The fan morphism cannot be written in homogeneous polynomials.') polys[i] *= x**d return SchemeMorphism_polynomial_toric_variety(self.parent(), polys)
• ## sage/schemes/generic/toric_variety.py

diff --git a/sage/schemes/generic/toric_variety.py b/sage/schemes/generic/toric_variety.py
 a from sage.rings.quotient_ring import QuotientRing_generic from sage.schemes.generic.ambient_space import AmbientSpace from sage.schemes.generic.homset import SchemeHomset_points_toric_field from sage.schemes.generic.toric_morphism import (SchemeMorphism_polynomial_toric_variety, SchemeMorphism_point_toric_field) sage: P1xP1._point_class(P1xP1, [1,2,3,4]) [1 : 2 : 3 : 4] """ from sage.schemes.generic.toric_morphism import SchemeMorphism_point_toric_field return SchemeMorphism_point_toric_field(*args, **kwds) def _morphism_class(self, *args, **kwds): def _homset_class(self, *args, **kwds): r""" Construct a morphism determined by action on points of self. Return the homset between two toric varieties. INPUT: - same as for :class:~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety. OUPUT: :class:~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety. TESTS:: sage: fan = FaceFan(lattice_polytope.octahedron(2)) sage: P1xP1 = ToricVariety(fan) sage: P1xP1.inject_variables() Defining z0, z1, z2, z3 sage: P1 = P1xP1.subscheme(z0-z2) sage: H = P1xP1.Hom(P1) sage: P1xP1._morphism_class(H, [z0,z1,z0,z3]) Scheme morphism: From: 2-d toric variety covered by 4 affine patches To:   Closed subscheme of 2-d toric variety covered by 4 affine patches defined by: z0 - z2 Defn: Defined on coordinates by sending [z0 : z1 : z2 : z3] to [z0 : z1 : z0 : z3] Same as :class:sage.schemes.generic.homset.SchemeHomset_generic. OUTPUT: A :class:sage.schemes.generic.toric_homset.SchemeHomset_toric_variety. EXAMPLES:: sage: P1xP1 = toric_varieties.P1xP1() sage: P1 = toric_varieties.P1() sage: hom_set = P1xP1.Hom(P1);  hom_set Set of morphisms From: 2-d CPR-Fano toric variety covered by 4 affine patches To:   1-d CPR-Fano toric variety covered by 2 affine patches sage: type(hom_set) """ return SchemeMorphism_polynomial_toric_variety(*args, **kwds) from sage.schemes.generic.toric_homset import SchemeHomset_toric_variety return SchemeHomset_toric_variety(*args, **kwds) def _repr_(self): r""" sage: P1xP1.coordinate_ring() Multivariate Polynomial Ring in z0, z1, z2, z3 over Rational Field TESTS:: sage: R = toric_varieties.A1().coordinate_ring();  R Multivariate Polynomial Ring in z over Rational Field sage: type(R) """ if "_coordinate_ring" not in self.__dict__: self._coordinate_ring = PolynomialRing(self.base_ring(), self.variable_names()) names = self.variable_names() self._coordinate_ring = PolynomialRing(self.base_ring(), len(names), names) return self._coordinate_ring def embedding_morphism(self): False sage: P1xP1.is_homogeneous(1) True Note that by homogeneous, we mean well-defined with respect to the homogeneous rescalings. So a polynomial that you would usually not call homogeneous can be homogeneous if there are no homogeneous rescalings, for example:: sage: A1. = toric_varieties.A1() sage: A1.is_homogeneous(z^3+z^7) True Finally, the degree group is really the Chow group A_{d-1}(X) and can contain torsion. For example, take \CC^2/\ZZ_2. Here, the Chow group is A_{d-1}(\CC^2/\ZZ_2) = \ZZ_2 and distinguishes even-degree homogeneous polynomials from odd-degree homogeneous polynomials:: sage: A2_Z2. = toric_varieties.A2_Z2() sage: A2_Z2.is_homogeneous(x+y+x^3+y^5+x^3*y^4) True sage: A2_Z2.is_homogeneous(x^2+x*y+y^4+(x*y)^5+x^4*y^4) True sage: A2_Z2.is_homogeneous(x+y^2) False """ if "_relation_matrix" not in self.__dict__: m = self.fan().ray_matrix().transpose().kernel().matrix() # We ignore degrees of torus factor coordinates m = m.augment(matrix(m.nrows(), self._torus_factor_dim)) self._relation_matrix = m relation_matrix = self._relation_matrix if '_homogeneous_degrees_group' not in self.__dict__: fan = self.fan() from sage.modules.free_module import FreeModule degrees_group = FreeModule(ZZ, fan.nrays()).quotient(fan.ray_matrix().rows()) self._homogeneous_degrees_group = degrees_group degrees_group = self._homogeneous_degrees_group S = self.coordinate_ring() try: polynomial = S(polynomial) monomials = polynomial.monomials() if not monomials: return True degree = relation_matrix * vector(monomials[0].degrees()) degree = degrees_group(vector(ZZ,monomials[0].degrees())) for monomial in monomials: if relation_matrix * vector(monomial.degrees()) != degree: if degrees_group(vector(ZZ,monomial.degrees())) != degree: return False return True