passagemath-polyhedra 10.6.37__cp314-cp314-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. passagemath_polyhedra/__init__.py +3 -0
  2. passagemath_polyhedra-10.6.37.dist-info/METADATA +367 -0
  3. passagemath_polyhedra-10.6.37.dist-info/METADATA.bak +369 -0
  4. passagemath_polyhedra-10.6.37.dist-info/RECORD +209 -0
  5. passagemath_polyhedra-10.6.37.dist-info/WHEEL +5 -0
  6. passagemath_polyhedra-10.6.37.dist-info/top_level.txt +3 -0
  7. passagemath_polyhedra.libs/libgcc_s-0cd532bd.so.1 +0 -0
  8. passagemath_polyhedra.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  9. passagemath_polyhedra.libs/libgomp-8949ffbe.so.1.0.0 +0 -0
  10. passagemath_polyhedra.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  11. sage/all__sagemath_polyhedra.py +50 -0
  12. sage/game_theory/all.py +8 -0
  13. sage/game_theory/catalog.py +6 -0
  14. sage/game_theory/catalog_normal_form_games.py +923 -0
  15. sage/game_theory/cooperative_game.py +844 -0
  16. sage/game_theory/matching_game.py +1181 -0
  17. sage/game_theory/normal_form_game.py +2697 -0
  18. sage/game_theory/parser.py +275 -0
  19. sage/geometry/all__sagemath_polyhedra.py +22 -0
  20. sage/geometry/cone.py +6940 -0
  21. sage/geometry/cone_catalog.py +847 -0
  22. sage/geometry/cone_critical_angles.py +1027 -0
  23. sage/geometry/convex_set.py +1119 -0
  24. sage/geometry/fan.py +3743 -0
  25. sage/geometry/fan_isomorphism.py +389 -0
  26. sage/geometry/fan_morphism.py +1884 -0
  27. sage/geometry/hasse_diagram.py +202 -0
  28. sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
  29. sage/geometry/hyperplane_arrangement/all.py +1 -0
  30. sage/geometry/hyperplane_arrangement/arrangement.py +3905 -0
  31. sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
  32. sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
  33. sage/geometry/hyperplane_arrangement/library.py +825 -0
  34. sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
  35. sage/geometry/hyperplane_arrangement/plot.py +520 -0
  36. sage/geometry/integral_points.py +35 -0
  37. sage/geometry/integral_points_generic_dense.cpython-314-x86_64-linux-musl.so +0 -0
  38. sage/geometry/integral_points_generic_dense.pyx +7 -0
  39. sage/geometry/lattice_polytope.py +5894 -0
  40. sage/geometry/linear_expression.py +773 -0
  41. sage/geometry/newton_polygon.py +767 -0
  42. sage/geometry/point_collection.cpython-314-x86_64-linux-musl.so +0 -0
  43. sage/geometry/point_collection.pyx +1008 -0
  44. sage/geometry/polyhedral_complex.py +2616 -0
  45. sage/geometry/polyhedron/all.py +8 -0
  46. sage/geometry/polyhedron/backend_cdd.py +460 -0
  47. sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
  48. sage/geometry/polyhedron/backend_field.py +347 -0
  49. sage/geometry/polyhedron/backend_normaliz.py +2503 -0
  50. sage/geometry/polyhedron/backend_number_field.py +168 -0
  51. sage/geometry/polyhedron/backend_polymake.py +765 -0
  52. sage/geometry/polyhedron/backend_ppl.py +582 -0
  53. sage/geometry/polyhedron/base.py +1206 -0
  54. sage/geometry/polyhedron/base0.py +1444 -0
  55. sage/geometry/polyhedron/base1.py +886 -0
  56. sage/geometry/polyhedron/base2.py +812 -0
  57. sage/geometry/polyhedron/base3.py +1845 -0
  58. sage/geometry/polyhedron/base4.py +1262 -0
  59. sage/geometry/polyhedron/base5.py +2700 -0
  60. sage/geometry/polyhedron/base6.py +1741 -0
  61. sage/geometry/polyhedron/base7.py +997 -0
  62. sage/geometry/polyhedron/base_QQ.py +1258 -0
  63. sage/geometry/polyhedron/base_RDF.py +98 -0
  64. sage/geometry/polyhedron/base_ZZ.py +934 -0
  65. sage/geometry/polyhedron/base_mutable.py +215 -0
  66. sage/geometry/polyhedron/base_number_field.py +122 -0
  67. sage/geometry/polyhedron/cdd_file_format.py +155 -0
  68. sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
  69. sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-x86_64-linux-musl.so +0 -0
  70. sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
  71. sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
  72. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-x86_64-linux-musl.so +0 -0
  73. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
  74. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
  75. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-x86_64-linux-musl.so +0 -0
  76. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
  77. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
  78. sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
  79. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  80. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
  81. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
  82. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-x86_64-linux-musl.so +0 -0
  83. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
  84. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
  85. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-x86_64-linux-musl.so +0 -0
  86. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
  87. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
  88. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-x86_64-linux-musl.so +0 -0
  89. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
  90. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
  91. sage/geometry/polyhedron/constructor.py +773 -0
  92. sage/geometry/polyhedron/double_description.py +753 -0
  93. sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
  94. sage/geometry/polyhedron/face.py +1060 -0
  95. sage/geometry/polyhedron/generating_function.py +1810 -0
  96. sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
  97. sage/geometry/polyhedron/library.py +3502 -0
  98. sage/geometry/polyhedron/misc.py +121 -0
  99. sage/geometry/polyhedron/modules/all.py +1 -0
  100. sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
  101. sage/geometry/polyhedron/palp_database.py +447 -0
  102. sage/geometry/polyhedron/parent.py +1279 -0
  103. sage/geometry/polyhedron/plot.py +1986 -0
  104. sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
  105. sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
  106. sage/geometry/polyhedron/representation.py +1723 -0
  107. sage/geometry/pseudolines.py +515 -0
  108. sage/geometry/relative_interior.py +445 -0
  109. sage/geometry/toric_plotter.py +1103 -0
  110. sage/geometry/triangulation/all.py +2 -0
  111. sage/geometry/triangulation/base.cpython-314-x86_64-linux-musl.so +0 -0
  112. sage/geometry/triangulation/base.pyx +963 -0
  113. sage/geometry/triangulation/data.h +147 -0
  114. sage/geometry/triangulation/data.pxd +4 -0
  115. sage/geometry/triangulation/element.py +914 -0
  116. sage/geometry/triangulation/functions.h +10 -0
  117. sage/geometry/triangulation/functions.pxd +4 -0
  118. sage/geometry/triangulation/point_configuration.py +2256 -0
  119. sage/geometry/triangulation/triangulations.h +49 -0
  120. sage/geometry/triangulation/triangulations.pxd +7 -0
  121. sage/geometry/voronoi_diagram.py +319 -0
  122. sage/interfaces/all__sagemath_polyhedra.py +1 -0
  123. sage/interfaces/polymake.py +2028 -0
  124. sage/numerical/all.py +13 -0
  125. sage/numerical/all__sagemath_polyhedra.py +11 -0
  126. sage/numerical/backends/all.py +1 -0
  127. sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
  128. sage/numerical/backends/cvxopt_backend.cpython-314-x86_64-linux-musl.so +0 -0
  129. sage/numerical/backends/cvxopt_backend.pyx +1006 -0
  130. sage/numerical/backends/cvxopt_backend_test.py +19 -0
  131. sage/numerical/backends/cvxopt_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  132. sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
  133. sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/numerical/backends/cvxpy_backend.pxd +41 -0
  135. sage/numerical/backends/cvxpy_backend.pyx +934 -0
  136. sage/numerical/backends/cvxpy_backend_test.py +13 -0
  137. sage/numerical/backends/generic_backend_test.py +24 -0
  138. sage/numerical/backends/interactivelp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/numerical/backends/interactivelp_backend.pxd +36 -0
  140. sage/numerical/backends/interactivelp_backend.pyx +1231 -0
  141. sage/numerical/backends/interactivelp_backend_test.py +12 -0
  142. sage/numerical/backends/logging_backend.py +391 -0
  143. sage/numerical/backends/matrix_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
  144. sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
  145. sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
  146. sage/numerical/backends/ppl_backend.cpython-314-x86_64-linux-musl.so +0 -0
  147. sage/numerical/backends/ppl_backend.pyx +1126 -0
  148. sage/numerical/backends/ppl_backend_test.py +13 -0
  149. sage/numerical/backends/scip_backend.cpython-314-x86_64-linux-musl.so +0 -0
  150. sage/numerical/backends/scip_backend.pxd +22 -0
  151. sage/numerical/backends/scip_backend.pyx +1289 -0
  152. sage/numerical/backends/scip_backend_test.py +13 -0
  153. sage/numerical/interactive_simplex_method.py +5338 -0
  154. sage/numerical/knapsack.py +665 -0
  155. sage/numerical/linear_functions.cpython-314-x86_64-linux-musl.so +0 -0
  156. sage/numerical/linear_functions.pxd +31 -0
  157. sage/numerical/linear_functions.pyx +1648 -0
  158. sage/numerical/linear_tensor.py +470 -0
  159. sage/numerical/linear_tensor_constraints.py +448 -0
  160. sage/numerical/linear_tensor_element.cpython-314-x86_64-linux-musl.so +0 -0
  161. sage/numerical/linear_tensor_element.pxd +6 -0
  162. sage/numerical/linear_tensor_element.pyx +459 -0
  163. sage/numerical/mip.cpython-314-x86_64-linux-musl.so +0 -0
  164. sage/numerical/mip.pxd +40 -0
  165. sage/numerical/mip.pyx +3667 -0
  166. sage/numerical/sdp.cpython-314-x86_64-linux-musl.so +0 -0
  167. sage/numerical/sdp.pxd +39 -0
  168. sage/numerical/sdp.pyx +1433 -0
  169. sage/rings/all__sagemath_polyhedra.py +3 -0
  170. sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
  171. sage/rings/polynomial/omega.py +982 -0
  172. sage/schemes/all__sagemath_polyhedra.py +2 -0
  173. sage/schemes/toric/all.py +10 -0
  174. sage/schemes/toric/chow_group.py +1248 -0
  175. sage/schemes/toric/divisor.py +2082 -0
  176. sage/schemes/toric/divisor_class.cpython-314-x86_64-linux-musl.so +0 -0
  177. sage/schemes/toric/divisor_class.pyx +322 -0
  178. sage/schemes/toric/fano_variety.py +1606 -0
  179. sage/schemes/toric/homset.py +650 -0
  180. sage/schemes/toric/ideal.py +451 -0
  181. sage/schemes/toric/library.py +1322 -0
  182. sage/schemes/toric/morphism.py +1958 -0
  183. sage/schemes/toric/points.py +1032 -0
  184. sage/schemes/toric/sheaf/all.py +1 -0
  185. sage/schemes/toric/sheaf/constructor.py +302 -0
  186. sage/schemes/toric/sheaf/klyachko.py +921 -0
  187. sage/schemes/toric/toric_subscheme.py +905 -0
  188. sage/schemes/toric/variety.py +3460 -0
  189. sage/schemes/toric/weierstrass.py +1078 -0
  190. sage/schemes/toric/weierstrass_covering.py +457 -0
  191. sage/schemes/toric/weierstrass_higher.py +288 -0
  192. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
  193. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
  194. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
  195. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
  196. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
  197. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
  198. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
  199. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
  200. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
  201. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
  202. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
  203. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
  204. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
  205. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
  206. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
  207. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
  208. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
  209. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
