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,812 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ r"""
3
+ Base class for polyhedra: Methods related to lattice points
4
+ """
5
+
6
+ # ****************************************************************************
7
+ # Copyright (C) 2008-2012 Marshall Hampton <hamptonio@gmail.com>
8
+ # Copyright (C) 2011-2015 Volker Braun <vbraun.name@gmail.com>
9
+ # Copyright (C) 2012-2018 Frederic Chapoton
10
+ # Copyright (C) 2013 Andrey Novoseltsev
11
+ # Copyright (C) 2014-2017 Moritz Firsching
12
+ # Copyright (C) 2014-2019 Thierry Monteil
13
+ # Copyright (C) 2015 Nathann Cohen
14
+ # Copyright (C) 2015-2017 Jeroen Demeyer
15
+ # Copyright (C) 2015-2017 Vincent Delecroix
16
+ # Copyright (C) 2015-2018 Dima Pasechnik
17
+ # Copyright (C) 2015-2020 Jean-Philippe Labbe <labbe at math.huji.ac.il>
18
+ # Copyright (C) 2015-2021 Matthias Koeppe
19
+ # Copyright (C) 2016-2019 Daniel Krenn
20
+ # Copyright (C) 2017 Marcelo Forets
21
+ # Copyright (C) 2017-2018 Mark Bell
22
+ # Copyright (C) 2019 Julian Ritter
23
+ # Copyright (C) 2019-2020 Laith Rastanawi
24
+ # Copyright (C) 2019-2020 Sophia Elia
25
+ # Copyright (C) 2019-2021 Jonathan Kliem <jonathan.kliem@gmail.com>
26
+ #
27
+ # This program is free software: you can redistribute it and/or modify
28
+ # it under the terms of the GNU General Public License as published by
29
+ # the Free Software Foundation, either version 2 of the License, or
30
+ # (at your option) any later version.
31
+ # https://www.gnu.org/licenses/
32
+ # ****************************************************************************
33
+
34
+ import itertools
35
+
36
+ from sage.misc.cachefunc import cached_method
37
+ from sage.rings.integer_ring import ZZ
38
+ from sage.modules.free_module_element import vector
39
+ from .base1 import Polyhedron_base1
40
+
41
+
42
+ class Polyhedron_base2(Polyhedron_base1):
43
+ """
44
+ Methods related to lattice points.
45
+
46
+ See :class:`sage.geometry.polyhedron.base.Polyhedron_base`.
47
+
48
+ TESTS::
49
+
50
+ sage: from sage.geometry.polyhedron.base2 import Polyhedron_base2
51
+ sage: P = polytopes.cube()
52
+ sage: Polyhedron_base2.is_lattice_polytope.f(P)
53
+ True
54
+ sage: Polyhedron_base2.lattice_polytope(P)
55
+ 3-d reflexive polytope in 3-d lattice M
56
+ sage: Polyhedron_base2.integral_points(P)
57
+ ((-1, -1, -1),
58
+ (-1, -1, 0),
59
+ (-1, -1, 1),
60
+ (-1, 0, -1),
61
+ (-1, 0, 0),
62
+ (-1, 0, 1),
63
+ (-1, 1, -1),
64
+ (-1, 1, 0),
65
+ (-1, 1, 1),
66
+ (0, -1, -1),
67
+ (0, -1, 0),
68
+ (0, -1, 1),
69
+ (0, 0, -1),
70
+ (0, 0, 0),
71
+ (0, 0, 1),
72
+ (0, 1, -1),
73
+ (0, 1, 0),
74
+ (0, 1, 1),
75
+ (1, -1, -1),
76
+ (1, -1, 0),
77
+ (1, -1, 1),
78
+ (1, 0, -1),
79
+ (1, 0, 0),
80
+ (1, 0, 1),
81
+ (1, 1, -1),
82
+ (1, 1, 0),
83
+ (1, 1, 1))
84
+ """
85
+
86
+ @cached_method
87
+ def is_lattice_polytope(self):
88
+ r"""
89
+ Return whether the polyhedron is a lattice polytope.
90
+
91
+ OUTPUT:
92
+
93
+ ``True`` if the polyhedron is compact and has only integral
94
+ vertices, ``False`` otherwise.
95
+
96
+ EXAMPLES::
97
+
98
+ sage: polytopes.cross_polytope(3).is_lattice_polytope()
99
+ True
100
+ sage: polytopes.regular_polygon(5).is_lattice_polytope() # needs sage.rings.number_field
101
+ False
102
+ """
103
+ if not self.is_compact():
104
+ return False
105
+ if self.base_ring() is ZZ:
106
+ return True
107
+ return all(v.is_integral() for v in self.vertex_generator())
108
+
109
+ @cached_method
110
+ def lattice_polytope(self, envelope=False):
111
+ r"""
112
+ Return an encompassing lattice polytope.
113
+
114
+ INPUT:
115
+
116
+ - ``envelope`` -- boolean (default: ``False``); if the
117
+ polyhedron has non-integral vertices, this option decides
118
+ whether to return a strictly larger lattice polytope or
119
+ raise a :exc:`ValueError`. This option has no effect if the
120
+ polyhedron has already integral vertices.
121
+
122
+ OUTPUT:
123
+
124
+ A :class:`LatticePolytope
125
+ <sage.geometry.lattice_polytope.LatticePolytopeClass>`. If the
126
+ polyhedron is compact and has integral vertices, the lattice
127
+ polytope equals the polyhedron. If the polyhedron is compact
128
+ but has at least one non-integral vertex, a strictly larger
129
+ lattice polytope is returned.
130
+
131
+ If the polyhedron is not compact, a :exc:`NotImplementedError` is
132
+ raised.
133
+
134
+ If the polyhedron is not integral and ``envelope=False``, a
135
+ :exc:`ValueError` is raised.
136
+
137
+ ALGORITHM:
138
+
139
+ For each non-integral vertex, a bounding box of integral
140
+ points is added and the convex hull of these integral points
141
+ is returned.
142
+
143
+ EXAMPLES:
144
+
145
+ First, a polyhedron with integral vertices::
146
+
147
+ sage: P = Polyhedron(vertices=[(1, 0), (0, 1), (-1, 0), (0, -1)])
148
+ sage: lp = P.lattice_polytope(); lp
149
+ 2-d reflexive polytope... in 2-d lattice M
150
+ sage: lp # optional - polytopes_db, needs palp sage.groups
151
+ 2-d reflexive polytope #3 in 2-d lattice M
152
+ sage: lp.vertices()
153
+ M(-1, 0),
154
+ M( 0, -1),
155
+ M( 0, 1),
156
+ M( 1, 0)
157
+ in 2-d lattice M
158
+
159
+ Here is a polyhedron with non-integral vertices::
160
+
161
+ sage: P = Polyhedron( vertices = [(1/2, 1/2), (0, 1), (-1, 0), (0, -1)])
162
+ sage: lp = P.lattice_polytope()
163
+ Traceback (most recent call last):
164
+ ...
165
+ ValueError: Some vertices are not integral. You probably want
166
+ to add the argument "envelope=True" to compute an enveloping
167
+ lattice polytope.
168
+ sage: lp = P.lattice_polytope(True)
169
+ sage: lp # optional - polytopes_db, needs palp sage.groups
170
+ 2-d reflexive polytope #5 in 2-d lattice M
171
+ sage: lp.vertices()
172
+ M(-1, 0),
173
+ M( 0, -1),
174
+ M( 1, 1),
175
+ M( 0, 1),
176
+ M( 1, 0)
177
+ in 2-d lattice M
178
+ """
179
+ if not self.is_compact():
180
+ raise NotImplementedError('only compact lattice polytopes are allowed')
181
+
182
+ try:
183
+ vertices = self.vertices_matrix(ZZ).columns()
184
+ except TypeError:
185
+ if not envelope:
186
+ raise ValueError('Some vertices are not integral. '
187
+ 'You probably want to add the argument '
188
+ '"envelope=True" to compute an enveloping lattice polytope.')
189
+ from sage.arith.misc import integer_ceil as ceil
190
+ from sage.arith.misc import integer_floor as floor
191
+ vertices = []
192
+ for v in self.vertex_generator():
193
+ vbox = [ set([floor(x), ceil(x)]) for x in v ]
194
+ vertices.extend( itertools.product(*vbox) )
195
+
196
+ # construct the (enveloping) lattice polytope
197
+ from sage.geometry.lattice_polytope import LatticePolytope
198
+ return LatticePolytope(vertices)
199
+
200
+ def _integral_points_PALP(self):
201
+ r"""
202
+ Return the integral points in the polyhedron using PALP.
203
+
204
+ This method is for testing purposes and will eventually be removed.
205
+
206
+ OUTPUT:
207
+
208
+ The list of integral points in the polyhedron. If the
209
+ polyhedron is not compact, a :exc:`ValueError` is raised.
210
+
211
+ EXAMPLES::
212
+
213
+ sage: Polyhedron(vertices=[(-1,-1),(1,0),(1,1),(0,1)])._integral_points_PALP() # needs palp
214
+ [M(-1, -1), M(0, 1), M(1, 0), M(1, 1), M(0, 0)]
215
+ sage: Polyhedron(vertices=[(-1/2,-1/2),(1,0),(1,1),(0,1)]).lattice_polytope(True).points() # needs palp
216
+ M(-1, -1),
217
+ M(-1, 0),
218
+ M( 0, -1),
219
+ M( 1, 1),
220
+ M( 0, 1),
221
+ M( 1, 0),
222
+ M( 0, 0)
223
+ in 2-d lattice M
224
+ sage: Polyhedron(vertices=[(-1/2,-1/2),(1,0),(1,1),(0,1)])._integral_points_PALP() # needs palp
225
+ [M(1, 1), M(0, 1), M(1, 0), M(0, 0)]
226
+ """
227
+ if not self.is_compact():
228
+ raise ValueError('can only enumerate points in a compact polyhedron')
229
+ lp = self.lattice_polytope(True)
230
+ # remove cached values to get accurate timings
231
+ try:
232
+ del lp._points
233
+ del lp._npoints
234
+ except AttributeError:
235
+ pass
236
+ if self.is_lattice_polytope():
237
+ return list(lp.points())
238
+ return [p for p in lp.points() if self.contains(p)]
239
+
240
+ @cached_method(do_pickle=True)
241
+ def h_star_vector(self):
242
+ r"""
243
+ Return the `h^*`-vector of the lattice polytope.
244
+
245
+ The `h^*`-vector records the coefficients of the polynomial in the
246
+ numerator of the Ehrhart series of a lattice polytope.
247
+
248
+ INPUT:
249
+
250
+ - ``self`` -- a lattice polytope
251
+
252
+ OUTPUT:
253
+
254
+ A list whose entries give the `h^*`-vector.
255
+
256
+ .. NOTE::
257
+
258
+ The backend of ``self`` should be ``'normaliz'``.
259
+ This function depends on Normaliz (i.e. the ``'pynormaliz'`` optional
260
+ package). See the Normaliz documentation for further details.
261
+
262
+ EXAMPLES:
263
+
264
+ The `h^*`-vector of a unimodular simplex S (a simplex with
265
+ volume = `\frac{1}{dim(S)!}`) is always 1. Here we test this on
266
+ simplices up to dimension 3::
267
+
268
+ sage: # optional - pynormaliz
269
+ sage: s1 = polytopes.simplex(1,backend='normaliz')
270
+ sage: s2 = polytopes.simplex(2,backend='normaliz')
271
+ sage: s3 = polytopes.simplex(3,backend='normaliz')
272
+ sage: [s1.h_star_vector(), s2.h_star_vector(), s3.h_star_vector()]
273
+ [[1], [1], [1]]
274
+
275
+ For a less trivial example, we compute the `h^*`-vector of the
276
+ `0/1`-cube, which has the Eulerian numbers `(3,i)` for `i \in [0,2]`
277
+ as an `h^*`-vector::
278
+
279
+ sage: cube = polytopes.cube(intervals='zero_one', backend='normaliz') # optional - pynormaliz
280
+ sage: cube.h_star_vector() # optional - pynormaliz
281
+ [1, 4, 1]
282
+ sage: from sage.combinat.combinat import eulerian_number
283
+ sage: [eulerian_number(3,i) for i in range(3)]
284
+ [1, 4, 1]
285
+
286
+ TESTS::
287
+
288
+ sage: s3 = polytopes.simplex(3)
289
+ sage: s3.h_star_vector()
290
+ Traceback (most recent call last):
291
+ ...
292
+ TypeError: The backend of self must be normaliz
293
+
294
+ sage: t = Polyhedron(vertices=[[0],[1/2]])
295
+ sage: t.h_star_vector()
296
+ Traceback (most recent call last):
297
+ ...
298
+ TypeError: The h_star vector is only defined for lattice polytopes
299
+
300
+ sage: t2 = Polyhedron(vertices=[[AA(sqrt(2))], [1/2]]) # needs sage.rings.number_field sage.symbolic
301
+ sage: t2.h_star_vector() # needs sage.rings.number_field sage.symbolic
302
+ Traceback (most recent call last):
303
+ ...
304
+ TypeError: The h_star vector is only defined for lattice polytopes
305
+
306
+ Check that the `h^*`-vector is pickled::
307
+
308
+ sage: new_cube = loads(dumps(cube)) # optional - pynormaliz
309
+ sage: new_cube.h_star_vector.is_in_cache() # optional - pynormaliz
310
+ True
311
+ """
312
+ if self.is_empty():
313
+ return 0
314
+ if not self.is_lattice_polytope():
315
+ raise TypeError('The h_star vector is only defined for lattice polytopes')
316
+ if not self.backend() == 'normaliz':
317
+ raise TypeError('The backend of self must be normaliz')
318
+ return self._h_star_vector_normaliz()
319
+
320
+ def _h_star_vector_normaliz(self):
321
+ r"""
322
+ Return the `h^*`-vector of a lattice polytope with backend = 'normaliz'.
323
+
324
+ INPUT:
325
+
326
+ - ``self`` -- a lattice polytope
327
+
328
+ OUTPUT:
329
+
330
+ The `h^*`-vector as a list.
331
+
332
+ .. NOTE::
333
+
334
+ The backend of ``self`` should be ``'normaliz'``.
335
+
336
+ TESTS::
337
+
338
+ sage: s3 = polytopes.simplex(3)
339
+ sage: s3._h_star_vector_normaliz()
340
+ Traceback (most recent call last):
341
+ ...
342
+ TypeError: the backend should be normaliz
343
+ """
344
+ raise TypeError("the backend should be normaliz")
345
+
346
+ def integral_points_count(self, **kwds):
347
+ r"""
348
+ Return the number of integral points in the polyhedron.
349
+
350
+ This generic version of this method simply calls :meth:`integral_points`.
351
+
352
+ EXAMPLES::
353
+
354
+ sage: P = polytopes.cube()
355
+ sage: P.integral_points_count()
356
+ 27
357
+
358
+ We shrink the polyhedron a little bit::
359
+
360
+ sage: Q = P*(8/9)
361
+ sage: Q.integral_points_count()
362
+ 1
363
+
364
+ Same for a polyhedron whose coordinates are not rationals. Note that
365
+ the answer is an integer even though there are no guarantees for
366
+ exactness::
367
+
368
+ sage: Q = P*RDF(8/9) # needs cddexec_gmp
369
+ sage: Q.integral_points_count() # needs cddexec_gmp
370
+ 1
371
+
372
+ Unbounded polyhedra (with or without lattice points) are not supported::
373
+
374
+ sage: P = Polyhedron(vertices=[[1/2, 1/3]], rays=[[1, 1]])
375
+ sage: P.integral_points_count()
376
+ Traceback (most recent call last):
377
+ ...
378
+ NotImplementedError: ...
379
+ sage: P = Polyhedron(vertices=[[1, 1]], rays=[[1, 1]])
380
+ sage: P.integral_points_count()
381
+ Traceback (most recent call last):
382
+ ...
383
+ NotImplementedError: ...
384
+ """
385
+ return len(self.integral_points())
386
+
387
+ def integral_points(self, threshold=100000):
388
+ r"""
389
+ Return the integral points in the polyhedron.
390
+
391
+ Uses either the naive algorithm (iterate over a rectangular
392
+ bounding box) or triangulation + Smith form.
393
+
394
+ INPUT:
395
+
396
+ - ``threshold`` -- integer (default: 100000); use the naive
397
+ algorithm as long as the bounding box is smaller than this
398
+
399
+ OUTPUT:
400
+
401
+ The list of integral points in the polyhedron. If the
402
+ polyhedron is not compact, a :exc:`ValueError` is raised.
403
+
404
+ EXAMPLES::
405
+
406
+ sage: Polyhedron(vertices=[(-1,-1),(1,0),(1,1),(0,1)]).integral_points()
407
+ ((-1, -1), (0, 0), (0, 1), (1, 0), (1, 1))
408
+
409
+ sage: simplex = Polyhedron([(1,2,3), (2,3,7), (-2,-3,-11)])
410
+ sage: simplex.integral_points()
411
+ ((-2, -3, -11), (0, 0, -2), (1, 2, 3), (2, 3, 7))
412
+
413
+ The polyhedron need not be full-dimensional::
414
+
415
+ sage: simplex = Polyhedron([(1,2,3,5), (2,3,7,5), (-2,-3,-11,5)])
416
+ sage: simplex.integral_points()
417
+ ((-2, -3, -11, 5), (0, 0, -2, 5), (1, 2, 3, 5), (2, 3, 7, 5))
418
+
419
+ sage: point = Polyhedron([(2,3,7)])
420
+ sage: point.integral_points()
421
+ ((2, 3, 7),)
422
+
423
+ sage: empty = Polyhedron()
424
+ sage: empty.integral_points()
425
+ ()
426
+
427
+ Here is a simplex where the naive algorithm of running over
428
+ all points in a rectangular bounding box no longer works fast
429
+ enough::
430
+
431
+ sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)]
432
+ sage: simplex = Polyhedron(v); simplex
433
+ A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
434
+ sage: len(simplex.integral_points())
435
+ 49
436
+
437
+ A case where rounding in the right direction goes a long way::
438
+
439
+ sage: P = 1/10*polytopes.hypercube(14, backend='field')
440
+ sage: P.integral_points()
441
+ ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),)
442
+
443
+ Finally, the 3-d reflexive polytope number 4078::
444
+
445
+ sage: v = [(1,0,0), (0,1,0), (0,0,1), (0,0,-1), (0,-2,1),
446
+ ....: (-1,2,-1), (-1,2,-2), (-1,1,-2), (-1,-1,2), (-1,-3,2)]
447
+ sage: P = Polyhedron(v)
448
+ sage: pts1 = P.integral_points() # Sage's own code
449
+ sage: all(P.contains(p) for p in pts1)
450
+ True
451
+ sage: pts2 = LatticePolytope(v).points() # needs palp
452
+ sage: for p in pts1: p.set_immutable()
453
+ sage: set(pts1) == set(pts2) # needs palp
454
+ True
455
+
456
+ sage: timeit('Polyhedron(v).integral_points()') # not tested - random
457
+ 625 loops, best of 3: 1.41 ms per loop
458
+ sage: timeit('LatticePolytope(v).points()') # not tested - random
459
+ 25 loops, best of 3: 17.2 ms per loop
460
+
461
+ TESTS:
462
+
463
+ Test some trivial cases (see :issue:`17937`)::
464
+
465
+ sage: P = Polyhedron(ambient_dim=1) # empty polyhedron in 1 dimension
466
+ sage: P.integral_points()
467
+ ()
468
+ sage: P = Polyhedron(ambient_dim=0) # empty polyhedron in 0 dimensions
469
+ sage: P.integral_points()
470
+ ()
471
+ sage: P = Polyhedron([[3]]) # single point in 1 dimension
472
+ sage: P.integral_points()
473
+ ((3),)
474
+ sage: P = Polyhedron([[1/2]]) # single non-integral point in 1 dimension
475
+ sage: P.integral_points()
476
+ ()
477
+ sage: P = Polyhedron([[]]) # single point in 0 dimensions
478
+ sage: P.integral_points()
479
+ ((),)
480
+
481
+ Test unbounded polyhedron::
482
+
483
+ sage: P = Polyhedron(rays=[[1,0,0]])
484
+ sage: P.integral_points()
485
+ Traceback (most recent call last):
486
+ ...
487
+ ValueError: can only enumerate points in a compact polyhedron
488
+ """
489
+ from sage.misc.misc_c import prod
490
+ if not self.is_compact():
491
+ raise ValueError('can only enumerate points in a compact polyhedron')
492
+ # Trivial cases: polyhedron with 0 or 1 vertices
493
+ if self.n_vertices() == 0:
494
+ return ()
495
+ if self.n_vertices() == 1:
496
+ v = self.vertices_list()[0]
497
+ try:
498
+ return (vector(ZZ, v),)
499
+ except TypeError: # vertex not integral
500
+ return ()
501
+
502
+ # for small bounding boxes, it is faster to naively iterate over the points of the box
503
+ box_min, box_max = self.bounding_box(integral_hull=True)
504
+ if box_min is None:
505
+ return ()
506
+ box_points = prod(max_coord-min_coord+1 for min_coord, max_coord in zip(box_min, box_max))
507
+ if not self.is_lattice_polytope() or \
508
+ (self.is_simplex() and box_points < 1000) or \
509
+ box_points < threshold:
510
+ from sage.geometry.integral_points import rectangular_box_points
511
+ return rectangular_box_points(list(box_min), list(box_max), self)
512
+
513
+ # for more complicate polytopes, triangulate & use smith normal form
514
+ from sage.geometry.integral_points import simplex_points
515
+ if self.is_simplex():
516
+ return simplex_points(self.Vrepresentation())
517
+ triangulation = self.triangulate()
518
+ points = set()
519
+ for simplex in triangulation:
520
+ triang_vertices = [self.Vrepresentation(i) for i in simplex]
521
+ new_points = simplex_points(triang_vertices)
522
+ for p in new_points:
523
+ p.set_immutable()
524
+ points.update(new_points)
525
+ # assert all(self.contains(p) for p in points) # slow
526
+ return tuple(points)
527
+
528
+ def get_integral_point(self, index, **kwds):
529
+ r"""
530
+ Return the ``index``-th integral point in this polyhedron.
531
+
532
+ This is equivalent to ``sorted(self.integral_points())[index]``.
533
+ However, so long as :meth:`integral_points_count` does not need to
534
+ enumerate all integral points, neither does this method. Hence it can
535
+ be significantly faster. If the polyhedron is not compact, a
536
+ :exc:`ValueError` is raised.
537
+
538
+ INPUT:
539
+
540
+ - ``index`` -- integer; the index of the integral point to be found. If
541
+ this is not in [0, ``self.integral_point_count()``), an :exc:`IndexError`
542
+ is raised.
543
+
544
+ - ``**kwds`` -- optional keyword parameters that are passed to
545
+ :meth:`integral_points_count`
546
+
547
+ ALGORITHM:
548
+
549
+ The function computes each of the components of the requested point in
550
+ turn. To compute x_i, the `i`-th component, it bisects the upper and lower
551
+ bounds on x_i given by the bounding box. At each bisection, it uses
552
+ :meth:`integral_points_count` to determine on which side of the
553
+ bisecting hyperplane the requested point lies.
554
+
555
+ .. SEEALSO::
556
+
557
+ :meth:`integral_points_count`.
558
+
559
+ EXAMPLES::
560
+
561
+ sage: P = Polyhedron(vertices=[(-1,-1),(1,0),(1,1),(0,1)])
562
+ sage: P.get_integral_point(1)
563
+ (0, 0)
564
+ sage: P.get_integral_point(4)
565
+ (1, 1)
566
+ sage: sorted(P.integral_points())
567
+ [(-1, -1), (0, 0), (0, 1), (1, 0), (1, 1)]
568
+ sage: P.get_integral_point(5)
569
+ Traceback (most recent call last):
570
+ ...
571
+ IndexError: ...
572
+
573
+ sage: Q = Polyhedron([(1,3), (2, 7), (9, 77)])
574
+ sage: [Q.get_integral_point(i) for i in range(Q.integral_points_count())] == sorted(Q.integral_points())
575
+ True
576
+ sage: Q.get_integral_point(0, explicit_enumeration_threshold=0, triangulation='cddlib') # optional - latte_int
577
+ (1, 3)
578
+ sage: Q.get_integral_point(0, explicit_enumeration_threshold=0, triangulation='cddlib', foo=True) # optional - latte_int
579
+ Traceback (most recent call last):
580
+ ...
581
+ RuntimeError: ...
582
+
583
+ sage: R = Polyhedron(vertices=[[1/2, 1/3]], rays=[[1, 1]])
584
+ sage: R.get_integral_point(0)
585
+ Traceback (most recent call last):
586
+ ...
587
+ ValueError: ...
588
+ """
589
+ from sage.arith.misc import integer_ceil as ceil
590
+ from sage.arith.misc import integer_floor as floor
591
+ if not self.is_compact():
592
+ raise ValueError('can only enumerate points in a compact polyhedron')
593
+
594
+ if not 0 <= index < self.integral_points_count(**kwds):
595
+ raise IndexError('polytope index out of range')
596
+
597
+ D = self.ambient_dim()
598
+ lower_bounds, upper_bounds = self.bounding_box()
599
+ coordinate = []
600
+ P = self
601
+ S = self.parent()
602
+ for i in range(D): # Now compute x_i, the ith component of coordinate.
603
+ lower, upper = ceil(lower_bounds[i]), floor(upper_bounds[i]) + 1 # So lower <= x_i < upper.
604
+ while lower < upper-1:
605
+ guess = (lower + upper) // 2 # > lower.
606
+ # Build new polyhedron by intersecting P with the halfspace {x_i < guess}.
607
+ P_lt_guess = P.intersection(S(None, ([[guess-1] + [0] * i + [-1] + [0] * (D - i - 1)], [])))
608
+ # Avoid computing P_geq_guess = P.intersection({x_i >= guess}) right now, it might not be needed.
609
+ P_lt_guess_count = P_lt_guess.integral_points_count(**kwds)
610
+ if P_lt_guess_count > index: # Move upper down to guess.
611
+ upper = guess
612
+ index -= 0
613
+ P = P_lt_guess
614
+ else: # P_lt_guess_count <= index: # Move lower up to guess.
615
+ lower = guess
616
+ index -= P_lt_guess_count
617
+ P_geq_guess = P.intersection(S(None, ([[-guess] + [0] * i + [1] + [0] * (D - i - 1)], [])))
618
+ P = P_geq_guess
619
+ coordinate.append(lower) # Record the new component that we have found.
620
+ point = vector(ZZ, coordinate)
621
+ point.set_immutable()
622
+ return point
623
+
624
+ def random_integral_point(self, **kwds):
625
+ r"""
626
+ Return an integral point in this polyhedron chosen uniformly at random.
627
+
628
+ INPUT:
629
+
630
+ - ``**kwds`` -- optional keyword parameters that are passed to
631
+ :meth:`get_integral_point`
632
+
633
+ OUTPUT:
634
+
635
+ The integral point in the polyhedron chosen uniformly at random. If the
636
+ polyhedron is not compact, a :exc:`ValueError` is raised. If the
637
+ polyhedron does not contain any integral points, an
638
+ :class:`~sage.categories.sets_cat.EmptySetError` is raised.
639
+
640
+ .. SEEALSO::
641
+
642
+ :meth:`get_integral_point`.
643
+
644
+ EXAMPLES::
645
+
646
+ sage: P = Polyhedron(vertices=[(-1,-1),(1,0),(1,1),(0,1)])
647
+ sage: P.random_integral_point() # random
648
+ (0, 0)
649
+ sage: P.random_integral_point() in P.integral_points()
650
+ True
651
+ sage: P.random_integral_point(explicit_enumeration_threshold=0, # random, optional - latte_int
652
+ ....: triangulation='cddlib')
653
+ (1, 1)
654
+ sage: P.random_integral_point(explicit_enumeration_threshold=0, # optional - latte_int
655
+ ....: triangulation='cddlib', foo=7)
656
+ Traceback (most recent call last):
657
+ ...
658
+ RuntimeError: ...
659
+
660
+ sage: Q = Polyhedron(vertices=[(2, 1/3)], rays=[(1, 2)])
661
+ sage: Q.random_integral_point()
662
+ Traceback (most recent call last):
663
+ ...
664
+ ValueError: ...
665
+
666
+ sage: R = Polyhedron(vertices=[(1/2, 0), (1, 1/2), (0, 1/2)])
667
+ sage: R.random_integral_point()
668
+ Traceback (most recent call last):
669
+ ...
670
+ EmptySetError: ...
671
+ """
672
+ from sage.misc.randstate import current_randstate
673
+
674
+ if not self.is_compact():
675
+ raise ValueError('can only sample integral points in a compact polyhedron')
676
+
677
+ count = self.integral_points_count()
678
+ if count == 0:
679
+ from sage.categories.sets_cat import EmptySetError
680
+ raise EmptySetError('polyhedron does not contain any integral points')
681
+
682
+ return self.get_integral_point(current_randstate().python_random().randint(0, count-1), **kwds)
683
+
684
+ def generating_function_of_integral_points(self, **kwds):
685
+ r"""
686
+ Return the multivariate generating function of the
687
+ integral points of this polyhedron.
688
+
689
+ To be precise, this returns
690
+
691
+ .. MATH::
692
+
693
+ \sum_{(r_0,\dots,r_{d-1}) \in \mathit{polyhedron}\cap \ZZ^d}
694
+ y_0^{r_0} \dots y_{d-1}^{r_{d-1}}.
695
+
696
+ This calls
697
+ :func:`~sage.geometry.polyhedron.generating_function.generating_function_of_integral_points`,
698
+ so have a look at the documentation and examples there.
699
+
700
+ INPUT:
701
+
702
+ The following keyword arguments are passed to
703
+ :func:`~sage.geometry.polyhedron.generating_function.generating_function_of_integral_points`:
704
+
705
+ - ``split`` -- boolean (default: ``False``) or list
706
+
707
+ - ``split=False`` computes the generating function directly,
708
+ without any splitting.
709
+
710
+ - When ``split`` is a list of disjoint polyhedra, then
711
+ for each of these polyhedra, this polyhedron is intersected with it,
712
+ its generating function computed and all these generating functions
713
+ are summed up.
714
+
715
+ - ``split=True`` splits into `d!` disjoint polyhedra.
716
+
717
+ - ``result_as_tuple`` -- (default: ``None``) a boolean or ``None``
718
+
719
+ This specifies whether the output is a (partial) factorization
720
+ (``result_as_tuple=False``) or a sum of such (partial)
721
+ factorizations (``result_as_tuple=True``). By default
722
+ (``result_as_tuple=None``), this is automatically determined.
723
+ If the output is a sum, it is represented as a tuple whose
724
+ entries are the summands.
725
+
726
+ - ``indices`` -- (default: ``None``) a list or tuple
727
+
728
+ If this
729
+ is ``None``, this is automatically determined.
730
+
731
+ - ``name`` -- (default: ``'y'``) a string
732
+
733
+ The variable names of the Laurent polynomial ring of the output
734
+ are this string followed by an integer.
735
+
736
+ - ``names`` -- list or tuple of names (strings), or a comma separated string
737
+
738
+ ``name`` is extracted from ``names``, therefore ``names`` has to contain
739
+ exactly one variable name, and ``name`` and``names`` cannot be specified
740
+ both at the same time.
741
+
742
+ - ``Factorization_sort`` (default: ``False``) and
743
+ ``Factorization_simplify`` (default: ``True``) -- booleans
744
+
745
+ These are passed on to
746
+ :class:`sage.structure.factorization.Factorization` when creating
747
+ the result.
748
+
749
+ - ``sort_factors`` -- boolean (default: ``False``)
750
+
751
+ If set, then the factors of the output are sorted such that the
752
+ numerator is first and only then all factors of the denominator. It
753
+ is ensured that the sorting is always the same; use this for
754
+ doctesting.
755
+
756
+ OUTPUT:
757
+
758
+ The generating function as a (partial)
759
+ :class:`~sage.structure.factorization.Factorization`
760
+ of the result whose factors are Laurent polynomials
761
+
762
+ The result might be a tuple of such factorizations
763
+ (depending on the parameter ``result_as_tuple``) as well.
764
+
765
+ .. NOTE::
766
+
767
+ At the moment, only polyhedra with nonnegative coordinates
768
+ (i.e. a polyhedron in the nonnegative orthant) are handled.
769
+
770
+ EXAMPLES::
771
+
772
+ sage: # needs sage.combinat
773
+ sage: P2 = (Polyhedron(ieqs=[(0, 0, 0, 1), (0, 0, 1, 0), (0, 1, 0, -1)]),
774
+ ....: Polyhedron(ieqs=[(0, -1, 0, 1), (0, 1, 0, 0), (0, 0, 1, 0)]))
775
+ sage: P2[0].generating_function_of_integral_points(sort_factors=True)
776
+ 1 * (-y0 + 1)^-1 * (-y1 + 1)^-1 * (-y0*y2 + 1)^-1
777
+ sage: P2[1].generating_function_of_integral_points(sort_factors=True)
778
+ 1 * (-y1 + 1)^-1 * (-y2 + 1)^-1 * (-y0*y2 + 1)^-1
779
+ sage: (P2[0] & P2[1]).Hrepresentation()
780
+ (An equation (1, 0, -1) x + 0 == 0,
781
+ An inequality (1, 0, 0) x + 0 >= 0,
782
+ An inequality (0, 1, 0) x + 0 >= 0)
783
+ sage: (P2[0] & P2[1]).generating_function_of_integral_points(sort_factors=True)
784
+ 1 * (-y1 + 1)^-1 * (-y0*y2 + 1)^-1
785
+
786
+ The number of integer partitions
787
+ `1 \leq r_0 \leq r_1 \leq r_2 \leq r_3 \leq r_4`::
788
+
789
+ sage: # needs sage.combinat
790
+ sage: P = Polyhedron(ieqs=[(-1, 1, 0, 0, 0, 0), (0, -1, 1, 0, 0, 0),
791
+ ....: (0, 0, -1, 1, 0, 0), (0, 0, 0, -1, 1, 0),
792
+ ....: (0, 0, 0, 0, -1, 1)])
793
+ sage: f = P.generating_function_of_integral_points(sort_factors=True); f
794
+ y0*y1*y2*y3*y4 * (-y4 + 1)^-1 * (-y3*y4 + 1)^-1 * (-y2*y3*y4 + 1)^-1 *
795
+ (-y1*y2*y3*y4 + 1)^-1 * (-y0*y1*y2*y3*y4 + 1)^-1
796
+ sage: f = f.value()
797
+ sage: P.<z> = PowerSeriesRing(ZZ)
798
+ sage: c = f.subs({y: z for y in f.parent().gens()}); c
799
+ z^5 + z^6 + 2*z^7 + 3*z^8 + 5*z^9 + 7*z^10 + 10*z^11 + 13*z^12 + 18*z^13 +
800
+ 23*z^14 + 30*z^15 + 37*z^16 + 47*z^17 + 57*z^18 + 70*z^19 + 84*z^20 +
801
+ 101*z^21 + 119*z^22 + 141*z^23 + 164*z^24 + O(z^25)
802
+ sage: ([Partitions(k, length=5).cardinality() for k in range(5,20)] ==
803
+ ....: c.truncate().coefficients(sparse=False)[5:20])
804
+ True
805
+
806
+ .. SEEALSO::
807
+
808
+ More examples can be found at
809
+ :func:`~sage.geometry.polyhedron.generating_function.generating_function_of_integral_points`.
810
+ """
811
+ from .generating_function import generating_function_of_integral_points
812
+ return generating_function_of_integral_points(self, **kwds)