passagemath-polyhedra 10.6.37__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.
Files changed (209) hide show
  1. passagemath_polyhedra/__init__.py +3 -0
  2. passagemath_polyhedra-10.6.37.dist-info/METADATA +367 -0
  3. passagemath_polyhedra-10.6.37.dist-info/METADATA.bak +369 -0
  4. passagemath_polyhedra-10.6.37.dist-info/RECORD +209 -0
  5. passagemath_polyhedra-10.6.37.dist-info/WHEEL +5 -0
  6. passagemath_polyhedra-10.6.37.dist-info/top_level.txt +3 -0
  7. passagemath_polyhedra.libs/libgcc_s-0cd532bd.so.1 +0 -0
  8. passagemath_polyhedra.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  9. passagemath_polyhedra.libs/libgomp-8949ffbe.so.1.0.0 +0 -0
  10. passagemath_polyhedra.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  11. sage/all__sagemath_polyhedra.py +50 -0
  12. sage/game_theory/all.py +8 -0
  13. sage/game_theory/catalog.py +6 -0
  14. sage/game_theory/catalog_normal_form_games.py +923 -0
  15. sage/game_theory/cooperative_game.py +844 -0
  16. sage/game_theory/matching_game.py +1181 -0
  17. sage/game_theory/normal_form_game.py +2697 -0
  18. sage/game_theory/parser.py +275 -0
  19. sage/geometry/all__sagemath_polyhedra.py +22 -0
  20. sage/geometry/cone.py +6940 -0
  21. sage/geometry/cone_catalog.py +847 -0
  22. sage/geometry/cone_critical_angles.py +1027 -0
  23. sage/geometry/convex_set.py +1119 -0
  24. sage/geometry/fan.py +3743 -0
  25. sage/geometry/fan_isomorphism.py +389 -0
  26. sage/geometry/fan_morphism.py +1884 -0
  27. sage/geometry/hasse_diagram.py +202 -0
  28. sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
  29. sage/geometry/hyperplane_arrangement/all.py +1 -0
  30. sage/geometry/hyperplane_arrangement/arrangement.py +3905 -0
  31. sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
  32. sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
  33. sage/geometry/hyperplane_arrangement/library.py +825 -0
  34. sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
  35. sage/geometry/hyperplane_arrangement/plot.py +520 -0
  36. sage/geometry/integral_points.py +35 -0
  37. sage/geometry/integral_points_generic_dense.cpython-314-x86_64-linux-musl.so +0 -0
  38. sage/geometry/integral_points_generic_dense.pyx +7 -0
  39. sage/geometry/lattice_polytope.py +5894 -0
  40. sage/geometry/linear_expression.py +773 -0
  41. sage/geometry/newton_polygon.py +767 -0
  42. sage/geometry/point_collection.cpython-314-x86_64-linux-musl.so +0 -0
  43. sage/geometry/point_collection.pyx +1008 -0
  44. sage/geometry/polyhedral_complex.py +2616 -0
  45. sage/geometry/polyhedron/all.py +8 -0
  46. sage/geometry/polyhedron/backend_cdd.py +460 -0
  47. sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
  48. sage/geometry/polyhedron/backend_field.py +347 -0
  49. sage/geometry/polyhedron/backend_normaliz.py +2503 -0
  50. sage/geometry/polyhedron/backend_number_field.py +168 -0
  51. sage/geometry/polyhedron/backend_polymake.py +765 -0
  52. sage/geometry/polyhedron/backend_ppl.py +582 -0
  53. sage/geometry/polyhedron/base.py +1206 -0
  54. sage/geometry/polyhedron/base0.py +1444 -0
  55. sage/geometry/polyhedron/base1.py +886 -0
  56. sage/geometry/polyhedron/base2.py +812 -0
  57. sage/geometry/polyhedron/base3.py +1845 -0
  58. sage/geometry/polyhedron/base4.py +1262 -0
  59. sage/geometry/polyhedron/base5.py +2700 -0
  60. sage/geometry/polyhedron/base6.py +1741 -0
  61. sage/geometry/polyhedron/base7.py +997 -0
  62. sage/geometry/polyhedron/base_QQ.py +1258 -0
  63. sage/geometry/polyhedron/base_RDF.py +98 -0
  64. sage/geometry/polyhedron/base_ZZ.py +934 -0
  65. sage/geometry/polyhedron/base_mutable.py +215 -0
  66. sage/geometry/polyhedron/base_number_field.py +122 -0
  67. sage/geometry/polyhedron/cdd_file_format.py +155 -0
  68. sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
  69. sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-x86_64-linux-musl.so +0 -0
  70. sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
  71. sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
  72. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-x86_64-linux-musl.so +0 -0
  73. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
  74. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
  75. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-x86_64-linux-musl.so +0 -0
  76. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
  77. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
  78. sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
  79. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  80. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
  81. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
  82. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-x86_64-linux-musl.so +0 -0
  83. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
  84. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
  85. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-x86_64-linux-musl.so +0 -0
  86. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
  87. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
  88. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-x86_64-linux-musl.so +0 -0
  89. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
  90. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
  91. sage/geometry/polyhedron/constructor.py +773 -0
  92. sage/geometry/polyhedron/double_description.py +753 -0
  93. sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
  94. sage/geometry/polyhedron/face.py +1060 -0
  95. sage/geometry/polyhedron/generating_function.py +1810 -0
  96. sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
  97. sage/geometry/polyhedron/library.py +3502 -0
  98. sage/geometry/polyhedron/misc.py +121 -0
  99. sage/geometry/polyhedron/modules/all.py +1 -0
  100. sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
  101. sage/geometry/polyhedron/palp_database.py +447 -0
  102. sage/geometry/polyhedron/parent.py +1279 -0
  103. sage/geometry/polyhedron/plot.py +1986 -0
  104. sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
  105. sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
  106. sage/geometry/polyhedron/representation.py +1723 -0
  107. sage/geometry/pseudolines.py +515 -0
  108. sage/geometry/relative_interior.py +445 -0
  109. sage/geometry/toric_plotter.py +1103 -0
  110. sage/geometry/triangulation/all.py +2 -0
  111. sage/geometry/triangulation/base.cpython-314-x86_64-linux-musl.so +0 -0
  112. sage/geometry/triangulation/base.pyx +963 -0
  113. sage/geometry/triangulation/data.h +147 -0
  114. sage/geometry/triangulation/data.pxd +4 -0
  115. sage/geometry/triangulation/element.py +914 -0
  116. sage/geometry/triangulation/functions.h +10 -0
  117. sage/geometry/triangulation/functions.pxd +4 -0
  118. sage/geometry/triangulation/point_configuration.py +2256 -0
  119. sage/geometry/triangulation/triangulations.h +49 -0
  120. sage/geometry/triangulation/triangulations.pxd +7 -0
  121. sage/geometry/voronoi_diagram.py +319 -0
  122. sage/interfaces/all__sagemath_polyhedra.py +1 -0
  123. sage/interfaces/polymake.py +2028 -0
  124. sage/numerical/all.py +13 -0
  125. sage/numerical/all__sagemath_polyhedra.py +11 -0
  126. sage/numerical/backends/all.py +1 -0
  127. sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
  128. sage/numerical/backends/cvxopt_backend.cpython-314-x86_64-linux-musl.so +0 -0
  129. sage/numerical/backends/cvxopt_backend.pyx +1006 -0
  130. sage/numerical/backends/cvxopt_backend_test.py +19 -0
  131. sage/numerical/backends/cvxopt_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  132. sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
  133. sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/numerical/backends/cvxpy_backend.pxd +41 -0
  135. sage/numerical/backends/cvxpy_backend.pyx +934 -0
  136. sage/numerical/backends/cvxpy_backend_test.py +13 -0
  137. sage/numerical/backends/generic_backend_test.py +24 -0
  138. sage/numerical/backends/interactivelp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/numerical/backends/interactivelp_backend.pxd +36 -0
  140. sage/numerical/backends/interactivelp_backend.pyx +1231 -0
  141. sage/numerical/backends/interactivelp_backend_test.py +12 -0
  142. sage/numerical/backends/logging_backend.py +391 -0
  143. sage/numerical/backends/matrix_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  144. sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
  145. sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
  146. sage/numerical/backends/ppl_backend.cpython-314-x86_64-linux-musl.so +0 -0
  147. sage/numerical/backends/ppl_backend.pyx +1126 -0
  148. sage/numerical/backends/ppl_backend_test.py +13 -0
  149. sage/numerical/backends/scip_backend.cpython-314-x86_64-linux-musl.so +0 -0
  150. sage/numerical/backends/scip_backend.pxd +22 -0
  151. sage/numerical/backends/scip_backend.pyx +1289 -0
  152. sage/numerical/backends/scip_backend_test.py +13 -0
  153. sage/numerical/interactive_simplex_method.py +5338 -0
  154. sage/numerical/knapsack.py +665 -0
  155. sage/numerical/linear_functions.cpython-314-x86_64-linux-musl.so +0 -0
  156. sage/numerical/linear_functions.pxd +31 -0
  157. sage/numerical/linear_functions.pyx +1648 -0
  158. sage/numerical/linear_tensor.py +470 -0
  159. sage/numerical/linear_tensor_constraints.py +448 -0
  160. sage/numerical/linear_tensor_element.cpython-314-x86_64-linux-musl.so +0 -0
  161. sage/numerical/linear_tensor_element.pxd +6 -0
  162. sage/numerical/linear_tensor_element.pyx +459 -0
  163. sage/numerical/mip.cpython-314-x86_64-linux-musl.so +0 -0
  164. sage/numerical/mip.pxd +40 -0
  165. sage/numerical/mip.pyx +3667 -0
  166. sage/numerical/sdp.cpython-314-x86_64-linux-musl.so +0 -0
  167. sage/numerical/sdp.pxd +39 -0
  168. sage/numerical/sdp.pyx +1433 -0
  169. sage/rings/all__sagemath_polyhedra.py +3 -0
  170. sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
  171. sage/rings/polynomial/omega.py +982 -0
  172. sage/schemes/all__sagemath_polyhedra.py +2 -0
  173. sage/schemes/toric/all.py +10 -0
  174. sage/schemes/toric/chow_group.py +1248 -0
  175. sage/schemes/toric/divisor.py +2082 -0
  176. sage/schemes/toric/divisor_class.cpython-314-x86_64-linux-musl.so +0 -0
  177. sage/schemes/toric/divisor_class.pyx +322 -0
  178. sage/schemes/toric/fano_variety.py +1606 -0
  179. sage/schemes/toric/homset.py +650 -0
  180. sage/schemes/toric/ideal.py +451 -0
  181. sage/schemes/toric/library.py +1322 -0
  182. sage/schemes/toric/morphism.py +1958 -0
  183. sage/schemes/toric/points.py +1032 -0
  184. sage/schemes/toric/sheaf/all.py +1 -0
  185. sage/schemes/toric/sheaf/constructor.py +302 -0
  186. sage/schemes/toric/sheaf/klyachko.py +921 -0
  187. sage/schemes/toric/toric_subscheme.py +905 -0
  188. sage/schemes/toric/variety.py +3460 -0
  189. sage/schemes/toric/weierstrass.py +1078 -0
  190. sage/schemes/toric/weierstrass_covering.py +457 -0
  191. sage/schemes/toric/weierstrass_higher.py +288 -0
  192. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
  193. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
  194. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
  195. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
  196. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
  197. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
  198. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
  199. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
  200. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
  201. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
  202. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
  203. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
  204. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
  205. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
  206. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
  207. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
  208. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
  209. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