@@ -0,0 +1,2028 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ r"""
3
+ Interface to polymake
4
+
5
+ polymake (https://polymake.org) is a mature open source package for
6
+ research in polyhedral geometry and related fields, developed since 1997
7
+ by Ewgenij Gawrilow and Michael Joswig and various contributors.
8
+
9
+ polymake has been described in [GJ1997]_, [GJ2006]_, [JMP2009]_, [GJRW2010]_,
10
+ [GHJ2016]_, and [AGHJLPR2017]_.
11
+ """
12
+
13
+
14
+ # ****************************************************************************
15
+ # Copyright (C) 2017 Simon King <simon.king@uni-jena.de>
16
+ #
17
+ # Distributed under the terms of the GNU General Public License (GPL)
18
+ #
19
+ # This code is distributed in the hope that it will be useful,
20
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22
+ # General Public License for more details.
23
+ #
24
+ # The full text of the GPL is available at:
25
+ #
26
+ # https://www.gnu.org/licenses/
27
+ # ****************************************************************************
28
+
29
+ import os
30
+ import re
31
+
32
+ from .interface import (Interface, InterfaceElement, InterfaceFunctionElement)
33
+ from sage.misc.verbose import get_verbose
34
+ from sage.misc.cachefunc import cached_method
35
+ from sage.interfaces.tab_completion import ExtraTabCompletion
36
+ from sage.structure.richcmp import rich_to_bool
37
+
38
+ _name_pattern = re.compile('SAGE[0-9]+')
39
+
40
+ _available_polymake_answers = {
41
+ 0: "returns prompt",
42
+ 1: "returns continuation prompt",
43
+ 2: "requests interactive input",
44
+ 3: "kills computation",
45
+ 4: "raises error",
46
+ 5: "issues warning",
47
+ 6: "shows additional information",
48
+ 7: "lost connection",
49
+ 8: "fails to respond timely"
50
+ }
51
+
52
+
53
+ class PolymakeError(RuntimeError):
54
+ """
55
+ Raised if polymake yields an error message.
56
+
57
+ TESTS::
58
+
59
+ sage: polymake.eval('print foo;') # optional - jupymake
60
+ Traceback (most recent call last):
61
+ ...
62
+ PolymakeError: Unquoted string "foo" may clash with future reserved word...
63
+ """
64
+ pass
65
+
66
+
67
+ def polymake_console(command=''):
68
+ """
69
+ Spawn a new polymake command-line session.
70
+
71
+ EXAMPLES::
72
+
73
+ sage: from sage.interfaces.polymake import polymake_console
74
+ sage: polymake_console() # not tested
75
+ Welcome to polymake version ...
76
+ ...
77
+ Ewgenij Gawrilow, Michael Joswig (TU Berlin)
78
+ http://www.polymake.org
79
+
80
+ This is free software licensed under GPL; see the source for copying conditions.
81
+ There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
82
+
83
+ Press F1 or enter 'help;' for basic instructions.
84
+
85
+ Application polytope currently uses following third-party software packages:
86
+ 4ti2, bliss, cdd, latte, libnormaliz, lrs, permlib, ppl, sketch, sympol, threejs, tikz, topcom, tosimplex
87
+ For more details: show_credits;
88
+ polytope >
89
+ """
90
+ from sage.repl.rich_output.display_manager import get_display_manager
91
+ if not get_display_manager().is_in_terminal():
92
+ raise RuntimeError('Can use the console only in the terminal. Try %%polymake magics instead.')
93
+ os.system(command or os.getenv('SAGE_POLYMAKE_COMMAND') or 'polymake')
94
+
95
+
96
+ class PolymakeAbstract(ExtraTabCompletion, Interface):
97
+ r"""
98
+ Abstract interface to the polymake interpreter.
99
+
100
+ This class should not be instantiated directly,
101
+ but through its subclasses Polymake (Pexpect interface)
102
+ or PolymakeJuPyMake (JuPyMake interface).
103
+
104
+ EXAMPLES::
105
+
106
+ sage: from sage.interfaces.polymake import PolymakeAbstract, polymake_jupymake
107
+
108
+ We test the verbosity management with very early doctests
109
+ because messages will not be repeated.
110
+
111
+ Testing the JuPyMake interface::
112
+
113
+ sage: isinstance(polymake_jupymake, PolymakeAbstract)
114
+ True
115
+ sage: p = polymake_jupymake.rand_sphere(4, 20, seed=5) # optional - jupymake
116
+ sage: p # optional - jupymake
117
+ Random spherical polytope of dimension 4; seed=5...
118
+ sage: set_verbose(3)
119
+ sage: p.H_VECTOR # optional - jupymake
120
+ polymake: used package ppl
121
+ The Parma Polyhedra Library ...
122
+ 1 16 40 16 1
123
+ sage: set_verbose(0)
124
+ sage: p.F_VECTOR # optional - jupymake
125
+ 20 94 148 74
126
+ """
127
+ def __init__(self, seed=None):
128
+ """
129
+ TESTS::
130
+
131
+ sage: from sage.interfaces.polymake import PolymakeAbstract
132
+ sage: PolymakeAbstract()
133
+ Polymake
134
+ """
135
+ Interface.__init__(self, "polymake")
136
+ self._seed = seed
137
+ self.__tab_completion = {}
138
+
139
+ @cached_method
140
+ def version(self):
141
+ """
142
+ Version of the polymake installation.
143
+
144
+ EXAMPLES::
145
+
146
+ sage: polymake.version() # optional - jupymake # random
147
+ '4...'
148
+ """
149
+ return self.get('$Polymake::Version')
150
+
151
+ # Pickling, etc.
152
+
153
+ def __reduce__(self):
154
+ """
155
+ EXAMPLES::
156
+
157
+ sage: from sage.interfaces.polymake import polymake
158
+ sage: loads(dumps(polymake)) is polymake
159
+ True
160
+ """
161
+ return reduce_load_Polymake, ()
162
+
163
+ def _object_class(self):
164
+ """
165
+ Return the class by which elements in this interface are implemented.
166
+
167
+ TESTS::
168
+
169
+ sage: C = polymake('cube(3)') # indirect doctest # optional - jupymake
170
+ sage: C # optional - jupymake
171
+ cube of dimension 3
172
+ sage: type(C) # optional - jupymake
173
+ <class 'sage.interfaces.polymake.PolymakeElement'>
174
+ """
175
+ return PolymakeElement
176
+
177
+ def _function_element_class(self):
178
+ """
179
+ Return the class by which member functions of this interface are implemented.
180
+
181
+ TESTS:
182
+
183
+ We use ellipses in the tests, to make it more robust against future
184
+ changes in polymake::
185
+
186
+ sage: p = polymake.rand_sphere(4, 20, seed=5) # optional - jupymake
187
+ sage: p.get_schedule # optional - jupymake # indirect doctest
188
+ Member function 'get_schedule' of Polymake::polytope::Polytope__Rational object
189
+ sage: p.get_schedule('"F_VECTOR"') # optional - jupymake # random
190
+ CONE_DIM : RAYS | INPUT_RAYS
191
+ precondition : BOUNDED ( POINTED : )
192
+ POINTED :
193
+ N_INPUT_RAYS : INPUT_RAYS
194
+ precondition : N_RAYS | N_INPUT_RAYS ( ppl.convex_hull.primal: FACETS, LINEAR_SPAN : RAYS | INPUT_RAYS )
195
+ sensitivity check for FacetPerm
196
+ ppl.convex_hull.primal: FACETS, LINEAR_SPAN : RAYS | INPUT_RAYS
197
+ INPUT_RAYS_IN_FACETS : INPUT_RAYS, FACETS
198
+ sensitivity check for VertexPerm
199
+ RAYS_IN_FACETS, RAYS, LINEALITY_SPACE : INPUT_RAYS_IN_FACETS, INPUT_RAYS
200
+ GRAPH.ADJACENCY : RAYS_IN_FACETS
201
+ DUAL_GRAPH.ADJACENCY : RAYS_IN_FACETS
202
+ N_EDGES : ADJACENCY ( applied to GRAPH )
203
+ N_EDGES : ADJACENCY ( applied to DUAL_GRAPH )
204
+ precondition : POINTED ( LINEALITY_DIM, LINEALITY_SPACE : )
205
+ LINEALITY_DIM, LINEALITY_SPACE :
206
+ COMBINATORIAL_DIM : CONE_DIM, LINEALITY_DIM
207
+ N_RAYS : RAYS
208
+ N_FACETS : FACETS
209
+ precondition : COMBINATORIAL_DIM ( F_VECTOR : N_FACETS, N_RAYS, GRAPH.N_EDGES, DUAL_GRAPH.N_EDGES, COMBINATORIAL_DIM )
210
+ F_VECTOR : N_FACETS, N_RAYS, GRAPH.N_EDGES, DUAL_GRAPH.N_EDGES, COMBINATORIAL_DIM
211
+ """
212
+ return PolymakeFunctionElement
213
+
214
+ def function_call(self, function, args=None, kwds=None):
215
+ """
216
+ EXAMPLES::
217
+
218
+ sage: polymake.rand_sphere(4, 30, seed=15) # optional - jupymake # indirect doctest
219
+ Random spherical polytope of dimension 4; seed=15...
220
+ """
221
+ args, kwds = self._convert_args_kwds(args, kwds)
222
+ self._check_valid_function_name(function)
223
+ s = self._function_call_string(function,
224
+ [s.name() for s in args],
225
+ ['{}=>{}'.format(key, value.name()) for key, value in kwds.items()])
226
+ return self(s)
227
+
228
+ def _function_call_string(self, function, args, kwds):
229
+ """
230
+ Return the string used to make function calls.
231
+
232
+ EXAMPLES::
233
+
234
+ sage: # optional - jupymake
235
+ sage: polymake._function_call_string('cube', ['2','7','3'], ['group=>1'])
236
+ 'cube(2,7,3, group=>1);'
237
+ sage: c = polymake('cube(2,7,3, group=>1)')
238
+ sage: c.VERTICES
239
+ 1 3 3
240
+ 1 7 3
241
+ 1 3 7
242
+ 1 7 7
243
+ sage: c.GROUP
244
+ full combinatorial group
245
+ """
246
+ if kwds:
247
+ if args:
248
+ call_str = "{}({}, {});".format(function, ",".join(list(args)), ",".join(list(kwds)))
249
+ return call_str
250
+ return "{}({});".format(function, ",".join(list(kwds)))
251
+ return "{}({});".format(function, ",".join(list(args)))
252
+
253
+ def _coerce_impl(self, x, use_special=True):
254
+ """
255
+ Implementation of coercion.
256
+
257
+ TESTS:
258
+
259
+ Test that dictionaries are converted to hashes::
260
+
261
+ sage: h = polymake({'"a"': 1, '"b"': 2}) # optional - jupymake
262
+ sage: h # optional - jupymake
263
+ HASH(0x...)
264
+ sage: h['"a"'] # optional - jupymake
265
+ 1
266
+ """
267
+ if isinstance(x, dict):
268
+ # Convert dictionaries to hashes.
269
+ # This is an adaptation of the list/tuple code from Interface._coerce_impl
270
+ A = []
271
+ z = {}
272
+ cls = self._object_class()
273
+
274
+ def convert(y):
275
+ return y if isinstance(y, cls) else self(y)
276
+
277
+ for k, v in x.items():
278
+ k = convert(k)
279
+ v = convert(v)
280
+ z[k] = v
281
+ A.append(f"{k.name()}=>{v.name()}")
282
+ r = self.new("{" + ",".join(A) + "}")
283
+
284
+ # this to avoid having the entries of the list be garbage collected
285
+ r.__sage_dict = z
286
+ return r
287
+
288
+ import sage.rings.abc
289
+ from sage.rings.integer import Integer
290
+ from sage.rings.rational import Rational
291
+ from sage.rings.real_double import RDF
292
+
293
+ def to_str(x):
294
+ if isinstance(x, list):
295
+ s = '['
296
+ for y in x:
297
+ s += to_str(y) + ', '
298
+ s += ']'
299
+ return s
300
+ if isinstance(x, (Integer, Rational, int)):
301
+ return '{}'.format(x)
302
+ parent = None
303
+ try:
304
+ parent = x.parent()
305
+ except AttributeError:
306
+ pass
307
+
308
+ if isinstance(parent, sage.rings.abc.NumberField_quadratic):
309
+ return x._polymake_init_()
310
+ try:
311
+ if x.parent().is_exact():
312
+ # No other exact rings are supported.
313
+ raise NotImplementedError
314
+ except AttributeError:
315
+ pass
316
+
317
+ try:
318
+ x = RDF(x)
319
+ return '{}'.format(x)
320
+ except (TypeError, ValueError):
321
+ pass
322
+
323
+ raise NotImplementedError
324
+
325
+ # Iteratively calling polymake for conversion takes a long time.
326
+ # However, it takes iterated arrays of integers, rationals and floats directly.
327
+ try:
328
+ return self.new(to_str(x))
329
+ except NotImplementedError:
330
+ pass
331
+
332
+ return super()._coerce_impl(x, use_special=use_special)
333
+
334
+ def console(self):
335
+ """
336
+ Raise an error, pointing to :meth:`~sage.interfaces.interface.Interface.interact` and :func:`polymake_console`.
337
+
338
+ EXAMPLES::
339
+
340
+ sage: polymake.console()
341
+ Traceback (most recent call last):
342
+ ...
343
+ NotImplementedError: Please use polymake_console() function or the .interact() method
344
+ """
345
+ raise NotImplementedError("Please use polymake_console() function or the .interact() method")
346
+
347
+ # Methods concerning interface communication
348
+
349
+ def _install_hints(self):
350
+ """
351
+ TESTS::
352
+
353
+ sage: print(polymake._install_hints())
354
+ Please install the optional polymake package for sage
355
+ or install polymake system-wide
356
+ (use the shell command 'sage --info polymake' for more information)
357
+ """
358
+ return "Please install the optional polymake package for sage" + os.linesep + "or install polymake system-wide" + os.linesep + "(use the shell command 'sage --info polymake' for more information)"
359
+
360
+ def _start(self):
361
+ """
362
+ Start the polymake interface in the application "polytope".
363
+
364
+ .. NOTE::
365
+
366
+ There should be no need to call this explicitly.
367
+
368
+ TESTS::
369
+
370
+ sage: polymake._start() # optional - jupymake
371
+
372
+ Since 'normal_fan' is not defined in the polymake application 'polytope',
373
+ we now get
374
+ ::
375
+
376
+ sage: 'normal_fan' in dir(polymake) # optional - jupymake
377
+ False
378
+ """
379
+ self.application("polytope")
380
+ self.eval('use Scalar::Util qw(reftype);')
381
+ self.eval('use Scalar::Util qw(blessed);')
382
+
383
+ def _assign_symbol(self):
384
+ """
385
+ TESTS::
386
+
387
+ sage: polymake._assign_symbol()
388
+ '='
389
+ """
390
+ return "="
391
+
392
+ def _equality_symbol(self):
393
+ """
394
+ TESTS::
395
+
396
+ sage: polymake._equality_symbol()
397
+ '=='
398
+ """
399
+ return "=="
400
+
401
+ def _read_in_file_command(self, filename):
402
+ r"""
403
+ TESTS::
404
+
405
+ sage: polymake._read_in_file_command('foobar')
406
+ 'eval read_file "foobar";\n'
407
+
408
+ Force use of file::
409
+
410
+ sage: L = polymake([42] * 400) # optional - jupymake
411
+ sage: len(L) # optional - jupymake
412
+ 400
413
+
414
+ Just below standard file cutoff of 1024::
415
+
416
+ sage: L = polymake([42] * 84) # optional - jupymake
417
+ sage: len(L) # optional - jupymake
418
+ 84
419
+ """
420
+ return 'eval read_file "{}";\n'.format(filename)
421
+
422
+ def _next_var_name(self):
423
+ r"""
424
+ Return the next unused variable name.
425
+
426
+ TESTS::
427
+
428
+ sage: print(polymake._next_var_name())
429
+ SAGE...
430
+ """
431
+ if self._available_vars:
432
+ return self._available_vars.pop(0)
433
+ try:
434
+ self.__seq += 1
435
+ except AttributeError:
436
+ self.__seq = 0
437
+ return r'SAGE{}'.format(self.__seq)
438
+
439
+ def clear(self, var):
440
+ r"""
441
+ Clear the variable named ``var``.
442
+
443
+ .. NOTE::
444
+
445
+ This is implicitly done when deleting an element in the interface.
446
+
447
+ TESTS::
448
+
449
+ sage: # optional - jupymake
450
+ sage: c = polymake.cube(15)
451
+ sage: polymake._available_vars = []
452
+ sage: old = c._name
453
+ sage: del c
454
+ sage: len(polymake._available_vars)
455
+ 1
456
+ sage: polymake._next_var_name() in old
457
+ True
458
+ """
459
+ self._available_vars.append(_name_pattern.search(var).group())
460
+
461
+ def _create(self, value, name=None):
462
+ """
463
+ Assign a value to a name in the polymake interface.
464
+
465
+ INPUT:
466
+
467
+ - ``value`` -- string; Polymake command (or value) whose result
468
+ is to be assigned to a variable
469
+ - ``name`` -- (optional) string; if given, the new variable has this
470
+ name; otherwise, the name is automatically generated
471
+
472
+ RETURN:
473
+
474
+ The command by which the assigned value can now be retrieved.
475
+
476
+ .. NOTE::
477
+
478
+ In order to overcome problems with the perl programming language,
479
+ we store *all* data as arrays. If the given value is an array
480
+ of length different from one, then the new variable contains that
481
+ array. Otherwise, the new variable is an array of length one whose
482
+ only entry is the given value, which has to be a scalar (which
483
+ also includes Perl references). In other words, perl hashes
484
+ are not suitable.
485
+
486
+ EXAMPLES::
487
+
488
+ sage: # optional - jupymake
489
+ sage: polymake._create("('foo', 'bar')", name='my_array')
490
+ '@my_array'
491
+ sage: print(polymake.eval('print join(", ", @my_array);'))
492
+ foo, bar
493
+ sage: polymake._create('"foobar"', name='my_string')
494
+ '$my_string[0]'
495
+ sage: print(polymake.eval('print $my_string[0];'))
496
+ foobar
497
+ """
498
+ name = self._next_var_name() if name is None else name
499
+ self.set(name, value)
500
+ # If value is a list, then @name is now equal to that list.
501
+ # Otherwise, value is obtained by $name[0]. So, we modify
502
+ # the name returned by _create so that it can be used to
503
+ # access the wrapped value.
504
+ if self.eval('print scalar @{};'.format(name)).strip() == '1':
505
+ return '$'+name+'[0]'
506
+ return '@'+name
507
+
508
+ def set(self, var, value):
509
+ """
510
+ Set the variable var to the given value.
511
+
512
+ Eventually, ``var`` is a reference to ``value``.
513
+
514
+ .. WARNING::
515
+
516
+ This method, although it doesn't start with an underscore, is
517
+ an internal method and not part of the interface. So, please do
518
+ not try to call it explicitly. Instead, use the polymake interface
519
+ as shown in the examples.
520
+
521
+ REMARK:
522
+
523
+ Polymake's user language is Perl. In Perl, if one wants to assign
524
+ the return value of a function to a variable, the syntax to do so
525
+ depends on the type of the return value. While this is fine in
526
+ compiled code, it seems quite awkward in user interaction.
527
+
528
+ To make this polymake pexpect interface a bit more user friendly,
529
+ we treat *all* variables as arrays. A scalar value (most typically
530
+ a reference) is thus interpreted as the only item in an array of
531
+ length one. It is, of course, possible to use the interface without
532
+ knowing these details.
533
+
534
+ EXAMPLES::
535
+
536
+ sage: c = polymake('cube(3)') # optional - jupymake # indirect doctest
537
+ sage: d = polymake.cube(3) # optional - jupymake
538
+
539
+ Equality is, for "big" objects such as polytopes, comparison by
540
+ identity::
541
+
542
+ sage: c == d # optional - jupymake
543
+ False
544
+
545
+ However, the list of vertices is equal::
546
+
547
+ sage: c.VERTICES == d.VERTICES # optional - jupymake
548
+ True
549
+
550
+ TESTS:
551
+
552
+ The following shows how polymake variables are wrapped in our interface.
553
+ It should, however, **never** be needed to do the following
554
+ *explicitly*::
555
+
556
+ sage: polymake.set('myvar', 'cube(3)') # optional - jupymake
557
+ sage: polymake.get('$myvar[0]') # optional - jupymake
558
+ 'Polymake::polytope::Polytope__Rational=ARRAY(...)'
559
+
560
+ The following tests against :issue:`22658`::
561
+
562
+ sage: P = polymake.new_object("Polytope", FACETS=[[12, -2, -3, -5, -8, -13, -21, -34, -55], # optional - jupymake
563
+ ....: [0, 1, 0, 0, 0, 0, 0, 0, 0],
564
+ ....: [0, 0, 0, 0, 0, 0, 0, 0, 1],
565
+ ....: [0, 0, 0, 0, 0, 0, 0, 1, 0],
566
+ ....: [0, 0, 0, 0, 0, 0, 1, 0, 0],
567
+ ....: [0, 0, 0, 0, 0, 1, 0, 0, 0],
568
+ ....: [0, 0, 0, 0, 1, 0, 0, 0, 0],
569
+ ....: [0, 0, 0, 1, 0, 0, 0, 0, 0],
570
+ ....: [0, 0, 1, 0, 0, 0, 0, 0, 0]])
571
+ sage: P.VERTICES # optional - jupymake
572
+ 1 6 0 0 0 0 0 0 0
573
+ 1 0 4 0 0 0 0 0 0
574
+ 1 0 0 0 0 0 0 0 0
575
+ 1 0 0 12/5 0 0 0 0 0
576
+ 1 0 0 0 0 0 0 0 12/55
577
+ 1 0 0 0 0 0 0 6/17 0
578
+ 1 0 0 0 0 0 4/7 0 0
579
+ 1 0 0 0 0 12/13 0 0 0
580
+ 1 0 0 0 3/2 0 0 0 0
581
+ sage: P.F_VECTOR # optional - jupymake
582
+ 9 36 84 126 126 84 36 9
583
+ """
584
+ if isinstance(value, str):
585
+ value = value.strip().rstrip(';').strip()
586
+ cmd = "@{}{}({});".format(var, self._assign_symbol(), value)
587
+ self.eval(cmd)
588
+
589
+ def get(self, cmd):
590
+ """
591
+ Return the string representation of an object in the polymake interface.
592
+
593
+ EXAMPLES::
594
+
595
+ sage: polymake.get('cube(3)') # optional - jupymake
596
+ 'Polymake::polytope::Polytope__Rational=ARRAY(...)'
597
+
598
+ Note that the above string representation is what polymake provides.
599
+ In our interface, we use what polymake calls a "description"::
600
+
601
+ sage: polymake('cube(3)') # optional - jupymake
602
+ cube of dimension 3
603
+ """
604
+ return self.eval("print {};".format(cmd)).strip()
605
+
606
+ def help(self, topic, pager=True):
607
+ """
608
+ Displays polymake's help on a given topic, as a string.
609
+
610
+ INPUT:
611
+
612
+ - ``topic`` -- string
613
+ - ``pager`` -- boolean (default: ``True``); when ``True``, display
614
+ help, otherwise return as a string
615
+
616
+ EXAMPLES::
617
+
618
+ sage: print(polymake.help('Polytope', pager=False)) # optional - jupymake # random
619
+ objects/Polytope:
620
+ Not necessarily bounded or unbounded polyhedron.
621
+ Nonetheless, the name "Polytope" is used for two reasons:
622
+ Firstly, combinatorially we always deal with polytopes; see the description of VERTICES_IN_FACETS for details.
623
+ The second reason is historical.
624
+ We use homogeneous coordinates, which is why Polytope is derived from Cone.
625
+ Note that a pointed polyhedron is projectively equivalent to a polytope.
626
+ Scalar is the numeric data type used for the coordinates.
627
+
628
+ In some cases, polymake expects user interaction to choose from
629
+ different available help topics. In these cases, a warning is given,
630
+ and the available help topics are displayed resp. printed, without
631
+ user interaction::
632
+
633
+ sage: polymake.help('TRIANGULATION') # optional - jupymake # random
634
+ doctest:warning
635
+ ...
636
+ UserWarning: Polymake expects user interaction. We abort and return the options that Polymake provides.
637
+ There are 5 help topics matching 'TRIANGULATION':
638
+ 1: objects/Visualization/Visual::Polytope/methods/TRIANGULATION
639
+ 2: objects/Visualization/Visual::PointConfiguration/methods/TRIANGULATION
640
+ 3: objects/Cone/properties/Triangulation and volume/TRIANGULATION
641
+ 4: objects/PointConfiguration/properties/Triangulation and volume/TRIANGULATION
642
+ 5: objects/Polytope/properties/Triangulation and volume/TRIANGULATION
643
+
644
+ If an unknown help topic is requested, a :exc:`PolymakeError`
645
+ results::
646
+
647
+ sage: polymake.help('Triangulation') # optional - jupymake
648
+ Traceback (most recent call last):
649
+ ...
650
+ PolymakeError: unknown help topic 'Triangulation'
651
+ """
652
+ H = self.eval('help("{}");\n'.format(topic))
653
+ if not H:
654
+ raise PolymakeError("unknown help topic '{}'".format(topic))
655
+ if pager:
656
+ from IPython.core.page import page
657
+ page(H, start=0)
658
+ else:
659
+ return H
660
+
661
+ def _tab_completion(self):
662
+ r"""
663
+ Return a list of polymake function names.
664
+
665
+ ..NOTE::
666
+
667
+ - The list of functions depends on the current application. The
668
+ result is cached, of course separately for each application.
669
+ - It is generally not the case that all the returned function
670
+ names can actually successfully be called.
671
+
672
+ TESTS::
673
+
674
+ sage: polymake.application('fan') # optional - jupymake
675
+ sage: 'normal_fan' in dir(polymake) # optional - jupymake # indirect doctest
676
+ True
677
+ sage: polymake.application('polytope') # optional - jupymake
678
+
679
+ Since ``'normal_fan'`` is not defined in the polymake application
680
+ ``'polytope'``, we now get::
681
+
682
+ sage: 'normal_fan' in dir(polymake) # optional - jupymake
683
+ False
684
+
685
+ Global functions from ``'core'`` are available::
686
+
687
+ sage: 'show_credits' in dir(polymake) # optional - jupymake
688
+ True
689
+
690
+ Global functions from ``'common'`` are available::
691
+
692
+ sage: 'lex_ordered' in dir(polymake) # optional - jupymake
693
+ True
694
+ """
695
+ if not self.is_running():
696
+ self._start()
697
+ try:
698
+ return self.__tab_completion[self._application]
699
+ except KeyError:
700
+ pass
701
+ s = self.eval("apropos '';").split('\n')
702
+ out = []
703
+ for name in s:
704
+ if (name.startswith("/common/functions/")
705
+ or name.startswith("/core/functions")
706
+ or name.startswith("/" + self._application + "/functions/")):
707
+ out.append(name.split("/")[-1])
708
+ self.__tab_completion[self._application] = sorted(out)
709
+ return self.__tab_completion[self._application]
710
+
711
+ # Polymake specific methods
712
+
713
+ def application(self, app):
714
+ """
715
+ Change to a given polymake application.
716
+
717
+ INPUT:
718
+
719
+ - ``app`` -- string; one of ``'common'``, ``'fulton'``, ``'group'``,
720
+ ``'matroid'``, ``'topaz'``, ``'fan'``, ``'graph'``, ``'ideal'``,
721
+ ``'polytope'``, ``'tropical'``
722
+
723
+ EXAMPLES:
724
+
725
+ We expose a computation that uses both the 'polytope' and the 'fan'
726
+ application of polymake. Let us start by defining a polytope `q` in
727
+ terms of inequalities. Polymake knows to compute the f- and h-vector
728
+ and finds that the polytope is very ample::
729
+
730
+ sage: # optional - jupymake
731
+ sage: q = polymake.new_object("Polytope", INEQUALITIES=[[5,-4,0,1],[-3,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1],[1,0,-1,0],[3,-1,0,0]])
732
+ sage: q.H_VECTOR
733
+ 1 5 5 1
734
+ sage: q.F_VECTOR
735
+ 8 14 8
736
+ sage: q.VERY_AMPLE
737
+ true
738
+
739
+ In the application 'fan', polymake can now compute the normal fan
740
+ of `q` and its (primitive) rays::
741
+
742
+ sage: # optional - jupymake
743
+ sage: polymake.application('fan')
744
+ sage: g = q.normal_fan()
745
+ sage: g.RAYS
746
+ -1 0 1/4
747
+ 0 -1 1/4
748
+ 1 0 0
749
+ 1 1 -1/4
750
+ 0 1 0
751
+ 0 0 -1
752
+ 0 -1 0
753
+ -1 0 0
754
+ sage: g.RAYS.primitive()
755
+ -4 0 1
756
+ 0 -4 1
757
+ 1 0 0
758
+ 4 4 -1
759
+ 0 1 0
760
+ 0 0 -1
761
+ 0 -1 0
762
+ -1 0 0
763
+
764
+ Note that the list of functions available by tab completion depends
765
+ on the application.
766
+
767
+ TESTS:
768
+
769
+ Since 'trop_witness' is not defined in the polymake application 'polytope'
770
+ but only in 'tropical', the following shows the effect of changing
771
+ the application. ::
772
+
773
+ sage: # optional - jupymake
774
+ sage: polymake.application('polytope')
775
+ sage: 'trop_witness' in dir(polymake)
776
+ False
777
+ sage: polymake.application('tropical')
778
+ sage: 'trop_witness' in dir(polymake)
779
+ True
780
+ sage: polymake.application('polytope')
781
+ sage: 'trop_witness' in dir(polymake)
782
+ False
783
+
784
+ For completeness, we show what happens when asking for an application
785
+ that doesn't exist::
786
+
787
+ sage: polymake.application('killerapp') # optional - jupymake
788
+ Traceback (most recent call last):
789
+ ...
790
+ ValueError: Unknown polymake application 'killerapp'
791
+
792
+ Of course, a different error results when we send an explicit
793
+ command in polymake to change to an unknown application::
794
+
795
+ sage: polymake.eval('application "killerapp";') # optional - jupymake
796
+ Traceback (most recent call last):
797
+ ...
798
+ PolymakeError: Unknown application killerapp
799
+ """
800
+ if app not in ["common", "fulton", "group", "matroid", "topaz", "fan", "graph", "ideal", "polytope", "tropical"]:
801
+ raise ValueError("Unknown polymake application '{}'".format(app))
802
+ self._application = app
803
+ self.eval('application "{}";'.format(app))
804
+
805
+ def new_object(self, name, *args, **kwds):
806
+ """
807
+ Return a new instance of a given polymake type, with given positional or named arguments.
808
+
809
+ INPUT:
810
+
811
+ - ``name`` of a polymake class (potentially templated), as string.
812
+ - further positional or named arguments, to be passed to the constructor.
813
+
814
+ EXAMPLES::
815
+
816
+ sage: # optional - jupymake
817
+ sage: q = polymake.new_object("Polytope<Rational>", INEQUALITIES=[[4,-4,0,1],[-4,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1]])
818
+ sage: q.N_VERTICES
819
+ 4
820
+ sage: q.BOUNDED
821
+ true
822
+ sage: q.VERTICES
823
+ 1 2 0 4
824
+ 1 3 0 8
825
+ 1 2 1 8
826
+ 1 3 1 8
827
+ sage: q.full_typename()
828
+ 'Polytope<Rational>'
829
+ """
830
+ try:
831
+ f = self.__new[name]
832
+ except AttributeError:
833
+ self.__new = {}
834
+ f = self.__new[name] = self._function_class()(self, "new {}".format(name))
835
+ except KeyError:
836
+ f = self.__new[name] = self._function_class()(self, "new {}".format(name))
837
+ return f(*args, **kwds)
838
+
839
+
840
+ # --------
841
+ # Elements
842
+ # --------
843
+
844
+ class PolymakeElement(ExtraTabCompletion, InterfaceElement):
845
+ """
846
+ Elements in the polymake interface.
847
+
848
+ EXAMPLES:
849
+
850
+ We support all "big" polymake types, Perl arrays of length
851
+ different from one, and Perl scalars::
852
+
853
+ sage: p = polymake.rand_sphere(4, 20, seed=5) # optional - jupymake
854
+ sage: p.typename() # optional - jupymake
855
+ 'Polytope'
856
+ sage: p # optional - jupymake
857
+ Random spherical polytope of dimension 4; seed=5...
858
+
859
+ Now, one can work with that element in Python syntax, for example::
860
+
861
+ sage: p.VERTICES[2][2] # optional - jupymake
862
+ 1450479926727001/2251799813685248
863
+ """
864
+ def _repr_(self):
865
+ """
866
+ String representation of polymake elements.
867
+
868
+ EXAMPLES:
869
+
870
+ In the case of a "big" object, if polymake provides a description
871
+ of the object that is not longer than single line, it is used for
872
+ printing::
873
+
874
+ sage: # optional - jupymake
875
+ sage: p = polymake.rand_sphere(3, 12, seed=15)
876
+ sage: p
877
+ Random spherical polytope of dimension 3; seed=15...
878
+ sage: c = polymake.cube(4)
879
+ sage: c
880
+ cube of dimension 4
881
+
882
+ We use the print representation of scalars to display scalars::
883
+
884
+ sage: p.N_VERTICES # optional - jupymake
885
+ 12
886
+
887
+ The items of a Perl arrays are shown separated by commas::
888
+
889
+ sage: p.get_member('list_properties') # optional - jupymake # random
890
+ POINTS, CONE_AMBIENT_DIM, BOUNDED, FEASIBLE, N_POINTS, POINTED,
891
+ CONE_DIM, FULL_DIM, LINEALITY_DIM, LINEALITY_SPACE,
892
+ COMBINATORIAL_DIM, AFFINE_HULL, VERTICES, N_VERTICES
893
+
894
+ We chose to print rule chains explicitly, so that the user doesn't
895
+ need to know how to list the rules using polymake commands::
896
+
897
+ sage: r = p.get_schedule('"H_VECTOR"') # optional - jupymake
898
+ sage: r # optional - jupymake # random
899
+ precondition : N_RAYS | N_INPUT_RAYS ( ppl.convex_hull.primal: FACETS, LINEAR_SPAN : RAYS | INPUT_RAYS )
900
+ sensitivity check for FacetPerm
901
+ ppl.convex_hull.primal: FACETS, LINEAR_SPAN : RAYS | INPUT_RAYS
902
+ RAYS_IN_FACETS : RAYS, FACETS
903
+ SIMPLICIAL : COMBINATORIAL_DIM, RAYS_IN_FACETS
904
+ N_FACETS : FACETS
905
+ precondition : COMBINATORIAL_DIM ( F_VECTOR : N_FACETS, N_RAYS, COMBINATORIAL_DIM )
906
+ F_VECTOR : N_FACETS, N_RAYS, COMBINATORIAL_DIM
907
+ precondition : SIMPLICIAL ( H_VECTOR : F_VECTOR )
908
+ H_VECTOR : F_VECTOR
909
+ sage: r.typeof() # optional - jupymake
910
+ ('Polymake::Core::Scheduler::RuleChain', 'ARRAY')
911
+
912
+ Similarly, polymake matrices and vectors are explicitly listed::
913
+
914
+ sage: # optional - jupymake
915
+ sage: c.VERTICES.typename()
916
+ 'Matrix'
917
+ sage: c.VERTICES[0].typename()
918
+ 'Vector'
919
+ sage: c.VERTICES
920
+ 1 -1 -1 -1 -1
921
+ 1 1 -1 -1 -1
922
+ 1 -1 1 -1 -1
923
+ 1 1 1 -1 -1
924
+ 1 -1 -1 1 -1
925
+ 1 1 -1 1 -1
926
+ 1 -1 1 1 -1
927
+ 1 1 1 1 -1
928
+ 1 -1 -1 -1 1
929
+ 1 1 -1 -1 1
930
+ 1 -1 1 -1 1
931
+ 1 1 1 -1 1
932
+ 1 -1 -1 1 1
933
+ 1 1 -1 1 1
934
+ 1 -1 1 1 1
935
+ 1 1 1 1 1
936
+ sage: c.VERTICES[0]
937
+ 1 -1 -1 -1 -1
938
+
939
+ For other types, we simply use the print representation offered
940
+ by polymake::
941
+
942
+ sage: p.TWO_FACE_SIZES.typename() # optional - jupymake
943
+ 'Map'
944
+ sage: p.TWO_FACE_SIZES # optional - jupymake
945
+ {(3 20)}
946
+ """
947
+ T1, T2 = self.typeof()
948
+ P = self._check_valid()
949
+ name = self._name
950
+ if T1:
951
+ Temp = self.typename()
952
+ if Temp:
953
+ T1 = Temp
954
+ if T1 in ['Matrix', 'Vector']:
955
+ out = P.get(name).strip()
956
+ elif 'RuleChain' in T1:
957
+ out = os.linesep.join(P.get('join("##",{}->list)'.format(name)).split('##'))
958
+ else:
959
+ try:
960
+ out = P.get('{}->description'.format(name)).strip()
961
+ except PolymakeError:
962
+ out = ''
963
+ if os.linesep in out:
964
+ out = ''
965
+ if not out:
966
+ if "Polytope" == T1:
967
+ out = "{}[{}]".format(P.get("{}->type->full_name".format(name)) or "PolymakeElement", _name_pattern.search(name).group())
968
+ elif T1 == '' and T2 == 'ARRAY':
969
+ out = P.eval('print join(", ", @{});'.format(name)).strip()
970
+ elif T1 == '' and T2 == 'HASH':
971
+ out = P.get('%{}'.format(name)).strip()
972
+ elif self._name[0] == '@':
973
+ out = P.eval('print join(", ", {});'.format(name)).strip()
974
+ else:
975
+ out = P.get(name).strip()
976
+ return out
977
+
978
+ def _richcmp_(self, other, op):
979
+ """
980
+ Comparison of polymake elements.
981
+
982
+ EXAMPLES:
983
+
984
+ The default for comparing equality for polytopes is *identity*::
985
+
986
+ sage: p1 = polymake.rand_sphere(3, 12, seed=15) # optional - jupymake
987
+ sage: p2 = polymake.rand_sphere(3, 12, seed=15) # optional - jupymake
988
+ sage: p1 == p2 # optional - jupymake
989
+ False
990
+
991
+ However, other data types are compared by equality, not identity::
992
+
993
+ sage: p1.VERTICES == p2.VERTICES # optional - jupymake
994
+ True
995
+
996
+ A computation applied to a polytope can change the available
997
+ properties, and thus we have
998
+ ::
999
+
1000
+ sage: p1.get_member('list_properties') == p2.get_member('list_properties') # optional - jupymake
1001
+ True
1002
+ sage: p1.F_VECTOR # optional - jupymake
1003
+ 12 30 20
1004
+ sage: p1.get_member('list_properties') == p2.get_member('list_properties') # optional - jupymake
1005
+ False
1006
+ """
1007
+ P = self._check_valid()
1008
+ if P.eval("print {} {} {};".format(self.name(), P._equality_symbol(), other.name())).strip() == P._true_symbol():
1009
+ return rich_to_bool(op, 0)
1010
+ if P.eval("print {} {} {};".format(self.name(), P._lessthan_symbol(), other.name())).strip() == P._true_symbol():
1011
+ return rich_to_bool(op, -1)
1012
+ if P.eval("print {} {} {};".format(self.name(), P._greaterthan_symbol(), other.name())).strip() == P._true_symbol():
1013
+ return rich_to_bool(op, 1)
1014
+ return NotImplemented
1015
+
1016
+ def __bool__(self):
1017
+ """
1018
+ Return whether this polymake element is equal to ``True``.
1019
+
1020
+ EXAMPLES::
1021
+
1022
+ sage: from sage.interfaces.polymake import polymake
1023
+ sage: bool(polymake(0)) # optional - jupymake
1024
+ False
1025
+ sage: bool(polymake(1)) # optional - jupymake
1026
+ True
1027
+ """
1028
+ P = self._check_valid()
1029
+ t = P._true_symbol()
1030
+ cmd = '{} {} {};'.format(self._name, P._equality_symbol(), t)
1031
+ return P.get(cmd) == t
1032
+
1033
+ def known_properties(self):
1034
+ """
1035
+ List the names of properties that have been computed so far on this element.
1036
+
1037
+ .. NOTE::
1038
+
1039
+ This is in many cases equivalent to use polymake's
1040
+ ``list_properties``, which returns a blank separated string
1041
+ representation of the list of properties. However, on some
1042
+ elements, ``list_properties`` would simply result in an error.
1043
+
1044
+ EXAMPLES::
1045
+
1046
+ sage: c = polymake.cube(4) # optional - jupymake
1047
+ sage: c.known_properties() # optional - jupymake
1048
+ ['AFFINE_HULL',
1049
+ 'BOUNDED',
1050
+ 'CONE_AMBIENT_DIM',
1051
+ 'CONE_DIM',
1052
+ ...
1053
+ 'VERTICES_IN_FACETS']
1054
+ sage: c.list_properties() # optional - jupymake
1055
+ CONE_AMBIENT_DIM, CONE_DIM, FACETS, AFFINE_HULL, VERTICES_IN_FACETS,
1056
+ BOUNDED...
1057
+
1058
+ A computation can change the list of known properties::
1059
+
1060
+ sage: c.F_VECTOR # optional - jupymake
1061
+ 16 32 24 8
1062
+ sage: c.known_properties() # optional - jupymake
1063
+ ['AFFINE_HULL',
1064
+ 'BOUNDED',
1065
+ 'COMBINATORIAL_DIM',
1066
+ 'CONE_AMBIENT_DIM',
1067
+ 'CONE_DIM',
1068
+ ...
1069
+ 'VERTICES_IN_FACETS']
1070
+ """
1071
+ P = self._check_valid()
1072
+ try:
1073
+ return sorted(P.get('join(", ", {}->list_properties)'.format(self._name)).split(', '))
1074
+ except PolymakeError:
1075
+ return []
1076
+
1077
+ @cached_method
1078
+ def _member_list(self):
1079
+ """
1080
+ The list of properties that polymake knows to compute for this element.
1081
+
1082
+ The resulting list is used for tab completion.
1083
+
1084
+ TESTS::
1085
+
1086
+ sage: c = polymake.cube(4) # optional - jupymake
1087
+ sage: c._member_list() # optional - jupymake
1088
+ ['AFFINE_HULL',
1089
+ ...
1090
+ 'WEAKLY_CENTERED',
1091
+ ...]
1092
+ """
1093
+ # return the members of a "big" object.
1094
+ P = self._check_valid()
1095
+ try:
1096
+ cmd = '$SAGETMP = ' + self._name + ' -> type;'
1097
+ P.eval(cmd)
1098
+ except (TypeError, PolymakeError): # this happens for a perl type that isn't a Polymake type
1099
+ return []
1100
+ cmd = 'print join(", ", sorted_uniq(sort { $a cmp $b } map { keys %{$_->properties} }$SAGETMP, @{$SAGETMP->super}));'
1101
+ try:
1102
+ out = P.eval(cmd).split(', ')
1103
+ except PolymakeError:
1104
+ return []
1105
+ return sorted(out)
1106
+
1107
+ def typename(self):
1108
+ """
1109
+ The name of the underlying base type of this element in polymake.
1110
+
1111
+ EXAMPLES::
1112
+
1113
+ sage: c = polymake.cube(4) # optional - jupymake
1114
+ sage: c.typename() # optional - jupymake
1115
+ 'Polytope'
1116
+ sage: c.VERTICES.typename() # optional - jupymake
1117
+ 'Matrix'
1118
+ """
1119
+ P = self._check_valid()
1120
+ try:
1121
+ return P.eval('print {}->type->name;'.format(self._name))
1122
+ except PolymakeError:
1123
+ return ''
1124
+
1125
+ def full_typename(self):
1126
+ """
1127
+ The name of the specialised type of this element.
1128
+
1129
+ EXAMPLES::
1130
+
1131
+ sage: c = polymake.cube(4) # optional - jupymake
1132
+ sage: c.full_typename() # optional - jupymake
1133
+ 'Polytope<Rational>'
1134
+ sage: c.VERTICES.full_typename() # optional - jupymake
1135
+ 'Matrix<Rational, NonSymmetric>'
1136
+ """
1137
+ P = self._check_valid()
1138
+ try:
1139
+ return P.eval('print {}->type->full_name;'.format(self._name))
1140
+ except PolymakeError:
1141
+ return ''
1142
+
1143
+ def qualified_typename(self):
1144
+ """
1145
+ The qualified name of the type of this element.
1146
+
1147
+ EXAMPLES::
1148
+
1149
+ sage: c = polymake.cube(4) # optional - jupymake
1150
+ sage: c.qualified_typename() # optional - jupymake
1151
+ 'polytope::Polytope<Rational>'
1152
+ sage: c.VERTICES.qualified_typename() # optional - jupymake
1153
+ 'common::Matrix<Rational, NonSymmetric>'
1154
+ """
1155
+ P = self._check_valid()
1156
+ try:
1157
+ return P.eval('print {}->type->qualified_name;'.format(self._name))
1158
+ except PolymakeError:
1159
+ return ''
1160
+
1161
+ def _tab_completion(self):
1162
+ """
1163
+ Return a list of available function and property names.
1164
+
1165
+ .. NOTE::
1166
+
1167
+ This currently returns the names of functions defined in the current
1168
+ application, regardless whether they can be applied to this element
1169
+ or not, together with the list of properties of this element that
1170
+ polymake knows how to compute. It does not contain the list of available
1171
+ member functions of this element. This may change in future versions
1172
+ of polymake.
1173
+
1174
+ EXAMPLES::
1175
+
1176
+ sage: c = polymake.cube(4) # optional - jupymake
1177
+ sage: c._tab_completion() # optional - jupymake
1178
+ ['AFFINE_HULL',
1179
+ ...
1180
+ 'zero_vector',
1181
+ 'zonotope',
1182
+ 'zonotope_tiling_lattice',
1183
+ 'zonotope_vertices_fukuda']
1184
+ """
1185
+ return sorted(self._member_list()+self.parent()._tab_completion())
1186
+
1187
+ def __getattr__(self, attrname):
1188
+ """
1189
+ Return a property of this element, or a polymake function with this
1190
+ element as first argument, or a member function of this element.
1191
+
1192
+ .. NOTE::
1193
+
1194
+ If the attribute name is known as the name of a property, it is
1195
+ interpreted as such. Otherwise, if it is known as a function in
1196
+ the current application, the function is returned with this
1197
+ element inserted as first argument, and potential further arguments,
1198
+ when called. Otherwise, it is assumed that it is a member function
1199
+ of this element, and treated as such. Note that member functions
1200
+ are currently invisible in tab completion, thus, the user has
1201
+ to know the name of the member function.
1202
+
1203
+ EXAMPLES:
1204
+
1205
+ A property::
1206
+
1207
+ sage: # optional - jupymake
1208
+ sage: c = polymake.cube(3)
1209
+ sage: c.H_VECTOR
1210
+ 1 5 5 1
1211
+ sage: c.N_VERTICES
1212
+ 8
1213
+ sage: d = polymake.cross(3)
1214
+ sage: d.N_VERTICES
1215
+ 6
1216
+
1217
+ A function::
1218
+
1219
+ sage: # optional - jupymake
1220
+ sage: c.minkowski_sum_fukuda
1221
+ minkowski_sum_fukuda (bound to Polymake::polytope::Polytope__Rational object)
1222
+ sage: s = c.minkowski_sum_fukuda(d)
1223
+ sage: s.N_VERTICES
1224
+ 24
1225
+ sage: s
1226
+ Polytope<Rational>[SAGE...]
1227
+
1228
+ A member function::
1229
+
1230
+ sage: # optional - jupymake
1231
+ sage: c = polymake.cube(2)
1232
+ sage: V = polymake.new_object('Vector', [1,0,0])
1233
+ sage: V
1234
+ 1 0 0
1235
+ sage: c.contains
1236
+ Member function 'contains' of Polymake::polytope::Polytope__Rational object
1237
+ sage: c.contains(V)
1238
+ true
1239
+ """
1240
+ P = self._check_valid()
1241
+ if attrname[:1] == "_":
1242
+ raise AttributeError
1243
+ if attrname not in P._tab_completion():
1244
+ # Does not appear in list of global functions.
1245
+ if attrname in self._member_list():
1246
+ try:
1247
+ return P('{}->{}'.format(self._name, attrname))
1248
+ except (TypeError, PolymakeError):
1249
+ raise AttributeError
1250
+ else:
1251
+ return P._function_element_class()(self, '{}->{}'.format(self._name, attrname), memberfunction=True)
1252
+ return P._function_element_class()(self, attrname, memberfunction=False)
1253
+
1254
+ def get_member_function(self, attrname):
1255
+ """
1256
+ Request a member function of this element.
1257
+
1258
+ .. NOTE::
1259
+
1260
+ It is not checked whether a member function with the given name
1261
+ exists.
1262
+
1263
+ EXAMPLES::
1264
+
1265
+ sage: # optional - jupymake
1266
+ sage: c = polymake.cube(2)
1267
+ sage: c.contains
1268
+ Member function 'contains' of Polymake::polytope::Polytope__Rational object
1269
+ sage: V = polymake.new_object('Vector', [1,0,0])
1270
+ sage: V
1271
+ 1 0 0
1272
+ sage: c.contains(V)
1273
+ true
1274
+
1275
+ Whether a member function of the given name actually exists for that
1276
+ object will only be clear when calling it::
1277
+
1278
+ sage: c.get_member_function("foo") # optional - jupymake
1279
+ Member function 'foo' of Polymake::polytope::Polytope__Rational object
1280
+ sage: c.get_member_function("foo")() # optional - jupymake
1281
+ Traceback (most recent call last):
1282
+ ...
1283
+ TypeError: Can't locate object method "foo" via package "Polymake::polytope::Polytope__Rational"
1284
+ """
1285
+ P = self._check_valid()
1286
+ return P._function_element_class()(self, '{}->{}'.format(self._name, attrname), memberfunction=True)
1287
+
1288
+ def get_member(self, attrname):
1289
+ """
1290
+ Get a member/property of this element.
1291
+
1292
+ .. NOTE::
1293
+
1294
+ Normally, it should be possible to just access the property
1295
+ in the usual Python syntax for attribute access. However, if
1296
+ that fails, one can request the member explicitly.
1297
+
1298
+ EXAMPLES::
1299
+
1300
+ sage: p = polymake.rand_sphere(4, 20, seed=5) # optional - jupymake
1301
+
1302
+ Normally, a property would be accessed as follows::
1303
+
1304
+ sage: p.F_VECTOR # optional - jupymake
1305
+ 20 94 148 74
1306
+
1307
+ However, explicit access is possible as well::
1308
+
1309
+ sage: p.get_member('F_VECTOR') # optional - jupymake
1310
+ 20 94 148 74
1311
+
1312
+ In some cases, the explicit access works better::
1313
+
1314
+ sage: p.type # optional - jupymake
1315
+ Member function 'type' of Polymake::polytope::Polytope__Rational object
1316
+ sage: p.get_member('type') # optional - jupymake
1317
+ Polytope<Rational>[SAGE...]
1318
+ sage: p.get_member('type').get_member('name') # optional - jupymake
1319
+ Polytope
1320
+
1321
+ Note that in the last example calling the erroneously constructed
1322
+ member function ``type`` still works::
1323
+
1324
+ sage: p.type() # optional - jupymake
1325
+ Polytope<Rational>[SAGE...]
1326
+ """
1327
+ P = self._check_valid()
1328
+ return P('{}->{}'.format(self.name(), attrname))
1329
+
1330
+ def __getitem__(self, key):
1331
+ """
1332
+ Indexing and slicing.
1333
+
1334
+ Slicing returns a Python list.
1335
+
1336
+ EXAMPLES::
1337
+
1338
+ sage: p = polymake.rand_sphere(3, 12, seed=15) # optional - jupymake
1339
+ sage: p.VERTICES[3] # optional - jupymake
1340
+ 1 7977905618560809/18014398509481984 -1671539598851959/144115188075855872 8075083879632623/9007199254740992
1341
+ sage: p.list_properties()[2] # optional - jupymake
1342
+ BOUNDED
1343
+
1344
+ Slicing::
1345
+
1346
+ sage: p.F_VECTOR[:] # optional - jupymake
1347
+ [12, 30, 20]
1348
+ sage: p.F_VECTOR[0:1] # optional - jupymake
1349
+ [12]
1350
+ sage: p.F_VECTOR[0:3:2] # optional - jupymake
1351
+ [12, 20]
1352
+ """
1353
+ P = self._check_valid()
1354
+ if isinstance(key, slice):
1355
+ indices = key.indices(len(self))
1356
+ return [self[i] for i in range(*indices)]
1357
+ _, T = self.typeof()
1358
+ if self._name.startswith('@'):
1359
+ return P('${}[{}]'.format(self._name[1:], key))
1360
+ if T == 'ARRAY':
1361
+ return P('{}[{}]'.format(self._name, key))
1362
+ if T == 'HASH':
1363
+ try:
1364
+ if key.parent() is self.parent():
1365
+ key = key._name
1366
+ else:
1367
+ key = str(key)
1368
+ except AttributeError:
1369
+ key = str(key)
1370
+ return P(self._name + "{" + key + "}")
1371
+ raise NotImplementedError("Cannot get items from Perl type {}".format(T))
1372
+
1373
+ def __iter__(self):
1374
+ """
1375
+ Return an iterator for ``self``.
1376
+
1377
+ OUTPUT: iterator
1378
+
1379
+ EXAMPLES::
1380
+
1381
+ sage: p = polymake.rand_sphere(3, 12, seed=15) # optional - jupymake
1382
+ sage: [ x for x in p.VERTICES[3] ] # optional - jupymake
1383
+ [1, 7977905618560809/18014398509481984, -1671539598851959/144115188075855872, 8075083879632623/9007199254740992]
1384
+ """
1385
+ for i in range(len(self)):
1386
+ yield self[i]
1387
+
1388
+ def __len__(self):
1389
+ """
1390
+ EXAMPLES::
1391
+
1392
+ sage: p = polymake.rand_sphere(3, 12, seed=15) # optional - jupymake
1393
+ sage: len(p.FACETS) # optional - jupymake
1394
+ 20
1395
+ sage: len(p.list_properties()) >= 12 # optional - jupymake
1396
+ True
1397
+ """
1398
+ P = self._check_valid()
1399
+ T1, T2 = self.typeof()
1400
+ name = self._name
1401
+ if T2 == 'ARRAY':
1402
+ return int(P.eval('print scalar @{+%s};' % name))
1403
+ if T2 == 'HASH':
1404
+ return int(P.eval('print scalar keys %' + ('{+%s};' % name)))
1405
+ if T1:
1406
+ raise TypeError("Don't know how to compute the length of {} object".format(T1))
1407
+ return int(P.eval('print scalar {};'.format(name)))
1408
+
1409
+ @cached_method
1410
+ def typeof(self):
1411
+ """
1412
+ Return the type of a polymake "big" object, and its
1413
+ underlying Perl type.
1414
+
1415
+ .. NOTE::
1416
+
1417
+ This is mainly for internal use.
1418
+
1419
+ EXAMPLES::
1420
+
1421
+ sage: # optional - jupymake
1422
+ sage: p = polymake.rand_sphere(3, 13, seed=12)
1423
+ sage: p.typeof()
1424
+ ('Polymake::polytope::Polytope__Rational', 'ARRAY')
1425
+ sage: p.VERTICES.typeof()
1426
+ ('Polymake::common::Matrix_A_Rational_I_NonSymmetric_Z', 'ARRAY')
1427
+ sage: p.get_schedule('"F_VECTOR"').typeof()
1428
+ ('Polymake::Core::Scheduler::RuleChain', 'ARRAY')
1429
+
1430
+ On "small" objects, it just returns empty strings::
1431
+
1432
+ sage: p.N_VERTICES.typeof() # optional - jupymake
1433
+ ('', '')
1434
+ sage: p.list_properties().typeof() # optional - jupymake
1435
+ ('', '')
1436
+ """
1437
+ P = self._check_valid()
1438
+ name = self._name
1439
+ T1, T2 = P.eval('print ref({});'.format(name)), P.eval('print reftype({});'.format(name))
1440
+ if T1 == 'false': # Polymake 3.4 returns this
1441
+ T1 = ''
1442
+ return T1, T2
1443
+
1444
+ def _sage_(self):
1445
+ """
1446
+ Convert ``self`` to a Sage object.
1447
+
1448
+ EXAMPLES::
1449
+
1450
+ sage: a = polymake(1/2); a # optional - jupymake
1451
+ 1/2
1452
+ sage: a.sage() # optional - jupymake
1453
+ 1/2
1454
+ sage: _.parent() # optional - jupymake
1455
+ Rational Field
1456
+
1457
+ Quadratic extensions::
1458
+
1459
+ sage: # needs sage.rings.number_field
1460
+ sage: K.<sqrt5> = QuadraticField(5)
1461
+ sage: polymake(K(0)).sage() # optional - jupymake
1462
+ 0
1463
+ sage: _.parent() # optional - jupymake
1464
+ Rational Field
1465
+ sage: polymake(sqrt5).sage() # optional - jupymake
1466
+ a
1467
+ sage: polymake(-sqrt5).sage() # optional - jupymake
1468
+ -a
1469
+ sage: polymake(1/3-1/2*sqrt5).sage() # optional - jupymake
1470
+ -1/2*a + 1/3
1471
+ sage: polymake(-1+sqrt5).sage() # optional - jupymake
1472
+ a - 1
1473
+
1474
+ Vectors::
1475
+
1476
+ sage: PP = polymake.cube(3) # optional - jupymake
1477
+ sage: PP.F_VECTOR.sage() # optional - jupymake
1478
+ (8, 12, 6)
1479
+ sage: _.parent() # optional - jupymake
1480
+ Ambient free module of rank 3 over the principal ideal domain Integer Ring
1481
+
1482
+ Matrices::
1483
+
1484
+ sage: polymake.unit_matrix(2).sage() # optional - jupymake
1485
+ [1 0]
1486
+ [0 1]
1487
+ sage: _.parent() # optional - jupymake
1488
+ Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
1489
+
1490
+ Polytopes::
1491
+
1492
+ sage: polymake.cube(3).sage() # optional - jupymake
1493
+ A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
1494
+ sage: polymake.icosahedron().sage() # optional - jupymake, needs sage.rings.number_field
1495
+ A 3-dimensional polyhedron in
1496
+ (Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?)^3
1497
+ defined as the convex hull of 12 vertices
1498
+ """
1499
+ T1, T2 = self.typeof()
1500
+ self._check_valid()
1501
+ try:
1502
+ # Try to just read things from the string representation.
1503
+ if 'Sparse' in T1:
1504
+ raise NotImplementedError
1505
+
1506
+ r = self._repr_()
1507
+ if 'Float' in T1:
1508
+ from sage.rings.real_double import RDF
1509
+ base_ring = RDF
1510
+ str_to_base_ring = RDF
1511
+ elif 'QuadraticExtension' in T1 and 'r' in r:
1512
+ i = r.find('r')
1513
+ i1 = min((r[i:]+' ').find(' '), (r[i:]+'\n').find('\n'))
1514
+ d = int(r[i+1:i+i1])
1515
+ from sage.rings.number_field.number_field import QuadraticField
1516
+ base_ring = QuadraticField(d)
1517
+
1518
+ def str_to_base_ring(s):
1519
+ m = re.match(r'(-?[0-9/]+)[+]?((-?[0-9/]+)r([0-9/]+))?', s)
1520
+ a, b = m.group(1), m.group(3)
1521
+ return base_ring(a) + base_ring(b) * base_ring.gen()
1522
+
1523
+ elif 'Rational' in T1:
1524
+ from sage.rings.rational_field import QQ
1525
+ base_ring = QQ
1526
+ str_to_base_ring = QQ
1527
+ else:
1528
+ raise NotImplementedError
1529
+
1530
+ if 'Vector' in T1:
1531
+ from sage.modules.free_module_element import vector
1532
+ if r == '':
1533
+ return vector(base_ring)
1534
+ return vector(base_ring, [str_to_base_ring(s) for s in r.split(' ')])
1535
+ elif 'Matrix' in T1:
1536
+ from sage.matrix.constructor import matrix
1537
+ if r == '':
1538
+ return matrix(base_ring)
1539
+ return matrix(base_ring, [[str_to_base_ring(s) for s in t.split(' ')] for t in r.split('\n')])
1540
+ except Exception:
1541
+ pass
1542
+
1543
+ if T1:
1544
+ Temp = self.typename()
1545
+ if Temp:
1546
+ T1 = Temp
1547
+ if T1 == 'QuadraticExtension':
1548
+ # We can't seem to access a, b, r by method calls, so let's parse.
1549
+ m = re.match(r'(-?[0-9/]+)[+]?((-?[0-9/]+)r([0-9/]+))?', repr(self))
1550
+ if m is None:
1551
+ raise NotImplementedError("Cannot parse QuadraticExtension element: {}".format(self))
1552
+ a, b, r = m.group(1), m.group(3), m.group(4)
1553
+ from sage.rings.rational_field import QQ
1554
+ if r is None:
1555
+ # Prints like a rational, so we can't know the extension. Coerce to rational.
1556
+ return QQ(a)
1557
+ else:
1558
+ from sage.rings.number_field.number_field import QuadraticField
1559
+ K = QuadraticField(r)
1560
+ return QQ(a) + QQ(b) * K.gen()
1561
+ elif T1 == 'Vector' or T1 == 'SparseVector':
1562
+ from sage.modules.free_module_element import vector
1563
+ return vector([x.sage() for x in self])
1564
+ elif T1 == 'Matrix' or T1 == 'SparseMatrix':
1565
+ from sage.matrix.constructor import matrix
1566
+ return matrix([x.sage() for x in self])
1567
+ elif T1 == 'Polytope':
1568
+ from sage.geometry.polyhedron.backend_polymake import Polyhedron_polymake
1569
+ return Polyhedron_polymake._from_polymake_polytope(None, self)
1570
+ else:
1571
+ return super()._sage_()
1572
+
1573
+ def _sage_doc_(self):
1574
+ """
1575
+ EXAMPLES::
1576
+
1577
+ sage: c = polymake.cube(3) # optional - jupymake
1578
+ sage: print(c._sage_doc_()) # optional - jupymake # random
1579
+ objects/Polytope:
1580
+ Not necessarily bounded or unbounded polyhedron.
1581
+ Nonetheless, the name "Polytope" is used for two reasons:
1582
+ Firstly, combinatorially we always deal with polytopes; see the description of VERTICES_IN_FACETS for details.
1583
+ The second reason is historical.
1584
+ We use homogeneous coordinates, which is why Polytope is derived from Cone.
1585
+ Note that a pointed polyhedron is projectively equivalent to a polytope.
1586
+ Scalar is the numeric data type used for the coordinates.
1587
+ <BLANKLINE>
1588
+ objects/Polytope/specializations/Polytope<Rational>:
1589
+ A rational polyhedron realized in Q^d
1590
+ sage: print(c.FACETS._sage_doc_()) # optional - jupymake # random
1591
+ property_types/Algebraic Types/SparseMatrix:
1592
+ A SparseMatrix is a two-dimensional associative array with row and column indices as keys; elements equal to the default value (ElementType(), which is 0 for most numerical types) are not stored, but implicitly encoded by the gaps in the key set. Each row and column is organized as an AVL-tree.
1593
+ <BLANKLINE>
1594
+ Use dense to convert this into its dense form.
1595
+ <BLANKLINE>
1596
+ You can create a new SparseMatrix by entering its entries row by row, as a list of SparseVectors e.g.:
1597
+ $A = new SparseMatrix<Int>(<< '.');
1598
+ (5) (1 1)
1599
+ (5) (4 2)
1600
+ (5)
1601
+ (5) (0 3) (1 -1)
1602
+ .
1603
+ """
1604
+ P = self._check_valid()
1605
+ # according to Julian Pfeifle, the only case in which the fully qualified
1606
+ # typename would not provide the doc.
1607
+ Tname = self.typename()
1608
+ Tqname = self.qualified_typename()
1609
+ Tfname = self.full_typename()
1610
+ if Tname == 'Polytope':
1611
+ try:
1612
+ doc = P.eval('help "Polytope";')
1613
+ except PolymakeError:
1614
+ doc = ''
1615
+ else:
1616
+ try:
1617
+ doc = P.eval('help "{}";'.format(Tname))
1618
+ except PolymakeError:
1619
+ doc = ''
1620
+ try:
1621
+ doc2 = P.eval('help "{}";'.format(Tqname))
1622
+ except PolymakeError:
1623
+ doc2 = ''
1624
+ if doc:
1625
+ if doc2:
1626
+ doc = doc+os.linesep+doc2
1627
+ else:
1628
+ doc = doc2
1629
+ try:
1630
+ doc3 = P.eval('help "{}";'.format(Tfname))
1631
+ except PolymakeError:
1632
+ doc3 = ''
1633
+ if doc:
1634
+ if doc3:
1635
+ doc = doc+os.linesep+doc3
1636
+ else:
1637
+ doc = doc3
1638
+ if doc:
1639
+ return doc
1640
+ return "Undocumented polymake type '{}'".format(self.full_typename())
1641
+
1642
+
1643
+ class PolymakeFunctionElement(InterfaceFunctionElement):
1644
+ """
1645
+ A callable (function or member function) bound to a polymake element.
1646
+
1647
+ EXAMPLES::
1648
+
1649
+ sage: # optional - jupymake
1650
+ sage: c = polymake.cube(2)
1651
+ sage: V = polymake.new_object('Vector', [1,0,0])
1652
+ sage: V
1653
+ 1 0 0
1654
+ sage: c.contains
1655
+ Member function 'contains' of Polymake::polytope::Polytope__Rational object
1656
+ sage: c.contains(V)
1657
+ true
1658
+ """
1659
+ def __init__(self, obj, name, memberfunction=False):
1660
+ """
1661
+ INPUT:
1662
+
1663
+ - ``obj`` -- Polymake object that this function is bound to
1664
+ - ``name`` -- string; it actually says how to call this function in
1665
+ polymake. So, if it is a member function, it will look like
1666
+ `"$SAGE123[0]->func_name"`.
1667
+ - ``memberfunction`` -- boolean (default: ``False``); whether this is a
1668
+ member function or a plain function applied with this element as
1669
+ first argument
1670
+
1671
+ EXAMPLES::
1672
+
1673
+ sage: p = polymake.rand_sphere(3, 13, seed=12) # optional - jupymake
1674
+ sage: p.minkowski_sum_fukuda # optional - jupymake
1675
+ minkowski_sum_fukuda (bound to Polymake::polytope::Polytope__Rational object)
1676
+ sage: p.get_schedule # optional - jupymake
1677
+ Member function 'get_schedule' of Polymake::polytope::Polytope__Rational object
1678
+ """
1679
+ self._obj = obj
1680
+ self._name = name
1681
+ self._is_memberfunc = memberfunction
1682
+
1683
+ def _repr_(self):
1684
+ """
1685
+ EXAMPLES::
1686
+
1687
+ sage: p = polymake.rand_sphere(3, 13, seed=12) # optional - jupymake
1688
+ sage: p.minkowski_sum_fukuda # optional - jupymake
1689
+ minkowski_sum_fukuda (bound to Polymake::polytope::Polytope__Rational object)
1690
+ sage: p.contains # optional - jupymake
1691
+ Member function 'contains' of Polymake::polytope::Polytope__Rational object
1692
+ """
1693
+ if self._is_memberfunc:
1694
+ return "Member function '{}' of {} object".format(self._name.split("->")[-1], self._obj.typeof()[0])
1695
+ return "{} (bound to {} object)".format(self._name, self._obj.typeof()[0])
1696
+
1697
+ def __call__(self, *args, **kwds):
1698
+ """
1699
+ EXAMPLES:
1700
+
1701
+ We consider both member functions of an element and global functions
1702
+ bound to an element::
1703
+
1704
+ sage: p = polymake.rand_sphere(3, 13, seed=12) # optional - jupymake
1705
+ sage: p.get_schedule('"VERTICES"') # optional - jupymake # random
1706
+ sensitivity check for VertexPerm
1707
+ cdd.convex_hull.canon: POINTED, RAYS, LINEALITY_SPACE : INPUT_RAYS
1708
+ sage: p.minkowski_sum_fukuda(p).F_VECTOR # optional - jupymake # not tested
1709
+ 13 33 22
1710
+ """
1711
+ if self._is_memberfunc:
1712
+ return self._obj._check_valid().function_call(self._name, list(args), kwds)
1713
+ return self._obj._check_valid().function_call(self._name, [self._obj] + list(args), kwds)
1714
+
1715
+ def _sage_doc_(self):
1716
+ """
1717
+ Return documentation of this function.
1718
+
1719
+ .. NOTE::
1720
+
1721
+ For unclear reasons, accessing documentation with ``?`` sometimes
1722
+ does not include the return value of this method.
1723
+
1724
+ EXAMPLES::
1725
+
1726
+ sage: p = polymake.rand_sphere(3, 13, seed=12) # optional - jupymake
1727
+ sage: print(p.get_schedule._sage_doc_()) # optional - jupymake # random
1728
+ objects/Core::Object/methods/get_schedule:
1729
+ get_schedule(request; ... ) -> Core::RuleChain
1730
+ <BLANKLINE>
1731
+ Compose an optimal chain of production rules providing all requested properties.
1732
+ The returned RuleChain object can be applied to the original object as well as to any other object
1733
+ with the same initial set of properties. If no feasible rule chain exists, `undef' is returned.
1734
+ <BLANKLINE>
1735
+ To watch the rule scheduler at work, e.g. to see announcements about tried preconditions,
1736
+ you may temporarily increase the verbosity levels $Verbose::rules and $Verbose::scheduler.
1737
+ <BLANKLINE>
1738
+ Arguments:
1739
+ String request : name of a property with optional alternatives or a property path in dotted notation.
1740
+ Several requests may be listed.
1741
+ <BLANKLINE>
1742
+ Returns Core::RuleChain
1743
+ sage: print(p.minkowski_sum_fukuda._sage_doc_()) # optional - jupymake # random
1744
+ functions/Producing a polytope from polytopes/minkowski_sum_fukuda:
1745
+ minkowski_sum_fukuda(summands) -> Polytope<Scalar>
1746
+ <BLANKLINE>
1747
+ Computes the (VERTICES of the) Minkowski sum of a list of polytopes using the algorithm by Fukuda described in
1748
+ Komei Fukuda, From the zonotope construction to the Minkowski addition of convex polytopes, J. Symbolic Comput., 38(4):1261-1272, 2004.
1749
+ <BLANKLINE>
1750
+ Arguments:
1751
+ Array<Polytope<Scalar>> summands
1752
+ <BLANKLINE>
1753
+ Returns Polytope<Scalar>
1754
+ <BLANKLINE>
1755
+ Example:
1756
+ > $p = minkowski_sum_fukuda([cube(2),simplex(2),cross(2)]);
1757
+ > print $p->VERTICES;
1758
+ 1 -2 -1
1759
+ 1 -1 -2
1760
+ 1 3 -1
1761
+ 1 3 1
1762
+ 1 2 -2
1763
+ 1 -2 2
1764
+ 1 -1 3
1765
+ 1 1 3
1766
+ """
1767
+ P = self._obj._check_valid()
1768
+ return P.help(self._name.split("->")[-1], pager=False)
1769
+
1770
+
1771
+ class PolymakeJuPyMake(PolymakeAbstract):
1772
+ r"""
1773
+ Interface to the polymake interpreter using JuPyMake.
1774
+
1775
+ In order to use this interface, you need to either install the
1776
+ optional polymake package for Sage, or install polymake system-wide
1777
+ on your computer; it is available from https://polymake.org.
1778
+ Also install the jupymake Python package.
1779
+
1780
+ Type ``polymake.[tab]`` for a list of most functions
1781
+ available from your polymake install. Type
1782
+ ``polymake.Function?`` for polymake's help about a given ``Function``.
1783
+ Type ``polymake(...)`` to create a new polymake
1784
+ object, and ``polymake.eval(...)`` to run a string using
1785
+ polymake and get the result back as a string.
1786
+
1787
+ EXAMPLES::
1788
+
1789
+ sage: from sage.interfaces.polymake import polymake_jupymake as polymake
1790
+ sage: type(polymake)
1791
+ <...sage.interfaces.polymake.PolymakeJuPyMake...
1792
+ sage: p = polymake.rand_sphere(4, 20, seed=5) # optional - jupymake
1793
+ sage: p # optional - jupymake
1794
+ Random spherical polytope of dimension 4; seed=5...
1795
+ sage: set_verbose(3)
1796
+ sage: p.H_VECTOR; # optional - jupymake # random
1797
+ used package ppl
1798
+ The Parma Polyhedra Library ...
1799
+ sage: p.H_VECTOR # optional - jupymake
1800
+ 1 16 40 16 1
1801
+ sage: set_verbose(0)
1802
+ sage: p.F_VECTOR # optional - jupymake
1803
+ 20 94 148 74
1804
+ sage: print(p.F_VECTOR._sage_doc_()) # optional - jupymake # random
1805
+ property_types/Algebraic Types/Vector:
1806
+ A type for vectors with entries of type Element.
1807
+
1808
+ You can perform algebraic operations such as addition or scalar multiplication.
1809
+
1810
+ You can create a new Vector by entering its elements, e.g.:
1811
+ $v = new Vector<Int>(1,2,3);
1812
+ or
1813
+ $v = new Vector<Int>([1,2,3]);
1814
+
1815
+ Python strings are translated to polymake (Perl) identifiers.
1816
+ To obtain Perl strings, use strings containing double-quote characters.
1817
+ Python dicts are translated to Perl hashes.
1818
+
1819
+ ::
1820
+
1821
+ sage: # long time, optional - internet jupymake perl_mongodb
1822
+ sage: L = polymake.db_query({'"_id"': '"F.4D.0047"'},
1823
+ ....: db='"LatticePolytopes"',
1824
+ ....: collection='"SmoothReflexive"'); L
1825
+ BigObjectArray
1826
+ sage: len(L)
1827
+ 1
1828
+ sage: P = L[0]
1829
+ sage: sorted(P.list_properties(), key=str)
1830
+ [..., LATTICE_POINTS_GENERATORS, ..., POINTED, ...]
1831
+ sage: P.F_VECTOR
1832
+ 20 40 29 9
1833
+ """
1834
+
1835
+ def __init__(self, seed=None, verbose=False):
1836
+ """
1837
+ Initialize ``self``.
1838
+
1839
+ INPUT:
1840
+
1841
+ - ``verbose`` -- boolean (default: ``False``); whether to print the
1842
+ commands passed to polymake
1843
+
1844
+ TESTS::
1845
+
1846
+ sage: from sage.interfaces.polymake import PolymakeJuPyMake
1847
+ sage: PolymakeJuPyMake()
1848
+ Polymake
1849
+ """
1850
+ self._verbose = verbose
1851
+ PolymakeAbstract.__init__(self, seed=seed)
1852
+
1853
+ _is_running = False # class variable
1854
+
1855
+ def is_running(self):
1856
+ """
1857
+ Return ``True`` if ``self`` is currently running.
1858
+
1859
+ TESTS::
1860
+
1861
+ sage: from sage.interfaces.polymake import PolymakeJuPyMake
1862
+ sage: pm = PolymakeJuPyMake()
1863
+ sage: pm(1) # optional - jupymake
1864
+ 1
1865
+ sage: pm.is_running() # optional - jupymake
1866
+ True
1867
+
1868
+ Several PolymakeJuPyMake interfaces can be created, but they all
1869
+ talk to the same polymake interpreter::
1870
+
1871
+ sage: pm2 = PolymakeJuPyMake()
1872
+ sage: pm2.is_running() # optional - jupymake
1873
+ True
1874
+ """
1875
+ return self._is_running
1876
+
1877
+ def _start(self):
1878
+ """
1879
+ Initialize the interpreter.
1880
+
1881
+ TESTS::
1882
+
1883
+ sage: from sage.interfaces.polymake import PolymakeJuPyMake
1884
+ sage: pm = PolymakeJuPyMake()
1885
+ sage: pm._start() # optional - jupymake
1886
+ sage: pm.is_running() # optional - jupymake
1887
+ True
1888
+ """
1889
+ from JuPyMake import InitializePolymake
1890
+ if not self.is_running():
1891
+ InitializePolymake() # Can only be called once
1892
+ PolymakeJuPyMake._is_running = True
1893
+ PolymakeAbstract._start(self)
1894
+ self.eval("sub Polymake::Core::Shell::Mock::fill_history {}")
1895
+ self._tab_completion() # Run it here already because it causes a segfault when invoked in actual tab completion situation?!
1896
+
1897
+ def eval(self, code, **kwds):
1898
+ r"""
1899
+ Evaluate a command.
1900
+
1901
+ INPUT:
1902
+
1903
+ - ``code`` -- a command (string) to be evaluated
1904
+
1905
+ Different reaction types of polymake, including warnings, comments,
1906
+ errors, request for user interaction, and yielding a continuation prompt,
1907
+ are taken into account.
1908
+
1909
+ EXAMPLES::
1910
+
1911
+ sage: from sage.interfaces.polymake import polymake_jupymake as polymake
1912
+ sage: p = polymake.cube(3) # optional - jupymake # indirect doctest
1913
+
1914
+ Here we see that remarks printed by polymake are displayed if
1915
+ the verbosity is positive::
1916
+
1917
+ sage: set_verbose(1)
1918
+ sage: p.N_LATTICE_POINTS # optional - jupymake # random
1919
+ used package latte
1920
+ LattE (Lattice point Enumeration) is a computer software dedicated to the
1921
+ problems of counting lattice points and integration inside convex polytopes.
1922
+ Copyright by Matthias Koeppe, Jesus A. De Loera and others.
1923
+ http://www.math.ucdavis.edu/~latte/
1924
+ 27
1925
+ sage: set_verbose(0)
1926
+
1927
+ If polymake raises an error, the polymake *interface* raises
1928
+ a :exc:`PolymakeError`::
1929
+
1930
+ sage: polymake.eval('FOOBAR(3);') # optional - jupymake
1931
+ Traceback (most recent call last):
1932
+ ...
1933
+ PolymakeError: Undefined subroutine &Polymake::User::FOOBAR called...
1934
+
1935
+ If a command is incomplete, then polymake returns a continuation
1936
+ prompt. In that case, we raise an error::
1937
+
1938
+ sage: polymake.eval('print 3') # optional - jupymake
1939
+ Traceback (most recent call last):
1940
+ ...
1941
+ SyntaxError: Incomplete polymake command 'print 3'
1942
+ sage: polymake.eval('print 3;') # optional - jupymake
1943
+ '3'
1944
+
1945
+ However, if the command contains line breaks but eventually is complete,
1946
+ no error is raised::
1947
+
1948
+ sage: print(polymake.eval('$tmp="abc";\nprint $tmp;')) # optional - jupymake
1949
+ abc
1950
+
1951
+ When requesting help, polymake sometimes expects the user to choose
1952
+ from a list. In that situation, we abort with a warning, and show
1953
+ the list from which the user can choose; we could demonstrate this using
1954
+ the :meth:`~sage.interfaces.polymake.PolymakeAbstract.help` method,
1955
+ but here we use an explicit code evaluation::
1956
+
1957
+ sage: print(polymake.eval('help "TRIANGULATION";')) # optional - jupymake # random
1958
+ doctest:warning
1959
+ ...
1960
+ UserWarning: Polymake expects user interaction. We abort and return
1961
+ the options that Polymake provides.
1962
+ There are 5 help topics matching 'TRIANGULATION':
1963
+ 1: objects/Cone/properties/Triangulation and volume/TRIANGULATION
1964
+ 2: objects/Polytope/properties/Triangulation and volume/TRIANGULATION
1965
+ 3: objects/Visualization/Visual::PointConfiguration/methods/TRIANGULATION
1966
+ 4: objects/Visualization/Visual::Polytope/methods/TRIANGULATION
1967
+ 5: objects/PointConfiguration/properties/Triangulation and volume/TRIANGULATION
1968
+
1969
+ By default, we just wait until polymake returns a result. However,
1970
+ it is possible to explicitly set a timeout. The following usually does
1971
+ work in an interactive session and often in doc tests, too. However,
1972
+ sometimes it hangs, and therefore we remove it from the tests, for now::
1973
+
1974
+ sage: c = polymake.cube(15) # optional - jupymake
1975
+ sage: polymake.eval('print {}->F_VECTOR;'.format(c.name()), timeout=1) # not tested # optional - jupymake
1976
+ Traceback (most recent call last):
1977
+ ...
1978
+ RuntimeError: Polymake fails to respond timely
1979
+
1980
+ We verify that after the timeout, polymake is still able
1981
+ to give answers::
1982
+
1983
+ sage: c # optional - jupymake
1984
+ cube of dimension 15
1985
+ sage: c.N_VERTICES # optional - jupymake
1986
+ 32768
1987
+
1988
+ Note, however, that the recovery after a timeout is not perfect.
1989
+ It may happen that in some situation the interface collapses and
1990
+ thus polymake would automatically be restarted, thereby losing all
1991
+ data that have been computed before.
1992
+ """
1993
+ if not self.is_running():
1994
+ self._start()
1995
+ from JuPyMake import ExecuteCommand
1996
+ if self._verbose:
1997
+ print("## eval: {}".format(code))
1998
+ parsed, stdout, stderr, error = ExecuteCommand(code)
1999
+ if get_verbose() > 0 or self._verbose:
2000
+ stderr = stderr.rstrip('\n\r')
2001
+ if stderr:
2002
+ print(stderr)
2003
+ if error:
2004
+ # "Error evaluating {} in {}: {}".format(code, self, error)
2005
+ raise PolymakeError(error)
2006
+ if not parsed:
2007
+ raise SyntaxError("Incomplete polymake command '{}'".format(code))
2008
+ return stdout
2009
+
2010
+ _eval_line = eval
2011
+
2012
+
2013
+ def reduce_load_Polymake():
2014
+ r"""
2015
+ Return the polymake interface object defined in :mod:`sage.interfaces.polymake`.
2016
+
2017
+ EXAMPLES::
2018
+
2019
+ sage: from sage.interfaces.polymake import reduce_load_Polymake
2020
+ sage: reduce_load_Polymake()
2021
+ Polymake
2022
+ """
2023
+ return polymake
2024
+
2025
+
2026
+ Polymake = PolymakeJuPyMake
2027
+
2028
+ polymake = polymake_jupymake = PolymakeJuPyMake()