Ticket #14353: trac_14353_factor_fan_morphism.patch
File trac_14353_factor_fan_morphism.patch, 9.1 KB (added by , 9 years ago) |
---|
-
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 1686 1686 for cone in self.codomain_fan()), 1687 1687 lattice=L, check=False) 1688 1688 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 231 231 raise TypeError, "x must be a fan morphism or a list/tuple of polynomials" 232 232 233 233 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 234 256 class SchemeHomset_points_toric_field(SchemeHomset_points): 235 257 """ 236 258 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 710 710 polys[i] *= x**d 711 711 return SchemeMorphism_polynomial_toric_variety(self.parent(), polys) 712 712 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)