Ticket #12892: trac_12892_toric_morphism_divisors.patch

File trac_12892_toric_morphism_divisors.patch, 7.8 KB (added by Volker Braun, 9 years ago)

Updated patch

  • sage/schemes/toric/morphism.py

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1372033129 14400
    #      Sun Jun 23 20:18:49 2013 -0400
    # Node ID 4574a4866e5d36c059ca69d446fabad739528d93
    # Parent  c24d8f842689edc4db10e9dd3f8ae088de12347f
    Trac #12892: Toric fibration morphisms
    
    Pull back toric divisors via toric morphisms
    
    diff --git a/sage/schemes/toric/morphism.py b/sage/schemes/toric/morphism.py
    a b  
    168168from sage.categories.morphism import Morphism
    169169
    170170from sage.structure.sequence  import Sequence
    171 from sage.rings.all import ZZ
     171from sage.rings.all import ZZ, gcd
    172172from sage.misc.all import cached_method
    173173from sage.matrix.constructor import matrix, block_matrix, zero_matrix, identity_matrix
    174174from sage.modules.free_module_element import vector
     
    544544            polys[ray_index] = R.gen(i)
    545545        return SchemeMorphism_polynomial_toric_variety(self.parent(), polys)
    546546       
     547    def pullback_divisor(self, divisor):
     548        r"""
     549        Pull back a toric divisor.
     550
     551        INPUT:
     552
     553        - ``divisor`` -- a torus-invariant QQ-Cartier divisor on the
     554          codomain of the embedding map.
     555
     556        OUTPUT:
     557
     558        A divisor on the domain of the embedding map (the orbit
     559        closure) that is isomorphic to the pull-back divisor `f^*(D)`
     560        but with possibly different linearization.
     561
     562        EXAMPLES::
     563
     564            sage: P2 = toric_varieties.P2()
     565            sage: P1 = P2.orbit_closure(P2.fan(1)[0])
     566            sage: f = P1.embedding_morphism()
     567            sage: D = P2.divisor([1,2,3]); D
     568            V(x) + 2*V(y) + 3*V(z)
     569            sage: f.pullback_divisor(D)
     570            4*V(z0) + 2*V(z1)
     571        """
     572        from sage.schemes.toric.divisor import is_ToricDivisor
     573        if not (is_ToricDivisor(divisor) and divisor.is_QQ_Cartier()):
     574            raise ValueError('The divisor must be torus-invariant and QQ-Cartier.')
     575        m = divisor.m(self._defining_cone)
     576        values = []
     577        codomain_rays = self.codomain().fan().rays()
     578        for ray in self.domain().fan().rays():
     579            ray = codomain_rays[self._reverse_ray_map()[ray]]
     580            value = divisor.function_value(ray) - m*ray
     581            values.append(value)
     582        return self.domain().divisor(values)
     583
    547584
    548585############################################################################
    549586# A morphism of toric varieties determined by a fan morphism
     
    11761213            graph.set_vertex(i, self.fiber_component(prim[i]))
    11771214        return graph
    11781215
     1216    def pullback_divisor(self, divisor):
     1217        r"""
     1218        Pull back a toric divisor.
     1219
     1220        INPUT:
     1221
     1222        - ``divisor`` -- a torus-invariant QQ-Cartier divisor on the
     1223          codomain of ``self``.
     1224
     1225        OUTPUT:
     1226
     1227        The pull-back divisor `f^*(D)`.
     1228
     1229        EXAMPLES::
     1230
     1231            sage: A2_Z2 = toric_varieties.A2_Z2()
     1232            sage: A2 = toric_varieties.A2()
     1233            sage: f = A2.hom( matrix([[1,0],[1,2]]), A2_Z2)
     1234            sage: f.pullback_divisor(A2_Z2.divisor(0))
     1235            V(x)
     1236
     1237            sage: A1 = toric_varieties.A1()
     1238            sage: square = A1.hom(matrix([[2]]), A1)
     1239            sage: D = A1.divisor(0);  D
     1240            V(z)
     1241            sage: square.pullback_divisor(D)
     1242            2*V(z)
     1243        """
     1244        from sage.schemes.toric.divisor import is_ToricDivisor
     1245        if not (is_ToricDivisor(divisor) and divisor.is_QQ_Cartier()):
     1246            raise ValueError('The divisor must be torus-invariant and QQ-Cartier.')
     1247        fm = self.fan_morphism()
     1248        values = []
     1249        for ray in self.domain().fan().rays():
     1250            value = divisor.function_value(fm(ray))
     1251            values.append(value)
     1252        return self.domain().divisor(values)
     1253
     1254
    11791255
    11801256############################################################################
    11811257# The embedding morphism of an orbit closure
     
    14171493        A cone of the base of the toric fibration.
    14181494        """
    14191495        return self._base_cone
     1496
     1497    def _image_ray_multiplicity(self, fiber_ray):
     1498        """
     1499        Find the image ray of ``fiber_ray`` with multiplicity in the relative star.
     1500
     1501        INPUT:
     1502
     1503        A ray of the domain fan (the fiber component).
     1504       
     1505        OUTPUT:
     1506
     1507        A pair ``(codomain ray index, multiplicity)``
     1508
     1509        EXAMPLES::
     1510
     1511            sage: polytope = Polyhedron(
     1512            ...       [(-3,0,-1,-1),(-1,2,-1,-1),(0,-1,0,0),(0,0,0,1),(0,0,1,0),
     1513            ...        (0,1,0,0),(0,2,-1,-1),(1,0,0,0),(2,0,-1,-1)])
     1514            sage: coarse_fan = FaceFan(polytope.lattice_polytope())
     1515            sage: P2 = toric_varieties.P2()
     1516            sage: proj24 = matrix([[0,0],[1,0],[0,0],[0,1]])
     1517            sage: fm = FanMorphism(proj24, coarse_fan, P2.fan(), subdivide=True)
     1518            sage: fibration = ToricVariety(fm.domain_fan()).hom(fm, P2)
     1519            sage: primitive_cone = Cone([(-1, 2, -1, 0)])
     1520            sage: fiber = fibration.fiber_component(primitive_cone)
     1521            sage: f = fiber.embedding_morphism()
     1522            sage: for r in fiber.fan().rays():
     1523            ...       print r, f._image_ray_multiplicity(r)
     1524            N(0, 1) (5, 1)
     1525            N(1, -3) (9, 2)
     1526            N(-1, 2) (14, 1)
     1527            sage: f._ray_index_map
     1528            {N(0, 1): 5, N(-3, 4): 11, N(-1, 2): 14, N(1, 0): 4, N(2, -6): 9}
     1529        """
     1530        try:
     1531            image_ray_index = self._ray_index_map[fiber_ray]
     1532            return (image_ray_index, 1)
     1533        except KeyError:
     1534            pass
     1535        multiplicity = None
     1536        image_ray_index = None
     1537        for ray, index in self._ray_index_map.iteritems():
     1538            d = gcd(ray)
     1539            if d*fiber_ray != ray:
     1540                continue
     1541            if multiplicity is not None and d>multiplicity:
     1542                continue
     1543            multiplicity = d
     1544            image_ray_index = index
     1545        return (image_ray_index, multiplicity)
     1546
     1547    def pullback_divisor(self, divisor):
     1548        r"""
     1549        Pull back a toric divisor.
     1550
     1551        INPUT:
     1552
     1553        - ``divisor`` -- a torus-invariant QQ-Cartier divisor on the
     1554          codomain of the embedding map.
     1555
     1556        OUTPUT:
     1557
     1558        A divisor on the domain of the embedding map (irreducible
     1559        component of a fiber of a toric morphism) that is isomorphic
     1560        to the pull-back divisor `f^*(D)` but with possibly different
     1561        linearization.
     1562
     1563        EXAMPLES::
     1564
     1565            sage: A1 = toric_varieties.A1()
     1566            sage: fan = Fan([(0,1,2)], [(1,1,0),(1,0,1),(1,-1,-1)]).subdivide(new_rays=[(1,0,0)])
     1567            sage: f = ToricVariety(fan).hom(matrix([[1],[0],[0]]), A1)
     1568            sage: D = f.domain().divisor([1,1,3,4]); D
     1569            V(z0) + V(z1) + 3*V(z2) + 4*V(z3)
     1570            sage: fiber = f.fiber_component(Cone([(1,1,0)]))
     1571            sage: fiber.embedding_morphism().pullback_divisor(D)
     1572            3*V(z0) + 2*V(z2)
     1573            sage: fiber = f.fiber_component(Cone([(1,0,0)]))
     1574            sage: fiber.embedding_morphism().pullback_divisor(D)
     1575            -3*V(z0) - 3*V(z1) - V(z2)
     1576        """
     1577        from sage.schemes.toric.divisor import is_ToricDivisor
     1578        if not (is_ToricDivisor(divisor) and divisor.is_QQ_Cartier()):
     1579            raise ValueError('The divisor must be torus-invariant and QQ-Cartier.')
     1580        m = divisor.m(self.defining_cone())
     1581        values = []
     1582        codomain_rays = self.codomain().fan().rays()
     1583        for ray in self.domain().fan().rays():
     1584            image_ray_index, multiplicity = self._image_ray_multiplicity(ray)
     1585            image_ray = codomain_rays[image_ray_index]
     1586            value = divisor.function_value(image_ray) - m*image_ray
     1587            value /= multiplicity
     1588            values.append(value)
     1589        return self.domain().divisor(values)
     1590
     1591
    14201592    def is_birational(self):
    14211593        r"""
    14221594        Check if ``self`` is birational.