passagemath-polyhedra 10.6.31rc3__cp314-cp314-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-polyhedra might be problematic. Click here for more details.

Files changed (208) hide show
  1. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +367 -0
  2. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +369 -0
  3. passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +208 -0
  4. passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +5 -0
  5. passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
  6. passagemath_polyhedra.libs/libgcc_s-0cd532bd.so.1 +0 -0
  7. passagemath_polyhedra.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  8. passagemath_polyhedra.libs/libgomp-8949ffbe.so.1.0.0 +0 -0
  9. passagemath_polyhedra.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  10. sage/all__sagemath_polyhedra.py +50 -0
  11. sage/game_theory/all.py +8 -0
  12. sage/game_theory/catalog.py +6 -0
  13. sage/game_theory/catalog_normal_form_games.py +923 -0
  14. sage/game_theory/cooperative_game.py +844 -0
  15. sage/game_theory/matching_game.py +1181 -0
  16. sage/game_theory/normal_form_game.py +2697 -0
  17. sage/game_theory/parser.py +275 -0
  18. sage/geometry/all__sagemath_polyhedra.py +22 -0
  19. sage/geometry/cone.py +6940 -0
  20. sage/geometry/cone_catalog.py +847 -0
  21. sage/geometry/cone_critical_angles.py +1027 -0
  22. sage/geometry/convex_set.py +1119 -0
  23. sage/geometry/fan.py +3743 -0
  24. sage/geometry/fan_isomorphism.py +389 -0
  25. sage/geometry/fan_morphism.py +1884 -0
  26. sage/geometry/hasse_diagram.py +202 -0
  27. sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
  28. sage/geometry/hyperplane_arrangement/all.py +1 -0
  29. sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
  30. sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
  31. sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
  32. sage/geometry/hyperplane_arrangement/library.py +825 -0
  33. sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
  34. sage/geometry/hyperplane_arrangement/plot.py +520 -0
  35. sage/geometry/integral_points.py +35 -0
  36. sage/geometry/integral_points_generic_dense.cpython-314-x86_64-linux-musl.so +0 -0
  37. sage/geometry/integral_points_generic_dense.pyx +7 -0
  38. sage/geometry/lattice_polytope.py +5894 -0
  39. sage/geometry/linear_expression.py +773 -0
  40. sage/geometry/newton_polygon.py +767 -0
  41. sage/geometry/point_collection.cpython-314-x86_64-linux-musl.so +0 -0
  42. sage/geometry/point_collection.pyx +1008 -0
  43. sage/geometry/polyhedral_complex.py +2616 -0
  44. sage/geometry/polyhedron/all.py +8 -0
  45. sage/geometry/polyhedron/backend_cdd.py +460 -0
  46. sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
  47. sage/geometry/polyhedron/backend_field.py +347 -0
  48. sage/geometry/polyhedron/backend_normaliz.py +2503 -0
  49. sage/geometry/polyhedron/backend_number_field.py +168 -0
  50. sage/geometry/polyhedron/backend_polymake.py +765 -0
  51. sage/geometry/polyhedron/backend_ppl.py +582 -0
  52. sage/geometry/polyhedron/base.py +1206 -0
  53. sage/geometry/polyhedron/base0.py +1444 -0
  54. sage/geometry/polyhedron/base1.py +886 -0
  55. sage/geometry/polyhedron/base2.py +812 -0
  56. sage/geometry/polyhedron/base3.py +1845 -0
  57. sage/geometry/polyhedron/base4.py +1262 -0
  58. sage/geometry/polyhedron/base5.py +2700 -0
  59. sage/geometry/polyhedron/base6.py +1741 -0
  60. sage/geometry/polyhedron/base7.py +997 -0
  61. sage/geometry/polyhedron/base_QQ.py +1258 -0
  62. sage/geometry/polyhedron/base_RDF.py +98 -0
  63. sage/geometry/polyhedron/base_ZZ.py +934 -0
  64. sage/geometry/polyhedron/base_mutable.py +215 -0
  65. sage/geometry/polyhedron/base_number_field.py +122 -0
  66. sage/geometry/polyhedron/cdd_file_format.py +155 -0
  67. sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
  68. sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-x86_64-linux-musl.so +0 -0
  69. sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
  70. sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
  71. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-x86_64-linux-musl.so +0 -0
  72. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
  73. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
  74. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-x86_64-linux-musl.so +0 -0
  75. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
  76. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
  77. sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
  78. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  79. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
  80. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
  81. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-x86_64-linux-musl.so +0 -0
  82. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
  83. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
  84. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-x86_64-linux-musl.so +0 -0
  85. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
  86. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
  87. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-x86_64-linux-musl.so +0 -0
  88. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
  89. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
  90. sage/geometry/polyhedron/constructor.py +773 -0
  91. sage/geometry/polyhedron/double_description.py +753 -0
  92. sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
  93. sage/geometry/polyhedron/face.py +1060 -0
  94. sage/geometry/polyhedron/generating_function.py +1810 -0
  95. sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
  96. sage/geometry/polyhedron/library.py +3502 -0
  97. sage/geometry/polyhedron/misc.py +121 -0
  98. sage/geometry/polyhedron/modules/all.py +1 -0
  99. sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
  100. sage/geometry/polyhedron/palp_database.py +447 -0
  101. sage/geometry/polyhedron/parent.py +1279 -0
  102. sage/geometry/polyhedron/plot.py +1986 -0
  103. sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
  104. sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
  105. sage/geometry/polyhedron/representation.py +1723 -0
  106. sage/geometry/pseudolines.py +515 -0
  107. sage/geometry/relative_interior.py +445 -0
  108. sage/geometry/toric_plotter.py +1103 -0
  109. sage/geometry/triangulation/all.py +2 -0
  110. sage/geometry/triangulation/base.cpython-314-x86_64-linux-musl.so +0 -0
  111. sage/geometry/triangulation/base.pyx +963 -0
  112. sage/geometry/triangulation/data.h +147 -0
  113. sage/geometry/triangulation/data.pxd +4 -0
  114. sage/geometry/triangulation/element.py +914 -0
  115. sage/geometry/triangulation/functions.h +10 -0
  116. sage/geometry/triangulation/functions.pxd +4 -0
  117. sage/geometry/triangulation/point_configuration.py +2256 -0
  118. sage/geometry/triangulation/triangulations.h +49 -0
  119. sage/geometry/triangulation/triangulations.pxd +7 -0
  120. sage/geometry/voronoi_diagram.py +319 -0
  121. sage/interfaces/all__sagemath_polyhedra.py +1 -0
  122. sage/interfaces/polymake.py +2028 -0
  123. sage/numerical/all.py +13 -0
  124. sage/numerical/all__sagemath_polyhedra.py +11 -0
  125. sage/numerical/backends/all.py +1 -0
  126. sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
  127. sage/numerical/backends/cvxopt_backend.cpython-314-x86_64-linux-musl.so +0 -0
  128. sage/numerical/backends/cvxopt_backend.pyx +1006 -0
  129. sage/numerical/backends/cvxopt_backend_test.py +19 -0
  130. sage/numerical/backends/cvxopt_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  131. sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
  132. sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-linux-musl.so +0 -0
  133. sage/numerical/backends/cvxpy_backend.pxd +41 -0
  134. sage/numerical/backends/cvxpy_backend.pyx +934 -0
  135. sage/numerical/backends/cvxpy_backend_test.py +13 -0
  136. sage/numerical/backends/generic_backend_test.py +24 -0
  137. sage/numerical/backends/interactivelp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  138. sage/numerical/backends/interactivelp_backend.pxd +36 -0
  139. sage/numerical/backends/interactivelp_backend.pyx +1231 -0
  140. sage/numerical/backends/interactivelp_backend_test.py +12 -0
  141. sage/numerical/backends/logging_backend.py +391 -0
  142. sage/numerical/backends/matrix_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  143. sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
  144. sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
  145. sage/numerical/backends/ppl_backend.cpython-314-x86_64-linux-musl.so +0 -0
  146. sage/numerical/backends/ppl_backend.pyx +1126 -0
  147. sage/numerical/backends/ppl_backend_test.py +13 -0
  148. sage/numerical/backends/scip_backend.cpython-314-x86_64-linux-musl.so +0 -0
  149. sage/numerical/backends/scip_backend.pxd +22 -0
  150. sage/numerical/backends/scip_backend.pyx +1289 -0
  151. sage/numerical/backends/scip_backend_test.py +13 -0
  152. sage/numerical/interactive_simplex_method.py +5338 -0
  153. sage/numerical/knapsack.py +665 -0
  154. sage/numerical/linear_functions.cpython-314-x86_64-linux-musl.so +0 -0
  155. sage/numerical/linear_functions.pxd +31 -0
  156. sage/numerical/linear_functions.pyx +1648 -0
  157. sage/numerical/linear_tensor.py +470 -0
  158. sage/numerical/linear_tensor_constraints.py +448 -0
  159. sage/numerical/linear_tensor_element.cpython-314-x86_64-linux-musl.so +0 -0
  160. sage/numerical/linear_tensor_element.pxd +6 -0
  161. sage/numerical/linear_tensor_element.pyx +459 -0
  162. sage/numerical/mip.cpython-314-x86_64-linux-musl.so +0 -0
  163. sage/numerical/mip.pxd +40 -0
  164. sage/numerical/mip.pyx +3667 -0
  165. sage/numerical/sdp.cpython-314-x86_64-linux-musl.so +0 -0
  166. sage/numerical/sdp.pxd +39 -0
  167. sage/numerical/sdp.pyx +1433 -0
  168. sage/rings/all__sagemath_polyhedra.py +3 -0
  169. sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
  170. sage/rings/polynomial/omega.py +982 -0
  171. sage/schemes/all__sagemath_polyhedra.py +2 -0
  172. sage/schemes/toric/all.py +10 -0
  173. sage/schemes/toric/chow_group.py +1248 -0
  174. sage/schemes/toric/divisor.py +2082 -0
  175. sage/schemes/toric/divisor_class.cpython-314-x86_64-linux-musl.so +0 -0
  176. sage/schemes/toric/divisor_class.pyx +322 -0
  177. sage/schemes/toric/fano_variety.py +1606 -0
  178. sage/schemes/toric/homset.py +650 -0
  179. sage/schemes/toric/ideal.py +451 -0
  180. sage/schemes/toric/library.py +1322 -0
  181. sage/schemes/toric/morphism.py +1958 -0
  182. sage/schemes/toric/points.py +1032 -0
  183. sage/schemes/toric/sheaf/all.py +1 -0
  184. sage/schemes/toric/sheaf/constructor.py +302 -0
  185. sage/schemes/toric/sheaf/klyachko.py +921 -0
  186. sage/schemes/toric/toric_subscheme.py +905 -0
  187. sage/schemes/toric/variety.py +3460 -0
  188. sage/schemes/toric/weierstrass.py +1078 -0
  189. sage/schemes/toric/weierstrass_covering.py +457 -0
  190. sage/schemes/toric/weierstrass_higher.py +288 -0
  191. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
  192. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
  193. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
  194. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
  195. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
  196. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
  197. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
  198. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
  199. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
  200. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
  201. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
  202. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
  203. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
  204. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
  205. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
  206. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
  207. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
  208. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