@@ -0,0 +1,1606 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ # sage.doctest: needs sage.geometry.polyhedron sage.graphs
3
+ r"""
4
+ Fano toric varieties
5
+
6
+ This module provides support for (Crepant Partial Resolutions of) Fano toric
7
+ varieties, corresponding to crepant subdivisions of face fans of reflexive
8
+ :class:`lattice polytopes
9
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`.
10
+ The interface is provided via :func:`CPRFanoToricVariety`.
11
+
12
+ A careful exposition of different flavours of Fano varieties can be found in
13
+ the paper by Benjamin Nill [Nil2005]_. The main goal of this module is to
14
+ support work with **Gorenstein weak Fano toric varieties**. Such a variety
15
+ corresponds to a **coherent crepant refinement of the normal fan of a
16
+ reflexive polytope** `\Delta`, where crepant means that primitive generators
17
+ of the refining rays lie on the facets of the polar polytope `\Delta^\circ`
18
+ and coherent (a.k.a. regular or projective) means that there exists a strictly
19
+ upper convex piecewise linear function whose domains of linearity are
20
+ precisely the maximal cones of the subdivision. These varieties are important
21
+ for string theory in physics, as they serve as ambient spaces for mirror pairs
22
+ of Calabi-Yau manifolds via constructions due to Victor V. Batyrev
23
+ [Bat1994]_ and Lev A. Borisov [Bor1993]_.
24
+
25
+ From the combinatorial point of view, the "crepant" requirement is much more simple
26
+ and natural to work with than "coherent." For this reason, the code in this
27
+ module will allow work with arbitrary crepant subdivisions without checking
28
+ whether they are coherent or not. We refer to corresponding toric varieties as
29
+ **CPR-Fano toric varieties**.
30
+
31
+ REFERENCES:
32
+
33
+ - [Bat1994]_
34
+ - [Bor1993]_
35
+ - [CD2007]_
36
+ - [Nil2005]_
37
+
38
+ AUTHORS:
39
+
40
+ - Andrey Novoseltsev (2010-05-18): initial version.
41
+
42
+ EXAMPLES:
43
+
44
+ Most of the functions available for Fano toric varieties are the same as
45
+ for general toric varieties, so here we will concentrate only on
46
+ Calabi-Yau subvarieties, which were the primary goal for creating this
47
+ module.
48
+
49
+ For our first example we realize the projective plane as a Fano toric
50
+ variety::
51
+
52
+ sage: simplex = LatticePolytope([(1,0), (0,1), (-1,-1)])
53
+ sage: P2 = CPRFanoToricVariety(Delta_polar=simplex)
54
+
55
+ Its anticanonical "hypersurface" is a one-dimensional Calabi-Yau
56
+ manifold::
57
+
58
+ sage: P2.anticanonical_hypersurface(monomial_points='all')
59
+ Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by:
60
+ a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2
61
+ + a4*z1^2*z2 + a5*z0*z2^2 + a3*z1*z2^2 + a2*z2^3
62
+
63
+ In many cases, it is sufficient to work with the "simplified polynomial
64
+ moduli space" of anticanonical hypersurfaces::
65
+
66
+ sage: P2.anticanonical_hypersurface(monomial_points='simplified')
67
+ Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by:
68
+ a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3
69
+
70
+ The mirror family to these hypersurfaces lives inside the Fano toric
71
+ variety obtained using ``simplex`` as ``Delta`` instead of ``Delta_polar``::
72
+
73
+ sage: FTV = CPRFanoToricVariety(Delta=simplex, coordinate_points='all')
74
+ sage: FTV.anticanonical_hypersurface(monomial_points='simplified')
75
+ Closed subscheme of 2-d CPR-Fano toric variety covered by 9 affine patches defined by:
76
+ a2*z2^3*z3^2*z4*z5^2*z8 + a1*z1^3*z3*z4^2*z7^2*z9
77
+ + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 + a0*z0^3*z5*z7*z8^2*z9^2
78
+
79
+ Here we have taken the resolved version of the ambient space for the
80
+ mirror family, but in fact we don't have to resolve singularities
81
+ corresponding to the interior points of facets - they are singular
82
+ points which do not lie on a generic anticanonical hypersurface::
83
+
84
+ sage: FTV = CPRFanoToricVariety(Delta=simplex, coordinate_points="all but facets")
85
+ sage: FTV.anticanonical_hypersurface(monomial_points='simplified')
86
+ Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by:
87
+ a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3
88
+
89
+ This looks very similar to our second version of the anticanonical
90
+ hypersurface of the projective plane, as expected, since all
91
+ one-dimensional Calabi-Yau manifolds are elliptic curves!
92
+
93
+ Now let's take a look at a toric realization of `M`-polarized K3 surfaces
94
+ studied by Adrian Clingher and Charles F. Doran in [CD2007]_::
95
+
96
+ sage: # needs polytopes_db
97
+ sage: p4318 = ReflexivePolytope(3, 4318)
98
+ sage: FTV = CPRFanoToricVariety(Delta_polar=p4318)
99
+ sage: FTV.anticanonical_hypersurface()
100
+ Closed subscheme of 3-d CPR-Fano toric variety covered by 4 affine patches defined by:
101
+ a0*z2^12 + a4*z2^6*z3^6 + a3*z3^12 + a8*z0*z1*z2*z3 + a2*z1^3 + a1*z0^2
102
+
103
+ Below you will find detailed descriptions of available functions. Current
104
+ functionality of this module is very basic, but it is under active
105
+ development and hopefully will improve in future releases of Sage. If there
106
+ are some particular features that you would like to see implemented ASAP,
107
+ please consider reporting them to the Sage Development Team or even
108
+ implementing them on your own as a patch for inclusion!
109
+ """
110
+ # The first example of the tutorial is taken from
111
+ # CPRFanoToricVariety_field.anticanonical_hypersurface
112
+
113
+ # ****************************************************************************
114
+ # Copyright (C) 2010 Andrey Novoseltsev <novoselt@gmail.com>
115
+ # Copyright (C) 2010 William Stein <wstein@gmail.com>
116
+ #
117
+ # Distributed under the terms of the GNU General Public License (GPL)
118
+ #
119
+ # https://www.gnu.org/licenses/
120
+ # ****************************************************************************
121
+
122
+ import re
123
+
124
+ from sage.geometry.cone import Cone
125
+ from sage.geometry.fan import FaceFan
126
+ from sage.geometry.fan import Fan
127
+ from sage.geometry.lattice_polytope import LatticePolytope
128
+ from sage.misc.latex import latex
129
+ from sage.misc.misc_c import prod
130
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
131
+ from sage.rings.rational_field import QQ
132
+
133
+ from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
134
+ from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
135
+ from sage.rings.fraction_field import FractionField_generic
136
+
137
+ from sage.schemes.toric.toric_subscheme import AlgebraicScheme_subscheme_toric
138
+ from sage.schemes.toric.variety import (
139
+ ToricVariety_field,
140
+ normalize_names)
141
+ from sage.structure.all import coercion_model
142
+ from sage.categories.fields import Fields
143
+ _Fields = Fields()
144
+
145
+
146
+ # Default coefficient for anticanonical hypersurfaces
147
+ DEFAULT_COEFFICIENT = "a"
148
+ # Default coefficients for nef complete intersections
149
+ DEFAULT_COEFFICIENTS = tuple(chr(i) for i in range(ord("a"), ord("z") + 1))
150
+
151
+
152
+ def is_CPRFanoToricVariety(x):
153
+ r"""
154
+ Check if ``x`` is a CPR-Fano toric variety.
155
+
156
+ INPUT:
157
+
158
+ - ``x`` -- anything
159
+
160
+ OUTPUT:
161
+
162
+ - ``True`` if ``x`` is a :class:`CPR-Fano toric variety
163
+ <CPRFanoToricVariety_field>` and ``False`` otherwise.
164
+
165
+ .. NOTE::
166
+
167
+ While projective spaces are Fano toric varieties mathematically, they
168
+ are not toric varieties in Sage due to efficiency considerations, so
169
+ this function will return ``False``.
170
+
171
+ EXAMPLES::
172
+
173
+ sage: from sage.schemes.toric.fano_variety import is_CPRFanoToricVariety
174
+ sage: is_CPRFanoToricVariety(1)
175
+ doctest:warning...
176
+ DeprecationWarning: The function is_CPRFanoToricVariety is deprecated; use 'isinstance(..., CPRFanoToricVariety_field)' instead.
177
+ See https://github.com/sagemath/sage/issues/38022 for details.
178
+ False
179
+ sage: FTV = toric_varieties.P2()
180
+ sage: FTV
181
+ 2-d CPR-Fano toric variety covered by 3 affine patches
182
+ sage: is_CPRFanoToricVariety(FTV)
183
+ True
184
+ sage: is_CPRFanoToricVariety(ProjectiveSpace(2))
185
+ False
186
+ """
187
+ from sage.misc.superseded import deprecation
188
+ deprecation(38022, "The function is_CPRFanoToricVariety is deprecated; use 'isinstance(..., CPRFanoToricVariety_field)' instead.")
189
+ return isinstance(x, CPRFanoToricVariety_field)
190
+
191
+
192
+ def CPRFanoToricVariety(Delta=None,
193
+ Delta_polar=None,
194
+ coordinate_points=None,
195
+ charts=None,
196
+ coordinate_names=None,
197
+ names=None,
198
+ coordinate_name_indices=None,
199
+ make_simplicial=False,
200
+ base_ring=None,
201
+ base_field=None,
202
+ check=True):
203
+ r"""
204
+ Construct a CPR-Fano toric variety.
205
+
206
+ .. NOTE::
207
+
208
+ See documentation of the module
209
+ :mod:`~sage.schemes.toric.fano_variety` for the used
210
+ definitions and supported varieties.
211
+
212
+ Due to the large number of available options, it is recommended to always
213
+ use keyword parameters.
214
+
215
+ INPUT:
216
+
217
+ - ``Delta`` -- reflexive :class:`lattice polytope
218
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`. The fan of the
219
+ constructed CPR-Fano toric variety will be a crepant subdivision of the
220
+ *normal fan* of ``Delta``. Either ``Delta`` or ``Delta_polar`` must be
221
+ given, but not both at the same time, since one is completely determined
222
+ by another via :meth:`polar
223
+ <sage.geometry.lattice_polytope.LatticePolytopeClass.polar>` method.
224
+
225
+ - ``Delta_polar`` -- reflexive :class:`lattice polytope
226
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`. The fan of the
227
+ constructed CPR-Fano toric variety will be a crepant subdivision of the
228
+ *face fan* of ``Delta_polar``. Either ``Delta`` or ``Delta_polar`` must
229
+ be given, but not both at the same time, since one is completely
230
+ determined by another via :meth:`polar
231
+ <sage.geometry.lattice_polytope.LatticePolytopeClass.polar>` method.
232
+
233
+ - ``coordinate_points`` -- list of integers or string. A list will be
234
+ interpreted as indices of (boundary) points of ``Delta_polar`` which
235
+ should be used as rays of the underlying fan. It must include all
236
+ vertices of ``Delta_polar`` and no repetitions are allowed. A string
237
+ must be one of the following descriptions of points of ``Delta_polar``:
238
+
239
+ * "vertices" (default),
240
+ * "all" (will not include the origin),
241
+ * "all but facets" (will not include points in the relative interior of
242
+ facets);
243
+
244
+ - ``charts`` -- list of lists of elements from ``coordinate_points``. Each
245
+ of these lists must define a generating cone of a fan subdividing the
246
+ normal fan of ``Delta``. Default ``charts`` correspond to the normal fan
247
+ of ``Delta`` without subdivision. The fan specified by ``charts`` will
248
+ be subdivided to include all of the requested ``coordinate_points``.
249
+
250
+ - ``coordinate_names`` -- names of variables for the coordinate ring, see
251
+ :func:`~sage.schemes.toric.variety.normalize_names`
252
+ for acceptable formats. If not given, indexed variable names will be
253
+ created automatically.
254
+
255
+ - ``names`` -- an alias of ``coordinate_names`` for internal
256
+ use. You may specify either ``names`` or ``coordinate_names``,
257
+ but not both.
258
+
259
+ - ``coordinate_name_indices`` -- list of integers, indices for indexed
260
+ variables. If not given, the index of each variable will coincide with
261
+ the index of the corresponding point of ``Delta_polar``.
262
+
263
+ - ``make_simplicial`` -- if ``True``, the underlying fan will be made
264
+ simplicial (default: ``False``)
265
+
266
+ - ``base_ring`` -- base field of the CPR-Fano toric variety
267
+ (default: `\QQ`)
268
+
269
+ - ``base_field`` -- alias for ``base_ring``. Takes precedence if
270
+ both are specified.
271
+
272
+ - ``check`` -- by default the input data will be checked for correctness
273
+ (e.g. that ``charts`` do form a subdivision of the normal fan of
274
+ ``Delta``). If you know for sure that the input is valid, you may
275
+ significantly decrease construction time using ``check=False`` option.
276
+
277
+ OUTPUT: :class:`CPR-Fano toric variety <CPRFanoToricVariety_field>`
278
+
279
+ EXAMPLES:
280
+
281
+ We start with the product of two projective lines::
282
+
283
+ sage: diamond = lattice_polytope.cross_polytope(2)
284
+ sage: diamond.vertices()
285
+ M( 1, 0), M( 0, 1),
286
+ M(-1, 0), M( 0, -1)
287
+ in 2-d lattice M
288
+ sage: P1xP1 = CPRFanoToricVariety(Delta_polar=diamond)
289
+ sage: P1xP1
290
+ 2-d CPR-Fano toric variety covered by 4 affine patches
291
+ sage: P1xP1.fan()
292
+ Rational polyhedral fan in 2-d lattice M
293
+ sage: P1xP1.fan().rays()
294
+ M( 1, 0), M( 0, 1),
295
+ M(-1, 0), M( 0, -1)
296
+ in 2-d lattice M
297
+
298
+ "Unfortunately," this variety is smooth to start with and we cannot
299
+ perform any subdivisions of the underlying fan without leaving the
300
+ category of CPR-Fano toric varieties. Our next example starts with a
301
+ square::
302
+
303
+ sage: square = diamond.polar()
304
+ sage: square.vertices()
305
+ N( 1, 1), N( 1, -1),
306
+ N(-1, -1), N(-1, 1)
307
+ in 2-d lattice N
308
+ sage: square.points()
309
+ N( 1, 1), N( 1, -1), N(-1, -1),
310
+ N(-1, 1), N(-1, 0), N( 0, -1),
311
+ N( 0, 0), N( 0, 1), N( 1, 0)
312
+ in 2-d lattice N
313
+
314
+ We will construct several varieties associated to it::
315
+
316
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square)
317
+ sage: FTV.fan().rays()
318
+ N( 1, 1), N( 1, -1),
319
+ N(-1, -1), N(-1, 1)
320
+ in 2-d lattice N
321
+ sage: FTV.gens()
322
+ (z0, z1, z2, z3)
323
+
324
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
325
+ ....: coordinate_points=[0,1,2,3,8])
326
+ sage: FTV.fan().rays()
327
+ N( 1, 1), N( 1, -1), N(-1, -1),
328
+ N(-1, 1), N( 1, 0)
329
+ in 2-d lattice N
330
+ sage: FTV.gens()
331
+ (z0, z1, z2, z3, z8)
332
+
333
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
334
+ ....: coordinate_points=[8,0,2,1,3],
335
+ ....: coordinate_names='x+')
336
+ sage: FTV.fan().rays()
337
+ N( 1, 0), N( 1, 1), N(-1, -1),
338
+ N( 1, -1), N(-1, 1)
339
+ in 2-d lattice N
340
+ sage: FTV.gens()
341
+ (x8, x0, x2, x1, x3)
342
+
343
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
344
+ ....: coordinate_points='all',
345
+ ....: coordinate_names="x y Z+")
346
+ sage: FTV.fan().rays()
347
+ N( 1, 1), N( 1, -1), N(-1, -1), N(-1, 1),
348
+ N(-1, 0), N( 0, -1), N( 0, 1), N( 1, 0)
349
+ in 2-d lattice N
350
+ sage: FTV.gens()
351
+ (x, y, Z2, Z3, Z4, Z5, Z7, Z8)
352
+
353
+ Note that ``Z6`` is "missing". This is due to the fact that the 6-th point
354
+ of ``square`` is the origin, and all automatically created names have the
355
+ same indices as corresponding points of
356
+ :meth:`~CPRFanoToricVariety_field.Delta_polar`. This is usually very
357
+ convenient, especially if you have to work with several partial
358
+ resolutions of the same Fano toric variety. However, you can change it, if
359
+ you want::
360
+
361
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
362
+ ....: coordinate_points='all',
363
+ ....: coordinate_names="x y Z+",
364
+ ....: coordinate_name_indices=list(range(8)))
365
+ sage: FTV.gens()
366
+ (x, y, Z2, Z3, Z4, Z5, Z6, Z7)
367
+
368
+ Note that you have to provide indices for *all* variables, including those
369
+ that have "completely custom" names. Again, this is usually convenient,
370
+ because you can add or remove "custom" variables without disturbing too
371
+ much "automatic" ones::
372
+
373
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
374
+ ....: coordinate_points='all',
375
+ ....: coordinate_names="x Z+",
376
+ ....: coordinate_name_indices=list(range(8)))
377
+ sage: FTV.gens()
378
+ (x, Z1, Z2, Z3, Z4, Z5, Z6, Z7)
379
+
380
+ If you prefer to always start from zero, you will have to shift indices
381
+ accordingly::
382
+
383
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
384
+ ....: coordinate_points='all',
385
+ ....: coordinate_names="x Z+",
386
+ ....: coordinate_name_indices=[0] + list(range(7)))
387
+ sage: FTV.gens()
388
+ (x, Z0, Z1, Z2, Z3, Z4, Z5, Z6)
389
+
390
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
391
+ ....: coordinate_points='all',
392
+ ....: coordinate_names="x y Z+",
393
+ ....: coordinate_name_indices=[0]*2 + list(range(6)))
394
+ sage: FTV.gens()
395
+ (x, y, Z0, Z1, Z2, Z3, Z4, Z5)
396
+
397
+ So you always can get any names you want, somewhat complicated default
398
+ behaviour was designed with the hope that in most cases you will have no
399
+ desire to provide different names.
400
+
401
+ Now we will use the possibility to specify initial charts::
402
+
403
+ sage: charts = [(0,1), (1,2), (2,3), (3,0)]
404
+
405
+ (these charts actually form exactly the face fan of our square) ::
406
+
407
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
408
+ ....: coordinate_points=[0,1,2,3,4],
409
+ ....: charts=charts)
410
+ sage: FTV.fan().rays()
411
+ N( 1, 1), N( 1, -1), N(-1, -1),
412
+ N(-1, 1), N(-1, 0)
413
+ in 2-d lattice N
414
+ sage: [cone.ambient_ray_indices() for cone in FTV.fan()]
415
+ [(0, 1), (1, 2), (2, 4), (3, 4), (0, 3)]
416
+
417
+ If charts are wrong, it should be detected::
418
+
419
+ sage: bad_charts = charts + [(3,0)]
420
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
421
+ ....: coordinate_points=[0,1,2,3,4],
422
+ ....: charts=bad_charts)
423
+ Traceback (most recent call last):
424
+ ...
425
+ ValueError: you have provided 5 cones, but only 4 of them are maximal!
426
+ Use discard_faces=True if you indeed need to construct a fan from these cones.
427
+
428
+ These charts are technically correct, they just happened to list one of
429
+ them twice, but it is assumed that such a situation will not happen. It is
430
+ especially important when you try to speed up your code::
431
+
432
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
433
+ ....: coordinate_points=[0,1,2,3,4],
434
+ ....: charts=bad_charts,
435
+ ....: check=False)
436
+ Traceback (most recent call last):
437
+ ...
438
+ IndexError: list assignment index out of range
439
+
440
+ In this case you still get an error message, but it is harder to figure out
441
+ what is going on. It may also happen that "everything will still work" in
442
+ the sense of not crashing, but work with such an invalid variety may lead to
443
+ mathematically wrong results, so use ``check=False`` carefully!
444
+
445
+ Here are some other possible mistakes::
446
+
447
+ sage: bad_charts = charts + [(0,2)]
448
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
449
+ ....: coordinate_points=[0,1,2,3,4],
450
+ ....: charts=bad_charts)
451
+ Traceback (most recent call last):
452
+ ...
453
+ ValueError: (0, 2) does not form a chart of a subdivision of
454
+ the face fan of 2-d reflexive polytope ... in 2-d lattice N!
455
+
456
+ sage: bad_charts = charts[:-1]
457
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
458
+ ....: coordinate_points=[0,1,2,3,4],
459
+ ....: charts=bad_charts)
460
+ Traceback (most recent call last):
461
+ ...
462
+ ValueError: given charts do not form a complete fan!
463
+
464
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
465
+ ....: coordinate_points=[1,2,3,4])
466
+ Traceback (most recent call last):
467
+ ...
468
+ ValueError: all 4 vertices of Delta_polar must be used for coordinates!
469
+ Got: [1, 2, 3, 4]
470
+
471
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
472
+ ....: coordinate_points=[0,0,1,2,3,4])
473
+ Traceback (most recent call last):
474
+ ...
475
+ ValueError: no repetitions are allowed for coordinate points!
476
+ Got: [0, 0, 1, 2, 3, 4]
477
+
478
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
479
+ ....: coordinate_points=[0,1,2,3,6])
480
+ Traceback (most recent call last):
481
+ ...
482
+ ValueError: the origin (point #6) cannot be used for a coordinate!
483
+ Got: [0, 1, 2, 3, 6]
484
+
485
+ Here is a shorthand for defining the toric variety and homogeneous
486
+ coordinates in one go::
487
+
488
+ sage: P1xP1.<a,b,c,d> = CPRFanoToricVariety(Delta_polar=diamond)
489
+ sage: (a^2+b^2) * (c+d)
490
+ a^2*c + b^2*c + a^2*d + b^2*d
491
+ """
492
+ if names is not None:
493
+ if coordinate_names is not None:
494
+ raise ValueError('You must not specify both coordinate_names and names!')
495
+ coordinate_names = names
496
+ # Check/normalize Delta_polar
497
+ if Delta is None and Delta_polar is None:
498
+ raise ValueError("either Delta or Delta_polar must be given!")
499
+ elif Delta is not None and Delta_polar is not None:
500
+ raise ValueError("Delta and Delta_polar cannot be given together!")
501
+ elif Delta_polar is None:
502
+ Delta_polar = Delta.polar()
503
+ elif not Delta_polar.is_reflexive():
504
+ raise ValueError("Delta_polar must be reflexive!")
505
+ # Check/normalize coordinate_points and construct fan rays
506
+ if coordinate_points is None:
507
+ coordinate_points = list(range(Delta_polar.nvertices()))
508
+ if charts is not None:
509
+ for chart in charts:
510
+ for point in chart:
511
+ if point not in coordinate_points:
512
+ coordinate_points.append(point)
513
+ elif coordinate_points == "vertices":
514
+ coordinate_points = list(range(Delta_polar.nvertices()))
515
+ elif coordinate_points == "all":
516
+ coordinate_points = list(range(Delta_polar.npoints()))
517
+ coordinate_points.remove(Delta_polar.origin())
518
+ elif coordinate_points == "all but facets":
519
+ coordinate_points = Delta_polar.skeleton_points(Delta_polar.dim() - 2)
520
+ elif isinstance(coordinate_points, str):
521
+ raise ValueError("unrecognized description of the coordinate points!"
522
+ "\nGot: %s" % coordinate_points)
523
+ elif check:
524
+ cp_set = set(coordinate_points)
525
+ if len(cp_set) != len(coordinate_points):
526
+ raise ValueError(
527
+ "no repetitions are allowed for coordinate points!\nGot: %s"
528
+ % coordinate_points)
529
+ if not cp_set.issuperset(list(range(Delta_polar.nvertices()))):
530
+ raise ValueError("all %d vertices of Delta_polar must be used "
531
+ "for coordinates!\nGot: %s"
532
+ % (Delta_polar.nvertices(), coordinate_points))
533
+ if Delta_polar.origin() in cp_set:
534
+ raise ValueError("the origin (point #%d) cannot be used for a "
535
+ "coordinate!\nGot: %s"
536
+ % (Delta_polar.origin(), coordinate_points))
537
+ point_to_ray = {point: n
538
+ for n, point in enumerate(coordinate_points)}
539
+ # This can be simplified if LatticePolytopeClass is adjusted.
540
+ rays = [Delta_polar.point(p) for p in coordinate_points]
541
+ # Check/normalize charts and construct the fan based on them.
542
+ if charts is None:
543
+ # Start with the face fan
544
+ fan = FaceFan(Delta_polar)
545
+ else:
546
+ # First of all, check that each chart is completely contained in a
547
+ # single facet of Delta_polar, otherwise they do not form a
548
+ # subdivision of the face fan of Delta_polar
549
+ if check:
550
+ ambient_points = Delta_polar.ambient().points()
551
+ facet_sets = [frozenset(Pindex for Pindex, point in enumerate(ambient_points)
552
+ if normal*point + Delta_polar.facet_constant(Hindex) == 0)
553
+ for Hindex, normal in enumerate(Delta_polar.facet_normals())]
554
+ for chart in charts:
555
+ is_bad = True
556
+ for fset in facet_sets:
557
+ if fset.issuperset(chart):
558
+ is_bad = False
559
+ break
560
+ if is_bad:
561
+ raise ValueError(
562
+ "%s does not form a chart of a subdivision of the "
563
+ "face fan of %s!" % (chart, Delta_polar))
564
+ # We will construct the initial fan from Cone objects: since charts
565
+ # may not use all of the necessary rays, alternative form is tedious
566
+ # With check=False it should not be long anyway.
567
+ cones = [Cone((rays[point_to_ray[point]] for point in chart),
568
+ check=check)
569
+ for chart in charts]
570
+ fan = Fan(cones, check=check)
571
+ if check and not fan.is_complete():
572
+ raise ValueError("given charts do not form a complete fan!")
573
+ # Subdivide this fan to use all required points
574
+ fan = fan.subdivide(new_rays=(ray for ray in rays
575
+ if ray not in fan.rays().set()),
576
+ make_simplicial=make_simplicial)
577
+ # Now create yet another fan making sure that the order of the rays is
578
+ # the same as requested (it is a bit difficult to get it from the start)
579
+ trans = {}
580
+ for n, ray in enumerate(fan.rays()):
581
+ trans[n] = rays.index(ray)
582
+ cones = tuple(tuple(sorted(trans[r] for r in cone.ambient_ray_indices()))
583
+ for cone in fan)
584
+ fan = Fan(cones, rays, check=False)
585
+ # Check/normalize base_field
586
+ if base_field is not None:
587
+ base_ring = base_field
588
+ if base_ring is None:
589
+ base_ring = QQ
590
+ elif base_ring not in _Fields:
591
+ raise TypeError("need a field to construct a Fano toric variety!"
592
+ "\n Got %s" % base_ring)
593
+ fan._is_complete = True # At this point it must be for sure
594
+ return CPRFanoToricVariety_field(
595
+ Delta_polar, fan, coordinate_points,
596
+ point_to_ray, coordinate_names, coordinate_name_indices, base_ring)
597
+
598
+
599
+ class CPRFanoToricVariety_field(ToricVariety_field):
600
+ r"""
601
+ Construct a CPR-Fano toric variety associated to a reflexive polytope.
602
+
603
+ .. WARNING::
604
+
605
+ This class does not perform any checks of correctness of input and it
606
+ does assume that the internal structure of the given parameters is
607
+ coordinated in a certain way. Use
608
+ :func:`CPRFanoToricVariety` to construct CPR-Fano toric varieties.
609
+
610
+ .. NOTE::
611
+
612
+ See documentation of the module
613
+ :mod:`~sage.schemes.toric.fano_variety` for the used
614
+ definitions and supported varieties.
615
+
616
+ INPUT:
617
+
618
+ - ``Delta_polar`` -- reflexive polytope
619
+
620
+ - ``fan`` -- rational polyhedral fan subdividing the face fan of
621
+ ``Delta_polar``
622
+
623
+ - ``coordinate_points`` -- list of indices of points of ``Delta_polar``
624
+ used for rays of ``fan``
625
+
626
+ - ``point_to_ray`` -- dictionary mapping the index of a coordinate point
627
+ to the index of the corresponding ray
628
+
629
+ - ``coordinate_names`` -- names of the variables of the coordinate ring in
630
+ the format accepted by
631
+ :func:`~sage.schemes.toric.variety.normalize_names`
632
+
633
+ - ``coordinate_name_indices`` -- indices for indexed variables,
634
+ if ``None``, will be equal to ``coordinate_points``
635
+
636
+ - ``base_field`` -- base field of the CPR-Fano toric variety
637
+
638
+ OUTPUT: :class:`CPR-Fano toric variety <CPRFanoToricVariety_field>`
639
+
640
+ TESTS::
641
+
642
+ sage: P1xP1 = CPRFanoToricVariety(
643
+ ....: Delta_polar=lattice_polytope.cross_polytope(2))
644
+ sage: P1xP1
645
+ 2-d CPR-Fano toric variety covered by 4 affine patches
646
+ """
647
+
648
+ def __init__(self, Delta_polar, fan, coordinate_points, point_to_ray,
649
+ coordinate_names, coordinate_name_indices, base_field):
650
+ r"""
651
+ See :class:`CPRFanoToricVariety_field` for documentation.
652
+
653
+ Use ``CPRFanoToricVariety`` to construct CPR-Fano toric varieties.
654
+
655
+ TESTS::
656
+
657
+ sage: P1xP1 = CPRFanoToricVariety(
658
+ ....: Delta_polar=lattice_polytope.cross_polytope(2))
659
+ sage: P1xP1
660
+ 2-d CPR-Fano toric variety covered by 4 affine patches
661
+ """
662
+ self._Delta_polar = Delta_polar
663
+ self._coordinate_points = tuple(coordinate_points)
664
+ self._point_to_ray = point_to_ray
665
+ # Check/normalize coordinate_indices
666
+ if coordinate_name_indices is None:
667
+ coordinate_name_indices = coordinate_points
668
+ super().__init__(fan, coordinate_names,
669
+ coordinate_name_indices, base_field)
670
+
671
+ def _latex_(self):
672
+ r"""
673
+ Return a LaTeX representation of ``self``.
674
+
675
+ OUTPUT: string
676
+
677
+ TESTS::
678
+
679
+ sage: P1xP1 = toric_varieties.P1xP1()
680
+ sage: print(P1xP1._latex_()) # needs polytopes_db
681
+ \mathbb{P}_{\Delta^{2}_{14}}
682
+ """
683
+ return r"\mathbb{P}_{%s}" % latex(self.Delta())
684
+
685
+ def _repr_(self):
686
+ r"""
687
+ Return a string representation of ``self``.
688
+
689
+ OUTPUT: string
690
+
691
+ TESTS::
692
+
693
+ sage: P1xP1 = toric_varieties.P1xP1()
694
+ sage: print(P1xP1._repr_())
695
+ 2-d CPR-Fano toric variety covered by 4 affine patches
696
+ """
697
+ return ("%d-d CPR-Fano toric variety covered by %d affine patches"
698
+ % (self.dimension_relative(), self.fan().ngenerating_cones()))
699
+
700
+ def anticanonical_hypersurface(self, **kwds):
701
+ r"""
702
+ Return an anticanonical hypersurface of ``self``.
703
+
704
+ .. NOTE::
705
+
706
+ The returned hypersurface may be actually a subscheme of
707
+ **another** CPR-Fano toric variety: if the base field of ``self``
708
+ does not include all of the required names for generic monomial
709
+ coefficients, it will be automatically extended.
710
+
711
+ Below `\Delta` is the reflexive polytope corresponding to ``self``,
712
+ i.e. the fan of ``self`` is a refinement of the normal fan of
713
+ `\Delta`. This function accepts only keyword parameters.
714
+
715
+ INPUT:
716
+
717
+ - ``monomial_points`` -- list of integers or a string. A list will be
718
+ interpreted as indices of points of `\Delta` which should be used
719
+ for monomials of this hypersurface. A string must be one of the
720
+ following descriptions of points of `\Delta`:
721
+
722
+ * "vertices",
723
+ * "vertices+origin",
724
+ * "all",
725
+ * "simplified" (default) -- all points of `\Delta` except for
726
+ the interior points of facets, this choice corresponds to working
727
+ with the "simplified polynomial moduli space" of anticanonical
728
+ hypersurfaces;
729
+
730
+ - ``coefficient_names`` -- names for the monomial coefficients, see
731
+ :func:`~sage.schemes.toric.variety.normalize_names`
732
+ for acceptable formats. If not given, indexed coefficient names will
733
+ be created automatically.
734
+
735
+ - ``coefficient_name_indices`` -- list of integers, indices for
736
+ indexed coefficients. If not given, the index of each coefficient
737
+ will coincide with the index of the corresponding point of `\Delta`.
738
+
739
+ - ``coefficients`` -- as an alternative to specifying coefficient
740
+ names and/or indices, you can give the coefficients themselves as
741
+ arbitrary expressions and/or strings. Using strings allows you to
742
+ easily add "parameters": the base field of ``self`` will be extended
743
+ to include all necessary names.
744
+
745
+ OUTPUT:
746
+
747
+ - an :class:`anticanonical hypersurface <AnticanonicalHypersurface>` of
748
+ ``self`` (with the extended base field, if necessary).
749
+
750
+ EXAMPLES:
751
+
752
+ We realize the projective plane as a Fano toric variety::
753
+
754
+ sage: simplex = LatticePolytope([(1,0), (0,1), (-1,-1)])
755
+ sage: P2 = CPRFanoToricVariety(Delta_polar=simplex)
756
+
757
+ Its anticanonical "hypersurface" is a one-dimensional Calabi-Yau
758
+ manifold::
759
+
760
+ sage: P2.anticanonical_hypersurface(monomial_points='all')
761
+ Closed subscheme of 2-d CPR-Fano toric variety
762
+ covered by 3 affine patches defined by:
763
+ a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2
764
+ + a4*z1^2*z2 + a5*z0*z2^2 + a3*z1*z2^2 + a2*z2^3
765
+
766
+ In many cases it is sufficient to work with the "simplified polynomial
767
+ moduli space" of anticanonical hypersurfaces::
768
+
769
+ sage: P2.anticanonical_hypersurface(monomial_points='simplified')
770
+ Closed subscheme of 2-d CPR-Fano toric variety
771
+ covered by 3 affine patches defined by:
772
+ a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3
773
+
774
+ The mirror family to these hypersurfaces lives inside the Fano toric
775
+ variety obtained using ``simplex`` as ``Delta`` instead of
776
+ ``Delta_polar``::
777
+
778
+ sage: FTV = CPRFanoToricVariety(Delta=simplex,
779
+ ....: coordinate_points='all')
780
+ sage: FTV.anticanonical_hypersurface(monomial_points='simplified')
781
+ Closed subscheme of 2-d CPR-Fano toric variety
782
+ covered by 9 affine patches defined by:
783
+ a2*z2^3*z3^2*z4*z5^2*z8 + a1*z1^3*z3*z4^2*z7^2*z9
784
+ + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 + a0*z0^3*z5*z7*z8^2*z9^2
785
+
786
+ Here we have taken the resolved version of the ambient space for the
787
+ mirror family, but in fact we don't have to resolve singularities
788
+ corresponding to the interior points of facets - they are singular
789
+ points which do not lie on a generic anticanonical hypersurface::
790
+
791
+ sage: FTV = CPRFanoToricVariety(Delta=simplex,
792
+ ....: coordinate_points="all but facets")
793
+ sage: FTV.anticanonical_hypersurface(monomial_points='simplified')
794
+ Closed subscheme of 2-d CPR-Fano toric variety
795
+ covered by 3 affine patches defined by:
796
+ a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3
797
+
798
+ This looks very similar to our second anticanonical
799
+ hypersurface of the projective plane, as expected, since all
800
+ one-dimensional Calabi-Yau manifolds are elliptic curves!
801
+
802
+ All anticanonical hypersurfaces constructed above were generic with
803
+ automatically generated coefficients. If you want, you can specify your
804
+ own names ::
805
+
806
+ sage: FTV.anticanonical_hypersurface(coefficient_names="a b c d")
807
+ Closed subscheme of 2-d CPR-Fano toric variety
808
+ covered by 3 affine patches defined by:
809
+ a*z0^3 + b*z1^3 + d*z0*z1*z2 + c*z2^3
810
+
811
+ or give concrete coefficients ::
812
+
813
+ sage: FTV.anticanonical_hypersurface(coefficients=[1, 2, 3, 4])
814
+ Closed subscheme of 2-d CPR-Fano toric variety
815
+ covered by 3 affine patches defined by:
816
+ z0^3 + 2*z1^3 + 4*z0*z1*z2 + 3*z2^3
817
+
818
+ or even mix numerical coefficients with some expressions ::
819
+
820
+ sage: H = FTV.anticanonical_hypersurface(
821
+ ....: coefficients=[0, "t", "1/t", "psi/(psi^2 + phi)"])
822
+ sage: H
823
+ Closed subscheme of 2-d CPR-Fano toric variety
824
+ covered by 3 affine patches defined by:
825
+ t*z1^3 + psi/(phi + psi^2)*z0*z1*z2 + 1/t*z2^3
826
+ sage: R = H.ambient_space().base_ring()
827
+ sage: R
828
+ Fraction Field of
829
+ Multivariate Polynomial Ring in phi, psi, t over Rational Field
830
+ """
831
+ # The example above is also copied to the tutorial section in the
832
+ # main documentation of the module.
833
+ return AnticanonicalHypersurface(self, **kwds)
834
+
835
+ def change_ring(self, F):
836
+ r"""
837
+ Return a CPR-Fano toric variety over field ``F``, otherwise the same
838
+ as ``self``.
839
+
840
+ INPUT:
841
+
842
+ - ``F`` -- field
843
+
844
+ OUTPUT: :class:`CPR-Fano toric variety <CPRFanoToricVariety_field>` over ``F``
845
+
846
+ .. NOTE::
847
+
848
+ There is no need to have any relation between ``F`` and the base
849
+ field of ``self``. If you do want to have such a relation, use
850
+ :meth:`base_extend` instead.
851
+
852
+ EXAMPLES::
853
+
854
+ sage: P1xP1 = toric_varieties.P1xP1()
855
+ sage: P1xP1.base_ring()
856
+ Rational Field
857
+ sage: P1xP1_RR = P1xP1.change_ring(RR)
858
+ sage: P1xP1_RR.base_ring()
859
+ Real Field with 53 bits of precision
860
+ sage: P1xP1_QQ = P1xP1_RR.change_ring(QQ)
861
+ sage: P1xP1_QQ.base_ring()
862
+ Rational Field
863
+ sage: P1xP1_RR.base_extend(QQ)
864
+ Traceback (most recent call last):
865
+ ...
866
+ ValueError: no natural map from the base ring
867
+ (=Real Field with 53 bits of precision) to R (=Rational Field)!
868
+ sage: R = PolynomialRing(QQ, 2, 'a')
869
+ sage: P1xP1.change_ring(R)
870
+ Traceback (most recent call last):
871
+ ...
872
+ TypeError: need a field to construct a Fano toric variety!
873
+ Got Multivariate Polynomial Ring in a0, a1 over Rational Field
874
+ """
875
+ if self.base_ring() == F:
876
+ return self
877
+ elif F not in _Fields:
878
+ raise TypeError("need a field to construct a Fano toric variety!"
879
+ "\n Got %s" % F)
880
+ else:
881
+ return CPRFanoToricVariety_field(self._Delta_polar, self._fan,
882
+ self._coordinate_points, self._point_to_ray,
883
+ self.variable_names(), None, F)
884
+ # coordinate_name_indices do not matter, we give explicit
885
+ # names for all variables
886
+
887
+ def coordinate_point_to_coordinate(self, point):
888
+ r"""
889
+ Return the variable of the coordinate ring corresponding to ``point``.
890
+
891
+ INPUT:
892
+
893
+ - ``point`` -- integer from the list of :meth:`coordinate_points`
894
+
895
+ OUTPUT: the corresponding generator of the coordinate ring of ``self``
896
+
897
+ EXAMPLES::
898
+
899
+ sage: diamond = lattice_polytope.cross_polytope(2)
900
+ sage: FTV = CPRFanoToricVariety(diamond, coordinate_points=[0,1,2,3,8])
901
+ sage: FTV.coordinate_points()
902
+ (0, 1, 2, 3, 8)
903
+ sage: FTV.gens()
904
+ (z0, z1, z2, z3, z8)
905
+ sage: FTV.coordinate_point_to_coordinate(8)
906
+ z8
907
+ """
908
+ return self.gen(self._point_to_ray[point])
909
+
910
+ def coordinate_points(self):
911
+ r"""
912
+ Return indices of points of :meth:`Delta_polar` used for coordinates.
913
+
914
+ OUTPUT: :class:`tuple` of integers
915
+
916
+ EXAMPLES::
917
+
918
+ sage: diamond = lattice_polytope.cross_polytope(2)
919
+ sage: square = diamond.polar()
920
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
921
+ ....: coordinate_points=[0,1,2,3,8])
922
+ sage: FTV.coordinate_points()
923
+ (0, 1, 2, 3, 8)
924
+ sage: FTV.gens()
925
+ (z0, z1, z2, z3, z8)
926
+
927
+ sage: FTV = CPRFanoToricVariety(Delta_polar=square,
928
+ ....: coordinate_points='all')
929
+ sage: FTV.coordinate_points()
930
+ (0, 1, 2, 3, 4, 5, 7, 8)
931
+ sage: FTV.gens()
932
+ (z0, z1, z2, z3, z4, z5, z7, z8)
933
+
934
+ Note that one point is missing, namely ::
935
+
936
+ sage: square.origin()
937
+ 6
938
+ """
939
+ return self._coordinate_points
940
+
941
+ def Delta(self):
942
+ r"""
943
+ Return the reflexive polytope associated to ``self``.
944
+
945
+ OUTPUT:
946
+
947
+ - reflexive :class:`lattice polytope
948
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`. The
949
+ underlying fan of ``self`` is a coherent subdivision of the
950
+ *normal fan* of this polytope.
951
+
952
+ EXAMPLES::
953
+
954
+ sage: diamond = lattice_polytope.cross_polytope(2)
955
+ sage: P1xP1 = CPRFanoToricVariety(Delta_polar=diamond)
956
+ sage: P1xP1.Delta() # needs polytopes_db
957
+ 2-d reflexive polytope #14 in 2-d lattice N
958
+ sage: P1xP1.Delta() is diamond.polar()
959
+ True
960
+ """
961
+ return self._Delta_polar.polar()
962
+
963
+ def Delta_polar(self):
964
+ r"""
965
+ Return polar of :meth:`Delta`.
966
+
967
+ OUTPUT:
968
+
969
+ - reflexive :class:`lattice polytope
970
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`. The
971
+ underlying fan of ``self`` is a coherent subdivision of the
972
+ *face fan* of this polytope.
973
+
974
+ EXAMPLES::
975
+
976
+ sage: diamond = lattice_polytope.cross_polytope(2)
977
+ sage: P1xP1 = CPRFanoToricVariety(Delta_polar=diamond)
978
+ sage: P1xP1.Delta_polar() # needs polytopes_db
979
+ 2-d reflexive polytope #3 in 2-d lattice M
980
+ sage: P1xP1.Delta_polar() is diamond
981
+ True
982
+ sage: P1xP1.Delta_polar() is P1xP1.Delta().polar()
983
+ True
984
+ """
985
+ return self._Delta_polar
986
+
987
+ def nef_complete_intersection(self, nef_partition, **kwds):
988
+ r"""
989
+ Return a nef complete intersection in ``self``.
990
+
991
+ .. NOTE::
992
+
993
+ The returned complete intersection may be actually a subscheme of
994
+ **another** CPR-Fano toric variety: if the base field of ``self``
995
+ does not include all of the required names for monomial
996
+ coefficients, it will be automatically extended.
997
+
998
+ Below `\Delta` is the reflexive polytope corresponding to ``self``,
999
+ i.e. the fan of ``self`` is a refinement of the normal fan of
1000
+ `\Delta`. Other polytopes are described in the documentation of
1001
+ :class:`nef-partitions <sage.geometry.lattice_polytope.NefPartition>`
1002
+ of :class:`reflexive polytopes
1003
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`.
1004
+
1005
+ Except for the first argument, ``nef_partition``, this method accepts
1006
+ only keyword parameters.
1007
+
1008
+ INPUT:
1009
+
1010
+ - ``nef_partition`` -- a `k`-part :class:`nef-partition
1011
+ <sage.geometry.lattice_polytope.NefPartition>` of `\Delta^\circ`, all
1012
+ other parameters (if given) must be lists of length `k`
1013
+
1014
+ - ``monomial_points`` -- the `i`-th element of this list is either a
1015
+ list of integers or a string. A list will be interpreted as indices
1016
+ of points of `\Delta_i` which should be used for monomials of the
1017
+ `i`-th polynomial of this complete intersection. A string must be one
1018
+ of the following descriptions of points of `\Delta_i`:
1019
+
1020
+ * "vertices",
1021
+ * "vertices+origin",
1022
+ * "all" (default),
1023
+
1024
+ when using this description, it is also OK to pass a single string as
1025
+ ``monomial_points`` instead of repeating it `k` times.
1026
+
1027
+ - ``coefficient_names`` -- the `i`-th element of this list specifies
1028
+ names for the monomial coefficients of the `i`-th polynomial, see
1029
+ :func:`~sage.schemes.toric.variety.normalize_names`
1030
+ for acceptable formats. If not given, indexed coefficient names will
1031
+ be created automatically.
1032
+
1033
+ - ``coefficient_name_indices`` -- the `i`-th element of this list
1034
+ specifies indices for indexed coefficients of the `i`-th polynomial.
1035
+ If not given, the index of each coefficient will coincide with the
1036
+ index of the corresponding point of `\Delta_i`.
1037
+
1038
+ - ``coefficients`` -- as an alternative to specifying coefficient
1039
+ names and/or indices, you can give the coefficients themselves as
1040
+ arbitrary expressions and/or strings. Using strings allows you to
1041
+ easily add "parameters": the base field of ``self`` will be extended
1042
+ to include all necessary names.
1043
+
1044
+ OUTPUT:
1045
+
1046
+ - a :class:`nef complete intersection <NefCompleteIntersection>` of
1047
+ ``self`` (with the extended base field, if necessary).
1048
+
1049
+ EXAMPLES:
1050
+
1051
+ We construct several complete intersections associated to the same
1052
+ nef-partition of the 3-dimensional reflexive polytope #2254::
1053
+
1054
+ sage: # needs polytopes_db
1055
+ sage: p = ReflexivePolytope(3, 2254)
1056
+ sage: np = p.nef_partitions()[1]; np
1057
+ Nef-partition {2, 3, 4, 7, 8} ⊔ {0, 1, 5, 6}
1058
+ sage: X = CPRFanoToricVariety(Delta_polar=p)
1059
+ sage: X.nef_complete_intersection(np)
1060
+ Closed subscheme of 3-d CPR-Fano toric variety
1061
+ covered by 10 affine patches defined by:
1062
+ a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2
1063
+ + a3*z2*z3*z4*z7*z8 + a1*z0*z2,
1064
+ b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4
1065
+ + b5*z1*z3*z4*z5*z6*z7*z8 + b2*z2*z3*z6^2*z8^3
1066
+ + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6
1067
+
1068
+ Now we include only monomials associated to vertices of `\Delta_i`::
1069
+
1070
+ sage: X.nef_complete_intersection(np, monomial_points='vertices') # needs polytopes_db
1071
+ Closed subscheme of 3-d CPR-Fano toric variety
1072
+ covered by 10 affine patches defined by:
1073
+ a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2
1074
+ + a3*z2*z3*z4*z7*z8 + a1*z0*z2,
1075
+ b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4
1076
+ + b2*z2*z3*z6^2*z8^3 + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6
1077
+
1078
+ (effectively, we set ``b5=0``). Next we provide coefficients explicitly
1079
+ instead of using default generic names::
1080
+
1081
+ sage: X.nef_complete_intersection(np, # needs polytopes_db
1082
+ ....: monomial_points='vertices',
1083
+ ....: coefficients=[("a", "a^2", "a/e", "c_i"), list(range(1,6))])
1084
+ Closed subscheme of 3-d CPR-Fano toric variety
1085
+ covered by 10 affine patches defined by:
1086
+ a*z1*z4^2*z5^2*z7^3 + a/e*z2*z4*z5*z6*z7^2*z8^2
1087
+ + (c_i)*z2*z3*z4*z7*z8 + (a^2)*z0*z2,
1088
+ 4*z1*z4*z5^2*z6^2*z7^2*z8^2 + z2*z5*z6^3*z7*z8^4
1089
+ + 3*z2*z3*z6^2*z8^3 + 2*z1*z3^2*z4 + 5*z0*z1*z5*z6
1090
+
1091
+ Finally, we take a look at the generic representative of these complete
1092
+ intersections in a completely resolved ambient toric variety::
1093
+
1094
+ sage: X = CPRFanoToricVariety(Delta_polar=p, # needs polytopes_db
1095
+ ....: coordinate_points='all')
1096
+ sage: X.nef_complete_intersection(np) # needs polytopes_db
1097
+ Closed subscheme of 3-d CPR-Fano toric variety
1098
+ covered by 22 affine patches defined by:
1099
+ a2*z2*z4*z5*z6*z7^2*z8^2*z9^2*z10^2*z11*z12*z13
1100
+ + a0*z1*z4^2*z5^2*z7^3*z9*z10^2*z12*z13
1101
+ + a3*z2*z3*z4*z7*z8*z9*z10*z11*z12 + a1*z0*z2,
1102
+ b0*z2*z5*z6^3*z7*z8^4*z9^3*z10^2*z11^2*z12*z13^2
1103
+ + b3*z1*z4*z5^2*z6^2*z7^2*z8^2*z9^2*z10^2*z11*z12*z13^2
1104
+ + b2*z2*z3*z6^2*z8^3*z9^2*z10*z11^2*z12*z13
1105
+ + b5*z1*z3*z4*z5*z6*z7*z8*z9*z10*z11*z12*z13
1106
+ + b1*z1*z3^2*z4*z11*z12 + b4*z0*z1*z5*z6*z13
1107
+ """
1108
+ return NefCompleteIntersection(self, nef_partition, **kwds)
1109
+
1110
+ def cartesian_product(self, other,
1111
+ coordinate_names=None, coordinate_indices=None):
1112
+ r"""
1113
+ Return the Cartesian product of ``self`` with ``other``.
1114
+
1115
+ INPUT:
1116
+
1117
+ - ``other`` -- a (possibly
1118
+ :class:`CPR-Fano <CPRFanoToricVariety_field>`) :class:`toric variety
1119
+ <sage.schemes.toric.variety.ToricVariety_field>`
1120
+
1121
+ - ``coordinate_names`` -- names of variables for the coordinate ring,
1122
+ see :func:`normalize_names` for acceptable formats. If not given,
1123
+ indexed variable names will be created automatically.
1124
+
1125
+ - ``coordinate_indices`` -- list of integers, indices for indexed
1126
+ variables. If not given, the index of each variable will coincide
1127
+ with the index of the corresponding ray of the fan.
1128
+
1129
+ OUTPUT:
1130
+
1131
+ - a :class:`toric variety
1132
+ <sage.schemes.toric.variety.ToricVariety_field>`, which is
1133
+ :class:`CPR-Fano <CPRFanoToricVariety_field>` if ``other`` was.
1134
+
1135
+ EXAMPLES::
1136
+
1137
+ sage: P1 = toric_varieties.P1()
1138
+ sage: P2 = toric_varieties.P2()
1139
+ sage: P1xP2 = P1.cartesian_product(P2); P1xP2
1140
+ 3-d CPR-Fano toric variety covered by 6 affine patches
1141
+ sage: P1xP2.fan().rays()
1142
+ N+N( 1, 0, 0), N+N(-1, 0, 0), N+N( 0, 1, 0),
1143
+ N+N( 0, 0, 1), N+N( 0, -1, -1)
1144
+ in 3-d lattice N+N
1145
+ sage: P1xP2.Delta_polar()
1146
+ 3-d reflexive polytope in 3-d lattice N+N
1147
+ """
1148
+ if isinstance(other, CPRFanoToricVariety_field):
1149
+ fan = self.fan().cartesian_product(other.fan())
1150
+ Delta_polar = LatticePolytope(fan.rays())
1151
+
1152
+ points = Delta_polar.points()
1153
+ point_to_ray = {}
1154
+ coordinate_points = []
1155
+ for ray_index, ray in enumerate(fan.rays()):
1156
+ point = points.index(ray)
1157
+ coordinate_points.append(point)
1158
+ point_to_ray[point] = ray_index
1159
+
1160
+ return CPRFanoToricVariety_field(Delta_polar, fan,
1161
+ coordinate_points, point_to_ray,
1162
+ coordinate_names, coordinate_indices,
1163
+ self.base_ring())
1164
+ return super().cartesian_product(other)
1165
+
1166
+ def resolve(self, **kwds):
1167
+ r"""
1168
+ Construct a toric variety whose fan subdivides the fan of ``self``.
1169
+
1170
+ This function accepts only keyword arguments, none of which are
1171
+ mandatory.
1172
+
1173
+ INPUT:
1174
+
1175
+ - ``new_points`` -- list of integers, indices of boundary points of
1176
+ :meth:`Delta_polar`, which should be added as rays to the
1177
+ subdividing fan
1178
+
1179
+ - all other arguments will be passed to
1180
+ :meth:`~sage.schemes.toric.variety.ToricVariety_field.resolve`
1181
+ method of (general) toric varieties; see its documentation for
1182
+ details
1183
+
1184
+ OUTPUT:
1185
+
1186
+ - :class:`CPR-Fano toric variety <CPRFanoToricVariety_field>` if there
1187
+ was no ``new_rays`` argument and :class:`toric variety
1188
+ <sage.schemes.toric.variety.ToricVariety_field>` otherwise.
1189
+
1190
+ EXAMPLES::
1191
+
1192
+ sage: diamond = lattice_polytope.cross_polytope(2)
1193
+ sage: FTV = CPRFanoToricVariety(Delta=diamond)
1194
+ sage: FTV.coordinate_points()
1195
+ (0, 1, 2, 3)
1196
+ sage: FTV.gens()
1197
+ (z0, z1, z2, z3)
1198
+ sage: FTV_res = FTV.resolve(new_points=[6,8])
1199
+ Traceback (most recent call last):
1200
+ ...
1201
+ ValueError: the origin (point #6)
1202
+ cannot be used for subdivision!
1203
+ sage: FTV_res = FTV.resolve(new_points=[8,5]); FTV_res
1204
+ 2-d CPR-Fano toric variety covered by 6 affine patches
1205
+ sage: FTV_res.coordinate_points()
1206
+ (0, 1, 2, 3, 8, 5)
1207
+ sage: FTV_res.gens()
1208
+ (z0, z1, z2, z3, z8, z5)
1209
+
1210
+ sage: TV_res = FTV.resolve(new_rays=[(1,2)]); TV_res
1211
+ 2-d toric variety covered by 5 affine patches
1212
+ sage: TV_res.gens()
1213
+ (z0, z1, z2, z3, z4)
1214
+ """
1215
+ # Reasons to override the base class:
1216
+ # - allow using polytope point indices for subdivision
1217
+ # - handle automatic name creation in a different fashion
1218
+ # - return CPR-Fano toric variety if the above feature was used and
1219
+ # just toric variety if subdivision involves rays
1220
+ if "new_rays" in kwds:
1221
+ if "new_points" in kwds:
1222
+ raise ValueError("you cannot give new_points and new_rays at "
1223
+ "the same time!")
1224
+ return super().resolve(**kwds)
1225
+ # Now we need to construct another Fano variety
1226
+ new_points = kwds.pop("new_points", ())
1227
+ coordinate_points = self.coordinate_points()
1228
+ new_points = tuple(point for point in new_points
1229
+ if point not in coordinate_points)
1230
+ Delta_polar = self._Delta_polar
1231
+ if Delta_polar.origin() in new_points:
1232
+ raise ValueError("the origin (point #%d) cannot be used for "
1233
+ "subdivision!" % Delta_polar.origin())
1234
+ if new_points:
1235
+ coordinate_points = coordinate_points + new_points
1236
+ point_to_ray = {point: n
1237
+ for n, point in enumerate(coordinate_points)}
1238
+ else:
1239
+ point_to_ray = self._point_to_ray
1240
+ new_rays = [Delta_polar.point(point) for point in new_points]
1241
+ coordinate_name_indices = kwds.pop("coordinate_name_indices",
1242
+ coordinate_points)
1243
+ fan = self.fan()
1244
+ if "coordinate_names" in kwds:
1245
+ coordinate_names = kwds.pop("coordinate_names")
1246
+ else:
1247
+ coordinate_names = list(self.variable_names())
1248
+ coordinate_names.extend(normalize_names(ngens=len(new_rays),
1249
+ indices=coordinate_name_indices[fan.nrays():],
1250
+ prefix=self._coordinate_prefix))
1251
+ coordinate_names.append(self._coordinate_prefix + "+")
1252
+ rfan = fan.subdivide(new_rays=new_rays, **kwds)
1253
+ resolution = CPRFanoToricVariety_field(Delta_polar, rfan,
1254
+ coordinate_points, point_to_ray, coordinate_names,
1255
+ coordinate_name_indices, self.base_ring())
1256
+ R = self.coordinate_ring()
1257
+ R_res = resolution.coordinate_ring()
1258
+ resolution_map = resolution.hom(R.hom(R_res.gens()[:R.ngens()]), self)
1259
+ resolution._resolution_map = resolution_map
1260
+ return resolution
1261
+
1262
+
1263
+ class AnticanonicalHypersurface(AlgebraicScheme_subscheme_toric):
1264
+ r"""
1265
+ Construct an anticanonical hypersurface of a CPR-Fano toric variety.
1266
+
1267
+ INPUT:
1268
+
1269
+ - ``P_Delta`` -- :class:`CPR-Fano toric variety
1270
+ <CPRFanoToricVariety_field>` associated to a reflexive polytope `\Delta`
1271
+
1272
+ - see :meth:`CPRFanoToricVariety_field.anticanonical_hypersurface` for
1273
+ documentation on all other acceptable parameters
1274
+
1275
+ OUTPUT:
1276
+
1277
+ :class:`anticanonical hypersurface <AnticanonicalHypersurface>` of
1278
+ ``P_Delta`` (with the extended base field, if necessary).
1279
+
1280
+ EXAMPLES::
1281
+
1282
+ sage: P1xP1 = toric_varieties.P1xP1()
1283
+ sage: import sage.schemes.toric.fano_variety as ftv
1284
+ sage: ftv.AnticanonicalHypersurface(P1xP1)
1285
+ Closed subscheme of 2-d CPR-Fano toric variety
1286
+ covered by 4 affine patches defined by:
1287
+ a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2
1288
+
1289
+ See :meth:`~CPRFanoToricVariety_field.anticanonical_hypersurface()` for a
1290
+ more elaborate example.
1291
+ """
1292
+ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None,
1293
+ coefficient_name_indices=None, coefficients=None):
1294
+ r"""
1295
+ See :meth:`CPRFanoToricVariety_field.anticanonical_hypersurface` for
1296
+ documentation.
1297
+
1298
+ TESTS::
1299
+
1300
+ sage: P1xP1 = toric_varieties.P1xP1()
1301
+ sage: import sage.schemes.toric.fano_variety as ftv
1302
+ sage: ftv.AnticanonicalHypersurface(P1xP1)
1303
+ Closed subscheme of 2-d CPR-Fano toric variety
1304
+ covered by 4 affine patches defined by:
1305
+ a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2
1306
+
1307
+ Check that finite fields are handled correctly :issue:`14899`::
1308
+
1309
+ sage: F = GF(5^2, "a") # needs sage.rings.finite_rings
1310
+ sage: X = P1xP1.change_ring(F) # needs sage.rings.finite_rings
1311
+ sage: X.anticanonical_hypersurface(monomial_points='all', # needs sage.rings.finite_rings
1312
+ ....: coefficients=[1]*X.Delta().npoints())
1313
+ Closed subscheme of 2-d CPR-Fano toric variety
1314
+ covered by 4 affine patches defined by:
1315
+ s^2*x^2 + s*t*x^2 + t^2*x^2 + s^2*x*y + s*t*x*y
1316
+ + t^2*x*y + s^2*y^2 + s*t*y^2 + t^2*y^2
1317
+ """
1318
+ if not isinstance(P_Delta, CPRFanoToricVariety_field):
1319
+ raise TypeError("anticanonical hypersurfaces can only be "
1320
+ "constructed for CPR-Fano toric varieties!"
1321
+ "\nGot: %s" % P_Delta)
1322
+ Delta = P_Delta.Delta()
1323
+ Delta_polar = Delta.polar()
1324
+ # Monomial points normalization
1325
+ if monomial_points == "vertices":
1326
+ monomial_points = list(range(Delta.nvertices()))
1327
+ elif monomial_points == "all":
1328
+ monomial_points = list(range(Delta.npoints()))
1329
+ elif monomial_points == "vertices+origin":
1330
+ monomial_points = list(range(Delta.nvertices()))
1331
+ monomial_points.append(Delta.origin())
1332
+ elif monomial_points == "simplified" or monomial_points is None:
1333
+ monomial_points = Delta.skeleton_points(Delta.dim() - 2)
1334
+ monomial_points.append(Delta.origin())
1335
+ elif isinstance(monomial_points, str):
1336
+ raise ValueError("%s is an unsupported description of monomial "
1337
+ "points!" % monomial_points)
1338
+ monomial_points = tuple(monomial_points)
1339
+ self._monomial_points = monomial_points
1340
+ # Make the necessary ambient space
1341
+ if coefficients is None:
1342
+ if coefficient_name_indices is None:
1343
+ coefficient_name_indices = monomial_points
1344
+ coefficient_names = normalize_names(
1345
+ coefficient_names, len(monomial_points),
1346
+ DEFAULT_COEFFICIENT, coefficient_name_indices)
1347
+ # We probably don't want it: the analog in else-branch is unclear.
1348
+ # self._coefficient_names = coefficient_names
1349
+ F = add_variables(P_Delta.base_ring(), coefficient_names)
1350
+ coefficients = [F(coef) for coef in coefficient_names]
1351
+ else:
1352
+ variables = set()
1353
+ nonstr = []
1354
+ regex = re.compile(r"[_A-Za-z]\w*")
1355
+ for c in coefficients:
1356
+ if isinstance(c, str):
1357
+ variables.update(regex.findall(c))
1358
+ else:
1359
+ nonstr.append(c)
1360
+ F = add_variables(P_Delta.base_ring(), sorted(variables))
1361
+ F = coercion_model.common_parent(F, *nonstr)
1362
+ coefficients = [F(_) for _ in coefficients]
1363
+ P_Delta = P_Delta.base_extend(F)
1364
+ if len(monomial_points) != len(coefficients):
1365
+ raise ValueError("cannot construct equation of the anticanonical"
1366
+ " hypersurface with %d monomials and %d coefficients"
1367
+ % (len(monomial_points), len(coefficients)))
1368
+ # Defining polynomial
1369
+ h = sum(coef * prod(P_Delta.coordinate_point_to_coordinate(n)
1370
+ ** (Delta.point(m) * Delta_polar.point(n) + 1)
1371
+ for n in P_Delta.coordinate_points())
1372
+ for m, coef in zip(monomial_points, coefficients))
1373
+ super().__init__(P_Delta, h)
1374
+
1375
+
1376
+ class NefCompleteIntersection(AlgebraicScheme_subscheme_toric):
1377
+ r"""
1378
+ Construct a nef complete intersection in a CPR-Fano toric variety.
1379
+
1380
+ INPUT:
1381
+
1382
+ - ``P_Delta`` -- a :class:`CPR-Fano toric variety
1383
+ <CPRFanoToricVariety_field>` associated to a reflexive polytope `\Delta`
1384
+
1385
+ - see :meth:`CPRFanoToricVariety_field.nef_complete_intersection` for
1386
+ documentation on all other acceptable parameters
1387
+
1388
+ OUTPUT:
1389
+
1390
+ - a :class:`nef complete intersection <NefCompleteIntersection>` of
1391
+ ``P_Delta`` (with the extended base field, if necessary).
1392
+
1393
+ EXAMPLES::
1394
+
1395
+ sage: o = lattice_polytope.cross_polytope(3)
1396
+ sage: np = o.nef_partitions()[0]; np
1397
+ Nef-partition {0, 1, 3} ⊔ {2, 4, 5}
1398
+ sage: X = CPRFanoToricVariety(Delta_polar=o)
1399
+ sage: X.nef_complete_intersection(np)
1400
+ Closed subscheme of 3-d CPR-Fano toric variety
1401
+ covered by 8 affine patches defined by:
1402
+ a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4,
1403
+ b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2
1404
+
1405
+ See :meth:`CPRFanoToricVariety_field.nef_complete_intersection` for a
1406
+ more elaborate example.
1407
+ """
1408
+ def __init__(self, P_Delta, nef_partition,
1409
+ monomial_points='all', coefficient_names=None,
1410
+ coefficient_name_indices=None, coefficients=None):
1411
+ r"""
1412
+ See :meth:`CPRFanoToricVariety_field.nef_complete_intersection` for
1413
+ documentation.
1414
+
1415
+ TESTS::
1416
+
1417
+ sage: o = lattice_polytope.cross_polytope(3)
1418
+ sage: np = o.nef_partitions()[0]
1419
+ sage: np
1420
+ Nef-partition {0, 1, 3} ⊔ {2, 4, 5}
1421
+ sage: X = CPRFanoToricVariety(Delta_polar=o)
1422
+ sage: from sage.schemes.toric.fano_variety import *
1423
+ sage: NefCompleteIntersection(X, np)
1424
+ Closed subscheme of 3-d CPR-Fano toric variety
1425
+ covered by 8 affine patches defined by:
1426
+ a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2
1427
+ + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4,
1428
+ b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5
1429
+ + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2
1430
+ """
1431
+ if not isinstance(P_Delta, CPRFanoToricVariety_field):
1432
+ raise TypeError("nef complete intersections can only be "
1433
+ "constructed for CPR-Fano toric varieties!"
1434
+ "\nGot: %s" % P_Delta)
1435
+ if nef_partition.Delta() is not P_Delta.Delta():
1436
+ raise ValueError("polytopes 'Delta' of the nef-partition and the "
1437
+ "CPR-Fano toric variety must be the same!")
1438
+ self._nef_partition = nef_partition
1439
+ k = nef_partition.nparts()
1440
+ # Pre-normalize all parameters
1441
+ if isinstance(monomial_points, str):
1442
+ monomial_points = [monomial_points] * k
1443
+ if coefficient_names is None:
1444
+ coefficient_names = [None] * k
1445
+ if coefficient_name_indices is None:
1446
+ coefficient_name_indices = [None] * k
1447
+ if coefficients is None:
1448
+ coefficients = [None] * k
1449
+
1450
+ polynomials = []
1451
+ Delta_polar = P_Delta.Delta_polar()
1452
+ for i in range(k):
1453
+ Delta_i = nef_partition.Delta(i)
1454
+ # Monomial points normalization
1455
+ if monomial_points[i] == "vertices":
1456
+ monomial_points[i] = list(range(Delta_i.nvertices()))
1457
+ elif monomial_points[i] == "all":
1458
+ monomial_points[i] = list(range(Delta_i.npoints()))
1459
+ elif monomial_points[i] == "vertices+origin":
1460
+ monomial_points[i] = list(range(Delta_i.nvertices()))
1461
+ if (Delta_i.origin() is not None
1462
+ and Delta_i.origin() >= Delta_i.nvertices()):
1463
+ monomial_points[i].append(Delta_i.origin())
1464
+ elif isinstance(monomial_points[i], str):
1465
+ raise ValueError("'%s' is an unsupported description of "
1466
+ "monomial points!" % monomial_points[i])
1467
+ monomial_points[i] = tuple(monomial_points[i])
1468
+ # Extend the base ring of the ambient space if necessary
1469
+ if coefficients[i] is None:
1470
+ if coefficient_name_indices[i] is None:
1471
+ coefficient_name_indices[i] = monomial_points[i]
1472
+ coefficient_names[i] = normalize_names(
1473
+ coefficient_names[i], len(monomial_points[i]),
1474
+ DEFAULT_COEFFICIENTS[i], coefficient_name_indices[i])
1475
+ F = add_variables(P_Delta.base_ring(), coefficient_names[i])
1476
+ coefficients[i] = [F(coef) for coef in coefficient_names[i]]
1477
+ else:
1478
+ variables = set()
1479
+ nonstr = []
1480
+ regex = re.compile(r"[_A-Za-z]\w*")
1481
+ for c in coefficients[i]:
1482
+ if isinstance(c, str):
1483
+ variables.update(regex.findall(c))
1484
+ else:
1485
+ nonstr.append(c)
1486
+ F = add_variables(P_Delta.base_ring(), sorted(variables))
1487
+ F = coercion_model.common_parent(F, *nonstr)
1488
+ coefficients[i] = [F(_) for _ in coefficients[i]]
1489
+ P_Delta = P_Delta.base_extend(F)
1490
+ if len(monomial_points[i]) != len(coefficients[i]):
1491
+ raise ValueError("cannot construct equation %d of the complete"
1492
+ " intersection with %d monomials and %d coefficients"
1493
+ % (i, len(monomial_points[i]), len(coefficients[i])))
1494
+ # Defining polynomial
1495
+ h = sum(coef * prod(P_Delta.coordinate_point_to_coordinate(n)
1496
+ ** (Delta_i.point(m) * Delta_polar.point(n)
1497
+ + (nef_partition.part_of_point(n) == i))
1498
+ for n in P_Delta.coordinate_points())
1499
+ for m, coef in zip(monomial_points[i], coefficients[i]))
1500
+ polynomials.append(h)
1501
+ self._monomial_points = tuple(monomial_points)
1502
+ super().__init__(P_Delta, polynomials)
1503
+
1504
+ def cohomology_class(self):
1505
+ r"""
1506
+ Return the class of ``self`` in the ambient space cohomology ring.
1507
+
1508
+ OUTPUT: a :class:`cohomology class <sage.schemes.generic.toric_variety.CohomologyClass>`
1509
+
1510
+ EXAMPLES::
1511
+
1512
+ sage: o = lattice_polytope.cross_polytope(3)
1513
+ sage: np = o.nef_partitions()[0]; np
1514
+ Nef-partition {0, 1, 3} ⊔ {2, 4, 5}
1515
+ sage: X = CPRFanoToricVariety(Delta_polar=o)
1516
+ sage: CI = X.nef_complete_intersection(np); CI
1517
+ Closed subscheme of 3-d CPR-Fano toric variety
1518
+ covered by 8 affine patches defined by:
1519
+ a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4,
1520
+ b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2
1521
+ sage: CI.cohomology_class() # needs sage.libs.singular
1522
+ [2*z3*z4 + 4*z3*z5 + 2*z4*z5]
1523
+ """
1524
+ X = self.ambient_space()
1525
+ H = X.cohomology_ring()
1526
+ return prod(sum(H.gen(X._point_to_ray[point])
1527
+ for point in part if point in X._coordinate_points)
1528
+ for part in self.nef_partition().parts(all_points=True))
1529
+
1530
+ def nef_partition(self):
1531
+ r"""
1532
+ Return the nef-partition associated to ``self``.
1533
+
1534
+ OUTPUT: a :class:`nef-partition <sage.geometry.lattice_polytope.NefPartition>`
1535
+
1536
+ EXAMPLES::
1537
+
1538
+ sage: o = lattice_polytope.cross_polytope(3)
1539
+ sage: np = o.nef_partitions()[0]; np
1540
+ Nef-partition {0, 1, 3} ⊔ {2, 4, 5}
1541
+ sage: X = CPRFanoToricVariety(Delta_polar=o)
1542
+ sage: CI = X.nef_complete_intersection(np); CI
1543
+ Closed subscheme of 3-d CPR-Fano toric variety
1544
+ covered by 8 affine patches defined by:
1545
+ a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4,
1546
+ b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2
1547
+ sage: CI.nef_partition()
1548
+ Nef-partition {0, 1, 3} ⊔ {2, 4, 5}
1549
+ sage: CI.nef_partition() is np
1550
+ True
1551
+ """
1552
+ return self._nef_partition
1553
+
1554
+
1555
+ def add_variables(field, variables):
1556
+ r"""
1557
+ Extend ``field`` to include all ``variables``.
1558
+
1559
+ INPUT:
1560
+
1561
+ - ``field`` -- a field
1562
+
1563
+ - ``variables`` -- list of strings
1564
+
1565
+ OUTPUT:
1566
+
1567
+ - a fraction field extending the original ``field``, which has all
1568
+ ``variables`` among its generators.
1569
+
1570
+ EXAMPLES:
1571
+
1572
+ We start with the rational field and slowly add more variables::
1573
+
1574
+ sage: from sage.schemes.toric.fano_variety import *
1575
+ sage: F = add_variables(QQ, []); F # No extension
1576
+ Rational Field
1577
+ sage: F = add_variables(QQ, ["a"]); F
1578
+ Fraction Field of Univariate Polynomial Ring in a over Rational Field
1579
+ sage: F = add_variables(F, ["a"]); F
1580
+ Fraction Field of Univariate Polynomial Ring in a over Rational Field
1581
+ sage: F = add_variables(F, ["b", "c"]); F
1582
+ Fraction Field of Multivariate Polynomial Ring in a, b, c over Rational Field
1583
+ sage: F = add_variables(F, ["c", "d", "b", "c", "d"]); F
1584
+ Fraction Field of Multivariate Polynomial Ring in a, b, c, d over Rational Field
1585
+ """
1586
+ if not variables:
1587
+ return field
1588
+ if isinstance(field, FractionField_generic):
1589
+ # Q(a) ---> Q(a, b) rather than Q(a)(b)
1590
+ R = field.ring()
1591
+ if isinstance(R, (PolynomialRing_generic, MPolynomialRing_base)):
1592
+ new_variables = list(R.variable_names())
1593
+ for v in variables:
1594
+ if v not in new_variables:
1595
+ new_variables.append(v)
1596
+ if len(new_variables) > R.ngens():
1597
+ return PolynomialRing(R.base_ring(),
1598
+ new_variables).fraction_field()
1599
+ else:
1600
+ return field
1601
+ # "Intelligent extension" didn't work, use the "usual one."
1602
+ new_variables = []
1603
+ for v in variables:
1604
+ if v not in new_variables:
1605
+ new_variables.append(v)
1606
+ return PolynomialRing(field, new_variables).fraction_field()