Ticket #14353: trac_14353_factor_fan_morphism.patch

File trac_14353_factor_fan_morphism.patch, 9.1 KB (added by vbraun, 9 years ago)

Updated patch

  • sage/geometry/fan_morphism.py

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1364372448 -3600
    # Node ID 8bb4a76722f0f8ede78e8d6545ceb9f12ef7197e
    # Parent  13fa8bc25c89ba70c1cfd61643c39a529fd91d6f
    Factor a toric morphism into a surjective and generically injective morphism
    
    diff --git a/sage/geometry/fan_morphism.py b/sage/geometry/fan_morphism.py
    a b  
    16861686                                        for cone in self.codomain_fan()),
    16871687                    lattice=L, check=False)
    16881688        return FanMorphism(m, self.domain_fan(), Sigma)
     1689
     1690    def factor(self):
     1691        r"""
     1692        Factor the fan morphism into a surjection and a generically
     1693        injective map.
     1694
     1695        OUTPUT:
     1696
     1697        Starting with a fan morphism $f$, this method returns a pair
     1698        $(f_1, f_2)$ of fan morphisms such that
     1699
     1700        * $f = f_1 \circ f_2$,
     1701
     1702        * $f_2$ is surjective, and
     1703
     1704        * $f_1$ is injective at a generic point of the domain (in
     1705          particular, on the maximal torus).
     1706
     1707        The intermediate fan (that is, the codomain fan of $f_1$) is
     1708        the image of the support of the domain fan (which is a cone)
     1709        intersected with the codomain fan of $f$, see
     1710        :meth:`~sage.geometry.fan.RationalPolyhedralFan.intersection`. The
     1711        map $f_2$ is the embedding of this intersection in the whole
     1712        codomain fan of $f$.
     1713
     1714        EXAMPLES::
     1715
     1716            sage: N = ToricLattice(3)
     1717            sage: n1 = N( 1,1,1)
     1718            sage: n2 = N( 0,1,1)
     1719            sage: n3 = N(-1,1,1)
     1720            sage: domain_fan = Fan([Cone([n1,n2]), Cone([n2,n3])])
     1721            sage: m = matrix([[0,1,3], [0,1,3]]).transpose()
     1722            sage: image_fan = Fan([Cone([(1,0), (0,1)])])
     1723            sage: fm = FanMorphism(m, domain_fan, image_fan)
     1724            sage: fm1, fm2 = fm.factor()
     1725
     1726            sage: fm2.is_surjective()
     1727            True
     1728            sage: fm1.is_injective()
     1729            True
     1730            sage: fm1 * fm2 == fm
     1731            True
     1732            sage: fm2.matrix() * fm1.matrix() == m
     1733            True
     1734
     1735            sage: fm.domain_fan() is fm2.domain_fan()
     1736            True
     1737            sage: fm.codomain_fan() is fm1.codomain_fan()                 
     1738            True
     1739            sage: fm2.codomain_fan() is fm1.domain_fan()
     1740            True
     1741
     1742        The second map need not be injective everywhere, for example
     1743        here ``fm1`` is injective on the maximal torus but not on the
     1744        divisor $z_1=0$ ::
     1745
     1746            sage: BlC2_patch = ToricVariety(Fan([Cone([(1,0),(1,1)])]))
     1747            sage: C2 = toric_varieties.A2()
     1748            sage: f = BlC2_patch.hom(identity_matrix(2), C2)
     1749            sage: fm1, fm2 = f.fan_morphism().factor()
     1750            sage: fm2.is_surjective()
     1751            True
     1752            sage: fm1.is_injective()
     1753            False
     1754            sage: f.as_polynomial_map()
     1755            Scheme morphism:
     1756              From: 2-d affine toric variety
     1757              To:   2-d affine toric variety
     1758              Defn: Defined on coordinates by sending [z0 : z1] to
     1759                    [z0*z1 : z1]
     1760        """
     1761        fan1 = self.domain_fan()
     1762        fan2 = self.codomain_fan()
     1763        # Construct fan1 --fm1--> fan ---fm2--> fan2
     1764        D, U, V = self.matrix().smith_form()
     1765        Vinv = V.inverse().change_ring(ZZ)
     1766        rk = D.rank()
     1767        # m1 and m2 are the matrices defining fm1 and fm2
     1768        # self.matrix() == m1 * m2
     1769        m1 = (self.matrix()*V).submatrix(col=0, ncols=rk)
     1770        m2 = Vinv.submatrix(row=0, nrows=rk)
     1771        m2_inv = V.submatrix(col=0, ncols=rk)  # right inverse of m2
     1772        # the natural morphism only using matrix and domain fan
     1773        minimal_model = FanMorphism(self, self.domain_fan())
     1774        # construct the intermediate fan
     1775        fan_img = fan2.intersection(minimal_model.codomain_fan())
     1776        fan = Fan([Cone([r*m2_inv for r in c.rays()])
     1777                   for c in fan_img.generating_cones()])
     1778        # construct the two fan morphisms
     1779        fm1 = FanMorphism(m1, fan1, fan)
     1780        fm2 = FanMorphism(m2, fan, fan2)
     1781        return fm2, fm1
  • sage/schemes/toric/homset.py

    diff --git a/sage/schemes/toric/homset.py b/sage/schemes/toric/homset.py
    a b  
    231231        raise TypeError, "x must be a fan morphism or a list/tuple of polynomials"
    232232
    233233
     234    def _an_element_(self):
     235        """
     236        Construct a sample morphism.
     237
     238        OUTPUT:
     239
     240        An element of the homset.
     241
     242        EXAMPLES::
     243
     244            sage: P2 = toric_varieties.P2()
     245            sage: homset = P2.Hom(P2)
     246            sage: homset.an_element()   # indirect doctest
     247            Scheme endomorphism of 2-d CPR-Fano toric variety covered by 3 affine patches
     248              Defn: Defined by sending Rational polyhedral fan in 2-d lattice N to
     249                    Rational polyhedral fan in 2-d lattice N.
     250        """
     251        from sage.matrix.constructor import zero_matrix
     252        zero = zero_matrix(self.domain().dimension_relative(),
     253                           self.codomain().dimension_relative())
     254        return self(zero)
     255
    234256class SchemeHomset_points_toric_field(SchemeHomset_points):
    235257    """
    236258    Set of rational points of a toric variety.
  • sage/schemes/toric/morphism.py

    diff --git a/sage/schemes/toric/morphism.py b/sage/schemes/toric/morphism.py
    a b  
    710710                polys[i] *= x**d
    711711        return SchemeMorphism_polynomial_toric_variety(self.parent(), polys)
    712712
     713    def is_injective(self):
     714        r"""
     715        Check if ``self`` is injective.
     716       
     717        See
     718        :meth:`~sage.geometry.fan_morphism.FanMorphism.is_injective`
     719        for a description of the toric algorithm.
     720               
     721        OUTPUT:
     722       
     723        Boolean. Whether ``self`` is injective.
     724
     725        EXAMPLES::
     726       
     727            sage: X = toric_varieties.A(2)
     728            sage: m = identity_matrix(2)
     729            sage: f = X.hom(m, X)
     730            sage: f.is_injective()
     731            True
     732           
     733            sage: Y = ToricVariety(Fan([Cone([(1,0), (1,1)])]))
     734            sage: f = Y.hom(m, X)
     735            sage: f.is_injective()
     736            False
     737        """       
     738        return self.fan_morphism().is_injective()
     739       
     740    def is_surjective(self):
     741        r"""
     742        Check if ``self`` is surjective.
     743       
     744        See
     745        :meth:`~sage.geometry.fan_morphism.FanMorphism.is_surjective`
     746        for a description of the toric algorithm.
     747               
     748        OUTPUT:
     749       
     750        Boolean. Whether ``self`` is surjective.
     751
     752        EXAMPLES::
     753       
     754            sage: X = toric_varieties.A(2)
     755            sage: m = identity_matrix(2)
     756            sage: f = X.hom(m, X)
     757            sage: f.is_surjective()
     758            True
     759           
     760            sage: Y = ToricVariety(Fan([Cone([(1,0), (1,1)])]))
     761            sage: f = Y.hom(m, X)
     762            sage: f.is_surjective()
     763            False
     764        """       
     765        return self.fan_morphism().is_surjective()
     766
     767    def factor(self):
     768        r"""
     769        Factor into a surjection and a generically injective map.
     770
     771        See
     772        :meth:`~sage.geometry.fan_morphism.FanMorphism.factor`
     773        for a description of the toric algorithm.
     774
     775        OUTPUT:
     776
     777        Starting with a toric morphism $f$, this method returns a pair
     778        $(f_1, f_2)$ of toric morphisms such that
     779
     780        * $f = f_1 \circ f_2$,
     781
     782        * $f_2$ is surjective, and
     783
     784        * $f_1$ is injective at a generic point of the domain (in
     785          particular, on the maximal torus).
     786
     787        EXAMPLES::
     788
     789            sage: N = ToricLattice(3)
     790            sage: n1 = N( 1,1,1)
     791            sage: n2 = N( 0,1,1)
     792            sage: n3 = N(-1,1,1)
     793            sage: domain = ToricVariety(Fan([Cone([n1,n2]), Cone([n2,n3])]))
     794            sage: m = matrix([[0,1,3], [0,1,3]]).transpose()
     795            sage: codomain = ToricVariety(Fan([Cone([(1,0), (0,1)])]))
     796            sage: f = domain.hom(m, codomain)
     797            sage: f1, f2 = f.factor()
     798            sage: f2
     799            Scheme morphism:
     800              From: 3-d toric variety covered by 2 affine patches
     801              To:   1-d affine toric variety
     802              Defn: Defined by sending Rational polyhedral fan in 3-d lattice N
     803                    to Rational polyhedral fan in 1-d lattice N.
     804            sage: f1
     805            Scheme morphism:
     806              From: 1-d affine toric variety
     807              To:   2-d affine toric variety
     808              Defn: Defined by sending Rational polyhedral fan in 1-d lattice N
     809                    to Rational polyhedral fan in 2-d lattice N.
     810           
     811            sage: f2.is_surjective()
     812            True
     813            sage: f1.is_injective()
     814            True
     815            sage: f1.fan_morphism() * f2.fan_morphism() == f.fan_morphism()
     816            True
     817        """
     818        fm1, fm2 = self.fan_morphism().factor()
     819        from sage.schemes.toric.all import ToricVariety
     820        X = self.domain()
     821        Y = ToricVariety(fm2.codomain_fan())
     822        Z = self.codomain()
     823        return Y.hom(fm1, Z), X.hom(fm2, Y)