@@ -0,0 +1,2082 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ # sage.doctest: needs palp sage.geometry.polyhedron sage.graphs
3
+ r"""
4
+ Toric divisors and divisor classes
5
+
6
+ Let `X` be a :class:`toric variety
7
+ <sage.schemes.toric.variety.ToricVariety_field>` corresponding to a
8
+ :class:`rational polyhedral fan <sage.geometry.fan.RationalPolyhedralFan>`
9
+ `\Sigma`. A :class:`toric divisor <ToricDivisor_generic>` `D` is a T-Weil
10
+ divisor over a given coefficient ring (usually `\ZZ` or `\QQ`), i.e. a formal
11
+ linear combination of torus-invariant subvarieties of `X` of codimension one.
12
+ In homogeneous coordinates `[z_0:\cdots:z_k]`, these are the subvarieties
13
+ `\{z_i=0\}`. Note that there is a finite number of such subvarieties, one for
14
+ each ray of `\Sigma`. We generally identify
15
+
16
+ * Toric divisor `D`,
17
+
18
+ * Sheaf `\mathcal{O}(D)` (if `D` is Cartier, it is a line bundle),
19
+
20
+ * Support function `\phi_D` (if `D` is `\QQ`-Cartier, it is a function
21
+ linear on each cone of `\Sigma`).
22
+
23
+ EXAMPLES:
24
+
25
+ We start with an illustration of basic divisor arithmetic::
26
+
27
+ sage: dP6 = toric_varieties.dP6()
28
+ sage: Dx,Du,Dy,Dv,Dz,Dw = dP6.toric_divisor_group().gens()
29
+ sage: Dx
30
+ V(x)
31
+ sage: -Dx
32
+ -V(x)
33
+ sage: 2*Dx
34
+ 2*V(x)
35
+ sage: Dx*2
36
+ 2*V(x)
37
+ sage: (1/2)*Dx + Dy/3 - Dz
38
+ 1/2*V(x) + 1/3*V(y) - V(z)
39
+ sage: Dx.parent()
40
+ Group of toric ZZ-Weil divisors
41
+ on 2-d CPR-Fano toric variety covered by 6 affine patches
42
+ sage: (Dx/2).parent()
43
+ Group of toric QQ-Weil divisors
44
+ on 2-d CPR-Fano toric variety covered by 6 affine patches
45
+
46
+ Now we create a more complicated variety to demonstrate divisors of different
47
+ types::
48
+
49
+ sage: F = Fan(cones=[(0,1,2,3), (0,1,4)],
50
+ ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)])
51
+ sage: X = ToricVariety(F)
52
+ sage: QQ_Cartier = X.divisor([2,2,1,1,1])
53
+ sage: Cartier = 2 * QQ_Cartier
54
+ sage: Weil = X.divisor([1,1,1,0,0])
55
+ sage: QQ_Weil = 1/2 * Weil
56
+ sage: [QQ_Weil.is_QQ_Weil(),
57
+ ....: QQ_Weil.is_Weil(),
58
+ ....: QQ_Weil.is_QQ_Cartier(),
59
+ ....: QQ_Weil.is_Cartier()]
60
+ [True, False, False, False]
61
+ sage: [Weil.is_QQ_Weil(),
62
+ ....: Weil.is_Weil(),
63
+ ....: Weil.is_QQ_Cartier(),
64
+ ....: Weil.is_Cartier()]
65
+ [True, True, False, False]
66
+ sage: [QQ_Cartier.is_QQ_Weil(),
67
+ ....: QQ_Cartier.is_Weil(),
68
+ ....: QQ_Cartier.is_QQ_Cartier(),
69
+ ....: QQ_Cartier.is_Cartier()]
70
+ [True, True, True, False]
71
+ sage: [Cartier.is_QQ_Weil(),
72
+ ....: Cartier.is_Weil(),
73
+ ....: Cartier.is_QQ_Cartier(),
74
+ ....: Cartier.is_Cartier()]
75
+ [True, True, True, True]
76
+
77
+ The toric (`\QQ`-Weil) divisors on a toric variety `X` modulo linear
78
+ equivalence generate the divisor **class group** `\mathrm{Cl}(X)`, implemented
79
+ by :class:`ToricRationalDivisorClassGroup`. If `X` is smooth, this equals the
80
+ **Picard group** `\mathop{\mathrm{Pic}}(X)`. We continue using del Pezzo
81
+ surface of degree 6 introduced above::
82
+
83
+ sage: Cl = dP6.rational_class_group(); Cl
84
+ The toric rational divisor class group
85
+ of a 2-d CPR-Fano toric variety covered by 6 affine patches
86
+ sage: Cl.ngens()
87
+ 4
88
+ sage: c0,c1,c2,c3 = Cl.gens()
89
+ sage: c = c0 + 2*c1 - c3; c
90
+ Divisor class [1, 2, 0, -1]
91
+
92
+ Divisors are mapped to their classes and lifted via::
93
+
94
+ sage: Dx.divisor_class()
95
+ Divisor class [1, 0, 0, 0]
96
+ sage: Dx.divisor_class() in Cl
97
+ True
98
+ sage: (-Dw + Dv + Dy).divisor_class()
99
+ Divisor class [1, 0, 0, 0]
100
+ sage: c0
101
+ Divisor class [1, 0, 0, 0]
102
+ sage: c0.lift()
103
+ V(x)
104
+
105
+ The (rational) divisor class group is where the Kaehler cone lives::
106
+
107
+ sage: Kc = dP6.Kaehler_cone(); Kc
108
+ 4-d cone in 4-d lattice
109
+ sage: Kc.rays()
110
+ Divisor class [0, 1, 1, 0],
111
+ Divisor class [0, 0, 1, 1],
112
+ Divisor class [1, 1, 0, 0],
113
+ Divisor class [1, 1, 1, 0],
114
+ Divisor class [0, 1, 1, 1]
115
+ in Basis lattice of The toric rational divisor class group
116
+ of a 2-d CPR-Fano toric variety covered by 6 affine patches
117
+ sage: Kc.ray(1).lift()
118
+ V(x) + V(w)
119
+
120
+ Given a divisor `D`, we have an associated line bundle (or a reflexive
121
+ sheaf, if `D` is not Cartier) `\mathcal{O}(D)`. Its sections are::
122
+
123
+ sage: P2 = toric_varieties.P2()
124
+ sage: H = P2.divisor(0); H
125
+ V(x)
126
+ sage: H.sections()
127
+ (M(-1, 0), M(-1, 1), M(0, 0))
128
+ sage: H.sections_monomials()
129
+ (z, y, x)
130
+
131
+ Note that the space of sections is always spanned by
132
+ monomials. Therefore, we can grade the sections (as homogeneous
133
+ monomials) by their weight under rescaling individual
134
+ coordinates. This weight data amounts to a point of the dual lattice.
135
+
136
+ In the same way, we can grade cohomology groups by their cohomological
137
+ degree and a weight::
138
+
139
+ sage: M = P2.fan().lattice().dual()
140
+ sage: H.cohomology(deg=0, weight=M(-1,0))
141
+ Vector space of dimension 1 over Rational Field
142
+ sage: _.dimension()
143
+ 1
144
+
145
+ Here is a more complicated example with `h^1(dP_6, \mathcal{O}(D))=4` ::
146
+
147
+ sage: D = dP6.divisor([0, 0, -1, 0, 2, -1])
148
+ sage: D.cohomology()
149
+ {0: Vector space of dimension 0 over Rational Field,
150
+ 1: Vector space of dimension 4 over Rational Field,
151
+ 2: Vector space of dimension 0 over Rational Field}
152
+ sage: D.cohomology(dim=True)
153
+ (0, 4, 0)
154
+
155
+ AUTHORS:
156
+
157
+ - Volker Braun, Andrey Novoseltsev (2010-09-07): initial version.
158
+ """
159
+
160
+
161
+ # ****************************************************************************
162
+ # Copyright (C) 2012 Volker Braun <vbraun.name@gmail.com>
163
+ # Copyright (C) 2012 Andrey Novoseltsev <novoselt@gmail.com>
164
+ #
165
+ # Distributed under the terms of the GNU General Public License (GPL)
166
+ # as published by the Free Software Foundation; either version 2 of
167
+ # the License, or (at your option) any later version.
168
+ # https://www.gnu.org/licenses/
169
+ # ****************************************************************************
170
+
171
+ from sage.combinat.combination import Combinations
172
+ import sage.geometry.abc
173
+ from sage.geometry.polyhedron.constructor import Polyhedron
174
+ from sage.geometry.toric_lattice_element import ToricLatticeElement
175
+ from sage.matrix.constructor import matrix
176
+ from sage.misc.cachefunc import cached_method
177
+ from sage.misc.flatten import flatten
178
+ from sage.misc.latex import latex
179
+ from sage.misc.lazy_import import lazy_import
180
+ from sage.misc.misc_c import prod
181
+ from sage.modules.free_module_element import vector
182
+ from sage.modules.free_module import (FreeModule_ambient_field,
183
+ FreeModule_ambient_pid)
184
+ from sage.rings.integer_ring import ZZ
185
+ from sage.rings.rational_field import QQ
186
+ from sage.schemes.generic.divisor import Divisor_generic
187
+ from sage.schemes.generic.divisor_group import DivisorGroup_generic
188
+ from sage.schemes.toric.divisor_class import ToricRationalDivisorClass
189
+ from sage.schemes.toric.variety import CohomologyRing, ToricVariety_field
190
+ from sage.structure.unique_representation import UniqueRepresentation
191
+ from sage.structure.element import Vector
192
+
193
+ lazy_import('sage.topology.simplicial_complex', 'SimplicialComplex')
194
+
195
+
196
+ def is_ToricDivisor(x):
197
+ r"""
198
+ Test whether ``x`` is a toric divisor.
199
+
200
+ INPUT:
201
+
202
+ - ``x`` -- anything
203
+
204
+ OUTPUT:
205
+
206
+ - ``True`` if ``x`` is an instance of :class:`ToricDivisor_generic` and
207
+ ``False`` otherwise.
208
+
209
+ EXAMPLES::
210
+
211
+ sage: from sage.schemes.toric.divisor import is_ToricDivisor
212
+ sage: is_ToricDivisor(1)
213
+ doctest:warning...
214
+ DeprecationWarning: The function is_ToricDivisor is deprecated;
215
+ use 'isinstance(..., ToricDivisor_generic)' instead.
216
+ See https://github.com/sagemath/sage/issues/38277 for details.
217
+ False
218
+ sage: P2 = toric_varieties.P2()
219
+ sage: D = P2.divisor(0); D
220
+ V(x)
221
+ sage: is_ToricDivisor(D)
222
+ True
223
+ """
224
+ from sage.misc.superseded import deprecation
225
+ deprecation(38277,
226
+ "The function is_ToricDivisor is deprecated; "
227
+ "use 'isinstance(..., ToricDivisor_generic)' instead.")
228
+ return isinstance(x, ToricDivisor_generic)
229
+
230
+
231
+ # ********************************************************
232
+ def ToricDivisor(toric_variety, arg=None, ring=None, check=True, reduce=True):
233
+ r"""
234
+ Construct a divisor of ``toric_variety``.
235
+
236
+ INPUT:
237
+
238
+ - ``toric_variety`` -- a :class:`toric variety
239
+ <sage.schemes.toric.variety.ToricVariety_field>`
240
+
241
+ - ``arg`` -- one of the following description of the toric divisor to be
242
+ constructed:
243
+
244
+ * ``None`` or 0 (the trivial divisor);
245
+
246
+ * monomial in the homogeneous coordinates;
247
+
248
+ * one-dimensional cone of the fan of ``toric_variety`` or a lattice
249
+ point generating such a cone;
250
+
251
+ * sequence of rational numbers, specifying multiplicities for each of
252
+ the toric divisors.
253
+
254
+ - ``ring`` -- usually either `\ZZ` or `\QQ`. The base ring of the
255
+ divisor group. If ``ring`` is not specified, a coefficient ring
256
+ suitable for ``arg`` is derived.
257
+
258
+ - ``check`` -- boolean (default: ``True``); whether to coerce
259
+ coefficients into base ring. Setting it to ``False`` can speed
260
+ up construction.
261
+
262
+ - ``reduce`` -- reduce (default: ``True``); whether to combine common
263
+ terms. Setting it to ``False`` can speed up construction.
264
+
265
+ .. WARNING::
266
+
267
+ The coefficients of the divisor must be in the base ring and
268
+ the terms must be reduced. If you set ``check=False`` and/or
269
+ ``reduce=False`` it is your responsibility to pass valid input
270
+ data ``arg``.
271
+
272
+ OUTPUT: a :class:`sage.schemes.toric.divisor.ToricDivisor_generic`
273
+
274
+ EXAMPLES::
275
+
276
+ sage: from sage.schemes.toric.divisor import ToricDivisor
277
+ sage: dP6 = toric_varieties.dP6()
278
+ sage: ToricDivisor(dP6, [(1,dP6.gen(2)), (1,dP6.gen(1))])
279
+ V(u) + V(y)
280
+ sage: ToricDivisor(dP6, (0,1,1,0,0,0), ring=QQ)
281
+ V(u) + V(y)
282
+ sage: dP6.inject_variables()
283
+ Defining x, u, y, v, z, w
284
+ sage: ToricDivisor(dP6, u + y)
285
+ Traceback (most recent call last):
286
+ ...
287
+ ValueError: u + y is not a monomial
288
+ sage: ToricDivisor(dP6, u*y)
289
+ V(u) + V(y)
290
+ sage: ToricDivisor(dP6, dP6.fan(dim=1)[2] )
291
+ V(y)
292
+ sage: cone = Cone(dP6.fan(dim=1)[2])
293
+ sage: ToricDivisor(dP6, cone)
294
+ V(y)
295
+ sage: N = dP6.fan().lattice()
296
+ sage: ToricDivisor(dP6, N(1,1) )
297
+ V(w)
298
+
299
+ We attempt to guess the correct base ring::
300
+
301
+ sage: ToricDivisor(dP6, [(1/2,u)])
302
+ 1/2*V(u)
303
+ sage: _.parent()
304
+ Group of toric QQ-Weil divisors on
305
+ 2-d CPR-Fano toric variety covered by 6 affine patches
306
+ sage: ToricDivisor(dP6, [(1/2,u), (1/2,u)])
307
+ V(u)
308
+ sage: _.parent()
309
+ Group of toric ZZ-Weil divisors on
310
+ 2-d CPR-Fano toric variety covered by 6 affine patches
311
+ sage: ToricDivisor(dP6, [(u,u)])
312
+ Traceback (most recent call last):
313
+ ...
314
+ TypeError: cannot deduce coefficient ring for [(u, u)]
315
+ """
316
+ assert isinstance(toric_variety, ToricVariety_field)
317
+
318
+ # First convert special arguments into lists
319
+ # of multiplicities or (multiplicity,coordinate)
320
+ # Zero divisor
321
+ if arg is None or arg in ZZ and arg == 0:
322
+ arg = []
323
+ check = False
324
+ reduce = False
325
+ # Divisor by lattice point (corresponding to a ray)
326
+ if isinstance(arg, ToricLatticeElement):
327
+ if arg not in toric_variety.fan().lattice():
328
+ raise ValueError("%s is not in the ambient lattice of %s"
329
+ % (arg, toric_variety.fan()))
330
+ arg = toric_variety.fan().cone_containing(arg)
331
+ # Divisor by a one-cone
332
+ if isinstance(arg, sage.geometry.abc.ConvexRationalPolyhedralCone):
333
+ fan = toric_variety.fan()
334
+ cone = fan.embed(arg)
335
+ if cone.dim() != 1:
336
+ raise ValueError("only 1-dimensional cones of the toric variety "
337
+ "define divisors")
338
+ arg = [(1, toric_variety.gen(cone.ambient_ray_indices()[0]))]
339
+ check = True # ensure that the 1 will be coerced into the coefficient ring
340
+ reduce = False
341
+ # Divisor by monomial
342
+ if arg in toric_variety.coordinate_ring():
343
+ if len(list(arg)) != 1:
344
+ raise ValueError(f"{arg} is not a monomial")
345
+ arg = arg.exponents()[0]
346
+ # By now either we have converted arg to a list, or it is something else
347
+ # which should be convertible to a list
348
+ if not isinstance(arg, list):
349
+ try:
350
+ arg = list(arg)
351
+ except TypeError:
352
+ raise TypeError(f"{arg} does not define a divisor")
353
+
354
+ # Now convert a list of multiplicities into pairs multiplicity-coordinate
355
+ try:
356
+ assert all(len(item) == 2 for item in arg)
357
+ except (AssertionError, TypeError):
358
+ n_rays = toric_variety.fan().nrays()
359
+ assert len(arg) == n_rays, \
360
+ 'Argument list {} is not of the required length {}!' \
361
+ .format(arg, n_rays)
362
+ arg = list(zip(arg, toric_variety.gens()))
363
+ reduce = False
364
+
365
+ # Now we must have a list of multiplicity-coordinate pairs
366
+ assert all(len(item) == 2 for item in arg)
367
+ if ring is None:
368
+ # if the coefficient ring was not given, try to use the most common ones.
369
+ try:
370
+ TDiv = ToricDivisorGroup(toric_variety, base_ring=ZZ)
371
+ return ToricDivisor_generic(arg, TDiv,
372
+ check=True, reduce=reduce)
373
+ except TypeError:
374
+ pass
375
+ try:
376
+ TDiv = ToricDivisorGroup(toric_variety, base_ring=QQ)
377
+ return ToricDivisor_generic(arg, TDiv,
378
+ check=True, reduce=reduce)
379
+ except TypeError:
380
+ raise TypeError(f"cannot deduce coefficient ring for {arg}")
381
+ TDiv = ToricDivisorGroup(toric_variety, ring)
382
+ return ToricDivisor_generic(arg, TDiv, check, reduce)
383
+
384
+
385
+ class ToricDivisor_generic(Divisor_generic):
386
+ """
387
+ Construct a :class:`(toric Weil) divisor <ToricDivisor_generic>` on the
388
+ given toric variety.
389
+
390
+ INPUT:
391
+
392
+ - ``v`` -- list of tuples (multiplicity, coordinate)
393
+
394
+ - ``parent`` -- :class:`ToricDivisorGroup`; the parent divisor group
395
+
396
+ - ``check`` -- boolean; type-check the entries of ``v``, see
397
+ :class:`~sage.schemes.generic.divisor_group.DivisorGroup_generic`
398
+
399
+ - ``reduce`` -- boolean; combine coefficients in ``v``, see
400
+ :class:`~sage.schemes.generic.divisor_group.DivisorGroup_generic`
401
+
402
+ .. WARNING::
403
+
404
+ Do not construct :class:`ToricDivisor_generic` objects manually.
405
+ Instead, use either the function :func:`ToricDivisor` or the method
406
+ :meth:`~sage.schemes.toric.variety.ToricVariety_field.divisor`
407
+ of toric varieties.
408
+
409
+ EXAMPLES::
410
+
411
+ sage: dP6 = toric_varieties.dP6()
412
+ sage: ray = dP6.fan().ray(0)
413
+ sage: ray
414
+ N(0, 1)
415
+ sage: D = dP6.divisor(ray); D
416
+ V(x)
417
+ sage: D.parent()
418
+ Group of toric ZZ-Weil divisors
419
+ on 2-d CPR-Fano toric variety covered by 6 affine patches
420
+ """
421
+
422
+ def __init__(self, v, parent, check=True, reduce=True):
423
+ """
424
+ See :class:`ToricDivisor_generic` for documentation.
425
+
426
+ EXAMPLES::
427
+
428
+ sage: dP6 = toric_varieties.dP6()
429
+ sage: from sage.schemes.toric.divisor import ToricDivisor_generic
430
+ sage: TDiv = dP6.toric_divisor_group()
431
+ sage: ToricDivisor_generic([], TDiv)
432
+ 0
433
+ sage: ToricDivisor_generic([(2,dP6.gen(1))], TDiv)
434
+ 2*V(u)
435
+ """
436
+ super().__init__(v, parent, check, reduce)
437
+
438
+ def _vector_(self, ring=None):
439
+ r"""
440
+ Return a vector representation.
441
+
442
+ INPUT:
443
+
444
+ - ``ring`` -- a ring (usually `\ZZ` or `\QQ`) for the
445
+ coefficients to live in). This is an optional argument, by
446
+ default a suitable ring is chosen automatically.
447
+
448
+ OUTPUT:
449
+
450
+ A vector whose ``self.scheme().fan().nrays()`` components are
451
+ the coefficients of the divisor.
452
+
453
+ EXAMPLES::
454
+
455
+ sage: dP6 = toric_varieties.dP6()
456
+ sage: D = dP6.divisor((0,1,1,0,0,0)); D
457
+ V(u) + V(y)
458
+ sage: D._vector_()
459
+ (0, 1, 1, 0, 0, 0)
460
+ sage: vector(D) # syntactic sugar
461
+ (0, 1, 1, 0, 0, 0)
462
+ sage: type( vector(D) )
463
+ <... 'sage.modules.vector_integer_dense.Vector_integer_dense'>
464
+ sage: D_QQ = dP6.divisor((0,1,1,0,0,0), base_ring=QQ);
465
+ sage: vector(D_QQ)
466
+ (0, 1, 1, 0, 0, 0)
467
+ sage: type( vector(D_QQ) )
468
+ <... 'sage.modules.vector_rational_dense.Vector_rational_dense'>
469
+
470
+ The vector representation is a suitable input for :func:`ToricDivisor` ::
471
+
472
+ sage: dP6.divisor(vector(D)) == D
473
+ True
474
+ """
475
+ if ring is None:
476
+ ring = self.base_ring()
477
+ X = self.parent().scheme()
478
+ v = vector(ring, [0] * X.ngens())
479
+ for coeff, variable in self:
480
+ v[X.gens().index(variable)] += coeff
481
+ return v
482
+
483
+ def coefficient(self, x):
484
+ r"""
485
+ Return the coefficient of ``x``.
486
+
487
+ INPUT:
488
+
489
+ - ``x`` -- one of the homogeneous coordinates, either given by
490
+ the variable or its index
491
+
492
+ OUTPUT: the coefficient of ``x``
493
+
494
+ EXAMPLES::
495
+
496
+ sage: P2 = toric_varieties.P2()
497
+ sage: D = P2.divisor((11,12,13)); D
498
+ 11*V(x) + 12*V(y) + 13*V(z)
499
+ sage: D.coefficient(1)
500
+ 12
501
+ sage: P2.inject_variables()
502
+ Defining x, y, z
503
+ sage: D.coefficient(y)
504
+ 12
505
+ """
506
+ try:
507
+ index = ZZ(x)
508
+ variable = self.parent().scheme().gen(index)
509
+ except TypeError:
510
+ variable = x
511
+
512
+ for coeff, var in self:
513
+ if var == variable:
514
+ return coeff
515
+ return self.base_ring().zero()
516
+
517
+ def function_value(self, point):
518
+ r"""
519
+ Return the value of the support function at ``point``.
520
+
521
+ Let `X` be the ambient toric variety of ``self``, `\Sigma` the fan
522
+ associated to `X`, and `N` the ambient lattice of `\Sigma`.
523
+
524
+ INPUT:
525
+
526
+ - ``point`` -- either an integer, interpreted as the index of a ray of
527
+ `\Sigma`, or a point of the lattice `N`
528
+
529
+ OUTPUT: integer or a rational number
530
+
531
+ EXAMPLES::
532
+
533
+ sage: P2 = toric_varieties.P2()
534
+ sage: D = P2.divisor([11,22,44]) # total degree 77
535
+ sage: D.function_value(0)
536
+ 11
537
+ sage: N = P2.fan().lattice()
538
+ sage: D.function_value( N(1,1) )
539
+ 33
540
+ sage: D.function_value( P2.fan().ray(0) )
541
+ 11
542
+ """
543
+ if not self.is_QQ_Cartier():
544
+ raise ValueError("support functions are associated to QQ-Cartier "
545
+ "divisors only, %s is not QQ-Cartier" % self)
546
+ try:
547
+ index = ZZ(point)
548
+ return self.coefficient(index)
549
+ except TypeError:
550
+ pass
551
+ fan = self.parent().scheme().fan()
552
+ assert point in fan.lattice(), 'The point ' + str(point) + ' is not in the N-lattice.'
553
+ cone = fan.cone_containing(point)
554
+ return point * self.m(cone)
555
+
556
+ def m(self, cone):
557
+ r"""
558
+ Return `m_\sigma` representing `\phi_D` on ``cone``.
559
+
560
+ Let `X` be the ambient toric variety of this divisor `D` associated to
561
+ the fan `\Sigma` in lattice `N`. Let `M` be the lattice dual to `N`.
562
+ Given the cone `\sigma =\langle v_1, \dots, v_k \rangle` in `\Sigma`,
563
+ this method searches for a vector `m_\sigma \in M_\QQ` such that
564
+ `\phi_D(v_i) = \langle m_\sigma, v_i \rangle` for all `i=1, \dots, k`,
565
+ where `\phi_D` is the support function of `D`.
566
+
567
+ INPUT:
568
+
569
+ - ``cone`` -- a cone in the fan of the toric variety
570
+
571
+ OUTPUT: if possible, a point of lattice `M`
572
+
573
+ - If the dual vector cannot be chosen integral, a rational vector is
574
+ returned.
575
+
576
+ - If there is no such vector (i.e. ``self`` is not even a
577
+ `\QQ`-Cartier divisor), a :exc:`ValueError` is raised.
578
+
579
+ EXAMPLES::
580
+
581
+ sage: F = Fan(cones=[(0,1,2,3), (0,1,4)],
582
+ ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)])
583
+ sage: X = ToricVariety(F)
584
+ sage: square_cone = X.fan().cone_containing(0,1,2,3)
585
+ sage: triangle_cone = X.fan().cone_containing(0,1,4)
586
+ sage: ray = X.fan().cone_containing(0)
587
+ sage: QQ_Cartier = X.divisor([2,2,1,1,1])
588
+ sage: QQ_Cartier.m(ray)
589
+ M(0, 2, 0)
590
+ sage: QQ_Cartier.m(square_cone)
591
+ (3/2, 0, 1/2)
592
+ sage: QQ_Cartier.m(triangle_cone)
593
+ M(1, 0, 1)
594
+ sage: QQ_Cartier.m(Cone(triangle_cone))
595
+ M(1, 0, 1)
596
+ sage: Weil = X.divisor([1,1,1,0,0])
597
+ sage: Weil.m(square_cone)
598
+ Traceback (most recent call last):
599
+ ...
600
+ ValueError: V(z0) + V(z1) + V(z2) is not QQ-Cartier,
601
+ cannot choose a dual vector on 3-d cone
602
+ of Rational polyhedral fan in 3-d lattice N
603
+ sage: Weil.m(triangle_cone)
604
+ M(1, 0, 0)
605
+ """
606
+ try:
607
+ return self._m[cone]
608
+ except AttributeError:
609
+ self._m = {}
610
+ except KeyError:
611
+ pass
612
+
613
+ X = self.parent().scheme()
614
+ M = X.fan().dual_lattice()
615
+ fan = X.fan()
616
+ cone = fan.embed(cone)
617
+ if cone.is_trivial():
618
+ m = M(0)
619
+ self._m[cone] = m
620
+ return m
621
+
622
+ assert cone.ambient() is fan
623
+ b = vector(self.coefficient(i) for i in cone.ambient_ray_indices())
624
+ A = cone.rays().column_matrix()
625
+ try:
626
+ if cone.dim() == X.dimension():
627
+ # either unique solution or ValueError (if not QQ-Cartier)
628
+ m = A.solve_left(b) # A m = b
629
+ else:
630
+ # under-determined system; try to find integral solution
631
+ D, U, V = A.smith_form() # D = U*A*V
632
+ bV = b * V
633
+ m = D.solve_left(bV) * U
634
+ except ValueError:
635
+ raise ValueError("%s is not QQ-Cartier, cannot choose a dual "
636
+ "vector on %s" % (self, cone))
637
+
638
+ try:
639
+ m = M(m)
640
+ except TypeError: # not integral
641
+ pass
642
+ self._m[cone] = m
643
+ return m
644
+
645
+ def is_Weil(self):
646
+ """
647
+ Return whether the divisor is a Weil-divisor.
648
+
649
+ EXAMPLES::
650
+
651
+ sage: P2 = toric_varieties.P2()
652
+ sage: D = P2.divisor([1,2,3])
653
+ sage: D.is_Weil()
654
+ True
655
+ sage: (D/2).is_Weil()
656
+ False
657
+ """
658
+ if self.base_ring() == ZZ:
659
+ return True
660
+ try:
661
+ vector(ZZ, vector(self))
662
+ return True
663
+ except TypeError:
664
+ return False
665
+
666
+ def is_QQ_Weil(self):
667
+ r"""
668
+ Return whether the divisor is a `\QQ`-Weil-divisor.
669
+
670
+ .. NOTE::
671
+
672
+ This function returns always ``True`` since
673
+ :class:`ToricDivisor <ToricDivisor_generic>` can only
674
+ describe `\QQ`-Weil divisors.
675
+
676
+ EXAMPLES::
677
+
678
+ sage: P2 = toric_varieties.P2()
679
+ sage: D = P2.divisor([1,2,3])
680
+ sage: D.is_QQ_Weil()
681
+ True
682
+ sage: (D/2).is_QQ_Weil()
683
+ True
684
+ """
685
+ return True
686
+
687
+ def is_Cartier(self):
688
+ r"""
689
+ Return whether the divisor is a Cartier-divisor.
690
+
691
+ .. NOTE::
692
+
693
+ The sheaf `\mathcal{O}(D)` associated to the given divisor
694
+ `D` is a line bundle if and only if the divisor is
695
+ Cartier.
696
+
697
+ EXAMPLES::
698
+
699
+ sage: X = toric_varieties.P4_11169()
700
+ sage: D = X.divisor(3)
701
+ sage: D.is_Cartier()
702
+ False
703
+ sage: D.is_QQ_Cartier()
704
+ True
705
+ """
706
+ try:
707
+ return self._is_Cartier
708
+ except AttributeError:
709
+ pass
710
+
711
+ self._is_Cartier = self.is_QQ_Cartier()
712
+ if self._is_Cartier:
713
+ fan = self.parent().scheme().fan()
714
+ M = fan.dual_lattice()
715
+ self._is_Cartier = all(self.m(c) in M for c in fan)
716
+ return self._is_Cartier
717
+
718
+ def is_QQ_Cartier(self):
719
+ r"""
720
+ Return whether the divisor is a `\QQ`-Cartier divisor.
721
+
722
+ A `\QQ`-Cartier divisor is a divisor such that some multiple
723
+ of it is Cartier.
724
+
725
+ EXAMPLES::
726
+
727
+ sage: X = toric_varieties.P4_11169()
728
+ sage: D = X.divisor(3)
729
+ sage: D.is_QQ_Cartier()
730
+ True
731
+
732
+ sage: X = toric_varieties.Cube_face_fan()
733
+ sage: D = X.divisor(3)
734
+ sage: D.is_QQ_Cartier()
735
+ False
736
+ """
737
+ try:
738
+ return self._is_QQ_Cartier
739
+ except AttributeError:
740
+ pass
741
+
742
+ try:
743
+ [self.m(c) for c in self.parent().scheme().fan()]
744
+ self._is_QQ_Cartier = True
745
+ except ValueError:
746
+ self._is_QQ_Cartier = False
747
+ return self._is_QQ_Cartier
748
+
749
+ def is_integral(self):
750
+ r"""
751
+ Return whether the coefficients of the divisor are all integral.
752
+
753
+ EXAMPLES::
754
+
755
+ sage: P2 = toric_varieties.P2()
756
+ sage: DZZ = P2.toric_divisor_group(base_ring=ZZ).gen(0); DZZ
757
+ V(x)
758
+ sage: DQQ = P2.toric_divisor_group(base_ring=QQ).gen(0); DQQ
759
+ V(x)
760
+ sage: DZZ.is_integral()
761
+ True
762
+ sage: DQQ.is_integral()
763
+ True
764
+ """
765
+ return all(coeff in ZZ for coeff, _ in self)
766
+
767
+ def move_away_from(self, cone):
768
+ """
769
+ Move the divisor away from the orbit closure of ``cone``.
770
+
771
+ INPUT:
772
+
773
+ - A ``cone`` of the fan of the toric variety.
774
+
775
+ OUTPUT:
776
+
777
+ A (rationally equivalent) divisor that is moved off the
778
+ orbit closure of the given cone.
779
+
780
+ .. NOTE::
781
+
782
+ A divisor that is Weil but not Cartier might be impossible
783
+ to move away. In this case, a :exc:`ValueError` is raised.
784
+
785
+ EXAMPLES::
786
+
787
+ sage: F = Fan(cones=[(0,1,2,3), (0,1,4)],
788
+ ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)])
789
+ sage: X = ToricVariety(F)
790
+ sage: square_cone = X.fan().cone_containing(0,1,2,3)
791
+ sage: triangle_cone = X.fan().cone_containing(0,1,4)
792
+ sage: line_cone = square_cone.intersection(triangle_cone)
793
+ sage: Cartier = X.divisor([2,2,1,1,1])
794
+ sage: Cartier
795
+ 2*V(z0) + 2*V(z1) + V(z2) + V(z3) + V(z4)
796
+ sage: Cartier.move_away_from(line_cone)
797
+ 3*V(z2) + 3*V(z3) - V(z4)
798
+ sage: QQ_Weil = X.divisor([1,0,1,1,0])
799
+ sage: QQ_Weil.move_away_from(line_cone)
800
+ 2*V(z2) + V(z3) - 1/2*V(z4)
801
+ """
802
+ m = self.m(cone)
803
+ X = self.parent().scheme()
804
+ fan = X.fan()
805
+ if m in fan.lattice():
806
+ ring = self._ring
807
+ else:
808
+ ring = m.base_ring()
809
+ divisor = list(vector(self))
810
+ values = [mult - m * ray for mult, ray in zip(divisor, fan.rays())]
811
+ return ToricDivisor(X, values, ring=ring)
812
+
813
+ def cohomology_class(self):
814
+ r"""
815
+ Return the degree-2 cohomology class associated to the divisor.
816
+
817
+ OUTPUT:
818
+
819
+ The corresponding cohomology class as an instance of
820
+ :class:`~sage.schemes.toric.variety.CohomologyClass`.
821
+ The cohomology class is the first Chern class of the
822
+ associated line bundle `\mathcal{O}(D)`.
823
+
824
+ EXAMPLES::
825
+
826
+ sage: dP6 = toric_varieties.dP6()
827
+ sage: D = dP6.divisor(dP6.fan().ray(0))
828
+ sage: D.cohomology_class() # needs sage.libs.singular
829
+ [y + v - w]
830
+ """
831
+ divisor = vector(self)
832
+ variety = self.parent().scheme()
833
+ HH = variety.cohomology_ring()
834
+ return sum([divisor[i] * HH.gen(i) for i in range(HH.ngens())])
835
+
836
+ def Chern_character(self):
837
+ r"""
838
+ Return the Chern character of the sheaf `\mathcal{O}(D)`
839
+ defined by the divisor `D`.
840
+
841
+ You can also use a shortcut :meth:`ch`.
842
+
843
+ EXAMPLES::
844
+
845
+ sage: dP6 = toric_varieties.dP6()
846
+ sage: N = dP6.fan().lattice()
847
+ sage: D3 = dP6.divisor(dP6.fan().cone_containing( N(0,1) ))
848
+ sage: D5 = dP6.divisor(dP6.fan().cone_containing( N(-1,-1) ))
849
+ sage: D6 = dP6.divisor(dP6.fan().cone_containing( N(0,-1) ))
850
+ sage: D = -D3 + 2*D5 - D6
851
+ sage: D.Chern_character() # needs sage.libs.singular
852
+ [5*w^2 + y - 2*v + w + 1]
853
+ sage: dP6.integrate(D.ch() * dP6.Td()) # needs sage.libs.singular
854
+ -4
855
+ """
856
+ return self.cohomology_class().exp()
857
+
858
+ ch = Chern_character
859
+
860
+ def divisor_class(self):
861
+ r"""
862
+ Return the linear equivalence class of the divisor.
863
+
864
+ OUTPUT:
865
+
866
+ The class of the divisor in `\mathop{Cl}(X)
867
+ \otimes_\ZZ \QQ` as an instance of
868
+ :class:`ToricRationalDivisorClassGroup`.
869
+
870
+ EXAMPLES::
871
+
872
+ sage: dP6 = toric_varieties.dP6()
873
+ sage: D = dP6.divisor(0)
874
+ sage: D.divisor_class()
875
+ Divisor class [1, 0, 0, 0]
876
+ """
877
+ if '_divisor_class' not in self.__dict__:
878
+ self._divisor_class = self.parent().scheme().rational_class_group()(self)
879
+ return self._divisor_class
880
+
881
+ def Chow_cycle(self, ring=ZZ):
882
+ r"""
883
+ Return the Chow homology class of the divisor.
884
+
885
+ INPUT:
886
+
887
+ - ``ring`` -- either ``ZZ`` (default) or ``QQ``; the base ring
888
+ of the Chow group
889
+
890
+ OUTPUT:
891
+
892
+ The :class:`~sage.schemes.toric.chow_group.ChowCycle`
893
+ represented by the divisor.
894
+
895
+ EXAMPLES::
896
+
897
+ sage: dP6 = toric_varieties.dP6()
898
+ sage: cone = dP6.fan(1)[5]
899
+ sage: D = dP6.divisor(cone); D
900
+ V(w)
901
+ sage: D.Chow_cycle()
902
+ ( 0 | -1, 0, 1, 1 | 0 )
903
+ sage: dP6.Chow_group()(cone)
904
+ ( 0 | -1, 0, 1, 1 | 0 )
905
+ """
906
+ toric_variety = self.parent().scheme()
907
+ fan = toric_variety.fan()
908
+ A = toric_variety.Chow_group(ring)
909
+ return sum(self.coefficient(i) * A(cone_1d)
910
+ for i, cone_1d in enumerate(fan(dim=1)))
911
+
912
+ def is_ample(self):
913
+ r"""
914
+ Return whether a `\QQ`-Cartier divisor is ample.
915
+
916
+ OUTPUT: ``True`` if the divisor is in the ample cone, ``False`` otherwise
917
+
918
+ .. NOTE::
919
+
920
+ * For a `\QQ`-Cartier divisor, some positive integral
921
+ multiple is Cartier. We return whether this associated
922
+ divisor is ample, i.e. corresponds to an ample line bundle.
923
+
924
+ * In the orbifold case, the ample cone is an open
925
+ and full-dimensional cone in the rational divisor class
926
+ group :class:`ToricRationalDivisorClassGroup`.
927
+
928
+ * If the variety has worse than orbifold singularities,
929
+ the ample cone is a full-dimensional cone within the
930
+ (not full-dimensional) subspace spanned by the Cartier
931
+ divisors inside the rational (Weil) divisor class group,
932
+ that is, :class:`ToricRationalDivisorClassGroup`. The
933
+ ample cone is then relative open (open in this
934
+ subspace).
935
+
936
+ * See also :meth:`is_nef`.
937
+
938
+ * A toric divisor is ample if and only if its support
939
+ function is strictly convex.
940
+
941
+ EXAMPLES::
942
+
943
+ sage: P2 = toric_varieties.P2()
944
+ sage: K = P2.K()
945
+ sage: (+K).is_ample()
946
+ False
947
+ sage: (0*K).is_ample()
948
+ False
949
+ sage: (-K).is_ample()
950
+ True
951
+
952
+ Example 6.1.3, 6.1.11, 6.1.17 of [CLS2011]_::
953
+
954
+ sage: from itertools import product
955
+ sage: fan = Fan(cones=[(0,1), (1,2), (2,3), (3,0)],
956
+ ....: rays=[(-1,2), (0,1), (1,0), (0,-1)])
957
+ sage: F2 = ToricVariety(fan,'u1, u2, u3, u4')
958
+ sage: def D(a, b): return a*F2.divisor(2) + b*F2.divisor(3)
959
+ sage: [ (a,b) for a,b in product(range(-3,3), repeat=2)
960
+ ....: if D(a,b).is_ample() ]
961
+ [(1, 1), (1, 2), (2, 1), (2, 2)]
962
+ sage: [ (a,b) for a,b in product(range(-3,3), repeat=2)
963
+ ....: if D(a,b).is_nef() ]
964
+ [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
965
+
966
+ A (worse than orbifold) singular Fano threefold::
967
+
968
+ sage: points = [(1,0,0),(0,1,0),(0,0,1),(-2,0,-1),(-2,-1,0),(-3,-1,-1),(1,1,1)]
969
+ sage: facets = [[0,1,3],[0,1,6],[0,2,4],[0,2,6],[0,3,5],[0,4,5],[1,2,3,4,5,6]]
970
+ sage: X = ToricVariety(Fan(cones=facets, rays=points))
971
+ sage: X.rational_class_group().dimension()
972
+ 4
973
+ sage: X.Kaehler_cone().rays()
974
+ Divisor class [1, 0, 0, 0]
975
+ in Basis lattice of The toric rational divisor class group
976
+ of a 3-d toric variety covered by 7 affine patches
977
+ sage: antiK = -X.K()
978
+ sage: antiK.divisor_class()
979
+ Divisor class [2, 0, 0, 0]
980
+ sage: antiK.is_ample()
981
+ True
982
+ """
983
+ try:
984
+ return self._is_ample
985
+ except AttributeError:
986
+ pass
987
+
988
+ assert self.is_QQ_Cartier(), 'The divisor must be QQ-Cartier.'
989
+ Kc = self.parent().scheme().Kaehler_cone()
990
+ self._is_ample = Kc.relative_interior_contains(self.divisor_class())
991
+ return self._is_ample
992
+
993
+ def is_nef(self):
994
+ r"""
995
+ Return whether a `\QQ`-Cartier divisor is nef.
996
+
997
+ OUTPUT:
998
+
999
+ - ``True`` if the divisor is in the closure of the ample cone,
1000
+ ``False`` otherwise.
1001
+
1002
+ .. NOTE::
1003
+
1004
+ * For a `\QQ`-Cartier divisor, some positive integral multiple is
1005
+ Cartier. We return whether this associated divisor is nef.
1006
+
1007
+ * The nef cone is the closure of the ample cone.
1008
+
1009
+ * See also :meth:`is_ample`.
1010
+
1011
+ * A toric divisor is nef if and only if its support
1012
+ function is convex (but not necessarily strictly
1013
+ convex).
1014
+
1015
+ * A toric Cartier divisor is nef if and only if its linear
1016
+ system is basepoint free.
1017
+
1018
+ EXAMPLES::
1019
+
1020
+ sage: P2 = toric_varieties.P2()
1021
+ sage: K = P2.K()
1022
+ sage: (+K).is_nef()
1023
+ False
1024
+ sage: (0*K).is_nef()
1025
+ True
1026
+ sage: (-K).is_nef()
1027
+ True
1028
+
1029
+ Example 6.1.3, 6.1.11, 6.1.17 of [CLS2011]_::
1030
+
1031
+ sage: from itertools import product
1032
+ sage: fan = Fan(cones=[(0,1), (1,2), (2,3), (3,0)],
1033
+ ....: rays=[(-1,2), (0,1), (1,0), (0,-1)])
1034
+ sage: F2 = ToricVariety(fan,'u1, u2, u3, u4')
1035
+ sage: def D(a, b): return a*F2.divisor(2) + b*F2.divisor(3)
1036
+ sage: [ (a,b) for a,b in product(range(-3,3), repeat=2)
1037
+ ....: if D(a,b).is_ample() ]
1038
+ [(1, 1), (1, 2), (2, 1), (2, 2)]
1039
+ sage: [ (a,b) for a,b in product(range(-3,3), repeat=2)
1040
+ ....: if D(a,b).is_nef() ]
1041
+ [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
1042
+ """
1043
+ try:
1044
+ return self._is_nef
1045
+ except AttributeError:
1046
+ pass
1047
+
1048
+ assert self.is_QQ_Cartier(), 'The divisor must be QQ-Cartier.'
1049
+ self._is_nef = self.divisor_class() in self.parent().scheme().Kaehler_cone()
1050
+ return self._is_nef
1051
+
1052
+ def polyhedron(self):
1053
+ r"""
1054
+ Return the polyhedron `P_D\subset M` associated to a toric
1055
+ divisor `D`.
1056
+
1057
+ OUTPUT: `P_D` as an instance of :class:`~sage.geometry.polyhedron.base.Polyhedron_base`
1058
+
1059
+ EXAMPLES::
1060
+
1061
+ sage: dP7 = toric_varieties.dP7()
1062
+ sage: D = dP7.divisor(2)
1063
+ sage: P_D = D.polyhedron(); P_D
1064
+ A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
1065
+ sage: P_D.Vrepresentation()
1066
+ (A vertex at (0, 0),)
1067
+ sage: D.is_nef()
1068
+ False
1069
+ sage: dP7.integrate(D.ch() * dP7.Td()) # needs sage.libs.singular
1070
+ 1
1071
+ sage: P_antiK = (-dP7.K()).polyhedron(); P_antiK
1072
+ A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 5 vertices
1073
+ sage: P_antiK.Vrepresentation()
1074
+ (A vertex at (1, -1), A vertex at (0, 1), A vertex at (1, 0),
1075
+ A vertex at (-1, 1), A vertex at (-1, -1))
1076
+ sage: P_antiK.integral_points()
1077
+ ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 0), (0, 1), (1, -1), (1, 0))
1078
+
1079
+ Example 6.1.3, 6.1.11, 6.1.17 of [CLS2011]_::
1080
+
1081
+ sage: fan = Fan(cones=[(0,1), (1,2), (2,3), (3,0)],
1082
+ ....: rays=[(-1,2), (0,1), (1,0), (0,-1)])
1083
+ sage: F2 = ToricVariety(fan,'u1, u2, u3, u4')
1084
+ sage: D = F2.divisor(3)
1085
+ sage: D.polyhedron().Vrepresentation()
1086
+ (A vertex at (0, 0), A vertex at (2, 1), A vertex at (0, 1))
1087
+ sage: Dprime = F2.divisor(1) + D
1088
+ sage: Dprime.polyhedron().Vrepresentation()
1089
+ (A vertex at (2, 1), A vertex at (0, 1), A vertex at (0, 0))
1090
+ sage: D.is_ample()
1091
+ False
1092
+ sage: D.is_nef()
1093
+ True
1094
+ sage: Dprime.is_nef()
1095
+ False
1096
+
1097
+ A more complicated example where `P_D` is not a lattice polytope::
1098
+
1099
+ sage: X = toric_varieties.BCdlOG_base()
1100
+ sage: antiK = -X.K()
1101
+ sage: P_D = antiK.polyhedron()
1102
+ sage: P_D
1103
+ A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
1104
+ sage: P_D.Vrepresentation()
1105
+ (A vertex at (1, -1, 0), A vertex at (1, -3, 1),
1106
+ A vertex at (1, 1, 1), A vertex at (-5, 1, 1),
1107
+ A vertex at (1, 1, -1/2), A vertex at (1, 1/2, -1/2),
1108
+ A vertex at (-1, -1, 0), A vertex at (-5, -3, 1))
1109
+ sage: P_D.Hrepresentation()
1110
+ (An inequality (-1, 0, 0) x + 1 >= 0, An inequality (0, -1, 0) x + 1 >= 0,
1111
+ An inequality (0, 0, -1) x + 1 >= 0, An inequality (1, 0, 4) x + 1 >= 0,
1112
+ An inequality (0, 1, 3) x + 1 >= 0, An inequality (0, 1, 2) x + 1 >= 0)
1113
+ sage: P_D.integral_points()
1114
+ ((-1, -1, 0), (0, -1, 0), (1, -1, 0), (-1, 0, 0), (0, 0, 0),
1115
+ (1, 0, 0), (-1, 1, 0), (0, 1, 0), (1, 1, 0), (-5, -3, 1),
1116
+ (-4, -3, 1), (-3, -3, 1), (-2, -3, 1), (-1, -3, 1), (0, -3, 1),
1117
+ (1, -3, 1), (-5, -2, 1), (-4, -2, 1), (-3, -2, 1), (-2, -2, 1),
1118
+ (-1, -2, 1), (0, -2, 1), (1, -2, 1), (-5, -1, 1), (-4, -1, 1),
1119
+ (-3, -1, 1), (-2, -1, 1), (-1, -1, 1), (0, -1, 1), (1, -1, 1),
1120
+ (-5, 0, 1), (-4, 0, 1), (-3, 0, 1), (-2, 0, 1), (-1, 0, 1),
1121
+ (0, 0, 1), (1, 0, 1), (-5, 1, 1), (-4, 1, 1), (-3, 1, 1),
1122
+ (-2, 1, 1), (-1, 1, 1), (0, 1, 1), (1, 1, 1))
1123
+ """
1124
+ try:
1125
+ return self._polyhedron
1126
+ except AttributeError:
1127
+ pass
1128
+
1129
+ fan = self.parent().scheme().fan()
1130
+ divisor = vector(self)
1131
+ ieqs = [[divisor[i]] + list(fan.ray(i)) for i in range(fan.nrays())]
1132
+ self._polyhedron = Polyhedron(ieqs=ieqs)
1133
+ return self._polyhedron
1134
+
1135
+ def sections(self):
1136
+ """
1137
+ Return the global sections (as points of the `M`-lattice) of
1138
+ the line bundle (or reflexive sheaf) associated to the
1139
+ divisor.
1140
+
1141
+ OUTPUT: a :class:`tuple` of points of lattice `M`
1142
+
1143
+ EXAMPLES::
1144
+
1145
+ sage: P2 = toric_varieties.P2()
1146
+ sage: P2.fan().nrays()
1147
+ 3
1148
+ sage: P2.divisor(0).sections()
1149
+ (M(-1, 0), M(-1, 1), M(0, 0))
1150
+ sage: P2.divisor(1).sections()
1151
+ (M(0, -1), M(0, 0), M(1, -1))
1152
+ sage: P2.divisor(2).sections()
1153
+ (M(0, 0), M(0, 1), M(1, 0))
1154
+
1155
+ The divisor can be non-nef yet still have sections::
1156
+
1157
+ sage: rays = [(1,0,0),(0,1,0),(0,0,1),(-2,0,-1),(-2,-1,0),(-3,-1,-1),(1,1,1),(-1,0,0)]
1158
+ sage: cones = [[0,1,3],[0,1,6],[0,2,4],[0,2,6],[0,3,5],[0,4,5],[1,3,7],[1,6,7],[2,4,7],[2,6,7],[3,5,7],[4,5,7]]
1159
+ sage: X = ToricVariety(Fan(rays=rays, cones=cones))
1160
+ sage: D = X.divisor(2); D
1161
+ V(z2)
1162
+ sage: D.is_nef()
1163
+ False
1164
+ sage: D.sections()
1165
+ (M(0, 0, 0),)
1166
+ sage: D.cohomology(dim=True)
1167
+ (1, 0, 0, 0)
1168
+ """
1169
+ try:
1170
+ return self._sections
1171
+ except AttributeError:
1172
+ pass
1173
+
1174
+ M = self.parent().scheme().fan().dual_lattice()
1175
+ self._sections = tuple(M(m)
1176
+ for m in self.polyhedron().integral_points())
1177
+ return self._sections
1178
+
1179
+ def sections_monomials(self):
1180
+ """
1181
+ Return the global sections of the line bundle associated to the
1182
+ Cartier divisor.
1183
+
1184
+ The sections are described as monomials in the generalized homogeneous
1185
+ coordinates.
1186
+
1187
+ OUTPUT: tuple of monomials in the coordinate ring of ``self``
1188
+
1189
+ EXAMPLES::
1190
+
1191
+ sage: P2 = toric_varieties.P2()
1192
+ sage: P2.fan().nrays()
1193
+ 3
1194
+ sage: P2.divisor(0).sections_monomials()
1195
+ (z, y, x)
1196
+ sage: P2.divisor(1).sections_monomials()
1197
+ (z, y, x)
1198
+ sage: P2.divisor(2).sections_monomials()
1199
+ (z, y, x)
1200
+
1201
+ From [Cox]_ page 38::
1202
+
1203
+ sage: lp = LatticePolytope([(1,0), (1,1), (0,1), (-1,0), (0,-1)])
1204
+ sage: lp # needs polytopes_db
1205
+ 2-d reflexive polytope #5 in 2-d lattice M
1206
+ sage: dP7 = ToricVariety(FaceFan(lp), 'x1, x2, x3, x4, x5')
1207
+ sage: AK = -dP7.K()
1208
+ sage: AK.sections()
1209
+ (N(-1, 0), N(-1, 1), N(0, -1), N(0, 0),
1210
+ N(0, 1), N(1, -1), N(1, 0), N(1, 1))
1211
+ sage: AK.sections_monomials()
1212
+ (x3*x4^2*x5, x2*x3^2*x4^2, x1*x4*x5^2, x1*x2*x3*x4*x5,
1213
+ x1*x2^2*x3^2*x4, x1^2*x2*x5^2, x1^2*x2^2*x3*x5, x1^2*x2^3*x3^2)
1214
+ """
1215
+ return tuple(self.monomial(m) for m in self.sections())
1216
+
1217
+ def monomial(self, point):
1218
+ r"""
1219
+ Return the monomial in the homogeneous coordinate ring
1220
+ associated to the ``point`` in the dual lattice.
1221
+
1222
+ INPUT:
1223
+
1224
+ - ``point`` -- a point in ``self.variety().fan().dual_lattice()``
1225
+
1226
+ OUTPUT:
1227
+
1228
+ For a fixed divisor ``D``, the sections are generated by
1229
+ monomials in :meth:`ToricVariety.coordinate_ring
1230
+ <sage.schemes.toric.variety.ToricVariety_field.coordinate_ring>`.
1231
+ Alternatively, the monomials can be described as `M`-lattice
1232
+ points in the polyhedron ``D.polyhedron()``. This method
1233
+ converts the points `m\in M` into homogeneous polynomials.
1234
+
1235
+ EXAMPLES::
1236
+
1237
+ sage: P2 = toric_varieties.P2()
1238
+ sage: O3_P2 = -P2.K()
1239
+ sage: M = P2.fan().dual_lattice()
1240
+ sage: O3_P2.monomial( M(0,0) )
1241
+ x*y*z
1242
+ """
1243
+ X = self.parent().scheme()
1244
+ fan = X.fan()
1245
+ assert point in fan.dual_lattice(), \
1246
+ f'{point} must be a point in the M-lattice'
1247
+ R = X.coordinate_ring()
1248
+ return prod([R.gen(i) ** (point * fan.ray(i) + self.coefficient(i))
1249
+ for i in range(fan.nrays())])
1250
+
1251
+ def Kodaira_map(self, names='z'):
1252
+ r"""
1253
+ Return the Kodaira map.
1254
+
1255
+ The Kodaira map is the rational map `X_\Sigma \to
1256
+ \mathbb{P}^{n-1}`, where `n` equals the number of sections. It
1257
+ is defined by the monomial sections of the line bundle.
1258
+
1259
+ If the divisor is ample and the toric variety smooth or of
1260
+ dimension 2, then this is an embedding.
1261
+
1262
+ INPUT:
1263
+
1264
+ - ``names`` -- string (default: ``'z'``); the
1265
+ variable names for the destination projective space
1266
+
1267
+ EXAMPLES::
1268
+
1269
+ sage: P1.<u,v> = toric_varieties.P1()
1270
+ sage: D = -P1.K()
1271
+ sage: D.Kodaira_map() # needs fpylll sage.libs.singular
1272
+ Scheme morphism:
1273
+ From: 1-d CPR-Fano toric variety covered by 2 affine patches
1274
+ To: Closed subscheme of Projective Space of dimension 2
1275
+ over Rational Field defined by: -z1^2 + z0*z2
1276
+ Defn: Defined on coordinates by sending [u : v] to (v^2 : u*v : u^2)
1277
+
1278
+ sage: dP6 = toric_varieties.dP6()
1279
+ sage: D = -dP6.K()
1280
+ sage: D.Kodaira_map(names='x') # needs fpylll sage.libs.singular
1281
+ Scheme morphism:
1282
+ From: 2-d CPR-Fano toric variety covered by 6 affine patches
1283
+ To: Closed subscheme of Projective Space of dimension 6
1284
+ over Rational Field defined by:
1285
+ -x1*x5 + x0*x6, -x2*x3 + x0*x5, -x1*x3 + x0*x4,
1286
+ x4*x5 - x3*x6, -x1*x2 + x0*x3, x3*x5 - x2*x6,
1287
+ x3*x4 - x1*x6, x3^2 - x1*x5, x2*x4 - x1*x5,
1288
+ -x1*x5^2 + x2*x3*x6, -x1*x5^3 + x2^2*x6^2
1289
+ Defn: Defined on coordinates by sending [x : u : y : v : z : w] to
1290
+ (x*u^2*y^2*v : x^2*u^2*y*w : u*y^2*v^2*z : x*u*y*v*z*w :
1291
+ x^2*u*z*w^2 : y*v^2*z^2*w : x*v*z^2*w^2)
1292
+ """
1293
+ sections = self.sections_monomials()
1294
+ if not sections:
1295
+ raise ValueError('the Kodaira map is not defined for divisors without sections')
1296
+ src = self.parent().scheme()
1297
+ from sage.schemes.projective.projective_space import ProjectiveSpace
1298
+ ambient = ProjectiveSpace(src.base_ring(), len(sections) - 1, names=names)
1299
+ A = matrix(ZZ, [list(s.exponents()[0]) for s in sections]).transpose()
1300
+ from sage.schemes.toric.ideal import ToricIdeal
1301
+ IA = ToricIdeal(A, names=names)
1302
+ dst = ambient.subscheme(IA)
1303
+ homset = src.Hom(dst)
1304
+ return homset(sections)
1305
+
1306
+ def _sheaf_complex(self, m):
1307
+ r"""
1308
+ Return a simplicial complex whose cohomology is isomorphic to the
1309
+ `m\in M`-graded piece of the sheaf cohomology.
1310
+
1311
+ Helper for :meth:`cohomology`.
1312
+
1313
+ INPUT:
1314
+
1315
+ - ``m`` -- a point in ``self.scheme().fan().dual_lattice()``
1316
+
1317
+ OUTPUT: a :class:`simplicial complex <sage.topology.simplicial_complex.SimplicialComplex>`
1318
+
1319
+ EXAMPLES::
1320
+
1321
+ sage: dP6 = toric_varieties.dP6()
1322
+ sage: D0 = dP6.divisor(0)
1323
+ sage: D2 = dP6.divisor(2)
1324
+ sage: D3 = dP6.divisor(3)
1325
+ sage: D = -D0 + 2*D2 - D3
1326
+ sage: M = dP6.fan().dual_lattice()
1327
+ sage: D._sheaf_complex( M(1,0) )
1328
+ Simplicial complex with vertex set (0, 1, 3) and facets {(3,), (0, 1)}
1329
+ """
1330
+ fan = self.parent().scheme().fan()
1331
+ ray_is_negative = [m * ray + self.coefficient(i) < 0
1332
+ for i, ray in enumerate(fan.rays())]
1333
+
1334
+ def cone_is_negative(cone): # and non-trivial
1335
+ if cone.is_trivial():
1336
+ return False
1337
+ return all(ray_is_negative[i] for i in cone.ambient_ray_indices())
1338
+
1339
+ negative_cones = [cone for cone in flatten(fan.cones()) if cone_is_negative(cone)]
1340
+ return SimplicialComplex([c.ambient_ray_indices() for c in negative_cones])
1341
+
1342
+ def _sheaf_cohomology(self, cplx):
1343
+ """
1344
+ Return the sheaf cohomology as the shifted, reduced cohomology
1345
+ of the complex.
1346
+
1347
+ Helper for :meth:`cohomology`.
1348
+
1349
+ INPUT:
1350
+
1351
+ - ``cplx`` -- simplicial complex
1352
+
1353
+ OUTPUT: integer vector
1354
+
1355
+ EXAMPLES::
1356
+
1357
+ sage: dP6 = toric_varieties.dP6()
1358
+ sage: D = dP6.divisor(1)
1359
+ sage: D._sheaf_cohomology( SimplicialComplex() )
1360
+ (1, 0, 0)
1361
+ sage: D._sheaf_cohomology( SimplicialComplex([[1,2],[2,3],[3,1]]) )
1362
+ (0, 0, 1)
1363
+
1364
+ A more complicated example to test that :issue:`10731` is fixed::
1365
+
1366
+ sage: cell24 = Polyhedron(vertices=[
1367
+ ....: (1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1),(1,-1,-1,1),(0,0,-1,1),
1368
+ ....: (0,-1,0,1),(-1,0,0,1),(1,0,0,-1),(0,1,0,-1),(0,0,1,-1),(-1,1,1,-1),
1369
+ ....: (1,-1,-1,0),(0,0,-1,0),(0,-1,0,0),(-1,0,0,0),(1,-1,0,0),(1,0,-1,0),
1370
+ ....: (0,1,1,-1),(-1,1,1,0),(-1,1,0,0),(-1,0,1,0),(0,-1,-1,1),(0,0,0,-1)])
1371
+ sage: X = ToricVariety(FaceFan(cell24.lattice_polytope())) # long time
1372
+ sage: D = -X.divisor(0) # long time
1373
+ sage: D.cohomology(dim=True) # long time
1374
+ (0, 0, 0, 0, 0)
1375
+ """
1376
+ d = self.parent().scheme().dimension()
1377
+ if cplx.dimension() == -1:
1378
+ return vector(ZZ, [1] + [0] * d)
1379
+
1380
+ HH = cplx.homology(base_ring=QQ, cohomology=True)
1381
+ HH_list = [0] * (d + 1)
1382
+ for h in HH.items():
1383
+ degree = h[0] + 1
1384
+ cohomology_dim = h[1].dimension()
1385
+ if degree > d or degree < 0:
1386
+ assert cohomology_dim == 0
1387
+ continue
1388
+ HH_list[degree] = cohomology_dim
1389
+
1390
+ return vector(ZZ, HH_list)
1391
+
1392
+ def _sheaf_cohomology_support(self):
1393
+ r"""
1394
+ Return the weights for which the cohomology groups can be non-vanishing.
1395
+
1396
+ OUTPUT:
1397
+
1398
+ A :class:`~sage.geometry.polyhedron.base.Polyhedron_base`
1399
+ object that contains all weights `m` for which the sheaf
1400
+ cohomology is *potentially* non-vanishing.
1401
+
1402
+ ALGORITHM:
1403
+
1404
+ See :meth:`cohomology` and note that every `d`-tuple (where
1405
+ `d` is the dimension of the variety) of rays determines one
1406
+ vertex in the chamber decomposition if none of the hyperplanes
1407
+ are parallel.
1408
+
1409
+ EXAMPLES::
1410
+
1411
+ sage: dP6 = toric_varieties.dP6()
1412
+ sage: D0 = dP6.divisor(0)
1413
+ sage: D2 = dP6.divisor(2)
1414
+ sage: D3 = dP6.divisor(3)
1415
+ sage: D = -D0 + 2*D2 - D3
1416
+ sage: supp = D._sheaf_cohomology_support()
1417
+ sage: supp
1418
+ A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
1419
+ sage: supp.Vrepresentation()
1420
+ (A vertex at (-1, 1), A vertex at (0, -1), A vertex at (3, -1), A vertex at (0, 2))
1421
+ """
1422
+ X = self.parent().scheme()
1423
+ fan = X.fan()
1424
+ if not X.is_complete():
1425
+ raise ValueError("%s is not complete, its cohomology is not "
1426
+ "finite-dimensional" % X)
1427
+ d = X.dimension()
1428
+ chamber_vertices = []
1429
+ for pindexlist in Combinations(range(fan.nrays()), d):
1430
+ A = matrix(ZZ, [fan.ray(p) for p in pindexlist])
1431
+ b = vector([self.coefficient(p) for p in pindexlist])
1432
+ try:
1433
+ chamber_vertices.append(A.solve_right(-b))
1434
+ except ValueError:
1435
+ pass
1436
+ return Polyhedron(vertices=chamber_vertices)
1437
+
1438
+ def cohomology(self, weight=None, deg=None, dim=False):
1439
+ r"""
1440
+ Return the cohomology of the line bundle associated to the
1441
+ Cartier divisor or reflexive sheaf associated to the Weil
1442
+ divisor.
1443
+
1444
+ .. NOTE::
1445
+
1446
+ The cohomology of a toric line bundle/reflexive sheaf is
1447
+ graded by the usual degree as well as by the `M`-lattice.
1448
+
1449
+ INPUT:
1450
+
1451
+ - ``weight`` -- (optional) a point of the `M`-lattice
1452
+
1453
+ - ``deg`` -- (optional) the degree of the cohomology group
1454
+
1455
+ - ``dim`` -- boolean; if ``False`` (default), the cohomology
1456
+ groups are returned as vector spaces. If ``True``, only the
1457
+ dimension of the vector space(s) is returned.
1458
+
1459
+ OUTPUT:
1460
+
1461
+ The vector space `H^\text{deg}(X,\mathcal{O}(D))` (if ``deg``
1462
+ is specified) or a dictionary ``{degree:cohomology(degree)}``
1463
+ of all degrees between 0 and the dimension of the variety.
1464
+
1465
+ If ``weight`` is specified, return only the subspace
1466
+ `H^\text{deg}(X,\mathcal{O}(D))_\text{weight}` of the
1467
+ cohomology of the given weight.
1468
+
1469
+ If ``dim==True``, the dimension of the cohomology vector space
1470
+ is returned instead of actual vector space. Moreover, if
1471
+ ``deg`` was not specified, a vector whose entries are the
1472
+ dimensions is returned instead of a dictionary.
1473
+
1474
+ ALGORITHM:
1475
+
1476
+ Roughly, Chech cohomology is used to compute the
1477
+ cohomology. For toric divisors, the local sections can be
1478
+ chosen to be monomials (instead of general homogeneous
1479
+ polynomials), this is the reason for the extra grading by
1480
+ `m\in M`. General references would be [Ful1993]_, [CLS2011]_. Here
1481
+ are some salient features of our implementation:
1482
+
1483
+ * First, a finite set of `M`-lattice points is identified that
1484
+ supports the cohomology. The toric divisor determines a
1485
+ (polyhedral) chamber decomposition of `M_\RR`, see Section
1486
+ 9.1 and Figure 4 of [CLS2011]_. The cohomology vanishes on the
1487
+ non-compact chambers. Hence, the convex hull of the vertices
1488
+ of the chamber decomposition contains all non-vanishing
1489
+ cohomology groups. This is returned by the private method
1490
+ :meth:`_sheaf_cohomology_support`.
1491
+
1492
+ It would be more efficient, but more difficult to implement,
1493
+ to keep track of all of the individual chambers. We leave
1494
+ this for future work.
1495
+
1496
+ * For each point `m\in M`, the weight-`m` part of the
1497
+ cohomology can be rewritten as the cohomology of a
1498
+ simplicial complex, see Exercise 9.1.10 of [CLS2011]_,
1499
+ [Per2007]_. This is returned by the private method
1500
+ :meth:`_sheaf_complex`.
1501
+
1502
+ The simplicial complex is the same for all points in a
1503
+ chamber, but we currently do not make use of this and
1504
+ compute each point `m\in M` separately.
1505
+
1506
+ * Finally, the cohomology (over `\QQ`) of this simplicial
1507
+ complex is computed in the private method
1508
+ :meth:`_sheaf_cohomology`. Summing over the supporting
1509
+ points `m\in M` yields the cohomology of the sheaf`.
1510
+
1511
+ EXAMPLES:
1512
+
1513
+ Example 9.1.7 of Cox, Little, Schenck: "Toric Varieties" [CLS2011]_::
1514
+
1515
+ sage: F = Fan(cones=[(0,1), (1,2), (2,3), (3,4), (4,5), (5,0)],
1516
+ ....: rays=[(1,0), (1,1), (0,1), (-1,0), (-1,-1), (0,-1)])
1517
+ sage: dP6 = ToricVariety(F)
1518
+ sage: D3 = dP6.divisor(2)
1519
+ sage: D5 = dP6.divisor(4)
1520
+ sage: D6 = dP6.divisor(5)
1521
+ sage: D = -D3 + 2*D5 - D6
1522
+ sage: D.cohomology()
1523
+ {0: Vector space of dimension 0 over Rational Field,
1524
+ 1: Vector space of dimension 4 over Rational Field,
1525
+ 2: Vector space of dimension 0 over Rational Field}
1526
+ sage: D.cohomology(deg=1)
1527
+ Vector space of dimension 4 over Rational Field
1528
+ sage: M = F.dual_lattice()
1529
+ sage: D.cohomology( M(0,0) )
1530
+ {0: Vector space of dimension 0 over Rational Field,
1531
+ 1: Vector space of dimension 1 over Rational Field,
1532
+ 2: Vector space of dimension 0 over Rational Field}
1533
+ sage: D.cohomology( weight=M(0,0), deg=1 )
1534
+ Vector space of dimension 1 over Rational Field
1535
+ sage: dP6.integrate(D.ch() * dP6.Td()) # needs sage.libs.singular
1536
+ -4
1537
+
1538
+ Note the different output options::
1539
+
1540
+ sage: D.cohomology()
1541
+ {0: Vector space of dimension 0 over Rational Field,
1542
+ 1: Vector space of dimension 4 over Rational Field,
1543
+ 2: Vector space of dimension 0 over Rational Field}
1544
+ sage: D.cohomology(dim=True)
1545
+ (0, 4, 0)
1546
+ sage: D.cohomology(weight=M(0,0))
1547
+ {0: Vector space of dimension 0 over Rational Field,
1548
+ 1: Vector space of dimension 1 over Rational Field,
1549
+ 2: Vector space of dimension 0 over Rational Field}
1550
+ sage: D.cohomology(weight=M(0,0), dim=True)
1551
+ (0, 1, 0)
1552
+ sage: D.cohomology(deg=1)
1553
+ Vector space of dimension 4 over Rational Field
1554
+ sage: D.cohomology(deg=1, dim=True)
1555
+ 4
1556
+ sage: D.cohomology(weight=M(0,0), deg=1)
1557
+ Vector space of dimension 1 over Rational Field
1558
+ sage: D.cohomology(weight=M(0,0), deg=1, dim=True)
1559
+ 1
1560
+
1561
+ Here is a Weil (non-Cartier) divisor example::
1562
+
1563
+ sage: K = toric_varieties.Cube_nonpolyhedral().K()
1564
+ sage: K.is_Weil()
1565
+ True
1566
+ sage: K.is_QQ_Cartier()
1567
+ False
1568
+ sage: K.cohomology(dim=True)
1569
+ (0, 0, 0, 1)
1570
+ """
1571
+ if '_cohomology_vector' in self.__dict__ and weight is None:
1572
+ # cache the cohomology but not the individual weight pieces
1573
+ HH = self._cohomology_vector
1574
+ else:
1575
+ X = self.parent().scheme()
1576
+ M = X.fan().dual_lattice()
1577
+ support = self._sheaf_cohomology_support()
1578
+ if weight is None:
1579
+ m_list = [M(p) for p in support.integral_points()]
1580
+ else:
1581
+ m_list = [M(weight)]
1582
+
1583
+ HH = vector(ZZ, [0] * (X.dimension() + 1))
1584
+ for m_point in m_list:
1585
+ cplx = self._sheaf_complex(m_point)
1586
+ HH += self._sheaf_cohomology(cplx)
1587
+
1588
+ if weight is None:
1589
+ self._cohomology_vector = HH
1590
+
1591
+ if dim:
1592
+ if deg is None:
1593
+ return HH
1594
+ else:
1595
+ return HH[deg]
1596
+ else:
1597
+ from sage.modules.free_module import VectorSpace
1598
+ vectorspaces = {k: VectorSpace(self.scheme().base_ring(), HH[k])
1599
+ for k in range(len(HH))}
1600
+ if deg is None:
1601
+ return vectorspaces
1602
+ else:
1603
+ return vectorspaces[deg]
1604
+
1605
+ def cohomology_support(self):
1606
+ r"""
1607
+ Return the weights for which the cohomology groups do not vanish.
1608
+
1609
+ OUTPUT:
1610
+
1611
+ A tuple of dual lattice points. ``self.cohomology(weight=m)``
1612
+ does not vanish if and only if ``m`` is in the output.
1613
+
1614
+ .. NOTE::
1615
+
1616
+ This method is provided for educational purposes and it is
1617
+ not an efficient way of computing the cohomology groups.
1618
+
1619
+ EXAMPLES::
1620
+
1621
+ sage: F = Fan(cones=[(0,1), (1,2), (2,3), (3,4), (4,5), (5,0)],
1622
+ ....: rays=[(1,0), (1,1), (0,1), (-1,0), (-1,-1), (0,-1)])
1623
+ sage: dP6 = ToricVariety(F)
1624
+ sage: D3 = dP6.divisor(2)
1625
+ sage: D5 = dP6.divisor(4)
1626
+ sage: D6 = dP6.divisor(5)
1627
+ sage: D = -D3 + 2*D5 - D6
1628
+ sage: D.cohomology_support()
1629
+ (M(0, 0), M(1, 0), M(2, 0), M(1, 1))
1630
+ """
1631
+ X = self.parent().scheme()
1632
+ M = X.fan().dual_lattice()
1633
+ support_hull = self._sheaf_cohomology_support()
1634
+ support_hull = [M(p) for p in support_hull.integral_points()]
1635
+ support = []
1636
+ for m in support_hull:
1637
+ cplx = self._sheaf_complex(m)
1638
+ HH = self._sheaf_cohomology(cplx)
1639
+ if sum(HH) > 0:
1640
+ support.append(m)
1641
+ return tuple(support)
1642
+
1643
+
1644
+ class ToricDivisorGroup(DivisorGroup_generic):
1645
+ r"""
1646
+ The group of (`\QQ`-T-Weil) divisors on a toric variety.
1647
+
1648
+ EXAMPLES::
1649
+
1650
+ sage: P2 = toric_varieties.P2()
1651
+ sage: P2.toric_divisor_group()
1652
+ Group of toric ZZ-Weil divisors
1653
+ on 2-d CPR-Fano toric variety covered by 3 affine patches
1654
+ """
1655
+
1656
+ def __init__(self, toric_variety, base_ring):
1657
+ r"""
1658
+ Construct an instance of :class:`ToricDivisorGroup`.
1659
+
1660
+ INPUT:
1661
+
1662
+ - ``toric_variety`` -- a
1663
+ :class:`toric variety
1664
+ <sage.schemes.toric.variety.ToricVariety_field>``
1665
+
1666
+ - ``base_ring`` -- the coefficient ring of this divisor group,
1667
+ usually `\ZZ` (default) or `\QQ`
1668
+
1669
+ Implementation note: :meth:`__classcall__` sets the default
1670
+ value for ``base_ring``.
1671
+
1672
+ OUTPUT: divisor group of the toric variety
1673
+
1674
+ EXAMPLES::
1675
+
1676
+ sage: P2 = toric_varieties.P2()
1677
+ sage: from sage.schemes.toric.divisor import ToricDivisorGroup
1678
+ sage: ToricDivisorGroup(P2, base_ring=ZZ)
1679
+ Group of toric ZZ-Weil divisors
1680
+ on 2-d CPR-Fano toric variety covered by 3 affine patches
1681
+
1682
+ Note that :class:`UniqueRepresentation` correctly distinguishes the
1683
+ parent classes even if the schemes are the same::
1684
+
1685
+ sage: from sage.schemes.generic.divisor_group import DivisorGroup
1686
+ sage: DivisorGroup(P2, ZZ) is ToricDivisorGroup(P2, ZZ)
1687
+ False
1688
+ """
1689
+ assert isinstance(toric_variety, ToricVariety_field), str(toric_variety) + ' is not a toric variety!'
1690
+ super().__init__(toric_variety, base_ring)
1691
+
1692
+ def _latex_(self):
1693
+ r"""
1694
+ Return a LaTeX representation of ``self``.
1695
+
1696
+ OUTPUT: string
1697
+
1698
+ TESTS::
1699
+
1700
+ sage: print(toric_varieties.P2().toric_divisor_group()._latex_()) # needs polytopes_db
1701
+ \mathrm{Div_T}\left(\mathbb{P}_{\Delta^{2}_{15}}, \Bold{Z}\right)
1702
+ """
1703
+ return (r"\mathrm{Div_T}\left(%s, %s\right)"
1704
+ % (latex(self.scheme()), latex(self.base_ring())))
1705
+
1706
+ def _repr_(self):
1707
+ """
1708
+ Return a string representation of the toric divisor group.
1709
+
1710
+ OUTPUT: string
1711
+
1712
+ EXAMPLES::
1713
+
1714
+ sage: toric_varieties.P2().toric_divisor_group()._repr_()
1715
+ 'Group of toric ZZ-Weil divisors
1716
+ on 2-d CPR-Fano toric variety covered by 3 affine patches'
1717
+ """
1718
+ ring = self.base_ring()
1719
+ if ring == ZZ:
1720
+ base_ring_str = 'ZZ'
1721
+ elif ring == QQ:
1722
+ base_ring_str = 'QQ'
1723
+ else:
1724
+ base_ring_str = '(' + str(ring) + ')'
1725
+ return 'Group of toric ' + base_ring_str + '-Weil divisors on ' + str(self.scheme())
1726
+
1727
+ def ngens(self):
1728
+ r"""
1729
+ Return the number of generators.
1730
+
1731
+ OUTPUT:
1732
+
1733
+ The number of generators of ``self``, which equals the number of
1734
+ rays in the fan of the toric variety.
1735
+
1736
+ EXAMPLES::
1737
+
1738
+ sage: P2 = toric_varieties.P2()
1739
+ sage: TDiv = P2.toric_divisor_group()
1740
+ sage: TDiv.ngens()
1741
+ 3
1742
+ """
1743
+ return self.scheme().fan().nrays()
1744
+
1745
+ @cached_method
1746
+ def gens(self) -> tuple:
1747
+ r"""
1748
+ Return the generators of the divisor group.
1749
+
1750
+ EXAMPLES::
1751
+
1752
+ sage: P2 = toric_varieties.P2()
1753
+ sage: TDiv = P2.toric_divisor_group()
1754
+ sage: TDiv.gens()
1755
+ (V(x), V(y), V(z))
1756
+ """
1757
+ one = self.base_ring().one()
1758
+ return tuple(ToricDivisor_generic([(one, c)], self)
1759
+ for c in self.scheme().gens())
1760
+
1761
+ def gen(self, i):
1762
+ r"""
1763
+ Return the ``i``-th generator of the divisor group.
1764
+
1765
+ INPUT:
1766
+
1767
+ - ``i`` -- integer
1768
+
1769
+ OUTPUT:
1770
+
1771
+ The divisor `z_i=0`, where `z_i` is the `i`-th homogeneous
1772
+ coordinate.
1773
+
1774
+ EXAMPLES::
1775
+
1776
+ sage: P2 = toric_varieties.P2()
1777
+ sage: TDiv = P2.toric_divisor_group()
1778
+ sage: TDiv.gen(2)
1779
+ V(z)
1780
+ """
1781
+ return self.gens()[i]
1782
+
1783
+ def _element_constructor_(self, x, check=True, reduce=True):
1784
+ r"""
1785
+ Construct a :class:`ToricDivisor_generic`.
1786
+
1787
+ INPUT:
1788
+
1789
+ - ``x`` -- something defining a toric divisor, see
1790
+ :func:`ToricDivisor`
1791
+
1792
+ - ``check``, ``reduce`` -- boolean; See
1793
+ :meth:`ToricDivisor_generic.__init__`
1794
+
1795
+ EXAMPLES::
1796
+
1797
+ sage: P2 = toric_varieties.P2()
1798
+ sage: TDiv = P2.toric_divisor_group()
1799
+ sage: TDiv._element_constructor_([ (1,P2.gen(2)) ])
1800
+ V(z)
1801
+ sage: TDiv( P2.fan(1)[0] )
1802
+ V(x)
1803
+
1804
+ TESTS:
1805
+
1806
+ Check for :issue:`12812`::
1807
+
1808
+ sage: TDiv(0)
1809
+ 0
1810
+ sage: TDiv(1)
1811
+ Traceback (most recent call last):
1812
+ ...
1813
+ TypeError: 'sage.rings.integer.Integer' object is not iterable
1814
+ sage: TDiv(TDiv.gen(0), check=True)
1815
+ V(x)
1816
+ """
1817
+ if isinstance(x, ToricDivisor_generic):
1818
+ if x.parent() is self:
1819
+ return x
1820
+ else:
1821
+ x = x._data
1822
+ return ToricDivisor(self.scheme(), x, self.base_ring(), check, reduce)
1823
+
1824
+ def base_extend(self, R):
1825
+ """
1826
+ Extend the scalars of ``self`` to ``R``.
1827
+
1828
+ INPUT:
1829
+
1830
+ - ``R`` -- ring
1831
+
1832
+ OUTPUT: toric divisor group
1833
+
1834
+ EXAMPLES::
1835
+
1836
+ sage: P2 = toric_varieties.P2()
1837
+ sage: DivZZ = P2.toric_divisor_group()
1838
+ sage: DivQQ = P2.toric_divisor_group(base_ring=QQ)
1839
+ sage: DivZZ.base_extend(QQ) is DivQQ
1840
+ True
1841
+ """
1842
+ # This check prevents extension to cohomology rings via coercion
1843
+ if isinstance(R, CohomologyRing):
1844
+ raise TypeError('coefficient ring cannot be a cohomology ring')
1845
+ if self.base_ring().has_coerce_map_from(R):
1846
+ return self
1847
+ if R.has_coerce_map_from(self.base_ring()):
1848
+ return ToricDivisorGroup(self.scheme(), base_ring=R)
1849
+ raise ValueError(f"the base of {self} cannot be extended to {R}")
1850
+
1851
+ Element = ToricDivisor_generic
1852
+
1853
+
1854
+ class ToricRationalDivisorClassGroup(FreeModule_ambient_field, UniqueRepresentation):
1855
+ r"""
1856
+ The rational divisor class group of a toric variety.
1857
+
1858
+ The **T-Weil divisor class group** `\mathop{Cl}(X)` of a toric
1859
+ variety `X` is a finitely generated abelian group and can contain
1860
+ torsion. Its rank equals the number of rays in the fan of `X`
1861
+ minus the dimension of `X`.
1862
+
1863
+ The **rational divisor class group** is `\mathop{Cl}(X)
1864
+ \otimes_\ZZ \QQ` and never includes torsion. If `X` is *smooth*,
1865
+ this equals the **Picard group** `\mathop{\mathrm{Pic}}(X)`, whose
1866
+ elements are the isomorphism classes of line bundles on `X`. The
1867
+ group law (which we write as addition) is the tensor product of
1868
+ the line bundles. The Picard group of a toric variety is always
1869
+ torsion-free.
1870
+
1871
+ .. WARNING::
1872
+
1873
+ Do not instantiate this class yourself. Use
1874
+ :meth:`~sage.schemes.toric.variety.ToricVariety_field.rational_class_group`
1875
+ method of :class:`toric varieties
1876
+ <sage.schemes.toric.variety.ToricVariety_field>` if you need
1877
+ the divisor class group. Or you can obtain it as the parent of any
1878
+ divisor class constructed, for example, via
1879
+ :meth:`ToricDivisor_generic.divisor_class`.
1880
+
1881
+ INPUT:
1882
+
1883
+ - ``toric_variety`` -- :class:`toric variety
1884
+ <sage.schemes.toric.variety.ToricVariety_field`
1885
+
1886
+ OUTPUT: rational divisor class group of a toric variety
1887
+
1888
+ EXAMPLES::
1889
+
1890
+ sage: P2 = toric_varieties.P2()
1891
+ sage: P2.rational_class_group()
1892
+ The toric rational divisor class group of a 2-d CPR-Fano
1893
+ toric variety covered by 3 affine patches
1894
+ sage: D = P2.divisor(0); D
1895
+ V(x)
1896
+ sage: Dclass = D.divisor_class(); Dclass
1897
+ Divisor class [1]
1898
+ sage: Dclass.lift()
1899
+ V(y)
1900
+ sage: Dclass.parent()
1901
+ The toric rational divisor class group of a 2-d CPR-Fano
1902
+ toric variety covered by 3 affine patches
1903
+ """
1904
+
1905
+ def __init__(self, toric_variety):
1906
+ r"""
1907
+ Construct the toric rational divisor class group.
1908
+
1909
+ EXAMPLES::
1910
+
1911
+ sage: P2 = toric_varieties.P2()
1912
+ sage: from sage.schemes.toric.divisor import ToricRationalDivisorClassGroup
1913
+ sage: ToricRationalDivisorClassGroup(P2)
1914
+ The toric rational divisor class group of a 2-d CPR-Fano
1915
+ toric variety covered by 3 affine patches
1916
+
1917
+ TESTS:
1918
+
1919
+ Make sure we lift integral classes to integral divisors::
1920
+
1921
+ sage: rays = [(1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, 0, 1), (2, -1, -1)]
1922
+ sage: cones = [(0, 2, 3), (0, 2, 4), (0, 3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4)]
1923
+ sage: X = ToricVariety(Fan(cones=cones, rays=rays))
1924
+ sage: Cl = X.rational_class_group()
1925
+ sage: Cl._projection_matrix
1926
+ [1 1 0 0 0]
1927
+ [0 2 1 1 1]
1928
+ sage: Cl._lift_matrix
1929
+ [ 0 0]
1930
+ [ 1 0]
1931
+ [ 0 0]
1932
+ [-2 1]
1933
+ [ 0 0]
1934
+ sage: Cl._lift_matrix.base_ring()
1935
+ Integer Ring
1936
+ """
1937
+ self._variety = toric_variety
1938
+ fan = toric_variety.fan()
1939
+ nrays = fan.nrays()
1940
+ rk = nrays - fan.lattice_dim()
1941
+ super().__init__(base_field=QQ, dimension=rk, sparse=False)
1942
+ gale = fan.Gale_transform()
1943
+ self._projection_matrix = gale.matrix_from_columns(range(nrays))
1944
+ D, U, V = self._projection_matrix.transpose().smith_form()
1945
+ assert all(D[i, i] == 1 for i in range(D.ncols())), \
1946
+ 'This is a property of the Gale transform.'
1947
+ self._lift_matrix = (V * D.transpose() * U).transpose()
1948
+
1949
+ def _repr_(self):
1950
+ r"""
1951
+ Return a string representation of ``self``.
1952
+
1953
+ OUTPUT: string
1954
+
1955
+ EXAMPLES::
1956
+
1957
+ sage: P2 = toric_varieties.P2()
1958
+ sage: from sage.schemes.toric.divisor import ToricRationalDivisorClassGroup
1959
+ sage: ToricRationalDivisorClassGroup(P2)._repr_()
1960
+ 'The toric rational divisor class group of a 2-d CPR-Fano toric variety covered by 3 affine patches'
1961
+ """
1962
+ return 'The toric rational divisor class group of a %s' % self._variety
1963
+
1964
+ def _latex_(self):
1965
+ r"""
1966
+ Return a LaTeX representation of ``self``.
1967
+
1968
+ OUTPUT: string
1969
+
1970
+ EXAMPLES::
1971
+
1972
+ sage: P2 = toric_varieties.P2()
1973
+ sage: from sage.schemes.toric.divisor import ToricRationalDivisorClassGroup
1974
+ sage: print(ToricRationalDivisorClassGroup(P2)._latex_()) # needs polytopes_db
1975
+ \mathop{Cl}_{\QQ}\left(\mathbb{P}_{\Delta^{2}_{15}}\right)
1976
+ """
1977
+ return '\\mathop{Cl}_{\\QQ}\\left(' + self._variety._latex_() + '\\right)'
1978
+
1979
+ def _element_constructor_(self, x):
1980
+ r"""
1981
+ Construct a :class:`ToricRationalDivisorClass`.
1982
+
1983
+ INPUT:
1984
+
1985
+ - ``x`` -- one of the following:
1986
+ * toric divisor;
1987
+ * vector;
1988
+ * list.
1989
+
1990
+ OUTPUT: :class:`ToricRationalDivisorClass`
1991
+
1992
+ EXAMPLES::
1993
+
1994
+ sage: dP6 = toric_varieties.dP6()
1995
+ sage: Cl = dP6.rational_class_group()
1996
+ sage: D = dP6.divisor(2)
1997
+ sage: Cl._element_constructor_(D)
1998
+ Divisor class [0, 0, 1, 0]
1999
+ sage: Cl(D)
2000
+ Divisor class [0, 0, 1, 0]
2001
+ """
2002
+ if isinstance(x, ToricDivisor_generic):
2003
+ x = self._projection_matrix * vector(x)
2004
+ if isinstance(x, Vector):
2005
+ x = list(x)
2006
+ return self.element_class(self, x)
2007
+
2008
+ Element = ToricRationalDivisorClass
2009
+
2010
+
2011
+ class ToricRationalDivisorClassGroup_basis_lattice(FreeModule_ambient_pid):
2012
+ r"""
2013
+ Construct the basis lattice of the ``group``.
2014
+
2015
+ INPUT:
2016
+
2017
+ - ``group`` -- :class:`toric rational divisor class group
2018
+ <ToricRationalDivisorClassGroup>`
2019
+
2020
+ OUTPUT: the basis lattice of ``group``
2021
+
2022
+ EXAMPLES::
2023
+
2024
+ sage: P1xP1 = toric_varieties.P1xP1()
2025
+ sage: L = P1xP1.Kaehler_cone().lattice()
2026
+ sage: L
2027
+ Basis lattice of The toric rational divisor class group of a
2028
+ 2-d CPR-Fano toric variety covered by 4 affine patches
2029
+ sage: L.basis()
2030
+ [Divisor class [1, 0], Divisor class [0, 1]]
2031
+ """
2032
+
2033
+ def __init__(self, group):
2034
+ r"""
2035
+ See :class:`ToricRationalDivisorClassGroup_basis_lattice` for
2036
+ documentation.
2037
+
2038
+ TESTS::
2039
+
2040
+ sage: P1xP1 = toric_varieties.P1xP1()
2041
+ sage: L = P1xP1.Kaehler_cone().lattice()
2042
+ sage: TestSuite(L).run()
2043
+ """
2044
+ assert isinstance(group, ToricRationalDivisorClassGroup)
2045
+ self._group = group
2046
+ self._variety = group._variety
2047
+ self._lift_matrix = group._lift_matrix
2048
+ super().__init__(ZZ, group.dimension(), coordinate_ring=QQ)
2049
+
2050
+ def _repr_(self):
2051
+ r"""
2052
+ Return a string representation of ``self``.
2053
+
2054
+ OUTPUT: string
2055
+
2056
+ TESTS::
2057
+
2058
+ sage: P1xP1 = toric_varieties.P1xP1()
2059
+ sage: L = P1xP1.Kaehler_cone().lattice()
2060
+ sage: print(L._repr_())
2061
+ Basis lattice of The toric rational divisor class group of a
2062
+ 2-d CPR-Fano toric variety covered by 4 affine patches
2063
+ """
2064
+ return "Basis lattice of {}".format(self._group)
2065
+
2066
+ def _latex_(self):
2067
+ r"""
2068
+ Return a LaTeX representation of ``self``.
2069
+
2070
+ OUTPUT: string
2071
+
2072
+ TESTS::
2073
+
2074
+ sage: P1xP1 = toric_varieties.P1xP1()
2075
+ sage: L = P1xP1.Kaehler_cone().lattice()
2076
+ sage: print(L._latex_()) # needs polytopes_db
2077
+ \text{Basis lattice of }
2078
+ \mathop{Cl}_{\QQ}\left(\mathbb{P}_{\Delta^{2}_{14}}\right)
2079
+ """
2080
+ return r"\text{{Basis lattice of }} {}".format(latex(self._group))
2081
+
2082
+ Element = ToricRationalDivisorClass