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 b  
    1616   sage/schemes/generic/ambient_space
    1717   sage/schemes/generic/affine_space
    1818   sage/schemes/generic/projective_space
    19    sage/schemes/generic/toric_variety
     19   sage/schemes/generic/toric_variety   
    2020   sage/schemes/generic/fano_toric_variety   
    2121   sage/schemes/generic/toric_variety_library
    2222   sage/schemes/generic/toric_divisor
    2323   sage/schemes/generic/toric_chow_group
    2424   sage/schemes/generic/toric_ideal
     25   sage/schemes/generic/toric_morphism
    2526   sage/schemes/generic/algebraic_scheme
    2627   sage/schemes/generic/hypersurface
    2728
    2829   sage/schemes/generic/homset
    2930   sage/schemes/generic/morphism
     31   sage/schemes/generic/toric_morphism
    3032   sage/schemes/generic/divisor
    3133
    3234   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 b  
    801801                                 "domain fan is not contained in a single "
    802802                                 "cone of the codomain fan!" % n)
    803803
    804     def codomain_fan(self):
     804    def codomain_fan(self, dim=None, codim=None):
    805805        r"""
    806806        Return the codomain fan of ``self``.
    807807       
     808        INPUT:
     809
     810        - ``dim`` -- dimension of the requested cones;
     811
     812        - ``codim`` -- codimension of the requested cones.
     813
    808814        OUTPUT:
    809815       
    810         - a :class:`fan <sage.geometry.fan.RationalPolyhedralFan>`.
     816        - :class:`rational polyhedral fan
     817          <sage.geometry.fan.RationalPolyhedralFan>` if no parameters were
     818          given, :class:`tuple` of :class:`cones
     819          <sage.geometry.cone.ConvexRationalPolyhedralCone>` otherwise.
    811820       
    812821        EXAMPLES::
    813822       
     
    820829            sage: fm.codomain_fan() is quadrant
    821830            True
    822831        """
    823         return self._codomain_fan
     832        return self._codomain_fan(dim=dim, codim=codim)
    824833
    825     def domain_fan(self):
     834    def domain_fan(self, dim=None, codim=None):
    826835        r"""
    827836        Return the codomain fan of ``self``.
    828837       
     838        INPUT:
     839
     840        - ``dim`` -- dimension of the requested cones;
     841
     842        - ``codim`` -- codimension of the requested cones.
     843
    829844        OUTPUT:
    830845       
    831         - a :class:`fan <sage.geometry.fan.RationalPolyhedralFan>`.
     846        - :class:`rational polyhedral fan
     847          <sage.geometry.fan.RationalPolyhedralFan>` if no parameters were
     848          given, :class:`tuple` of :class:`cones
     849          <sage.geometry.cone.ConvexRationalPolyhedralCone>` otherwise.
    832850       
    833851        EXAMPLES::
    834852       
     
    841859            sage: fm.domain_fan() is quadrant_bl
    842860            True
    843861        """
    844         return self._domain_fan
     862        return self._domain_fan(dim=dim, codim=codim)
    845863       
    846864    def image_cone(self, cone):
    847865        r"""
  • sage/schemes/generic/scheme.py

    diff --git a/sage/schemes/generic/scheme.py b/sage/schemes/generic/scheme.py
    a b  
    1818#                  http://www.gnu.org/licenses/
    1919#*******************************************************************************
    2020
     21from sage.misc.all import cached_method
    2122from sage.structure.parent import Parent
    2223from sage.misc.all import cached_method
    2324from 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
    - +  
     1r"""
     2Set of homomorphisms between two toric varieties.
     3
     4For schemes `X` and `Y`, this module implements the set of morphisms
     5`Hom(X,Y)`. This is done by :class:`SchemeHomset_generic`.
     6
     7As a special case, the hom sets can also represent the points of a
     8scheme. Recall that the `K`-rational points of a scheme `X` over `k`
     9can be identified with the set of morphisms `Spec(K) \to X`. In Sage,
     10the rational points are implemented by such scheme morphisms. This is
     11done by :class:`SchemeHomset_points` and its subclasses.
     12
     13.. note::
     14
     15    You should not create the homsets manually. Instead, use the
     16    :meth:`~sage.structure.parent.Hom` method that is inherited by all
     17    schemes.
     18"""
     19
     20from sage.rings.all import ZZ, is_RingHomomorphism
     21from sage.matrix.matrix import is_Matrix
     22from sage.matrix.matrix_space import MatrixSpace
     23from sage.geometry.fan_morphism import FanMorphism
     24
     25from sage.schemes.generic.homset import SchemeHomset_generic
     26
     27
     28class SchemeHomset_toric_variety(SchemeHomset_generic):
     29    """
     30    Set of homomorphisms between two toric varieties.
     31
     32    EXAMPLES::
     33
     34        sage: P1xP1 = toric_varieties.P1xP1()
     35        sage: P1 = toric_varieties.P1()
     36        sage: hom_set = P1xP1.Hom(P1);  hom_set
     37        Set of morphisms
     38         From: 2-d CPR-Fano toric variety covered by 4 affine patches
     39         To:   1-d CPR-Fano toric variety covered by 2 affine patches
     40        sage: type(hom_set)
     41        <class 'sage.schemes.generic.toric_homset.SchemeHomset_toric_variety_with_category'>
     42
     43        sage: hom_set(matrix([[1],[0]]))
     44        Scheme morphism:
     45          From: 2-d CPR-Fano toric variety covered by 4 affine patches
     46          To:   1-d CPR-Fano toric variety covered by 2 affine patches
     47          Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N
     48                to Rational polyhedral fan in 1-d lattice N.
     49    """
     50
     51    def __init__(self, X, Y, category=None, check=True, base=ZZ):
     52        SchemeHomset_generic.__init__(self, X, Y, category=category, check=check, base=base)
     53        self.register_conversion(MatrixSpace(ZZ, X.fan().dim(), Y.fan().dim()))
     54
     55    def _element_constructor_(self, x, check=True):
     56        """
     57        Construct a scheme morphism.
     58
     59        INPUT:
     60
     61        - `x` -- anything that defines a morphism of toric
     62          varieties. A matrix, fan morphism, or a list or tuple of
     63          homogeneous polynomials that define a morphism.
     64
     65        - ``check`` -- boolean (default: ``True``) passed onto
     66          functions called by this to be more careful about input
     67          argument type checking
     68
     69        OUTPUT:
     70
     71        The morphism of toric varieties determined by ``x``.
     72       
     73        EXAMPLES:
     74
     75        First, construct from fan morphism::
     76
     77            sage: dP8.<t,x0,x1,x2> = toric_varieties.dP8()
     78            sage: P2.<y0,y1,y2> = toric_varieties.P2()
     79            sage: Hom = dP8.Hom(P2)
     80
     81            sage: fm = FanMorphism(identity_matrix(2), dP8.fan(), P2.fan())
     82            sage: Hom(fm)
     83            Scheme morphism:
     84              From: 2-d CPR-Fano toric variety covered by 4 affine patches
     85              To:   2-d CPR-Fano toric variety covered by 3 affine patches
     86              Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N
     87                    to Rational polyhedral fan in 2-d lattice N.
     88
     89        A matrix will automatically be converted to a fan morphism::
     90
     91            sage: Hom(identity_matrix(2))
     92            Scheme morphism:
     93              From: 2-d CPR-Fano toric variety covered by 4 affine patches
     94              To:   2-d CPR-Fano toric variety covered by 3 affine patches
     95              Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N
     96                    to Rational polyhedral fan in 2-d lattice N.
     97
     98        Alternatively, one can use homogeneous polynomials to define morphisms::
     99
     100            sage: P2.inject_variables()
     101            Defining y0, y1, y2
     102            sage: dP8.inject_variables()
     103            Defining t, x0, x1, x2
     104            sage: Hom([x0,x1,x2])
     105            Scheme morphism:
     106              From: 2-d CPR-Fano toric variety covered by 4 affine patches
     107              To:   2-d CPR-Fano toric variety covered by 3 affine patches
     108              Defn: Defined on coordinates by sending [t : x0 : x1 : x2] to
     109                    [x0 : x1 : x2]
     110
     111        A morphism of the coordinate ring will also work::
     112
     113            sage: ring_hom = P2.coordinate_ring().hom([x0,x1,x2], dP8.coordinate_ring())
     114            sage: ring_hom
     115            Ring morphism:
     116              From: Multivariate Polynomial Ring in y0, y1, y2 over Rational Field
     117              To:   Multivariate Polynomial Ring in t, x0, x1, x2 over Rational Field
     118              Defn: y0 |--> x0
     119                    y1 |--> x1
     120                    y2 |--> x2
     121            sage: Hom(ring_hom)
     122            Scheme morphism:
     123              From: 2-d CPR-Fano toric variety covered by 4 affine patches
     124              To:   2-d CPR-Fano toric variety covered by 3 affine patches
     125              Defn: Defined on coordinates by sending [t : x0 : x1 : x2] to
     126                    [x0 : x1 : x2]
     127        """
     128        from sage.schemes.generic.toric_morphism import SchemeMorphism_polynomial_toric_variety
     129        if isinstance(x, (list, tuple)):
     130            return SchemeMorphism_polynomial_toric_variety(self, x, check=check)
     131       
     132        if is_RingHomomorphism(x):
     133            assert x.domain() is self.codomain().coordinate_ring()
     134            assert x.codomain() is self.domain().coordinate_ring()
     135            return SchemeMorphism_polynomial_toric_variety(self, x.im_gens(), check=check)
     136
     137        from sage.schemes.generic.toric_morphism import SchemeMorphism_fan_toric_variety
     138        if isinstance(x, FanMorphism):
     139            return SchemeMorphism_fan_toric_variety(self, x, check=check)
     140
     141        if is_Matrix(x):
     142            fm = FanMorphism(x, self.domain().fan(), self.codomain().fan())
     143            return SchemeMorphism_fan_toric_variety(self, fm, check=check)
     144       
     145        raise TypeError, "x must be a fan morphism or a list/tuple of polynomials"
     146
     147
     148
  • sage/schemes/generic/toric_morphism.py

    diff --git a/sage/schemes/generic/toric_morphism.py b/sage/schemes/generic/toric_morphism.py
    a b  
    1 """
     1r"""
    22Morphisms of Toric Varieties
    33
     4There are three "obvious" ways to map toric varieties to toric
     5varieties:
    46
     71. Polynomial maps in local coordinates, the usual morphisms in
     8   algebraic geometry.
     9
     102. Polynomial maps in the (global) homogeneous coordinates.
     11
     123. Toric morphisms, that is, algebraic morphisms equivariant with
     13   respect to the torus action on the toric variety.
     14
     15Both 2 and 3 are special cases of 1, which is just to say that we
     16always remain within the realm of algebraic geometry. But apart from
     17that, none is included in one of the other cases. In the examples
     18below, we will explore some algebraic maps that can or can not be
     19written as a toric morphism. Often a toric morphism can be written
     20with polynomial maps in homogeneous coordinates, but sometimes it
     21cannot.
     22
     23The toric morphisms are perhaps the most mysterious at the
     24beginning. Let us quickly review their definition (See Definition
     253.3.3 of [CLS]_). Let `\Sigma_1` a fan in `N_{1,\RR}` and `\Sigma_2` a
     26fan in `N_{2,\RR}`. A morphism `\phi: X_{\Sigma_1} \to X_{\Sigma_2}`
     27of the associated toric varieties is toric if `\phi` maps the maximal
     28torus `T_{N_1} \subseteq X_{\Sigma_1}` into `T_{N_2} \subseteq
     29X_{\Sigma_2}` and `\phi|_{T_N}` is a group homomorphism.
     30
     31The data defining a toric morphism is precisely what defines a fan
     32morphism (see :mod:`~sage.geometry.fan_morphism`), extending the more
     33familiar dictionary between toric varieties and fans. Toric geometry
     34is a functor from the category of fans and fan morphisms to the
     35category of toric varieties and toric morphisms.
     36
     37.. note::
     38
     39    Do not create the toric morphisms (or any morphism of schemes)
     40    directly from the the ``SchemeMorphism...`` classes. Instead, use the
     41    :meth:`~sage.schemes.generic.scheme.hom` method common to all
     42    algebraic schemes to create new homomorphisms.
     43
     44EXAMPLES:
     45
     46First, consider the following embedding of `\mathbb{P}^1` into
     47`\mathbb{P}^2` ::
     48
     49    sage: P2.<x,y,z> = toric_varieties.P2()
     50    sage: P1.<u,v> = toric_varieties.P1()
     51    sage: P1.hom([0,u^2+v^2,u*v], P2)
     52    Scheme morphism:
     53      From: 1-d CPR-Fano toric variety covered by 2 affine patches
     54      To:   2-d CPR-Fano toric variety covered by 3 affine patches
     55      Defn: Defined on coordinates by sending [u : v] to
     56            [0 : u^2 + v^2 : u*v]
     57
     58This is a well-defined morphism of algebraic varieties because
     59homogeneously rescaled points of `\mathbb{P}^1` map to the same point
     60in `\mathbb{P}^2` up to its homogeneous rescalings. It is not
     61equivariant with respect to the torus actions
     62
     63.. math::
     64
     65    \CC^\times \times \mathbb{P}^1,
     66    (\mu,[u:v]) \mapsto [u:\mu v]
     67    ,\quad
     68    \CC^\times \times \mathbb{P}^2,
     69    (\alpha,\beta,[x:y:z]) \mapsto [x:\alpha y:\beta z]
     70    ,
     71
     72though. Hence it is not a toric morphism. Clearly, the problem is that
     73the map in homogeneous coordinates contains summands that transform
     74differently under the torus action. However, this is not the only
     75difficulty. For example, consider ::
     76
     77    sage: phi = P1.hom([0,u,v], P2);  phi
     78    Scheme morphism:
     79      From: 1-d CPR-Fano toric variety covered by 2 affine patches
     80      To:   2-d CPR-Fano toric variety covered by 3 affine patches
     81      Defn: Defined on coordinates by sending [u : v] to
     82            [0 : u : v]
     83
     84This map is actually the embedding of the
     85:meth:`~sage.schemes.generic.toric_variety.ToricVariety_field.orbit_closure`
     86associated to one of the rays of the fan of `\mathbb{P}^2`. Now the
     87morphism is equivariant with respect to **some** map `\CC^\times \to
     88(\CC^\times)^2` of the maximal tori of `\mathbb{P}^1` and
     89`\mathbb{P}^2`. But this map of the maximal tori cannot be the same as
     90``phi`` defined above. Indeed, the image of ``phi`` completely misses
     91the maximal torus `T_{\mathbb{P}^2} = \{ [x:y:z] | x\not=0, y\not=0,
     92z\not=0 \}` of `\mathbb{P}^2`.
     93
     94Consider instead the following morphism of fans::
     95 
     96    sage: fm = FanMorphism( matrix(ZZ,[[1,0]]), P1.fan(), P2.fan() );  fm
     97    Fan morphism defined by the matrix
     98    [1 0]
     99    Domain fan: Rational polyhedral fan in 1-d lattice N
     100    Codomain fan: Rational polyhedral fan in 2-d lattice N
     101
     102which also defines a morphism of toric varieties::
     103
     104    sage: P1.hom(fm, P2)
     105    Scheme morphism:
     106      From: 1-d CPR-Fano toric variety covered by 2 affine patches
     107      To:   2-d CPR-Fano toric variety covered by 3 affine patches
     108      Defn: Defined by sending the Rational polyhedral fan in 1-d lattice N
     109            to Rational polyhedral fan in 2-d lattice N.
     110
     111The fan morphism map is equivalent to the polynomial map::
     112
     113    sage: _.as_polynomial_map()
     114    Scheme morphism:
     115      From: 1-d CPR-Fano toric variety covered by 2 affine patches
     116      To:   2-d CPR-Fano toric variety covered by 3 affine patches
     117      Defn: Defined on coordinates by sending [u : v] to
     118            [u : v : v]
     119
     120Finally, here is an example of a fan morphism that cannot be written
     121with homogeneous polynomials. Consider the blowup `O_{\mathbb{P}^1}(2)
     122\to \CC^2/\ZZ_2`. In terms of toric data, this blowup is::
     123           
     124    sage: A2_Z2 = toric_varieties.A2_Z2()
     125    sage: A2_Z2.fan().rays()
     126    (N(1, 0), N(1, 2))
     127    sage: O2_P1 = A2_Z2.resolve(new_rays=[(1,1)])
     128    sage: blowup = O2_P1.hom(identity_matrix(2), A2_Z2)
     129    sage: blowup.as_polynomial_map()
     130    Traceback (most recent call last):
     131    ...
     132    TypeError: The fan morphism cannot be written in homogeneous polynomials.
     133
     134If we denote the homogeneous coordinates of `O_{\mathbb{P}^1}(2)` by
     135`x`, `t`, `y` corresponding to the rays `(1,2)`, `(1,1)`, and `(1,0)`
     136then the blow-up map is [BB]_:
     137
     138.. math::
     139
     140    f: O_{\mathbb{P}^1}(2) \to \CC^2/\ZZ_2, \quad
     141    (x,t,y) \mapsto \left( x\sqrt{t}, y\sqrt{t} \right)
     142
     143which requires square roots.
     144
     145REFERENCES:
     146
     147.. [BB]
     148    Gavin Brown, Jaroslaw Buczynski:
     149    Maps of toric varieties in Cox coordinates,
     150    http://arxiv.org/abs/1004.4924
    5151"""
    6152
    7153
    8154#*****************************************************************************
    9 #  Copyright (C) 2010 Volker Braun <vbraun.name@gmail.com>
     155#  Copyright (C) 2011 Volker Braun <vbraun.name@gmail.com>
    10156#  Copyright (C) 2010 Andrey Novoseltsev <novoselt@gmail.com>
    11157#  Copyright (C) 2006 William Stein <wstein@gmail.com>
    12158#  Distributed under the terms of the GNU General Public License (GPL)
     
    14160#*****************************************************************************
    15161
    16162from sage.structure.sequence  import Sequence
     163from sage.rings.all import ZZ
    17164
    18 import scheme     
     165from sage.schemes.generic.scheme import is_Scheme     
    19166from sage.schemes.generic.morphism import (
    20167    is_SchemeMorphism,
    21     SchemeMorphism_point, SchemeMorphism_polynomial
     168    SchemeMorphism, SchemeMorphism_point, SchemeMorphism_polynomial
    22169)
    23170
    24171
    25172
     173############################################################################
     174# A points on a toric variety determined by homogeneous coordinates.
    26175class SchemeMorphism_point_toric_field(SchemeMorphism_point):
    27176    """
    28     Construct a morphism determined by giving coordinates in a field.
     177    A point of a toric variety determined by homogeneous coordinates
     178    in a field.
    29179
    30180    .. WARNING::
    31181
    32         You should not create objects of this class directly.
     182        You should not create objects of this class directly. Use the
     183        :meth:`~sage.schemes.generic.scheme.hom` method of
     184        :class:`toric varieties
     185        <sage.schemes.generic.toric_variety.ToricVariety_field>`
     186        instead.
    33187
    34188    INPUT:
    35189
    36     - ``X`` -- subscheme of a toric variety.
     190    - ``X`` -- toric variety or subscheme of a toric variety.
    37191
    38192    - ``coordinates`` -- list of coordinates in the base field of ``X``.
    39193
     
    42196
    43197    OUTPUT:
    44198
    45     - :class:`SchemeMorphism_point_toric_field`.
     199    A :class:`SchemeMorphism_point_toric_field`.
    46200
    47201    TESTS::
    48202
     
    64218            [1 : 2 : 3 : 4]
    65219        """
    66220        # Convert scheme to its set of points over the base ring
    67         if scheme.is_Scheme(X):
     221        if is_Scheme(X):
    68222            X = X(X.base_ring())
    69223        super(SchemeMorphism_point_toric_field, self).__init__(X)
    70224        if check:
     
    87241
    88242
    89243
     244############################################################################
     245# A morphism of toric varieties determined by homogeneous polynomials.
    90246class SchemeMorphism_polynomial_toric_variety(SchemeMorphism_polynomial):
    91247    """
    92     Construct a morphism determined by homogeneous polynomials.
     248    A morphism determined by homogeneous polynomials.
    93249
    94250    .. WARNING::
    95251
    96         You should not create objects of this class directly.
     252        You should not create objects of this class directly. Use the
     253        :meth:`~sage.schemes.generic.scheme.hom` method of
     254        :class:`toric varieties
     255        <sage.schemes.generic.toric_variety.ToricVariety_field>`
     256        instead.
    97257
    98258    INPUT:
    99259
    100     - same as for
    101       :class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial`.
     260    Same as for
     261    :class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial`.
    102262
    103263    OUPUT:
    104264
    105     - :class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety`.
     265    A :class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety`.
    106266
    107267    TESTS::
    108268
     
    152312            for p in self.defining_polynomials():
    153313                if not self.domain().ambient_space().is_homogeneous(p):
    154314                    raise ValueError("%s is not homogeneous!" % p)
     315               
     316    def as_fan_morphism(self):
     317        """
     318        Express the morphism as a map defined by a fan morphism.
    155319
     320        OUTPUT:
    156321
     322        A :class:`SchemeMorphism_polynomial_toric_variety`. Raises a
     323        ``TypeError`` if the morphism cannot be written in terms of
     324        homogeneous polynomials.
    157325
     326        EXAMPLES::
     327       
     328            sage: A1.<z> = toric_varieties.A1()
     329            sage: P1 = toric_varieties.P1()
     330            sage: patch = A1.hom([1,z], P1)
     331            sage: patch.as_fan_morphism()
     332            Traceback (most recent call last):
     333            ...
     334            NotImplementedError
     335        """
     336        raise NotImplementedError
     337
     338       
     339############################################################################
     340# A morphism of toric varieties determined by a fan morphism
     341class SchemeMorphism_fan_toric_variety(SchemeMorphism):
     342    """
     343    Construct a morphism determined by a fan morphism
     344
     345    .. WARNING::
     346
     347        You should not create objects of this class directly. Use the
     348        :meth:`~sage.schemes.generic.scheme.hom` method of
     349        :class:`toric varieties
     350        <sage.schemes.generic.toric_variety.ToricVariety_field>`
     351        instead.
     352
     353    INPUT:
     354
     355    - ``parent`` -- homset whose domain and codomain are toric varieties.
     356
     357    - ``fan_morphism`` -- A morphism of fans whose domain and codomain
     358      fans equal the fans of the domain and codomain in the ``parent``
     359      homset.
     360
     361    - ``check`` -- boolean (optional, default:``True``). Whether to
     362      check the input for consistency.
     363   
     364    OUPUT:
     365
     366    A :class:`~sage.schemes.generic.morphism.SchemeMorphism_fan_toric_variety`.
     367
     368    EXAMPLES::
     369
     370        sage: P2 = toric_varieties.P2()
     371        sage: dP8 = toric_varieties.dP8()
     372        sage: f = dP8.hom(identity_matrix(2), P2);  f
     373        Scheme morphism:
     374          From: 2-d CPR-Fano toric variety covered by 4 affine patches
     375          To:   2-d CPR-Fano toric variety covered by 3 affine patches
     376          Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N
     377                to Rational polyhedral fan in 2-d lattice N.
     378        sage: type(f)
     379        <class 'sage.schemes.generic.toric_morphism.SchemeMorphism_fan_toric_variety'>
     380
     381    Slightly more explicit construction::
     382
     383        sage: P1xP1 = toric_varieties.P1xP1()
     384        sage: P1 = toric_varieties.P1()
     385        sage: hom_set = P1xP1.Hom(P1)
     386        sage: fm = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() )
     387        sage: hom_set(fm)
     388        Scheme morphism:
     389          From: 2-d CPR-Fano toric variety covered by 4 affine patches
     390          To:   1-d CPR-Fano toric variety covered by 2 affine patches
     391          Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N
     392               to Rational polyhedral fan in 1-d lattice N.
     393           
     394        sage: P1xP1.hom(fm, P1)
     395        Scheme morphism:
     396          From: 2-d CPR-Fano toric variety covered by 4 affine patches
     397          To:   1-d CPR-Fano toric variety covered by 2 affine patches
     398          Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N
     399                to Rational polyhedral fan in 1-d lattice N.
     400    """
     401
     402    def __init__(self, parent, fan_morphism, check=True):
     403        r"""
     404        See :class:`SchemeMorphism_polynomial_toric_variety` for documentation.
     405
     406        TESTS::
     407
     408            sage: P1xP1 = toric_varieties.P1xP1()
     409            sage: P1 = toric_varieties.P1()
     410            sage: hom_set = P1xP1.Hom(P1)
     411            sage: fan_morphism = FanMorphism( matrix(ZZ,[[1],[0]]), P1xP1.fan(), P1.fan() )
     412            sage: from sage.schemes.generic.toric_morphism import SchemeMorphism_fan_toric_variety
     413            sage: SchemeMorphism_fan_toric_variety(hom_set, fan_morphism)
     414            Scheme morphism:
     415              From: 2-d CPR-Fano toric variety covered by 4 affine patches
     416              To:   1-d CPR-Fano toric variety covered by 2 affine patches
     417              Defn: Defined by sending the Rational polyhedral fan in 2-d lattice N
     418                    to Rational polyhedral fan in 1-d lattice N.
     419        """
     420        SchemeMorphism.__init__(self, parent)
     421        if check and self.domain().fan()!=fan_morphism.domain_fan():
     422            raise ValueError('The fan morphism domain must be the fan of the domain.')
     423        if check and self.codomain().fan()!=fan_morphism.codomain_fan():
     424            raise ValueError('The fan morphism codomain must be the fan of the codomain.')
     425        self._fan_morphism = fan_morphism
     426
     427    def _repr_defn(self):
     428        """
     429        Return a string representation of the definition of ``self``.
     430
     431        OUTPUT:
     432
     433        String.
     434
     435        EXAMPLES::
     436
     437            sage: P1xP1 = toric_varieties.P1xP1()
     438            sage: P1 = toric_varieties.P1()
     439            sage: f = P1xP1.hom(matrix([[1],[0]]), P1)
     440            sage: f._repr_defn()
     441            'Defined by sending the Rational polyhedral fan in 2-d lattice N to Rational polyhedral fan in 1-d lattice N.'
     442        """
     443        s  = 'Defined by sending the '
     444        s += str(self.domain().fan())
     445        s += ' to '
     446        s += str(self.codomain().fan())
     447        s += '.'
     448        return s
     449
     450    def fan_morphism(self):
     451        """
     452        Return the defining fan morphism.
     453
     454        OUTPUT:
     455
     456        A :class:`~sage.geometry.fan_morphism.FanMorphism`.
     457
     458        EXAMPLES::
     459
     460            sage: P1xP1 = toric_varieties.P1xP1()
     461            sage: P1 = toric_varieties.P1()
     462            sage: f = P1xP1.hom(matrix([[1],[0]]), P1)
     463            sage: f.fan_morphism()
     464            Fan morphism defined by the matrix
     465            [1]
     466            [0]
     467            Domain fan: Rational polyhedral fan in 2-d lattice N
     468            Codomain fan: Rational polyhedral fan in 1-d lattice N
     469        """
     470        return self._fan_morphism
     471
     472    def as_polynomial_map(self):
     473        """
     474        Express the morphism via homogeneous polynomials.
     475
     476        OUTPUT:
     477
     478        A :class:`SchemeMorphism_polynomial_toric_variety`. Raises a
     479        ``TypeError`` if the morphism cannot be written in terms of
     480        homogeneous polynomials.
     481       
     482        EXAMPLES::
     483
     484            sage: A1 = toric_varieties.A1()
     485            sage: square = A1.hom(matrix([[2]]), A1)
     486            sage: square.as_polynomial_map()
     487            Scheme endomorphism of 1-d affine toric variety
     488              Defn: Defined on coordinates by sending [z] to
     489                    [z^2]
     490
     491            sage: P1 = toric_varieties.P1()
     492            sage: patch = A1.hom(matrix([[1]]), P1)
     493            sage: patch.as_polynomial_map()
     494            Scheme morphism:
     495              From: 1-d affine toric variety
     496              To:   1-d CPR-Fano toric variety covered by 2 affine patches
     497              Defn: Defined on coordinates by sending [z] to
     498                    [z : 1]
     499        """
     500        R = self.domain().coordinate_ring()
     501        phi = self.fan_morphism()
     502        polys = [R.one()] * phi.codomain_fan().nrays()
     503        for rho, x in zip(phi.domain_fan(1), R.gens()):
     504            ray = rho.ray(0)
     505            sigma = phi.image_cone(rho)
     506            degrees = sigma.ray_matrix().solve_right(phi(ray))
     507            for i, d in zip(sigma.ambient_ray_indices(), degrees):
     508                try:
     509                    d = ZZ(d)
     510                except TypeError:
     511                    raise TypeError('The fan morphism cannot be written in homogeneous polynomials.')
     512                polys[i] *= x**d
     513        return SchemeMorphism_polynomial_toric_variety(self.parent(), polys)
     514
  • sage/schemes/generic/toric_variety.py

    diff --git a/sage/schemes/generic/toric_variety.py b/sage/schemes/generic/toric_variety.py
    a b  
    245245from sage.rings.quotient_ring import QuotientRing_generic
    246246from sage.schemes.generic.ambient_space import AmbientSpace
    247247from sage.schemes.generic.homset import SchemeHomset_points_toric_field
    248 from sage.schemes.generic.toric_morphism import (SchemeMorphism_polynomial_toric_variety,
    249                                                  SchemeMorphism_point_toric_field)
    250248
    251249
    252250
     
    706704            sage: P1xP1._point_class(P1xP1, [1,2,3,4])
    707705            [1 : 2 : 3 : 4]
    708706        """
     707        from sage.schemes.generic.toric_morphism import SchemeMorphism_point_toric_field
    709708        return SchemeMorphism_point_toric_field(*args, **kwds)
    710709
    711     def _morphism_class(self, *args, **kwds):
     710    def _homset_class(self, *args, **kwds):
    712711        r"""
    713         Construct a morphism determined by action on points of ``self``.
     712        Return the homset between two toric varieties.
    714713
    715714        INPUT:
    716715
    717         - same as for
    718           :class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety`.
    719 
    720         OUPUT:
    721 
    722         :class:`~sage.schemes.generic.morphism.SchemeMorphism_polynomial_toric_variety`.
    723 
    724         TESTS::
    725 
    726             sage: fan = FaceFan(lattice_polytope.octahedron(2))
    727             sage: P1xP1 = ToricVariety(fan)
    728             sage: P1xP1.inject_variables()
    729             Defining z0, z1, z2, z3
    730             sage: P1 = P1xP1.subscheme(z0-z2)
    731             sage: H = P1xP1.Hom(P1)
    732             sage: P1xP1._morphism_class(H, [z0,z1,z0,z3])
    733             Scheme morphism:
    734               From: 2-d toric variety covered by 4 affine patches
    735               To:   Closed subscheme of 2-d toric variety
    736               covered by 4 affine patches defined by:
    737               z0 - z2
    738               Defn: Defined on coordinates by sending
    739                     [z0 : z1 : z2 : z3] to [z0 : z1 : z0 : z3]
     716        Same as :class:`sage.schemes.generic.homset.SchemeHomset_generic`.
     717
     718        OUTPUT:
     719
     720        A :class:`sage.schemes.generic.toric_homset.SchemeHomset_toric_variety`.
     721
     722        EXAMPLES::
     723
     724            sage: P1xP1 = toric_varieties.P1xP1()
     725            sage: P1 = toric_varieties.P1()
     726            sage: hom_set = P1xP1.Hom(P1);  hom_set
     727            Set of morphisms
     728             From: 2-d CPR-Fano toric variety covered by 4 affine patches
     729             To:   1-d CPR-Fano toric variety covered by 2 affine patches
     730            sage: type(hom_set)
     731            <class 'sage.schemes.generic.toric_homset.SchemeHomset_toric_variety_with_category'>
    740732        """
    741         return SchemeMorphism_polynomial_toric_variety(*args, **kwds)
     733        from sage.schemes.generic.toric_homset import SchemeHomset_toric_variety
     734        return SchemeHomset_toric_variety(*args, **kwds)
    742735
    743736    def _repr_(self):
    744737        r"""
     
    960953            sage: P1xP1.coordinate_ring()
    961954            Multivariate Polynomial Ring in z0, z1, z2, z3
    962955            over Rational Field
     956
     957        TESTS::
     958
     959            sage: R = toric_varieties.A1().coordinate_ring();  R
     960            Multivariate Polynomial Ring in z over Rational Field
     961            sage: type(R)
     962            <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular'>
    963963        """
    964964        if "_coordinate_ring" not in self.__dict__:
    965             self._coordinate_ring = PolynomialRing(self.base_ring(),
    966                                                    self.variable_names())
     965            names = self.variable_names()
     966            self._coordinate_ring = PolynomialRing(self.base_ring(), len(names), names)
    967967        return self._coordinate_ring
    968968
    969969    def embedding_morphism(self):
     
    11481148            False
    11491149            sage: P1xP1.is_homogeneous(1)
    11501150            True
     1151
     1152        Note that by homogeneous, we mean well-defined with respect to
     1153        the homogeneous rescalings. So a polynomial that you would
     1154        usually not call homogeneous can be homogeneous if there are
     1155        no homogeneous rescalings, for example::
     1156
     1157            sage: A1.<z> = toric_varieties.A1()
     1158            sage: A1.is_homogeneous(z^3+z^7)
     1159            True
     1160
     1161        Finally, the degree group is really the Chow group
     1162        `A_{d-1}(X)` and can contain torsion. For example, take
     1163        `\CC^2/\ZZ_2`. Here, the Chow group is `A_{d-1}(\CC^2/\ZZ_2) =
     1164        \ZZ_2` and distinguishes even-degree homogeneous polynomials
     1165        from odd-degree homogeneous polynomials::
     1166
     1167            sage: A2_Z2.<x,y> = toric_varieties.A2_Z2()
     1168            sage: A2_Z2.is_homogeneous(x+y+x^3+y^5+x^3*y^4)
     1169            True
     1170            sage: A2_Z2.is_homogeneous(x^2+x*y+y^4+(x*y)^5+x^4*y^4)
     1171            True
     1172            sage: A2_Z2.is_homogeneous(x+y^2)
     1173            False
    11511174        """
    1152         if "_relation_matrix" not in self.__dict__:
    1153             m = self.fan().ray_matrix().transpose().kernel().matrix()
    1154             # We ignore degrees of torus factor coordinates
    1155             m = m.augment(matrix(m.nrows(), self._torus_factor_dim))
    1156             self._relation_matrix = m
    1157         relation_matrix = self._relation_matrix
     1175        if '_homogeneous_degrees_group' not in self.__dict__:
     1176            fan = self.fan()
     1177            from sage.modules.free_module import FreeModule
     1178            degrees_group = FreeModule(ZZ, fan.nrays()).quotient(fan.ray_matrix().rows())
     1179            self._homogeneous_degrees_group = degrees_group
     1180        degrees_group = self._homogeneous_degrees_group
    11581181        S = self.coordinate_ring()
    11591182        try:
    11601183            polynomial = S(polynomial)
     
    11641187        monomials = polynomial.monomials()
    11651188        if not monomials:
    11661189            return True
    1167         degree = relation_matrix * vector(monomials[0].degrees())
     1190        degree = degrees_group(vector(ZZ,monomials[0].degrees()))
    11681191        for monomial in monomials:
    1169             if relation_matrix * vector(monomial.degrees()) != degree:
     1192            if degrees_group(vector(ZZ,monomial.degrees())) != degree:
    11701193                return False
    11711194        return True
    11721195