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,1258 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ r"""
3
+ Base class for polyhedra over `\QQ`
4
+ """
5
+
6
+ from sage.rings.rational_field import QQ
7
+ from sage.misc.cachefunc import cached_method
8
+ from sage.misc.misc_c import prod
9
+ from .base import Polyhedron_base
10
+
11
+
12
+ class Polyhedron_QQ(Polyhedron_base):
13
+ r"""
14
+ Base class for Polyhedra over `\QQ`.
15
+
16
+ TESTS::
17
+
18
+ sage: p = Polyhedron([(0,0)], base_ring=QQ); p
19
+ A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
20
+ sage: TestSuite(p).run()
21
+ """
22
+ def _is_zero(self, x):
23
+ """
24
+ Test whether ``x`` is zero.
25
+
26
+ INPUT:
27
+
28
+ - ``x`` -- a number in the base ring
29
+
30
+ OUTPUT: boolean
31
+
32
+ EXAMPLES::
33
+
34
+ sage: p = Polyhedron([(0,0)], base_ring=QQ)
35
+ sage: p._is_zero(0)
36
+ True
37
+ sage: p._is_zero(1/100000)
38
+ False
39
+ """
40
+ return x == 0
41
+
42
+ def _is_nonneg(self, x):
43
+ """
44
+ Test whether ``x`` is nonnegative.
45
+
46
+ INPUT:
47
+
48
+ - ``x`` -- a number in the base ring
49
+
50
+ OUTPUT: boolean
51
+
52
+ EXAMPLES::
53
+
54
+ sage: p = Polyhedron([(0,0)], base_ring=QQ)
55
+ sage: p._is_nonneg(1)
56
+ True
57
+ sage: p._is_nonneg(-1/100000)
58
+ False
59
+ """
60
+ return x >= 0
61
+
62
+ def _is_positive(self, x):
63
+ """
64
+ Test whether ``x`` is positive.
65
+
66
+ INPUT:
67
+
68
+ - ``x`` -- a number in the base ring
69
+
70
+ OUTPUT: boolean
71
+
72
+ EXAMPLES::
73
+
74
+ sage: p = Polyhedron([(0,0)], base_ring=QQ)
75
+ sage: p._is_positive(1)
76
+ True
77
+ sage: p._is_positive(0)
78
+ False
79
+ """
80
+ return x > 0
81
+
82
+ _base_ring = QQ
83
+
84
+ def integral_points_count(self, verbose=False, use_Hrepresentation=False,
85
+ explicit_enumeration_threshold=1000, preprocess=True, **kwds):
86
+ r"""
87
+ Return the number of integral points in the polyhedron.
88
+
89
+ This method uses the optional package ``latte_int``
90
+ if an estimate for lattice points based on bounding boxes
91
+ exceeds ``explicit_enumeration_threshold``.
92
+
93
+ INPUT:
94
+
95
+ - ``verbose`` -- boolean (default: ``False``); whether to display
96
+ verbose output
97
+
98
+ - ``use_Hrepresentation`` -- boolean (default: ``False``); whether
99
+ to send the H or V representation to LattE
100
+
101
+ - ``preprocess`` -- boolean (default: ``True``); whether, if the integral hull
102
+ is known to lie in a coordinate hyperplane, to tighten bounds to reduce dimension
103
+
104
+ .. SEEALSO::
105
+
106
+ :mod:`~sage.interfaces.latte` the interface to LattE interfaces
107
+
108
+ EXAMPLES::
109
+
110
+ sage: P = polytopes.cube()
111
+ sage: P.integral_points_count()
112
+ 27
113
+ sage: P.integral_points_count(explicit_enumeration_threshold=0) # optional - latte_int
114
+ 27
115
+
116
+ We enlarge the polyhedron to force the use of the generating function methods
117
+ implemented in LattE integrale, rather than explicit enumeration::
118
+
119
+ sage: (1000000000*P).integral_points_count(verbose=True) # optional - latte_int
120
+ This is LattE integrale...
121
+ ...
122
+ Total time:...
123
+ 8000000012000000006000000001
124
+
125
+ We shrink the polyhedron a little bit::
126
+
127
+ sage: Q = P*(8/9)
128
+ sage: Q.integral_points_count()
129
+ 1
130
+ sage: Q.integral_points_count(explicit_enumeration_threshold=0)
131
+ 1
132
+
133
+ Unbounded polyhedra (with or without lattice points) are not supported::
134
+
135
+ sage: P = Polyhedron(vertices=[[1/2, 1/3]], rays=[[1, 1]])
136
+ sage: P.integral_points_count()
137
+ Traceback (most recent call last):
138
+ ...
139
+ NotImplementedError: ...
140
+ sage: P = Polyhedron(vertices=[[1, 1]], rays=[[1, 1]])
141
+ sage: P.integral_points_count()
142
+ Traceback (most recent call last):
143
+ ...
144
+ NotImplementedError: ...
145
+
146
+ "Fibonacci" knapsacks (preprocessing helps a lot)::
147
+
148
+ sage: def fibonacci_knapsack(d, b, backend=None):
149
+ ....: lp = MixedIntegerLinearProgram(base_ring=QQ)
150
+ ....: x = lp.new_variable(nonnegative=True)
151
+ ....: lp.add_constraint(lp.sum(fibonacci(i+3)*x[i] for i in range(d)) <= b)
152
+ ....: return lp.polyhedron(backend=backend)
153
+ sage: fibonacci_knapsack(20, 12).integral_points_count() # does not finish with preprocess=False # needs sage.combinat
154
+ 33
155
+
156
+ TESTS:
157
+
158
+ We check that :issue:`21491` is fixed::
159
+
160
+ sage: P = Polyhedron(ieqs=[], eqns=[[-10,0,1],[-10,1,0]])
161
+ sage: P.integral_points_count()
162
+ 1
163
+ sage: P = Polyhedron(ieqs=[], eqns=[[-11,0,2],[-10,1,0]])
164
+ sage: P.integral_points_count()
165
+ 0
166
+ """
167
+ if self.is_empty():
168
+ return 0
169
+ if self.dimension() == 0:
170
+ return 1 if self.is_lattice_polytope() else 0
171
+ if not self.is_compact():
172
+ # LattE just prints the warning 'readCddExtFile:: Given polyhedron is unbounded!!!'
173
+ # but then returns 0.
174
+ raise NotImplementedError('Unbounded polyhedra are not supported')
175
+
176
+ # for small bounding boxes, it is faster to naively iterate over the points of the box
177
+ box_min, box_max = self.bounding_box(integral_hull=True)
178
+ if box_min is None:
179
+ return 0
180
+ box_points = prod(max_coord-min_coord+1 for min_coord, max_coord in zip(box_min, box_max))
181
+
182
+ if explicit_enumeration_threshold is None or box_points <= explicit_enumeration_threshold:
183
+ return len(self.integral_points())
184
+
185
+ p = self
186
+
187
+ if preprocess:
188
+ # If integral hull is known to lie in a coordinate hyperplane,
189
+ # tighten bounds to reduce dimension.
190
+ rat_box_min, rat_box_max = self.bounding_box(integral=False)
191
+ if any(a == b and (ra < a or b < rb)
192
+ for ra, a, b, rb in zip(rat_box_min, box_min, box_max, rat_box_max)):
193
+ lp, x = self.to_linear_program(return_variable=True)
194
+ for i, a in enumerate(box_min):
195
+ lp.set_min(x[i], a)
196
+ for i, b in enumerate(box_max):
197
+ lp.set_max(x[i], b)
198
+ p = lp.polyhedron() # this recomputes the double description, which is wasteful
199
+ if p.is_empty():
200
+ return 0
201
+ if p.dimension() == 0:
202
+ return 1 if p.is_lattice_polytope() else 0
203
+
204
+ # LattE does not like V-representation of lower-dimensional polytopes.
205
+ if not p.is_full_dimensional():
206
+ use_Hrepresentation = True
207
+
208
+ from sage.interfaces.latte import count
209
+ return count(
210
+ p.cdd_Hrepresentation() if use_Hrepresentation else p.cdd_Vrepresentation(),
211
+ cdd=True,
212
+ verbose=verbose,
213
+ **kwds)
214
+
215
+ @cached_method(do_pickle=True)
216
+ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False,
217
+ dual=None, irrational_primal=None,
218
+ irrational_all_primal=None, maxdet=None,
219
+ no_decomposition=None, compute_vertex_cones=None,
220
+ smith_form=None, dualization=None,
221
+ triangulation=None,
222
+ triangulation_max_height=None, **kwds):
223
+ r"""
224
+ Return the Ehrhart polynomial of this polyhedron.
225
+
226
+ The polyhedron must be a lattice polytope. Let `P` be a lattice
227
+ polytope in `\RR^d` and define `L(P,t) = \# (tP\cap \ZZ^d)`.
228
+ Then E. Ehrhart proved in 1962 that `L` coincides with a
229
+ rational polynomial of degree `d` for integer `t`. `L` is called the
230
+ *Ehrhart polynomial* of `P`. For more information see the
231
+ :wikipedia:`Ehrhart_polynomial`. The Ehrhart polynomial may be computed
232
+ using either LattE Integrale or Normaliz by setting ``engine`` to
233
+ 'latte' or 'normaliz' respectively.
234
+
235
+ INPUT:
236
+
237
+ - ``engine`` -- string; the backend to use. Allowed values are:
238
+
239
+ * ``None`` (default); When no input is given the Ehrhart polynomial
240
+ is computed using LattE Integrale (optional)
241
+ * ``'latte'``; use LattE integrale program (optional)
242
+ * ``'normaliz'``; use Normaliz program (optional package pynormaliz).
243
+ The backend of ``self`` must be set to ``'normaliz'``.
244
+
245
+ - ``variable`` -- string (default: ``'t'``); the variable in which the
246
+ Ehrhart polynomial should be expressed
247
+
248
+ - When the ``engine`` is ``'latte'``, the additional input values are:
249
+
250
+ * ``verbose`` -- boolean (default: ``False``); if ``True``, print the
251
+ whole output of the LattE command
252
+
253
+ The following options are passed to the LattE command, for details
254
+ consult `the LattE documentation
255
+ <https://www.math.ucdavis.edu/~latte/software/packages/latte_current/>`__:
256
+
257
+ * ``dual`` -- boolean; triangulate and signed-decompose in the dual
258
+ space
259
+ * ``irrational_primal`` -- boolean; triangulate in the dual space,
260
+ signed-decompose in the primal space using irrationalization.
261
+ * ``irrational_all_primal`` -- boolean; triangulate and signed-decompose
262
+ in the primal space using irrationalization.
263
+ * ``maxdet`` -- integer; decompose down to an index (determinant) of
264
+ ``maxdet`` instead of index 1 (unimodular cones).
265
+ * ``no_decomposition`` -- boolean; do not signed-decompose
266
+ simplicial cones.
267
+ * ``compute_vertex_cones`` -- string; either 'cdd' or 'lrs' or '4ti2'
268
+ * ``smith_form`` -- string; either 'ilio' or 'lidia'
269
+ * ``dualization`` -- string; either 'cdd' or '4ti2'
270
+ * ``triangulation`` -- string; 'cddlib', '4ti2' or 'topcom'
271
+ * ``triangulation_max_height`` -- integer; use a uniform distribution
272
+ of height from 1 to this number
273
+
274
+ OUTPUT: a univariate polynomial in ``variable`` over a rational field
275
+
276
+ .. SEEALSO::
277
+
278
+ :mod:`~sage.interfaces.latte` the interface to LattE Integrale
279
+ `PyNormaliz <https://pypi.org/project/PyNormaliz>`_
280
+
281
+ EXAMPLES:
282
+
283
+ To start, we find the Ehrhart polynomial of a three-dimensional
284
+ ``simplex``, first using ``engine='latte'``. Leaving the engine
285
+ unspecified sets the ``engine`` to ``'latte'`` by default::
286
+
287
+ sage: simplex = Polyhedron(vertices=[(0,0,0),(3,3,3),(-3,2,1),(1,-1,-2)])
288
+ sage: simplex = simplex.change_ring(QQ)
289
+ sage: poly = simplex.ehrhart_polynomial(engine='latte') # optional - latte_int
290
+ sage: poly # optional - latte_int
291
+ 7/2*t^3 + 2*t^2 - 1/2*t + 1
292
+ sage: poly(1) # optional - latte_int
293
+ 6
294
+ sage: len(simplex.integral_points())
295
+ 6
296
+ sage: poly(2) # optional - latte_int
297
+ 36
298
+ sage: len((2*simplex).integral_points())
299
+ 36
300
+
301
+ Now we find the same Ehrhart polynomial, this time using
302
+ ``engine='normaliz'``. To use the Normaliz engine, the ``simplex`` must
303
+ be defined with ``backend='normaliz'``::
304
+
305
+ sage: # optional - pynormaliz
306
+ sage: simplex = Polyhedron(vertices=[(0,0,0), (3,3,3),
307
+ ....: (-3,2,1), (1,-1,-2)],
308
+ ....: backend='normaliz')
309
+ sage: simplex = simplex.change_ring(QQ)
310
+ sage: poly = simplex.ehrhart_polynomial(engine='normaliz')
311
+ sage: poly
312
+ 7/2*t^3 + 2*t^2 - 1/2*t + 1
313
+
314
+ If the ``engine='normaliz'``, the backend should be ``'normaliz'``, otherwise
315
+ it returns an error::
316
+
317
+ sage: simplex = Polyhedron(vertices=[(0,0,0), (3,3,3),
318
+ ....: (-3,2,1), (1,-1,-2)])
319
+ sage: simplex = simplex.change_ring(QQ)
320
+ sage: simplex.ehrhart_polynomial(engine='normaliz')
321
+ Traceback (most recent call last):
322
+ ...
323
+ TypeError: The backend of the polyhedron should be 'normaliz'
324
+
325
+ The polyhedron should be compact::
326
+
327
+ sage: C = Polyhedron(rays=[[1,2], [2,1]], # optional - pynormaliz
328
+ ....: backend='normaliz')
329
+ sage: C = C.change_ring(QQ) # optional - pynormaliz
330
+ sage: C.ehrhart_polynomial() # optional - pynormaliz
331
+ Traceback (most recent call last):
332
+ ...
333
+ ValueError: Ehrhart polynomial only defined for compact polyhedra
334
+
335
+ The polyhedron should have integral vertices::
336
+
337
+ sage: L = Polyhedron(vertices=[[0], [1/2]])
338
+ sage: L.ehrhart_polynomial()
339
+ Traceback (most recent call last):
340
+ ...
341
+ TypeError: the polytope has nonintegral vertices, use ehrhart_quasipolynomial with backend 'normaliz'
342
+
343
+ TESTS:
344
+
345
+ The cache of the Ehrhart polynomial is being pickled::
346
+
347
+ sage: # optional - latte_int
348
+ sage: P = polytopes.cube().change_ring(QQ)
349
+ sage: P.ehrhart_polynomial()
350
+ 8*t^3 + 12*t^2 + 6*t + 1
351
+ sage: Q = loads(dumps(P))
352
+ sage: Q.ehrhart_polynomial.is_in_cache()
353
+ True
354
+
355
+ sage: L = Polyhedron(vertices=[[QQ(0)]])
356
+ sage: L.ehrhart_polynomial()
357
+ 1
358
+ """
359
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
360
+ from sage.rings.rational_field import QQ
361
+ R = PolynomialRing(QQ, variable)
362
+
363
+ # check if ``self`` is compact and has vertices in ZZ
364
+ if self.is_empty():
365
+ return R.zero()
366
+
367
+ if not self.is_compact():
368
+ raise ValueError("Ehrhart polynomial only defined for compact polyhedra")
369
+
370
+ if any(not v.is_integral() for v in self.vertex_generator()):
371
+ raise TypeError("the polytope has nonintegral vertices, use ehrhart_quasipolynomial with backend 'normaliz'")
372
+
373
+ if self.dimension() == 0:
374
+ return R.one()
375
+
376
+ # Passes to specific latte or normaliz subfunction depending on engine
377
+ if engine is None:
378
+ # set default engine to latte
379
+ engine = 'latte'
380
+
381
+ if engine == 'latte':
382
+ poly = self._ehrhart_polynomial_latte(verbose, dual,
383
+ irrational_primal, irrational_all_primal, maxdet,
384
+ no_decomposition, compute_vertex_cones, smith_form,
385
+ dualization, triangulation, triangulation_max_height,
386
+ **kwds)
387
+ return poly.change_variable_name(variable)
388
+ # TO DO: replace this change of variable by creating the appropriate
389
+ # polynomial ring in the latte interface.
390
+
391
+ elif engine == 'normaliz':
392
+ return self._ehrhart_polynomial_normaliz(variable)
393
+ else:
394
+ raise ValueError("engine must be 'latte' or 'normaliz'")
395
+
396
+ @cached_method(do_pickle=True)
397
+ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False,
398
+ dual=None, irrational_primal=None, irrational_all_primal=None,
399
+ maxdet=None, no_decomposition=None, compute_vertex_cones=None,
400
+ smith_form=None, dualization=None, triangulation=None,
401
+ triangulation_max_height=None, **kwds):
402
+ r"""
403
+ Compute the Ehrhart quasipolynomial of this polyhedron with rational
404
+ vertices.
405
+
406
+ If the polyhedron is a lattice polytope, returns the Ehrhart polynomial,
407
+ a univariate polynomial in ``variable`` over a rational field.
408
+ If the polyhedron has rational, nonintegral vertices, returns a tuple
409
+ of polynomials in ``variable`` over a rational field.
410
+ The Ehrhart counting function of a polytope `P` with rational
411
+ vertices is given by a *quasipolynomial*. That is, there exists a
412
+ positive integer `l` and `l` polynomials
413
+ `ehr_{P,i} \text{ for } i \in \{1,\dots,l \}` such that if `t` is
414
+ equivalent to `i` mod `l` then `tP \cap \mathbb Z^d = ehr_{P,i}(t)`.
415
+
416
+ INPUT:
417
+
418
+ - ``variable`` -- string (default: ``'t'``); the variable in which the
419
+ Ehrhart polynomial should be expressed
420
+
421
+ - ``engine`` -- string; the backend to use. Allowed values are:
422
+
423
+ * ``None`` (default); When no input is given the Ehrhart polynomial
424
+ is computed using Normaliz (optional)
425
+ * ``'latte'``; use LattE Integrale program (requires optional package
426
+ 'latte_int')
427
+ * ``'normaliz'``; use the Normaliz program (requires optional package
428
+ 'pynormaliz'). The backend of ``self`` must be set to 'normaliz'.
429
+
430
+ - When the ``engine`` is 'latte', the additional input values are:
431
+
432
+ * ``verbose`` -- boolean (default: ``False``); if ``True``, print the
433
+ whole output of the LattE command
434
+
435
+ The following options are passed to the LattE command, for details
436
+ consult `the LattE documentation
437
+ <https://www.math.ucdavis.edu/~latte/software/packages/latte_current/>`__:
438
+
439
+ * ``dual`` -- boolean; triangulate and signed-decompose in the dual
440
+ space
441
+ * ``irrational_primal`` -- boolean; triangulate in the dual space,
442
+ signed-decompose in the primal space using irrationalization.
443
+ * ``irrational_all_primal`` -- boolean; triangulate and signed-decompose
444
+ in the primal space using irrationalization.
445
+ * ``maxdet`` -- integer; decompose down to an index (determinant) of
446
+ ``maxdet`` instead of index 1 (unimodular cones).
447
+ * ``no_decomposition`` -- boolean; do not signed-decompose
448
+ simplicial cones.
449
+ * ``compute_vertex_cones`` -- string; either ``'cdd'`` or ``'lrs'`` or ``'4ti2'``
450
+ * ``smith_form`` -- string; either ``'ilio'`` or ``'lidia'``
451
+ * ``dualization`` -- string; either ``'cdd'`` or ``'4ti2'``
452
+ * ``triangulation`` -- string; ``'cddlib'``, ``'4ti2'`` or ``'topcom'``
453
+ * ``triangulation_max_height`` -- integer; use a uniform distribution of
454
+ height from 1 to this number
455
+
456
+ OUTPUT:
457
+
458
+ A univariate polynomial over a rational field or a tuple of such
459
+ polynomials.
460
+
461
+ .. SEEALSO::
462
+
463
+ :mod:`~sage.interfaces.latte` the interface to LattE Integrale
464
+ `PyNormaliz <https://pypi.org/project/PyNormaliz>`_
465
+
466
+ .. WARNING::
467
+
468
+ If the polytope has rational, non integral vertices,
469
+ it must have ``backend='normaliz'``.
470
+
471
+ EXAMPLES:
472
+
473
+ As a first example, consider the line segment [0,1/2]. If we
474
+ dilate this line segment by an even integral factor `k`,
475
+ then the dilated line segment will contain `k/2 +1` lattice points.
476
+ If `k` is odd then there will be `k/2+1/2` lattice points in
477
+ the dilated line segment. Note that it is necessary to set the
478
+ backend of the polytope to 'normaliz'::
479
+
480
+ sage: line_seg = Polyhedron(vertices=[[0], [1/2]], # optional - pynormaliz
481
+ ....: backend='normaliz'); line_seg
482
+ A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices
483
+ sage: line_seg.ehrhart_quasipolynomial() # optional - pynormaliz
484
+ (1/2*t + 1, 1/2*t + 1/2)
485
+
486
+ For a more exciting example, let us look at the subpolytope of the
487
+ 3 dimensional permutahedron fixed by the reflection
488
+ across the hyperplane `x_1 = x_4`::
489
+
490
+ sage: verts = [[3/2, 3, 4, 3/2],
491
+ ....: [3/2, 4, 3, 3/2],
492
+ ....: [5/2, 1, 4, 5/2],
493
+ ....: [5/2, 4, 1, 5/2],
494
+ ....: [7/2, 1, 2, 7/2],
495
+ ....: [7/2, 2, 1, 7/2]]
496
+ sage: subpoly = Polyhedron(vertices=verts, # optional - pynormaliz
497
+ ....: backend='normaliz')
498
+ sage: eq = subpoly.ehrhart_quasipolynomial(); eq # optional - pynormaliz
499
+ (4*t^2 + 3*t + 1, 4*t^2 + 2*t)
500
+ sage: eq = subpoly.ehrhart_quasipolynomial(); eq # optional - pynormaliz
501
+ (4*t^2 + 3*t + 1, 4*t^2 + 2*t)
502
+ sage: even_ep = eq[0] # optional - pynormaliz
503
+ sage: odd_ep = eq[1] # optional - pynormaliz
504
+ sage: even_ep(2) # optional - pynormaliz
505
+ 23
506
+ sage: ts = 2*subpoly # optional - pynormaliz
507
+ sage: ts.integral_points_count() # optional - pynormaliz latte_int
508
+ 23
509
+ sage: odd_ep(1) # optional - pynormaliz
510
+ 6
511
+ sage: subpoly.integral_points_count() # optional - pynormaliz latte_int
512
+ 6
513
+
514
+ A polytope with rational nonintegral vertices must have
515
+ ``backend='normaliz'``::
516
+
517
+ sage: line_seg = Polyhedron(vertices=[[0], [1/2]])
518
+ sage: line_seg.ehrhart_quasipolynomial()
519
+ Traceback (most recent call last):
520
+ ...
521
+ TypeError: The backend of the polyhedron should be 'normaliz'
522
+
523
+ The polyhedron should be compact::
524
+
525
+ sage: C = Polyhedron(rays=[[1/2,2], [2,1]], # optional - pynormaliz
526
+ ....: backend='normaliz')
527
+ sage: C.ehrhart_quasipolynomial() # optional - pynormaliz
528
+ Traceback (most recent call last):
529
+ ...
530
+ ValueError: Ehrhart quasipolynomial only defined for compact polyhedra
531
+
532
+ If the polytope happens to be a lattice polytope, the Ehrhart
533
+ polynomial is returned::
534
+
535
+ sage: # optional - pynormaliz
536
+ sage: simplex = Polyhedron(vertices=[(0,0,0), (3,3,3),
537
+ ....: (-3,2,1), (1,-1,-2)],
538
+ ....: backend='normaliz')
539
+ sage: simplex = simplex.change_ring(QQ)
540
+ sage: poly = simplex.ehrhart_quasipolynomial(
541
+ ....: engine='normaliz'); poly
542
+ 7/2*t^3 + 2*t^2 - 1/2*t + 1
543
+ sage: simplex.ehrhart_polynomial() # optional - latte_int
544
+ 7/2*t^3 + 2*t^2 - 1/2*t + 1
545
+
546
+ TESTS:
547
+
548
+ The cache of the Ehrhart quasipolynomial is being pickled::
549
+
550
+ sage: # optional - pynormaliz
551
+ sage: P = polytopes.cuboctahedron(backend='normaliz')/2
552
+ sage: P.ehrhart_quasipolynomial()
553
+ (5/6*t^3 + 2*t^2 + 5/3*t + 1, 5/6*t^3 + 1/2*t^2 + 1/6*t - 1/2)
554
+ sage: Q = loads(dumps(P))
555
+ sage: Q.ehrhart_quasipolynomial.is_in_cache()
556
+ True
557
+
558
+ sage: # optional - latte_int
559
+ sage: P = polytopes.cuboctahedron().change_ring(QQ)
560
+ sage: P.ehrhart_quasipolynomial(engine='latte')
561
+ 20/3*t^3 + 8*t^2 + 10/3*t + 1
562
+ sage: Q = loads(dumps(P))
563
+ sage: Q.ehrhart_quasipolynomial.is_in_cache(engine='latte')
564
+ True
565
+ """
566
+ if self.is_empty():
567
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
568
+ from sage.rings.rational_field import QQ
569
+ R = PolynomialRing(QQ, 't')
570
+ return R.zero()
571
+
572
+ if not self.is_compact():
573
+ raise ValueError("Ehrhart quasipolynomial only defined for compact polyhedra")
574
+
575
+ if engine is None:
576
+ # setting the default to 'normaliz'
577
+ engine = 'normaliz'
578
+ if engine == 'normaliz':
579
+ return self._ehrhart_quasipolynomial_normaliz(variable)
580
+ if engine == 'latte':
581
+ if any(not v.is_integral() for v in self.vertex_generator()):
582
+ raise TypeError("the polytope has nonintegral vertices, the engine and backend of self should be 'normaliz'")
583
+ poly = self._ehrhart_polynomial_latte(verbose, dual,
584
+ irrational_primal, irrational_all_primal, maxdet,
585
+ no_decomposition, compute_vertex_cones, smith_form,
586
+ dualization, triangulation, triangulation_max_height,
587
+ **kwds)
588
+ return poly.change_variable_name(variable)
589
+ # TO DO: replace this change of variable by creating the appropriate
590
+ # polynomial ring in the latte interface.
591
+ else:
592
+ raise TypeError("the engine should be 'latte' or 'normaliz'")
593
+
594
+ def _ehrhart_quasipolynomial_normaliz(self, variable='t'):
595
+ r"""
596
+ Compute the Ehrhart quasipolynomial of a lattice or rational polytope
597
+ using the Normaliz engine.
598
+
599
+ INPUT:
600
+
601
+ - ``variable`` -- string (default: ``'t'``); the variable in which the
602
+ Ehrhart polynomial is expressed
603
+
604
+ OUTPUT:
605
+
606
+ A univariate polynomial over a rational field or a tuple of such
607
+ polynomials.
608
+
609
+ EXAMPLES:
610
+
611
+ The subpolytope of the 3 dimensional permutahedron fixed by the
612
+ reflection across the hyperplane `x_1 = x_4`::
613
+
614
+ sage: verts = [[3/2, 3, 4, 3/2],
615
+ ....: [3/2, 4, 3, 3/2],
616
+ ....: [5/2, 1, 4, 5/2],
617
+ ....: [5/2, 4, 1, 5/2],
618
+ ....: [7/2, 1, 2, 7/2],
619
+ ....: [7/2, 2, 1, 7/2]]
620
+ sage: subpoly = Polyhedron(vertices=verts, # optional - pynormaliz
621
+ ....: backend='normaliz')
622
+ sage: eq = subpoly._ehrhart_quasipolynomial_normaliz(); eq # optional - pynormaliz
623
+ (4*t^2 + 3*t + 1, 4*t^2 + 2*t)
624
+ sage: even_ep = eq[0] # optional - pynormaliz
625
+ sage: odd_ep = eq[1] # optional - pynormaliz
626
+ sage: even_ep(2) # optional - pynormaliz
627
+ 23
628
+ sage: ts = 2*subpoly # optional - pynormaliz
629
+ sage: ts.integral_points_count() # optional - pynormaliz latte_int
630
+ 23
631
+ sage: odd_ep(1) # optional - pynormaliz
632
+ 6
633
+ sage: subpoly.integral_points_count() # optional - pynormaliz latte_int
634
+ 6
635
+
636
+ TESTS::
637
+
638
+ sage: line_seg = Polyhedron(vertices=[[0],[1/2]])
639
+ sage: line_seg._ehrhart_quasipolynomial_normaliz()
640
+ Traceback (most recent call last):
641
+ ...
642
+ TypeError: The backend of the polyhedron should be 'normaliz'
643
+ """
644
+ raise TypeError("The backend of the polyhedron should be 'normaliz'")
645
+
646
+ _ehrhart_polynomial_normaliz = _ehrhart_quasipolynomial_normaliz
647
+
648
+ def _ehrhart_polynomial_latte(self, verbose=False, dual=None,
649
+ irrational_primal=None, irrational_all_primal=None, maxdet=None,
650
+ no_decomposition=None, compute_vertex_cones=None, smith_form=None,
651
+ dualization=None, triangulation=None, triangulation_max_height=None,
652
+ **kwds):
653
+ r"""
654
+ Return the Ehrhart polynomial of this polyhedron using LattE integrale.
655
+
656
+ Let `P` be a lattice polytope in `\RR^d` and define `L(P,t) = \# (tP
657
+ \cap \ZZ^d)`. Then E. Ehrhart proved in 1962 that `L` coincides with a
658
+ rational polynomial of degree `d` for integer `t`. `L` is called the
659
+ *Ehrhart polynomial* of `P`. For more information see the
660
+ :wikipedia:`Ehrhart_polynomial`.
661
+
662
+ INPUT:
663
+
664
+ - ``verbose`` -- boolean (default: ``False``); if ``True``, print the
665
+ whole output of the LattE command
666
+
667
+ The following options are passed to the LattE command, for details you
668
+ should consult `the LattE documentation
669
+ <https://www.math.ucdavis.edu/~latte/software/packages/latte_current/>`__:
670
+
671
+ - ``dual`` -- boolean; triangulate and signed-decompose in the dual
672
+ space
673
+
674
+ - ``irrational_primal`` -- boolean; triangulate in the dual space,
675
+ signed-decompose in the primal space using irrationalization
676
+
677
+ - ``irrational_all_primal`` -- boolean; triangulate and signed-decompose
678
+ in the primal space using irrationalization
679
+
680
+ - ``maxdet`` -- integer; decompose down to an index (determinant) of
681
+ ``maxdet`` instead of index 1 (unimodular cones)
682
+
683
+ - ``no_decomposition`` -- boolean; do not signed-decompose simplicial cones
684
+
685
+ - ``compute_vertex_cones`` -- string; either ``'cdd'`` or ``'lrs'`` or ``'4ti2'``
686
+
687
+ - ``smith_form`` -- string; either ``'ilio'`` or ``'lidia'``
688
+
689
+ - ``dualization`` -- string; either ``'cdd'`` or ``'4ti2'``
690
+
691
+ - ``triangulation`` -- string; ``'cddlib'``, ``'4ti2'`` or ``'topcom'``
692
+
693
+ - ``triangulation_max_height`` -- integer; use a uniform distribution of
694
+ height from 1 to this number
695
+
696
+ .. NOTE::
697
+
698
+ Any additional argument is forwarded to LattE's executable
699
+ ``count``. All occurrences of '_' will be replaced with a '-'.
700
+
701
+ OUTPUT: a univariate polynomial over a rational field
702
+
703
+ ALGORITHM:
704
+
705
+ This method calls the program ``count`` from LattE integrale, a program
706
+ for lattice point enumeration (see
707
+ https://www.math.ucdavis.edu/~latte/).
708
+
709
+ .. SEEALSO::
710
+
711
+ :mod:`~sage.interfaces.latte` the interface to LattE integrale
712
+
713
+ EXAMPLES::
714
+
715
+ sage: P = Polyhedron(vertices=[(0,0,0), (3,3,3), (-3,2,1), (1,-1,-2)])
716
+ sage: p = P._ehrhart_polynomial_latte(); p # optional - latte_int
717
+ 7/2*t^3 + 2*t^2 - 1/2*t + 1
718
+ sage: p(1) # optional - latte_int
719
+ 6
720
+ sage: len(P.integral_points())
721
+ 6
722
+ sage: p(2) # optional - latte_int
723
+ 36
724
+ sage: len((2*P).integral_points())
725
+ 36
726
+
727
+ The unit hypercubes::
728
+
729
+ sage: # optional - latte_int
730
+ sage: from itertools import product
731
+ sage: def hypercube(d):
732
+ ....: return Polyhedron(vertices=list(product([0,1], repeat=d)))
733
+ sage: hypercube(3)._ehrhart_polynomial_latte()
734
+ t^3 + 3*t^2 + 3*t + 1
735
+ sage: hypercube(4)._ehrhart_polynomial_latte()
736
+ t^4 + 4*t^3 + 6*t^2 + 4*t + 1
737
+ sage: hypercube(5)._ehrhart_polynomial_latte()
738
+ t^5 + 5*t^4 + 10*t^3 + 10*t^2 + 5*t + 1
739
+ sage: hypercube(6)._ehrhart_polynomial_latte()
740
+ t^6 + 6*t^5 + 15*t^4 + 20*t^3 + 15*t^2 + 6*t + 1
741
+
742
+ TESTS:
743
+
744
+ Test options::
745
+
746
+ sage: P = Polyhedron(ieqs=[[1,-1,1,0], [-1,2,-1,0], [1,1,-2,0]], eqns=[[-1,2,-1,-3]], base_ring=ZZ)
747
+
748
+ sage: p = P._ehrhart_polynomial_latte(maxdet=5, verbose=True) # optional - latte_int
749
+ This is LattE integrale ...
750
+ ...
751
+ Invocation: ...count... --ehrhart-polynomial '--redundancy-check=none' --cdd '--maxdet=5' /dev/stdin
752
+ ...
753
+ sage: p # optional - latte_int
754
+ 1/2*t^2 + 3/2*t + 1
755
+
756
+ sage: p = P._ehrhart_polynomial_latte(dual=True, verbose=True) # optional - latte_int
757
+ This is LattE integrale ...
758
+ ...
759
+ Invocation: ...count... --ehrhart-polynomial '--redundancy-check=none' --cdd --dual /dev/stdin
760
+ ...
761
+ sage: p # optional - latte_int
762
+ 1/2*t^2 + 3/2*t + 1
763
+
764
+ sage: p = P._ehrhart_polynomial_latte(irrational_primal=True, verbose=True) # optional - latte_int
765
+ This is LattE integrale ...
766
+ ...
767
+ Invocation: ...count... --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-primal /dev/stdin
768
+ ...
769
+ sage: p # optional - latte_int
770
+ 1/2*t^2 + 3/2*t + 1
771
+
772
+ sage: p = P._ehrhart_polynomial_latte(irrational_all_primal=True, verbose=True) # optional - latte_int
773
+ This is LattE integrale ...
774
+ ...
775
+ Invocation: ...count... --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-all-primal /dev/stdin
776
+ ...
777
+ sage: p # optional - latte_int
778
+ 1/2*t^2 + 3/2*t + 1
779
+
780
+ Test bad options::
781
+
782
+ sage: P._ehrhart_polynomial_latte(bim_bam_boum=19) # optional - latte_int
783
+ Traceback (most recent call last):
784
+ ...
785
+ RuntimeError: LattE integrale program failed (exit code 1):
786
+ ...
787
+ Invocation: ...count... --ehrhart-polynomial '--redundancy-check=none' --cdd '--bim-bam-boum=19' /dev/stdin
788
+ Unknown command/option --bim-bam-boum=19
789
+ """
790
+
791
+ # note: the options below are explicitly written in the function
792
+ # declaration in order to keep tab completion (see #18211).
793
+ kwds.update({
794
+ 'dual' : dual,
795
+ 'irrational_primal' : irrational_primal,
796
+ 'irrational_all_primal' : irrational_all_primal,
797
+ 'maxdet' : maxdet,
798
+ 'no_decomposition' : no_decomposition,
799
+ 'compute_vertex_cones' : compute_vertex_cones,
800
+ 'smith_form' : smith_form,
801
+ 'dualization' : dualization,
802
+ 'triangulation' : triangulation,
803
+ 'triangulation_max_height': triangulation_max_height})
804
+
805
+ from sage.interfaces.latte import count
806
+ ine = self.cdd_Hrepresentation()
807
+ return count(ine, cdd=True, ehrhart_polynomial=True, verbose=verbose, **kwds)
808
+
809
+ def fixed_subpolytope(self, vertex_permutation):
810
+ r"""
811
+ Return the fixed subpolytope of this polytope by the cyclic action of
812
+ ``vertex_permutation``.
813
+
814
+ The fixed subpolytope of this polytope under the ``vertex_permutation``
815
+ is the subset of this polytope that is fixed pointwise.
816
+
817
+ INPUT:
818
+
819
+ - ``vertex_permutation`` -- permutation; a permutation of the vertices
820
+ of ``self``
821
+
822
+ OUTPUT: a subpolytope of ``self``
823
+
824
+ .. NOTE::
825
+
826
+ The vertex_permutation is obtained as a permutation of the vertices
827
+ represented as a permutation. For example, vertex_permutation =
828
+ self.restricted_automorphism_group(output='permutation').
829
+
830
+ Requiring a lattice polytope as opposed to a rational polytope as
831
+ input is purely conventional.
832
+
833
+ EXAMPLES:
834
+
835
+ The fixed subpolytopes of the cube can be obtained as follows::
836
+
837
+ sage: Cube = polytopes.cube(backend = 'normaliz') # optional - pynormaliz
838
+ sage: AG = Cube.restricted_automorphism_group( # optional - pynormaliz
839
+ ....: output='permutation')
840
+ sage: reprs = AG.conjugacy_classes_representatives() # optional - pynormaliz
841
+
842
+ The fixed subpolytope of the identity element of the group is the entire
843
+ cube::
844
+
845
+ sage: reprs[0] # optional - pynormaliz
846
+ ()
847
+ sage: Cube.fixed_subpolytope(vertex_permutation=reprs[0]) # optional - pynormaliz
848
+ A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8
849
+ vertices
850
+ sage: _.vertices() # optional - pynormaliz
851
+ (A vertex at (-1, -1, -1),
852
+ A vertex at (-1, -1, 1),
853
+ A vertex at (-1, 1, -1),
854
+ A vertex at (-1, 1, 1),
855
+ A vertex at (1, -1, -1),
856
+ A vertex at (1, -1, 1),
857
+ A vertex at (1, 1, -1),
858
+ A vertex at (1, 1, 1))
859
+
860
+ You can obtain non-trivial examples::
861
+
862
+ sage: G = AG([(0,1),(2,3),(4,5),(6,7)]) # optional - pynormaliz
863
+ sage: fsp = Cube.fixed_subpolytope(G); fsp # optional - pynormaliz
864
+ A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
865
+ sage: fsp.vertices() # optional - pynormaliz
866
+ (A vertex at (-1, -1, 0),
867
+ A vertex at (-1, 1, 0),
868
+ A vertex at (1, -1, 0),
869
+ A vertex at (1, 1, 0))
870
+
871
+ The next example shows that :meth:`fixed_subpolytope` works for rational polytopes::
872
+
873
+ sage: # optional - pynormaliz
874
+ sage: P = Polyhedron(vertices=[[0], [1/2]],
875
+ ....: backend='normaliz')
876
+ sage: P.vertices()
877
+ (A vertex at (0), A vertex at (1/2))
878
+ sage: G = P.restricted_automorphism_group(
879
+ ....: output='permutation'); G
880
+ Permutation Group with generators [(0,1)]
881
+ sage: len(G)
882
+ 2
883
+ sage: fixed_set = P.fixed_subpolytope(G.gens()[0])
884
+ sage: fixed_set
885
+ A 0-dimensional polyhedron in QQ^1 defined as the convex hull of 1 vertex
886
+ sage: fixed_set.vertices_list()
887
+ [[1/4]]
888
+ """
889
+ if self.is_empty():
890
+ raise NotImplementedError('empty polyhedra are not supported')
891
+ if not self.is_compact():
892
+ raise NotImplementedError('unbounded polyhedra are not supported')
893
+
894
+ orbits = frozenset([frozenset(i) for i in vertex_permutation.cycle_tuples(singletons=True)])
895
+
896
+ # If its the identity, returns the polytope
897
+ if not orbits:
898
+ return self
899
+
900
+ # Make an index shift flag
901
+ shift = True
902
+ if 0 in vertex_permutation.domain():
903
+ shift = False
904
+
905
+ vertices = []
906
+ for orbit in orbits:
907
+ size = len(orbit)
908
+ if shift:
909
+ # in this case, the indices in the orbit are 1 more than the index in the V
910
+ s = sum([(self.Vrepresentation()[i-1]).vector() for i in orbit])
911
+ else:
912
+ s = sum([(self.Vrepresentation()[i]).vector() for i in orbit])
913
+ orbit_barycenter = (1/QQ(size)) * s
914
+ vertices += [orbit_barycenter]
915
+
916
+ P = self.parent().change_ring(self.base_ring().fraction_field(),backend='normaliz')
917
+ return P.element_class(P, [vertices,[],[]], None)
918
+
919
+ def fixed_subpolytopes(self, conj_class_reps):
920
+ r"""
921
+ Return the fixed subpolytopes of this polytope under the actions of the
922
+ given conjugacy class representatives.
923
+
924
+ The ``conj_class_reps`` are representatives of the conjugacy classes of
925
+ a subgroup of the automorphism group of this polytope.
926
+ For an element of the automorphism group, the fixed subpolytope
927
+ is the subset of this polytope that is fixed pointwise.
928
+
929
+ INPUT:
930
+
931
+ - ``conj_class_reps`` -- list of representatives of the conjugacy
932
+ classes of the subgroup of the :meth:`restricted_automorphism_group` of
933
+ the polytope. Each element is written as a permutation of the vertices
934
+ of the polytope.
935
+
936
+ OUTPUT:
937
+
938
+ A dictionary where the elements of ``conj_class_reps`` are keys and the
939
+ fixed subpolytopes are values.
940
+
941
+ .. NOTE::
942
+
943
+ Two elements in the same conjugacy class fix lattice-isomorphic
944
+ subpolytopes.
945
+
946
+ EXAMPLES:
947
+
948
+ Here is an example for the square::
949
+
950
+ sage: # optional - pynormaliz, needs sage.groups
951
+ sage: p = polytopes.hypercube(2, backend='normaliz'); p
952
+ A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
953
+ sage: aut_p = p.restricted_automorphism_group(
954
+ ....: output='permutation')
955
+ sage: aut_p.order()
956
+ 8
957
+ sage: conj_list = aut_p.conjugacy_classes_representatives()
958
+ sage: fixedpolytopes_dict = p.fixed_subpolytopes(conj_list)
959
+ sage: fixedpolytopes_dict[aut_p([(0,3),(1,2)])]
960
+ A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
961
+
962
+ TESTS::
963
+
964
+ sage: P = Polyhedron(vertices=[[1, 1]], rays=[[1, 1]])
965
+ sage: aut_P = P.restricted_automorphism_group(output='permutation') # needs sage.groups
966
+ sage: conj_list = aut_P.conjugacy_classes_representatives() # needs sage.groups
967
+ sage: P.fixed_subpolytopes(conj_list) # needs sage.groups
968
+ Traceback (most recent call last):
969
+ ...
970
+ NotImplementedError: unbounded polyhedra are not supported
971
+ """
972
+ if self.is_empty():
973
+ raise NotImplementedError('empty polyhedra are not supported')
974
+ if not self.is_compact():
975
+ raise NotImplementedError('unbounded polyhedra are not supported')
976
+ fixed_subpolytopes = {}
977
+
978
+ for element in conj_class_reps:
979
+ fixed_subpoly = self.fixed_subpolytope(element)
980
+ fixed_subpolytopes[element] = fixed_subpoly
981
+ return fixed_subpolytopes
982
+
983
+ def Hstar_function(self, acting_group=None, output=None):
984
+ r"""
985
+ Return `H^*` as a rational function in `t` with coefficients in
986
+ the ring of class functions of the ``acting_group``
987
+ of this polytope.
988
+
989
+ Here, `H^*(t) = \sum_{m} \chi_{m\text{self}}t^m \det(Id-\rho(t))`.
990
+ The irreducible characters of ``acting_group`` form an orthonormal basis
991
+ for the ring of class functions with values in `\CC`.
992
+ The coefficients of `H^*(t)` are expressed in this basis.
993
+
994
+ INPUT:
995
+
996
+ - ``acting_group`` -- (default=None) a permgroup object. A subgroup of
997
+ the polytope's ``restricted_automorphism_group``. If
998
+ ``None``, it is set to the full ``restricted_automorphism_group`` of the
999
+ polytope. The acting group should always use ``output='permutation'``.
1000
+
1001
+ - ``output`` -- string. an output option. The allowed values are:
1002
+
1003
+ * ``None`` (default): returns the rational function `H^*(t)`. `H^*`
1004
+ is a rational function in `t` with coefficients in the ring of
1005
+ class functions.
1006
+ * ``'e_series_list'``: Returns a list of the ehrhart_series for the
1007
+ fixed_subpolytopes of each conjugacy class representative.
1008
+ * ``'determinant_vec'``: Returns a list of the determinants
1009
+ of `Id-\rho*t` for each conjugacy class representative.
1010
+ * ``'Hstar_as_lin_comb'``: Returns a vector of the coefficients
1011
+ of the irreducible representations in the expression of `H^*`.
1012
+ * ``'prod_det_es'``: Returns a vector of the product of
1013
+ determinants and the Ehrhart series.
1014
+ * ``'complete'``: Returns a list with ``Hstar``,
1015
+ ``Hstar_as_lin_comb``, character table of the acting group, and
1016
+ whether ``Hstar`` is effective.
1017
+
1018
+ OUTPUT:
1019
+
1020
+ The default output is the rational function `H^*`. `H^*` is a rational
1021
+ function in `t` with coefficients in the ring of class functions.
1022
+ There are several output options to see the intermediary outputs of the
1023
+ function.
1024
+
1025
+ EXAMPLES:
1026
+
1027
+ The `H^*`-polynomial of the standard (`d-1`)-dimensional simplex
1028
+ `S = conv(e_1, \dots, e_d)` under its :meth:`restricted_automorphism_group`
1029
+ is equal to 1 = `\chi_{trivial}` (Prop 6.1 [Stap2011]_).
1030
+ Here is the computation for the 3-dimensional standard simplex::
1031
+
1032
+ sage: # optional - pynormaliz
1033
+ sage: S = polytopes.simplex(3, backend='normaliz'); S
1034
+ A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 4 vertices
1035
+ sage: G = S.restricted_automorphism_group(
1036
+ ....: output='permutation')
1037
+ sage: G.is_isomorphic(SymmetricGroup(4))
1038
+ True
1039
+ sage: Hstar = S._Hstar_function_normaliz(G); Hstar
1040
+ chi_4
1041
+ sage: G.character_table()
1042
+ [ 1 -1 1 1 -1]
1043
+ [ 3 -1 0 -1 1]
1044
+ [ 2 0 -1 2 0]
1045
+ [ 3 1 0 -1 -1]
1046
+ [ 1 1 1 1 1]
1047
+
1048
+ The next example is Example 7.6 in [Stap2011]_, and shows that `H^*` is not always
1049
+ a polynomial. Let P be the polytope with vertices
1050
+ `\pm(0,0,1),\pm(1,0,1), \pm(0,1,1), \pm(1,1,1)` and let
1051
+ G = `\Zmod{2}` act on P as follows::
1052
+
1053
+ sage: # optional - pynormaliz
1054
+ sage: P = Polyhedron(vertices=[[0,0,1], [0,0,-1], [1,0,1],
1055
+ ....: [-1,0,-1], [0,1,1],
1056
+ ....: [0,-1,-1], [1,1,1], [-1,-1,-1]],
1057
+ ....: backend='normaliz')
1058
+ sage: K = P.restricted_automorphism_group(
1059
+ ....: output='permutation')
1060
+ sage: G = K.subgroup(gens=[K([(0,2),(1,3),(4,6),(5,7)])])
1061
+ sage: conj_reps = G.conjugacy_classes_representatives()
1062
+ sage: Dict = P.permutations_to_matrices(conj_reps,
1063
+ ....: acting_group=G)
1064
+ sage: list(Dict.keys())[0]
1065
+ (0,2)(1,3)(4,6)(5,7)
1066
+ sage: list(Dict.values())[0]
1067
+ [-1 0 1 0]
1068
+ [ 0 1 0 0]
1069
+ [ 0 0 1 0]
1070
+ [ 0 0 0 1]
1071
+ sage: len(G)
1072
+ 2
1073
+ sage: G.character_table()
1074
+ [ 1 1]
1075
+ [ 1 -1]
1076
+
1077
+ Then we calculate the rational function `H^*(t)`::
1078
+
1079
+ sage: Hst = P._Hstar_function_normaliz(G); Hst # optional - pynormaliz
1080
+ (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3
1081
+ + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1)
1082
+
1083
+ To see the exact as written in [Stap2011]_, we can format it as
1084
+ ``'Hstar_as_lin_comb'``. The first coordinate is the coefficient of the
1085
+ trivial character; the second is the coefficient of the sign character::
1086
+
1087
+ sage: lin = P._Hstar_function_normaliz( # optional - pynormaliz
1088
+ ....: G, output='Hstar_as_lin_comb'); lin
1089
+ ((t^4 + 3*t^3 + 8*t^2 + 3*t + 1)/(t + 1),
1090
+ (3*t^3 + 2*t^2 + 3*t)/(t + 1))
1091
+ """
1092
+ if self.is_empty():
1093
+ raise NotImplementedError('empty polyhedra are not supported')
1094
+ if not self.is_compact():
1095
+ raise NotImplementedError('unbounded polyhedra are not supported')
1096
+ if not self.backend() == 'normaliz':
1097
+ raise TypeError("the backend of the polyhedron should be 'normaliz'")
1098
+ else:
1099
+ return self._Hstar_function_normaliz(acting_group, output)
1100
+
1101
+ def _Hstar_function_normaliz(self, acting_group=None, output=None):
1102
+ r"""
1103
+ Return `H^*` as a rational function in `t` with coefficients in
1104
+ the ring of class functions of the ``acting_group`` of ``self``.
1105
+
1106
+ INPUT:
1107
+
1108
+ - ``acting_group`` -- (default=None) a permgroup object. A subgroup of
1109
+ ``self``'s ``restricted_automorphism_group`` output as a permutation.
1110
+ If ``None``, it is set to the full ``restricted_automorphism_group``
1111
+ of ``self``. The acting group should always use ``output='permutation'``.
1112
+
1113
+ - ``output`` -- string. an output option. The allowed values are:
1114
+
1115
+ * ``None`` (default): Returns the rational function `H^*(t)`. `H^*`
1116
+ is a rational function in `t` with coefficients in the ring of
1117
+ class functions.
1118
+ * ``'e_series_list'``: Returns a list of the ehrhart_series
1119
+ for the fixed_subpolytopes of each conjugacy class representative.
1120
+ * ``'determinant_vec'``: Returns a list of the determinants
1121
+ of `Id-\rho*t` for each conjugacy class representative.
1122
+ * ``'Hstar_as_lin_comb'``: Returns a vector of the coefficients
1123
+ of the irreducible representations in the expression of `H^*`.
1124
+ * ``'prod_det_es'``: Returns a vector of the product of
1125
+ determinants and the Ehrhart series.
1126
+ * ``'complete'``: Returns a list with ``Hstar``,
1127
+ ``Hstar_as_lin_comb``, character table of the acting group, and
1128
+ whether ``Hstar`` is effective.
1129
+
1130
+ OUTPUT:
1131
+
1132
+ The default output is the rational function `H^*`. `H^*` is a rational
1133
+ function in `t` with coefficients in the ring of class functions.
1134
+ There are several output options to see the intermediary outputs of the
1135
+ function.
1136
+
1137
+ TESTS::
1138
+
1139
+ sage: p = Polyhedron(vertices = [[0],[1/2]])
1140
+ sage: p._Hstar_function_normaliz()
1141
+ Traceback (most recent call last):
1142
+ ...
1143
+ TypeError: the backend of the polyhedron should be 'normaliz'
1144
+ """
1145
+ raise TypeError("the backend of the polyhedron should be 'normaliz'")
1146
+
1147
+ def is_effective(self, Hstar, Hstar_as_lin_comb):
1148
+ r"""
1149
+ Test for the effectiveness of the ``Hstar`` series of this polytope.
1150
+
1151
+ The ``Hstar`` series of the polytope is determined by the action of a
1152
+ subgroup of the polytope's :meth:`restricted_automorphism_group`. The
1153
+ ``Hstar`` series is effective if it is a polynomial in `t` and the
1154
+ coefficient of each `t^i` is an effective character in the ring of
1155
+ class functions of the acting group. A character `\rho` is effective if
1156
+ the coefficients of the irreducible representations in the expression
1157
+ of `\rho` are nonnegative integers.
1158
+
1159
+ INPUT:
1160
+
1161
+ - ``Hstar`` -- a rational function in `t` with coefficients in the ring
1162
+ of class functions
1163
+
1164
+ - ``Hstar_as_lin_comb`` -- vector. The coefficients of the irreducible
1165
+ representations of the acting group in the expression of ``Hstar`` as
1166
+ a linear combination of irreducible representations with coefficients
1167
+ in the field of rational functions in `t`.
1168
+
1169
+ OUTPUT: boolean; whether the ``Hstar`` series is effective
1170
+
1171
+ .. SEEALSO::
1172
+
1173
+ :meth:`Hstar_function`
1174
+
1175
+ EXAMPLES:
1176
+
1177
+ The `H^*` series of the two-dimensional permutahedron under the action
1178
+ of the symmetric group is effective::
1179
+
1180
+ sage: # optional - pynormaliz
1181
+ sage: p3 = polytopes.permutahedron(3, backend='normaliz')
1182
+ sage: G = p3.restricted_automorphism_group(
1183
+ ....: output='permutation')
1184
+ sage: reflection12 = G([(0,2),(1,4),(3,5)])
1185
+ sage: reflection23 = G([(0,1),(2,3),(4,5)])
1186
+ sage: S3 = G.subgroup(gens=[reflection12, reflection23])
1187
+ sage: S3.is_isomorphic(SymmetricGroup(3))
1188
+ True
1189
+ sage: Hstar = p3.Hstar_function(S3)
1190
+ sage: Hlin = p3.Hstar_function(S3,
1191
+ ....: output='Hstar_as_lin_comb')
1192
+ sage: p3.is_effective(Hstar, Hlin)
1193
+ True
1194
+
1195
+ If the `H^*`-series is not polynomial, then it is not effective::
1196
+
1197
+ sage: # optional - pynormaliz
1198
+ sage: P = Polyhedron(vertices=[[0,0,1], [0,0,-1], [1,0,1],
1199
+ ....: [-1,0,-1], [0,1,1],
1200
+ ....: [0,-1,-1], [1,1,1], [-1,-1,-1]],
1201
+ ....: backend='normaliz')
1202
+ sage: G = P.restricted_automorphism_group(
1203
+ ....: output='permutation')
1204
+ sage: H = G.subgroup(gens=[G([(0,2),(1,3),(4,6),(5,7)])])
1205
+ sage: Hstar = P.Hstar_function(H); Hstar
1206
+ (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3
1207
+ + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1)
1208
+ sage: Hstar_lin = P.Hstar_function(H,
1209
+ ....: output='Hstar_as_lin_comb')
1210
+ sage: P.is_effective(Hstar, Hstar_lin)
1211
+ False
1212
+ """
1213
+ if self.is_empty():
1214
+ raise NotImplementedError('empty polyhedra are not supported')
1215
+ if not self.is_compact():
1216
+ raise NotImplementedError('unbounded polyhedra are not supported')
1217
+ if self.backend() == 'normaliz':
1218
+ return self._is_effective_normaliz(Hstar, Hstar_as_lin_comb)
1219
+ else:
1220
+ raise TypeError("the backend of the polyhedron should be 'normaliz'")
1221
+
1222
+ def _is_effective_normaliz(self, Hstar, Hstar_as_lin_comb):
1223
+ r"""
1224
+ Test for the effectiveness of the ``Hstar`` series of this polytope.
1225
+
1226
+ The ``Hstar`` series of the polytope is determined by the action of a
1227
+ subgroup of the polytope's :meth:`restricted_automorphism_group`. The
1228
+ ``Hstar`` series is effective if it is a polynomial in `t` and the
1229
+ coefficient of each `t^i` is an effective character in the ring of
1230
+ class functions of the acting group. A character `\rho` is effective if
1231
+ the coefficients of the irreducible representations in the expression
1232
+ of `\rho` are nonnegative integers.
1233
+
1234
+ INPUT:
1235
+
1236
+ - ``Hstar`` -- a rational function in `t` with coefficients in the ring
1237
+ of class functions
1238
+
1239
+ - ``Hstar_as_lin_comb`` -- vector. The coefficients of the irreducible
1240
+ representations of the acting group in the expression of ``Hstar`` as
1241
+ a linear combination of irreducible representations with coefficients
1242
+ in the field of rational functions in `t`.
1243
+
1244
+ OUTPUT: boolean; whether the ``Hstar`` series is effective
1245
+
1246
+ TESTS::
1247
+
1248
+ sage: p1 = Polyhedron(vertices=[[0], [1/2]])
1249
+ sage: p2 = Polyhedron(vertices=[[0], [1/2]], # optional - pynormaliz
1250
+ ....: backend='normaliz')
1251
+ sage: Hstar = p2.Hstar_function() # optional - pynormaliz
1252
+ sage: Hstarlin = p2.Hstar_function(output='Hstar_as_lin_comb') # optional - pynormaliz
1253
+ sage: p1._is_effective_normaliz(Hstar, Hstarlin) # optional - pynormaliz
1254
+ Traceback (most recent call last):
1255
+ ...
1256
+ TypeError: the backend of the polyhedron should be 'normaliz'
1257
+ """
1258
+ raise TypeError("the backend of the polyhedron should be 'normaliz'")