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,914 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ """
3
+ A triangulation
4
+
5
+ In Sage, the
6
+ :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`
7
+ and :class:`Triangulation` satisfy a parent/element relationship. In
8
+ particular, each triangulation refers back to its point
9
+ configuration. If you want to triangulate a point configuration, you
10
+ should construct a point configuration first and then use one of its
11
+ methods to triangulate it according to your requirements. You should
12
+ never have to construct a :class:`Triangulation` object directly.
13
+
14
+ EXAMPLES:
15
+
16
+ First, we select the internal implementation for enumerating
17
+ triangulations::
18
+
19
+ sage: PointConfiguration.set_engine('internal') # to make doctests independent of TOPCOM
20
+
21
+ Here is a simple example of how to triangulate a point configuration::
22
+
23
+ sage: p = [[0,-1,-1],[0,0,1],[0,1,0], [1,-1,-1],[1,0,1],[1,1,0]]
24
+ sage: points = PointConfiguration(p)
25
+ sage: triang = points.triangulate(); triang
26
+ (<0,1,2,5>, <0,1,3,5>, <1,3,4,5>)
27
+ sage: triang.plot(axes=False) # needs sage.plot
28
+ Graphics3d Object
29
+
30
+ See :mod:`sage.geometry.triangulation.point_configuration` for more details.
31
+ """
32
+
33
+ #*****************************************************************************
34
+ # Copyright (C) 2010 Volker Braun <vbraun.name@gmail.com>
35
+ #
36
+ # This program is free software: you can redistribute it and/or modify
37
+ # it under the terms of the GNU General Public License as published by
38
+ # the Free Software Foundation, either version 2 of the License, or
39
+ # (at your option) any later version.
40
+ # https://www.gnu.org/licenses/
41
+ #*****************************************************************************
42
+
43
+ from sage.structure.richcmp import richcmp
44
+ from sage.structure.element import Element
45
+ from sage.rings.integer_ring import ZZ
46
+ from sage.rings.rational_field import QQ
47
+ from sage.modules.free_module_element import vector
48
+ from sage.misc.cachefunc import cached_method
49
+ from sage.sets.set import Set
50
+
51
+
52
+ ########################################################################
53
+ def triangulation_render_2d(triangulation, **kwds):
54
+ r"""
55
+ Return a graphical representation of a 2-d triangulation.
56
+
57
+ INPUT:
58
+
59
+ - ``triangulation`` -- a :class:`Triangulation`
60
+
61
+ - ``**kwds`` -- keywords that are passed on to the graphics primitives
62
+
63
+ OUTPUT: a 2-d graphics object
64
+
65
+ EXAMPLES::
66
+
67
+ sage: points = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
68
+ sage: triang = points.triangulate()
69
+ sage: triang.plot(axes=False, aspect_ratio=1) # indirect doctest # needs sage.plot
70
+ Graphics object consisting of 12 graphics primitives
71
+ """
72
+ from sage.plot.all import point2d, line2d, polygon2d
73
+ points = [point.reduced_affine() for point in triangulation.point_configuration()]
74
+ coord = [ [p[0], p[1]] for p in points ]
75
+ plot_points = sum([ point2d(p,
76
+ zorder=2, pointsize=10, **kwds)
77
+ for p in coord ])
78
+
79
+ tmp_lines = []
80
+ for t in triangulation:
81
+ if len(t) >= 2:
82
+ tmp_lines.append([t[0], t[1]])
83
+ if len(t) >= 3:
84
+ tmp_lines.append([t[0], t[2]])
85
+ tmp_lines.append([t[1], t[2]])
86
+ all_lines = []
87
+ interior_lines = []
88
+ for l in tmp_lines:
89
+ if l not in all_lines:
90
+ all_lines.append(l)
91
+ else:
92
+ interior_lines.append(l)
93
+ exterior_lines = [l for l in all_lines if l not in interior_lines]
94
+
95
+ plot_interior_lines = sum([ line2d([ coord[l[0]], coord[l[1]] ],
96
+ zorder=1, rgbcolor=(0,1,0), **kwds)
97
+ for l in interior_lines ])
98
+ plot_exterior_lines = sum([ line2d([ coord[l[0]], coord[l[1]] ],
99
+ zorder=1, rgbcolor=(0,0,1), **kwds)
100
+ for l in exterior_lines ])
101
+
102
+ plot_triangs = sum([ polygon2d([coord[t[0]], coord[t[1]], coord[t[2]]],
103
+ zorder=0, rgbcolor=(0.8, 1, 0.8), **kwds)
104
+ for t in triangulation if len(t) >= 3 ])
105
+
106
+ return \
107
+ plot_points + \
108
+ plot_interior_lines + plot_exterior_lines + \
109
+ plot_triangs
110
+
111
+
112
+ def triangulation_render_3d(triangulation, **kwds):
113
+ r"""
114
+ Return a graphical representation of a 3-d triangulation.
115
+
116
+ INPUT:
117
+
118
+ - ``triangulation`` -- a :class:`Triangulation`
119
+
120
+ - ``**kwds`` -- keywords that are passed on to the graphics primitives
121
+
122
+ OUTPUT: a 3-d graphics object
123
+
124
+ EXAMPLES::
125
+
126
+ sage: p = [[0,-1,-1],[0,0,1],[0,1,0], [1,-1,-1],[1,0,1],[1,1,0]]
127
+ sage: points = PointConfiguration(p)
128
+ sage: triang = points.triangulate()
129
+ sage: triang.plot(axes=False) # indirect doctest # needs sage.plot
130
+ Graphics3d Object
131
+ """
132
+ from sage.plot.plot3d.all import point3d, line3d, polygon3d
133
+ points = [ point.reduced_affine() for point in triangulation.point_configuration() ]
134
+ coord = [ [p[0], p[1], p[2] ] for p in points ]
135
+ plot_points = sum([ point3d(p, size=15,
136
+ **kwds)
137
+ for p in coord ])
138
+
139
+ tmp_lines = []
140
+ for t in triangulation:
141
+ if len(t) >= 2:
142
+ tmp_lines.append([t[0], t[1]])
143
+ if len(t) >= 3:
144
+ tmp_lines.append([t[0], t[2]])
145
+ tmp_lines.append([t[1], t[2]])
146
+ if len(t) >= 4:
147
+ tmp_lines.append([t[0], t[3]])
148
+ tmp_lines.append([t[1], t[3]])
149
+ tmp_lines.append([t[2], t[3]])
150
+ all_lines = []
151
+ interior_lines = []
152
+ for l in tmp_lines:
153
+ if l not in all_lines:
154
+ all_lines.append(l)
155
+ else:
156
+ interior_lines.append(l)
157
+ exterior_lines = [l for l in all_lines if l not in interior_lines]
158
+
159
+ from sage.plot.plot3d.texture import Texture
160
+ line_int = Texture(color='darkblue', ambient=1, diffuse=0)
161
+ line_ext = Texture(color='green', ambient=1, diffuse=0)
162
+ triang_int = Texture(opacity=0.3, specular=0, shininess=0, diffuse=0, ambient=1, color='yellow')
163
+ triang_ext = Texture(opacity=0.6, specular=0, shininess=0, diffuse=0, ambient=1, color='green')
164
+
165
+ plot_interior_lines = sum([ line3d([ coord[l[0]], coord[l[1]] ],
166
+ thickness=2, texture=line_int, **kwds)
167
+ for l in interior_lines ])
168
+ plot_exterior_lines = sum([ line3d([ coord[l[0]], coord[l[1]] ],
169
+ thickness=3, texture=line_ext, **kwds)
170
+ for l in exterior_lines ])
171
+
172
+ tmp_triangs = []
173
+ for t in triangulation:
174
+ if len(t) >= 3:
175
+ tmp_triangs.append([t[0], t[1], t[2]])
176
+ if len(t) >= 4:
177
+ tmp_triangs.append([t[0], t[1], t[3]])
178
+ tmp_triangs.append([t[0], t[2], t[3]])
179
+ tmp_triangs.append([t[1], t[2], t[3]])
180
+ all_triangs = []
181
+ interior_triangs = []
182
+ for l in tmp_triangs:
183
+ if l not in all_triangs:
184
+ all_triangs.append(l)
185
+ else:
186
+ interior_triangs.append(l)
187
+ exterior_triangs = [l for l in all_triangs if l not in interior_triangs]
188
+
189
+ plot_interior_triangs = \
190
+ sum([polygon3d([coord[t[0]], coord[t[1]], coord[t[2]]],
191
+ texture=triang_int, **kwds)
192
+ for t in interior_triangs])
193
+ plot_exterior_triangs = \
194
+ sum([polygon3d([coord[t[0]], coord[t[1]], coord[t[2]]],
195
+ texture=triang_ext, **kwds)
196
+ for t in exterior_triangs])
197
+
198
+ return plot_points + \
199
+ plot_interior_lines + plot_exterior_lines + \
200
+ plot_interior_triangs + plot_exterior_triangs
201
+
202
+
203
+ ########################################################################
204
+ class Triangulation(Element):
205
+ """
206
+ A triangulation of a
207
+ :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`.
208
+
209
+ .. WARNING::
210
+
211
+ You should never create :class:`Triangulation` objects
212
+ manually. See
213
+ :meth:`~sage.geometry.triangulation.point_configuration.PointConfiguration.triangulate`
214
+ and
215
+ :meth:`~sage.geometry.triangulation.point_configuration.PointConfiguration.triangulations`
216
+ to triangulate point configurations.
217
+ """
218
+ def __init__(self, triangulation, parent, check=True):
219
+ """
220
+ The constructor of a ``Triangulation`` object.
221
+
222
+ Note that an internal reference to the underlying ``PointConfiguration`` is
223
+ kept.
224
+
225
+ INPUT:
226
+
227
+ - ``parent`` -- a
228
+ :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`
229
+
230
+ - ``triangulation`` -- an iterable of integers or an iterable of
231
+ iterables (e.g. a list of lists), specifying the maximal simplices
232
+ of the triangulation. In the first case, each integer specifies a simplex
233
+ by the correspondence :meth:`PointConfiguration.simplex_to_int`. In the second
234
+ case, a simplex is specified by listing the indices of the included points.
235
+
236
+ - ``check`` -- boolean; whether to perform checks that the
237
+ triangulation is, indeed, a triangulation of the point
238
+ configuration
239
+
240
+ NOTE:
241
+
242
+ Passing ``check=False`` allows you to create triangulations of
243
+ subsets of the points of the configuration, see
244
+ :meth:`~sage.geometry.triangulation.point_configuration.PointConfiguration.bistellar_flips`.
245
+
246
+ EXAMPLES::
247
+
248
+ sage: p = [[0,1],[0,0],[1,0]]
249
+ sage: points = PointConfiguration(p)
250
+ sage: from sage.geometry.triangulation.point_configuration import Triangulation
251
+ sage: Triangulation([(0,1,2)], points)
252
+ (<0,1,2>)
253
+ sage: Triangulation([1], points)
254
+ (<0,1,2>)
255
+ """
256
+ Element.__init__(self, parent=parent)
257
+ self._point_configuration = parent
258
+
259
+ try:
260
+ triangulation = tuple(sorted( tuple(sorted(t)) for t in triangulation))
261
+ except TypeError:
262
+ triangulation = tuple( self.point_configuration().int_to_simplex(i)
263
+ for i in triangulation )
264
+ assert not check or all( len(t) == self.point_configuration().dim()+1
265
+ for t in triangulation)
266
+ self._triangulation = triangulation
267
+
268
+ def point_configuration(self):
269
+ """
270
+ Return the point configuration underlying the triangulation.
271
+
272
+ EXAMPLES::
273
+
274
+ sage: pconfig = PointConfiguration([[0,0],[0,1],[1,0]])
275
+ sage: pconfig
276
+ A point configuration in affine 2-space over Integer Ring
277
+ consisting of 3 points. The triangulations of this point
278
+ configuration are assumed to be connected, not necessarily
279
+ fine, not necessarily regular.
280
+ sage: triangulation = pconfig.triangulate()
281
+ sage: triangulation
282
+ (<0,1,2>)
283
+ sage: triangulation.point_configuration()
284
+ A point configuration in affine 2-space over Integer Ring
285
+ consisting of 3 points. The triangulations of this point
286
+ configuration are assumed to be connected, not necessarily
287
+ fine, not necessarily regular.
288
+ sage: pconfig == triangulation.point_configuration()
289
+ True
290
+ """
291
+ return self._point_configuration
292
+
293
+ def _richcmp_(self, right, op):
294
+ r"""
295
+ Compare ``self`` and ``right``.
296
+
297
+ INPUT:
298
+
299
+ - ``right`` -- a triangulation
300
+
301
+ TESTS::
302
+
303
+ sage: pc = PointConfiguration([[0,0],[0,1],[1,0]])
304
+ sage: t1 = pc.triangulate()
305
+ sage: from sage.geometry.triangulation.point_configuration import Triangulation
306
+ sage: t2 = Triangulation([[2,1,0]], pc)
307
+ sage: t1 is t2
308
+ False
309
+ sage: t1 == t2 # indirect doctest
310
+ True
311
+ sage: t1 != Triangulation(((0,1),(1,2)), pc, check=False)
312
+ True
313
+ """
314
+ return richcmp(self._triangulation, right._triangulation, op)
315
+
316
+ def __iter__(self):
317
+ """
318
+ Iterate through the simplices of the triangulation.
319
+
320
+ EXAMPLES::
321
+
322
+ sage: PointConfiguration.set_engine('internal') # to make doctests independent of TOPCOM
323
+ sage: pc = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
324
+ sage: triangulation = pc.triangulate()
325
+ sage: iter = triangulation.__iter__()
326
+ sage: next(iter)
327
+ (1, 3, 4)
328
+ sage: next(iter)
329
+ (2, 3, 4)
330
+ sage: next(iter)
331
+ Traceback (most recent call last):
332
+ ...
333
+ StopIteration
334
+ """
335
+ yield from self._triangulation
336
+
337
+ def __getitem__(self, i):
338
+ """
339
+ Access the point indices of the `i`-th simplex of the triangulation.
340
+
341
+ INPUT:
342
+
343
+ - ``i`` -- integer; the index of a simplex
344
+
345
+ OUTPUT:
346
+
347
+ A tuple of integers. The vertex indices of the `i`-th simplex.
348
+
349
+ EXAMPLES::
350
+
351
+ sage: PointConfiguration.set_engine('internal') # to make doctests independent of TOPCOM
352
+ sage: pc = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
353
+ sage: triangulation = pc.triangulate()
354
+ sage: triangulation[1]
355
+ (2, 3, 4)
356
+ """
357
+ return self._triangulation[i]
358
+
359
+ def __len__(self):
360
+ """
361
+ Return the length of the triangulation.
362
+
363
+ TESTS::
364
+
365
+ sage: PointConfiguration.set_engine('internal') # to make doctests independent of TOPCOM
366
+ sage: pc = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
367
+ sage: triangulation = next(pc.triangulations())
368
+ sage: triangulation.__len__()
369
+ 2
370
+ sage: len(triangulation) # equivalent
371
+ 2
372
+ """
373
+ return len(self._triangulation)
374
+
375
+ def _repr_(self):
376
+ r"""
377
+ Return a string representation.
378
+
379
+ TESTS::
380
+
381
+ sage: PointConfiguration.set_engine('internal') # to make doctests independent of TOPCOM
382
+ sage: pc = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1],[2,2]])
383
+ sage: t = pc.triangulations()
384
+ sage: next(t)._repr_()
385
+ '(<1,4,5>, <2,4,5>)'
386
+ """
387
+ #s = 'A triangulation'
388
+ #s += ' in QQ^'+str(self.point_configuration().ambient_dim())
389
+ #s += ' consisting of '+str(len(self))+' simplices.'
390
+ s = '('
391
+ s += ', '.join([ '<'+','.join(map(str,t))+'>' for t in self._triangulation])
392
+ s += ')'
393
+ return s
394
+
395
+ def plot(self, **kwds):
396
+ r"""
397
+ Produce a graphical representation of the triangulation.
398
+
399
+ EXAMPLES::
400
+
401
+ sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
402
+ sage: triangulation = p.triangulate()
403
+ sage: triangulation
404
+ (<1,3,4>, <2,3,4>)
405
+ sage: triangulation.plot(axes=False) # needs sage.plot
406
+ Graphics object consisting of 12 graphics primitives
407
+ """
408
+ dim = self.point_configuration().dim()
409
+
410
+ if dim == 2:
411
+ return triangulation_render_2d(self, **kwds)
412
+
413
+ if dim == 3:
414
+ return triangulation_render_3d(self, **kwds)
415
+
416
+ raise NotImplementedError('Plotting '+str(dim)+'-dimensional triangulations not implemented!')
417
+
418
+ def gkz_phi(self):
419
+ r"""
420
+ Calculate the GKZ phi vector of the triangulation.
421
+
422
+ The phi vector is a vector of length equals to the number of
423
+ points in the point configuration. For a fixed triangulation
424
+ `T`, the entry corresponding to the `i`-th point `p_i` is
425
+
426
+ .. MATH::
427
+
428
+ \phi_T(p_i) = \sum_{t\in T, t\owns p_i} Vol(t)
429
+
430
+ that is, the total volume of all simplices containing `p_i`.
431
+ See also [GKZ1994]_ page 220 equation 1.4.
432
+
433
+ OUTPUT: the phi vector of self
434
+
435
+ EXAMPLES::
436
+
437
+ sage: p = PointConfiguration([[0,0],[1,0],[2,1],[1,2],[0,1]])
438
+ sage: p.triangulate().gkz_phi()
439
+ (3, 1, 5, 2, 4)
440
+ sage: p.lexicographic_triangulation().gkz_phi()
441
+ (1, 3, 4, 2, 5)
442
+ """
443
+ vec = vector(ZZ, self.point_configuration().n_points())
444
+ for simplex in self:
445
+ vol = self.point_configuration().volume(simplex)
446
+ for i in simplex:
447
+ vec[i] = vec[i] + vol
448
+ return vec
449
+
450
+ def enumerate_simplices(self):
451
+ r"""
452
+ Return the enumerated simplices.
453
+
454
+ OUTPUT: a tuple of integers that uniquely specifies the triangulation
455
+
456
+ EXAMPLES::
457
+
458
+ sage: pc = PointConfiguration(matrix([
459
+ ....: [ 0, 0, 0, 0, 0, 2, 4,-1, 1, 1, 0, 0, 1, 0],
460
+ ....: [ 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0],
461
+ ....: [ 0, 2, 0, 0, 0, 0,-1, 0, 1, 0, 1, 0, 0, 1],
462
+ ....: [ 0, 1, 1, 0, 0, 1, 0,-2, 1, 0, 0,-1, 1, 1],
463
+ ....: [ 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 0, 0, 0]
464
+ ....: ]).columns())
465
+ sage: triangulation = pc.lexicographic_triangulation()
466
+ sage: triangulation.enumerate_simplices()
467
+ (1678, 1688, 1769, 1779, 1895, 1905, 2112, 2143, 2234, 2360, 2555, 2580,
468
+ 2610, 2626, 2650, 2652, 2654, 2661, 2663, 2667, 2685, 2755, 2757, 2759,
469
+ 2766, 2768, 2772, 2811, 2881, 2883, 2885, 2892, 2894, 2898)
470
+
471
+ You can recreate the triangulation from this list by passing
472
+ it to the constructor::
473
+
474
+ sage: from sage.geometry.triangulation.point_configuration import Triangulation
475
+ sage: Triangulation([1678, 1688, 1769, 1779, 1895, 1905, 2112, 2143,
476
+ ....: 2234, 2360, 2555, 2580, 2610, 2626, 2650, 2652, 2654, 2661, 2663,
477
+ ....: 2667, 2685, 2755, 2757, 2759, 2766, 2768, 2772, 2811, 2881, 2883,
478
+ ....: 2885, 2892, 2894, 2898], pc)
479
+ (<1,3,4,7,10,13>, <1,3,4,8,10,13>, <1,3,6,7,10,13>, <1,3,6,8,10,13>,
480
+ <1,4,6,7,10,13>, <1,4,6,8,10,13>, <2,3,4,6,7,12>, <2,3,4,7,12,13>,
481
+ <2,3,6,7,12,13>, <2,4,6,7,12,13>, <3,4,5,6,9,12>, <3,4,5,8,9,12>,
482
+ <3,4,6,7,11,12>, <3,4,6,9,11,12>, <3,4,7,10,11,13>, <3,4,7,11,12,13>,
483
+ <3,4,8,9,10,12>, <3,4,8,10,12,13>, <3,4,9,10,11,12>, <3,4,10,11,12,13>,
484
+ <3,5,6,8,9,12>, <3,6,7,10,11,13>, <3,6,7,11,12,13>, <3,6,8,9,10,12>,
485
+ <3,6,8,10,12,13>, <3,6,9,10,11,12>, <3,6,10,11,12,13>, <4,5,6,8,9,12>,
486
+ <4,6,7,10,11,13>, <4,6,7,11,12,13>, <4,6,8,9,10,12>, <4,6,8,10,12,13>,
487
+ <4,6,9,10,11,12>, <4,6,10,11,12,13>)
488
+ """
489
+ pc = self._point_configuration
490
+ return tuple( pc.simplex_to_int(t) for t in self )
491
+
492
+ def fan(self, origin=None):
493
+ r"""
494
+ Construct the fan of cones over the simplices of the triangulation.
495
+
496
+ INPUT:
497
+
498
+ - ``origin`` -- ``None`` (default) or coordinates of a
499
+ point. The common apex of all cones of the fan. If ``None``,
500
+ the triangulation must be a star triangulation and the
501
+ distinguished central point is used as the origin.
502
+
503
+ OUTPUT:
504
+
505
+ A :class:`~sage.geometry.fan.RationalPolyhedralFan`. The
506
+ coordinates of the points are shifted so that the apex of the
507
+ fan is the origin of the coordinate system.
508
+
509
+ .. NOTE:: If the set of cones over the simplices is not a fan, a
510
+ suitable exception is raised.
511
+
512
+ EXAMPLES::
513
+
514
+ sage: pc = PointConfiguration([(0,0), (1,0), (0,1), (-1,-1)], star=0, fine=True)
515
+ sage: triangulation = pc.triangulate()
516
+ sage: fan = triangulation.fan(); fan
517
+ Rational polyhedral fan in 2-d lattice N
518
+ sage: fan.is_equivalent(toric_varieties.P2().fan()) # needs palp sage.graphs
519
+ True
520
+
521
+ Toric diagrams (the `\ZZ_5` hyperconifold)::
522
+
523
+ sage: vertices=[(0, 1, 0), (0, 3, 1), (0, 2, 3), (0, 0, 2)]
524
+ sage: interior=[(0, 1, 1), (0, 1, 2), (0, 2, 1), (0, 2, 2)]
525
+ sage: points = vertices + interior
526
+ sage: pc = PointConfiguration(points, fine=True)
527
+ sage: triangulation = pc.triangulate()
528
+ sage: fan = triangulation.fan((-1,0,0)); fan
529
+ Rational polyhedral fan in 3-d lattice N
530
+ sage: fan.rays()
531
+ N(1, 1, 0),
532
+ N(1, 3, 1),
533
+ N(1, 2, 3),
534
+ N(1, 0, 2),
535
+ N(1, 1, 1),
536
+ N(1, 1, 2),
537
+ N(1, 2, 1),
538
+ N(1, 2, 2)
539
+ in 3-d lattice N
540
+ """
541
+ from sage.geometry.fan import Fan
542
+ if origin is None:
543
+ origin = self.point_configuration().star_center()
544
+ R = self.base_ring()
545
+ origin = vector(R, origin)
546
+ points = self.point_configuration().points()
547
+ return Fan(self, (vector(R, p) - origin for p in points))
548
+
549
+ @cached_method
550
+ def simplicial_complex(self):
551
+ r"""
552
+ Return ``self`` as an (abstract) simplicial complex.
553
+
554
+ OUTPUT: a :class:`~sage.topology.simplicial_complex.SimplicialComplex`
555
+
556
+ EXAMPLES::
557
+
558
+ sage: p = polytopes.cuboctahedron()
559
+ sage: sc = p.triangulate(engine='internal').simplicial_complex(); sc # needs sage.graphs
560
+ Simplicial complex with 12 vertices and 16 facets
561
+
562
+ Any convex set is contractable, so its reduced homology groups vanish::
563
+
564
+ sage: sc.homology() # needs sage.graphs
565
+ {0: 0, 1: 0, 2: 0, 3: 0}
566
+ """
567
+ from sage.topology.simplicial_complex import SimplicialComplex
568
+ return SimplicialComplex(self)
569
+
570
+ @cached_method
571
+ def _boundary_simplex_dictionary(self):
572
+ """
573
+ Return facets and the simplices they bound.
574
+
575
+ TESTS::
576
+
577
+ sage: triangulation = polytopes.hypercube(2).triangulate(engine='internal')
578
+ sage: triangulation._boundary_simplex_dictionary()
579
+ {(0, 1): ((0, 1, 3),),
580
+ (0, 3): ((0, 1, 3),),
581
+ (1, 2): ((1, 2, 3),),
582
+ (1, 3): ((0, 1, 3), (1, 2, 3)),
583
+ (2, 3): ((1, 2, 3),)}
584
+
585
+ sage: triangulation = polytopes.cube().triangulate(engine='internal')
586
+ sage: triangulation._boundary_simplex_dictionary()
587
+ {(0, 1, 2): ((0, 1, 2, 7),),
588
+ (0, 1, 5): ((0, 1, 5, 7),),
589
+ (0, 1, 7): ((0, 1, 2, 7), (0, 1, 5, 7)),
590
+ (0, 2, 3): ((0, 2, 3, 7),),
591
+ (0, 2, 7): ((0, 1, 2, 7), (0, 2, 3, 7)),
592
+ (0, 3, 4): ((0, 3, 4, 7),),
593
+ (0, 3, 7): ((0, 2, 3, 7), (0, 3, 4, 7)),
594
+ (0, 4, 5): ((0, 4, 5, 7),),
595
+ (0, 4, 7): ((0, 3, 4, 7), (0, 4, 5, 7)),
596
+ (0, 5, 7): ((0, 1, 5, 7), (0, 4, 5, 7)),
597
+ (1, 2, 7): ((0, 1, 2, 7),),
598
+ (1, 5, 6): ((1, 5, 6, 7),),
599
+ (1, 5, 7): ((0, 1, 5, 7), (1, 5, 6, 7)),
600
+ (1, 6, 7): ((1, 5, 6, 7),),
601
+ (2, 3, 7): ((0, 2, 3, 7),),
602
+ (3, 4, 7): ((0, 3, 4, 7),),
603
+ (4, 5, 7): ((0, 4, 5, 7),),
604
+ (5, 6, 7): ((1, 5, 6, 7),)}
605
+ """
606
+ result = dict()
607
+ for simplex in self:
608
+ for i in range(len(simplex)):
609
+ facet = simplex[:i] + simplex[i+1:]
610
+ result[facet] = result.get(facet, tuple()) + (simplex,)
611
+ return result
612
+
613
+ @cached_method
614
+ def boundary(self):
615
+ """
616
+ Return the boundary of the triangulation.
617
+
618
+ OUTPUT:
619
+
620
+ The outward-facing boundary simplices (of dimension `d-1`) of
621
+ the `d`-dimensional triangulation as a set. Each boundary is
622
+ returned by a tuple of point indices.
623
+
624
+ EXAMPLES::
625
+
626
+ sage: triangulation = polytopes.cube().triangulate(engine='internal')
627
+ sage: triangulation
628
+ (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>)
629
+ sage: triangulation.boundary()
630
+ frozenset({(0, 1, 2),
631
+ (0, 1, 5),
632
+ (0, 2, 3),
633
+ (0, 3, 4),
634
+ (0, 4, 5),
635
+ (1, 2, 7),
636
+ (1, 5, 6),
637
+ (1, 6, 7),
638
+ (2, 3, 7),
639
+ (3, 4, 7),
640
+ (4, 5, 7),
641
+ (5, 6, 7)})
642
+ sage: triangulation.interior_facets()
643
+ frozenset({(0, 1, 7), (0, 2, 7), (0, 3, 7), (0, 4, 7), (0, 5, 7), (1, 5, 7)})
644
+ """
645
+ return frozenset(facet for facet, bounded_simplices
646
+ in self._boundary_simplex_dictionary().items()
647
+ if len(bounded_simplices) == 1)
648
+
649
+ @cached_method
650
+ def boundary_simplicial_complex(self):
651
+ r"""
652
+ Return the boundary of ``self`` as an (abstract) simplicial complex.
653
+
654
+ OUTPUT: a :class:`~sage.topology.simplicial_complex.SimplicialComplex`
655
+
656
+ EXAMPLES::
657
+
658
+ sage: p = polytopes.cuboctahedron()
659
+ sage: triangulation = p.triangulate(engine='internal')
660
+ sage: bd_sc = triangulation.boundary_simplicial_complex(); bd_sc # needs sage.graphs
661
+ Simplicial complex with 12 vertices and 20 facets
662
+
663
+ The boundary of every convex set is a topological sphere, so it has
664
+ spherical homology::
665
+
666
+ sage: bd_sc.homology() # needs sage.graphs
667
+ {0: 0, 1: 0, 2: Z}
668
+
669
+ It is a subcomplex of ``self`` as a :meth:`simplicial_complex`::
670
+
671
+ sage: sc = triangulation.simplicial_complex() # needs sage.graphs
672
+ sage: all(f in sc for f in bd_sc.maximal_faces()) # needs sage.graphs
673
+ True
674
+ """
675
+ from sage.topology.simplicial_complex import SimplicialComplex
676
+ return SimplicialComplex(self.boundary(), maximality_check=False)
677
+
678
+ @cached_method
679
+ def interior_facets(self):
680
+ """
681
+ Return the interior facets of the triangulation.
682
+
683
+ OUTPUT:
684
+
685
+ The inward-facing boundary simplices (of dimension `d-1`) of
686
+ the `d`-dimensional triangulation as a set. Each boundary is
687
+ returned by a tuple of point indices.
688
+
689
+ EXAMPLES::
690
+
691
+ sage: triangulation = polytopes.cube().triangulate(engine='internal')
692
+ sage: triangulation
693
+ (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>)
694
+ sage: triangulation.boundary()
695
+ frozenset({(0, 1, 2),
696
+ (0, 1, 5),
697
+ (0, 2, 3),
698
+ (0, 3, 4),
699
+ (0, 4, 5),
700
+ (1, 2, 7),
701
+ (1, 5, 6),
702
+ (1, 6, 7),
703
+ (2, 3, 7),
704
+ (3, 4, 7),
705
+ (4, 5, 7),
706
+ (5, 6, 7)})
707
+ sage: triangulation.interior_facets()
708
+ frozenset({(0, 1, 7), (0, 2, 7), (0, 3, 7), (0, 4, 7), (0, 5, 7), (1, 5, 7)})
709
+ """
710
+ return frozenset(facet for facet, bounded_simplices
711
+ in self._boundary_simplex_dictionary().items()
712
+ if len(bounded_simplices) == 2)
713
+
714
+ def polyhedral_complex(self, **kwds):
715
+ """
716
+ Return ``self`` as a :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex`.
717
+
718
+ OUTPUT:
719
+
720
+ A :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex` whose maximal cells
721
+ are the simplices of the triangulation.
722
+
723
+ EXAMPLES::
724
+
725
+ sage: P = polytopes.cube()
726
+ sage: pc = PointConfiguration(P.vertices())
727
+ sage: T = pc.placing_triangulation(); T
728
+ (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>)
729
+ sage: C = T.polyhedral_complex(); C # needs sage.graphs
730
+ Polyhedral complex with 6 maximal cells
731
+ sage: [P.vertices_list() for P in C.maximal_cells_sorted()] # needs sage.graphs
732
+ [[[-1, -1, -1], [-1, -1, 1], [-1, 1, 1], [1, -1, -1]],
733
+ [[-1, -1, -1], [-1, 1, -1], [-1, 1, 1], [1, 1, -1]],
734
+ [[-1, -1, -1], [-1, 1, 1], [1, -1, -1], [1, 1, -1]],
735
+ [[-1, -1, 1], [-1, 1, 1], [1, -1, -1], [1, -1, 1]],
736
+ [[-1, 1, 1], [1, -1, -1], [1, -1, 1], [1, 1, 1]],
737
+ [[-1, 1, 1], [1, -1, -1], [1, 1, -1], [1, 1, 1]]]
738
+ """
739
+ from sage.geometry.polyhedral_complex import PolyhedralComplex
740
+ from sage.geometry.polyhedron.constructor import Polyhedron
741
+ ambient_dim = self.point_configuration().ambient_dim()
742
+ points = self.point_configuration().points()
743
+ return PolyhedralComplex([Polyhedron(vertices=[points[i] for i in simplex])
744
+ for simplex in self],
745
+ ambient_dim=ambient_dim,
746
+ maximality_check=False,
747
+ face_to_face_check=False,
748
+ **kwds)
749
+
750
+ def boundary_polyhedral_complex(self, **kwds):
751
+ r"""
752
+ Return the boundary of ``self`` as a :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex`.
753
+
754
+ OUTPUT:
755
+
756
+ A :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex` whose maximal cells
757
+ are the simplices of the boundary of ``self``.
758
+
759
+ EXAMPLES::
760
+
761
+ sage: P = polytopes.cube()
762
+ sage: pc = PointConfiguration(P.vertices())
763
+ sage: T = pc.placing_triangulation(); T
764
+ (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>)
765
+ sage: bd_C = T.boundary_polyhedral_complex(); bd_C # needs sage.graphs
766
+ Polyhedral complex with 12 maximal cells
767
+ sage: [P.vertices_list() for P in bd_C.maximal_cells_sorted()] # needs sage.graphs
768
+ [[[-1, -1, -1], [-1, -1, 1], [-1, 1, 1]],
769
+ [[-1, -1, -1], [-1, -1, 1], [1, -1, -1]],
770
+ [[-1, -1, -1], [-1, 1, -1], [-1, 1, 1]],
771
+ [[-1, -1, -1], [-1, 1, -1], [1, 1, -1]],
772
+ [[-1, -1, -1], [1, -1, -1], [1, 1, -1]],
773
+ [[-1, -1, 1], [-1, 1, 1], [1, -1, 1]],
774
+ [[-1, -1, 1], [1, -1, -1], [1, -1, 1]],
775
+ [[-1, 1, -1], [-1, 1, 1], [1, 1, -1]],
776
+ [[-1, 1, 1], [1, -1, 1], [1, 1, 1]],
777
+ [[-1, 1, 1], [1, 1, -1], [1, 1, 1]],
778
+ [[1, -1, -1], [1, -1, 1], [1, 1, 1]],
779
+ [[1, -1, -1], [1, 1, -1], [1, 1, 1]]]
780
+
781
+ It is a subcomplex of ``self`` as a :meth:`polyhedral_complex`::
782
+
783
+ sage: C = T.polyhedral_complex() # needs sage.graphs
784
+ sage: bd_C.is_subcomplex(C) # needs sage.graphs
785
+ True
786
+ """
787
+ from sage.geometry.polyhedral_complex import PolyhedralComplex
788
+ from sage.geometry.polyhedron.constructor import Polyhedron
789
+ ambient_dim = self.point_configuration().ambient_dim()
790
+ points = self.point_configuration().points()
791
+ return PolyhedralComplex([Polyhedron(vertices=[points[i] for i in simplex])
792
+ for simplex in self.boundary()],
793
+ ambient_dim=ambient_dim,
794
+ maximality_check=False,
795
+ face_to_face_check=False,
796
+ **kwds)
797
+
798
+ @cached_method
799
+ def normal_cone(self):
800
+ r"""
801
+ Return the (closure of the) normal cone of the triangulation.
802
+
803
+ Recall that a regular triangulation is one that equals the
804
+ "crease lines" of a convex piecewise-linear function. This
805
+ support function is not unique, for example, you can scale it
806
+ by a positive constant. The set of all piecewise-linear
807
+ functions with fixed creases forms an open cone. This cone can
808
+ be interpreted as the cone of normal vectors at a point of the
809
+ secondary polytope, which is why we call it normal cone. See
810
+ [GKZ1994]_ Section 7.1 for details.
811
+
812
+ OUTPUT:
813
+
814
+ The closure of the normal cone. The `i`-th entry equals the
815
+ value of the piecewise-linear function at the `i`-th point of
816
+ the configuration.
817
+
818
+ For an irregular triangulation, the normal cone is empty. In
819
+ this case, a single point (the origin) is returned.
820
+
821
+ EXAMPLES::
822
+
823
+ sage: triangulation = polytopes.hypercube(2).triangulate(engine='internal')
824
+ sage: triangulation
825
+ (<0,1,3>, <1,2,3>)
826
+ sage: N = triangulation.normal_cone(); N
827
+ 4-d cone in 4-d lattice
828
+ sage: N.rays()
829
+ ( 0, 0, 0, -1),
830
+ ( 0, 0, 1, 1),
831
+ ( 0, 0, -1, -1),
832
+ ( 1, 0, 0, 1),
833
+ (-1, 0, 0, -1),
834
+ ( 0, 1, 0, -1),
835
+ ( 0, -1, 0, 1)
836
+ in Ambient free module of rank 4
837
+ over the principal ideal domain Integer Ring
838
+ sage: N.dual().rays() # needs sage.libs.pari
839
+ (1, -1, 1, -1)
840
+ in Ambient free module of rank 4
841
+ over the principal ideal domain Integer Ring
842
+
843
+ TESTS::
844
+
845
+ sage: polytopes.simplex(2).triangulate().normal_cone()
846
+ 3-d cone in 3-d lattice
847
+ sage: _.dual().is_trivial() # needs sage.libs.pari
848
+ True
849
+ """
850
+ if not self.point_configuration().base_ring().is_subring(QQ):
851
+ raise NotImplementedError('Only base rings ZZ and QQ are supported')
852
+ from ppl import Constraint_System, Linear_Expression, C_Polyhedron
853
+ from sage.matrix.constructor import matrix
854
+ from sage.arith.functions import lcm
855
+ pc = self.point_configuration()
856
+ cs = Constraint_System()
857
+ for facet in self.interior_facets():
858
+ s0, s1 = self._boundary_simplex_dictionary()[facet]
859
+ p = set(s0).difference(facet).pop()
860
+ q = set(s1).difference(facet).pop()
861
+ origin = pc.point(p).reduced_affine_vector()
862
+ base_indices = [i for i in s0 if i != p]
863
+ base = matrix([ pc.point(i).reduced_affine_vector()-origin for i in base_indices ])
864
+ sol = base.solve_left( pc.point(q).reduced_affine_vector()-origin )
865
+ relation = [0]*pc.n_points()
866
+ relation[p] = sum(sol)-1
867
+ relation[q] = 1
868
+ for i, base_i in enumerate(base_indices):
869
+ relation[base_i] = -sol[i]
870
+ rel_denom = lcm([QQ(r).denominator() for r in relation])
871
+ relation = [ ZZ(r*rel_denom) for r in relation ]
872
+ ex = Linear_Expression(relation,0)
873
+ cs.insert(ex >= 0)
874
+ from sage.modules.free_module import FreeModule
875
+ ambient = FreeModule(ZZ, self.point_configuration().n_points())
876
+ if cs.empty():
877
+ cone = C_Polyhedron(ambient.dimension(), 'universe')
878
+ else:
879
+ cone = C_Polyhedron(cs)
880
+ from sage.geometry.cone import _Cone_from_PPL
881
+ return _Cone_from_PPL(cone, lattice=ambient)
882
+
883
+ def adjacency_graph(self):
884
+ """
885
+ Return a graph showing which simplices are adjacent in the triangulation.
886
+
887
+ OUTPUT:
888
+
889
+ A graph consisting of vertices referring to the simplices in the
890
+ triangulation, and edges showing which simplices are adjacent to each
891
+ other.
892
+
893
+ .. SEEALSO::
894
+
895
+ * To obtain the triangulation's 1-skeleton, use
896
+ :meth:`SimplicialComplex.graph` through
897
+ ``MyTriangulation.simplicial_complex().graph()``.
898
+
899
+ AUTHORS:
900
+
901
+ * Stephen Farley (2013-08-10): initial version
902
+
903
+ EXAMPLES::
904
+
905
+ sage: p = PointConfiguration([[1,0,0], [0,1,0], [0,0,1], [-1,0,1],
906
+ ....: [1,0,-1], [-1,0,0], [0,-1,0], [0,0,-1]])
907
+ sage: t = p.triangulate()
908
+ sage: t.adjacency_graph() # needs sage.graphs
909
+ Graph on 8 vertices
910
+ """
911
+ vertices = [Set(_) for _ in list(self)]
912
+ from sage.graphs.graph import Graph
913
+ return Graph([vertices,
914
+ lambda x,y: len(x-y) == 1])