passagemath-polyhedra 10.6.31rc3__cp314-cp314-macosx_13_0_arm64.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 (205) hide show
  1. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +368 -0
  2. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +371 -0
  3. passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +205 -0
  4. passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +6 -0
  5. passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
  6. passagemath_polyhedra.dylibs/libgmp.10.dylib +0 -0
  7. sage/all__sagemath_polyhedra.py +50 -0
  8. sage/game_theory/all.py +8 -0
  9. sage/game_theory/catalog.py +6 -0
  10. sage/game_theory/catalog_normal_form_games.py +923 -0
  11. sage/game_theory/cooperative_game.py +844 -0
  12. sage/game_theory/matching_game.py +1181 -0
  13. sage/game_theory/normal_form_game.py +2697 -0
  14. sage/game_theory/parser.py +275 -0
  15. sage/geometry/all__sagemath_polyhedra.py +22 -0
  16. sage/geometry/cone.py +6940 -0
  17. sage/geometry/cone_catalog.py +847 -0
  18. sage/geometry/cone_critical_angles.py +1027 -0
  19. sage/geometry/convex_set.py +1119 -0
  20. sage/geometry/fan.py +3743 -0
  21. sage/geometry/fan_isomorphism.py +389 -0
  22. sage/geometry/fan_morphism.py +1884 -0
  23. sage/geometry/hasse_diagram.py +202 -0
  24. sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
  25. sage/geometry/hyperplane_arrangement/all.py +1 -0
  26. sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
  27. sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
  28. sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
  29. sage/geometry/hyperplane_arrangement/library.py +825 -0
  30. sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
  31. sage/geometry/hyperplane_arrangement/plot.py +520 -0
  32. sage/geometry/integral_points.py +35 -0
  33. sage/geometry/integral_points_generic_dense.cpython-314-darwin.so +0 -0
  34. sage/geometry/integral_points_generic_dense.pyx +7 -0
  35. sage/geometry/lattice_polytope.py +5894 -0
  36. sage/geometry/linear_expression.py +773 -0
  37. sage/geometry/newton_polygon.py +767 -0
  38. sage/geometry/point_collection.cpython-314-darwin.so +0 -0
  39. sage/geometry/point_collection.pyx +1008 -0
  40. sage/geometry/polyhedral_complex.py +2616 -0
  41. sage/geometry/polyhedron/all.py +8 -0
  42. sage/geometry/polyhedron/backend_cdd.py +460 -0
  43. sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
  44. sage/geometry/polyhedron/backend_field.py +347 -0
  45. sage/geometry/polyhedron/backend_normaliz.py +2503 -0
  46. sage/geometry/polyhedron/backend_number_field.py +168 -0
  47. sage/geometry/polyhedron/backend_polymake.py +765 -0
  48. sage/geometry/polyhedron/backend_ppl.py +582 -0
  49. sage/geometry/polyhedron/base.py +1206 -0
  50. sage/geometry/polyhedron/base0.py +1444 -0
  51. sage/geometry/polyhedron/base1.py +886 -0
  52. sage/geometry/polyhedron/base2.py +812 -0
  53. sage/geometry/polyhedron/base3.py +1845 -0
  54. sage/geometry/polyhedron/base4.py +1262 -0
  55. sage/geometry/polyhedron/base5.py +2700 -0
  56. sage/geometry/polyhedron/base6.py +1741 -0
  57. sage/geometry/polyhedron/base7.py +997 -0
  58. sage/geometry/polyhedron/base_QQ.py +1258 -0
  59. sage/geometry/polyhedron/base_RDF.py +98 -0
  60. sage/geometry/polyhedron/base_ZZ.py +934 -0
  61. sage/geometry/polyhedron/base_mutable.py +215 -0
  62. sage/geometry/polyhedron/base_number_field.py +122 -0
  63. sage/geometry/polyhedron/cdd_file_format.py +155 -0
  64. sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
  65. sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-darwin.so +0 -0
  66. sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
  67. sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
  68. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-darwin.so +0 -0
  69. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
  70. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
  71. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-darwin.so +0 -0
  72. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
  73. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
  74. sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
  75. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-darwin.so +0 -0
  76. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
  77. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
  78. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-darwin.so +0 -0
  79. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
  80. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
  81. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-darwin.so +0 -0
  82. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
  83. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
  84. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-darwin.so +0 -0
  85. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
  86. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
  87. sage/geometry/polyhedron/constructor.py +773 -0
  88. sage/geometry/polyhedron/double_description.py +753 -0
  89. sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
  90. sage/geometry/polyhedron/face.py +1060 -0
  91. sage/geometry/polyhedron/generating_function.py +1810 -0
  92. sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
  93. sage/geometry/polyhedron/library.py +3502 -0
  94. sage/geometry/polyhedron/misc.py +121 -0
  95. sage/geometry/polyhedron/modules/all.py +1 -0
  96. sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
  97. sage/geometry/polyhedron/palp_database.py +447 -0
  98. sage/geometry/polyhedron/parent.py +1279 -0
  99. sage/geometry/polyhedron/plot.py +1986 -0
  100. sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
  101. sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
  102. sage/geometry/polyhedron/representation.py +1723 -0
  103. sage/geometry/pseudolines.py +515 -0
  104. sage/geometry/relative_interior.py +445 -0
  105. sage/geometry/toric_plotter.py +1103 -0
  106. sage/geometry/triangulation/all.py +2 -0
  107. sage/geometry/triangulation/base.cpython-314-darwin.so +0 -0
  108. sage/geometry/triangulation/base.pyx +963 -0
  109. sage/geometry/triangulation/data.h +147 -0
  110. sage/geometry/triangulation/data.pxd +4 -0
  111. sage/geometry/triangulation/element.py +914 -0
  112. sage/geometry/triangulation/functions.h +10 -0
  113. sage/geometry/triangulation/functions.pxd +4 -0
  114. sage/geometry/triangulation/point_configuration.py +2256 -0
  115. sage/geometry/triangulation/triangulations.h +49 -0
  116. sage/geometry/triangulation/triangulations.pxd +7 -0
  117. sage/geometry/voronoi_diagram.py +319 -0
  118. sage/interfaces/all__sagemath_polyhedra.py +1 -0
  119. sage/interfaces/polymake.py +2028 -0
  120. sage/numerical/all.py +13 -0
  121. sage/numerical/all__sagemath_polyhedra.py +11 -0
  122. sage/numerical/backends/all.py +1 -0
  123. sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
  124. sage/numerical/backends/cvxopt_backend.cpython-314-darwin.so +0 -0
  125. sage/numerical/backends/cvxopt_backend.pyx +1006 -0
  126. sage/numerical/backends/cvxopt_backend_test.py +19 -0
  127. sage/numerical/backends/cvxopt_sdp_backend.cpython-314-darwin.so +0 -0
  128. sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
  129. sage/numerical/backends/cvxpy_backend.cpython-314-darwin.so +0 -0
  130. sage/numerical/backends/cvxpy_backend.pxd +41 -0
  131. sage/numerical/backends/cvxpy_backend.pyx +934 -0
  132. sage/numerical/backends/cvxpy_backend_test.py +13 -0
  133. sage/numerical/backends/generic_backend_test.py +24 -0
  134. sage/numerical/backends/interactivelp_backend.cpython-314-darwin.so +0 -0
  135. sage/numerical/backends/interactivelp_backend.pxd +36 -0
  136. sage/numerical/backends/interactivelp_backend.pyx +1231 -0
  137. sage/numerical/backends/interactivelp_backend_test.py +12 -0
  138. sage/numerical/backends/logging_backend.py +391 -0
  139. sage/numerical/backends/matrix_sdp_backend.cpython-314-darwin.so +0 -0
  140. sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
  141. sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
  142. sage/numerical/backends/ppl_backend.cpython-314-darwin.so +0 -0
  143. sage/numerical/backends/ppl_backend.pyx +1126 -0
  144. sage/numerical/backends/ppl_backend_test.py +13 -0
  145. sage/numerical/backends/scip_backend.cpython-314-darwin.so +0 -0
  146. sage/numerical/backends/scip_backend.pxd +22 -0
  147. sage/numerical/backends/scip_backend.pyx +1289 -0
  148. sage/numerical/backends/scip_backend_test.py +13 -0
  149. sage/numerical/interactive_simplex_method.py +5338 -0
  150. sage/numerical/knapsack.py +665 -0
  151. sage/numerical/linear_functions.cpython-314-darwin.so +0 -0
  152. sage/numerical/linear_functions.pxd +31 -0
  153. sage/numerical/linear_functions.pyx +1648 -0
  154. sage/numerical/linear_tensor.py +470 -0
  155. sage/numerical/linear_tensor_constraints.py +448 -0
  156. sage/numerical/linear_tensor_element.cpython-314-darwin.so +0 -0
  157. sage/numerical/linear_tensor_element.pxd +6 -0
  158. sage/numerical/linear_tensor_element.pyx +459 -0
  159. sage/numerical/mip.cpython-314-darwin.so +0 -0
  160. sage/numerical/mip.pxd +40 -0
  161. sage/numerical/mip.pyx +3667 -0
  162. sage/numerical/sdp.cpython-314-darwin.so +0 -0
  163. sage/numerical/sdp.pxd +39 -0
  164. sage/numerical/sdp.pyx +1433 -0
  165. sage/rings/all__sagemath_polyhedra.py +3 -0
  166. sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
  167. sage/rings/polynomial/omega.py +982 -0
  168. sage/schemes/all__sagemath_polyhedra.py +2 -0
  169. sage/schemes/toric/all.py +10 -0
  170. sage/schemes/toric/chow_group.py +1248 -0
  171. sage/schemes/toric/divisor.py +2082 -0
  172. sage/schemes/toric/divisor_class.cpython-314-darwin.so +0 -0
  173. sage/schemes/toric/divisor_class.pyx +322 -0
  174. sage/schemes/toric/fano_variety.py +1606 -0
  175. sage/schemes/toric/homset.py +650 -0
  176. sage/schemes/toric/ideal.py +451 -0
  177. sage/schemes/toric/library.py +1322 -0
  178. sage/schemes/toric/morphism.py +1958 -0
  179. sage/schemes/toric/points.py +1032 -0
  180. sage/schemes/toric/sheaf/all.py +1 -0
  181. sage/schemes/toric/sheaf/constructor.py +302 -0
  182. sage/schemes/toric/sheaf/klyachko.py +921 -0
  183. sage/schemes/toric/toric_subscheme.py +905 -0
  184. sage/schemes/toric/variety.py +3460 -0
  185. sage/schemes/toric/weierstrass.py +1078 -0
  186. sage/schemes/toric/weierstrass_covering.py +457 -0
  187. sage/schemes/toric/weierstrass_higher.py +288 -0
  188. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
  189. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
  190. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
  191. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
  192. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
  193. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
  194. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
  195. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
  196. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
  197. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
  198. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
  199. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
  200. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
  201. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
  202. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
  203. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
  204. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
  205. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
@@ -0,0 +1,12 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ import pytest
3
+ from sage.numerical.backends.generic_backend_test import GenericBackendTests
4
+ from sage.numerical.backends.generic_backend import GenericBackend
5
+ from sage.numerical.mip import MixedIntegerLinearProgram
6
+
7
+
8
+ class TestInteractiveLPBackend(GenericBackendTests):
9
+
10
+ @pytest.fixture
11
+ def backend(self) -> GenericBackend:
12
+ return MixedIntegerLinearProgram(solver='InteractiveLP').get_backend()
@@ -0,0 +1,391 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ r"""
3
+ Logging Backend
4
+
5
+ It records, for debugging and unit testing purposes, all calls to
6
+ backend methods in one of three ways.
7
+
8
+ See :class:`LoggingBackendFactory` for more information.
9
+ """
10
+
11
+ # ****************************************************************************
12
+ # Copyright (C) 2016 Matthias Koeppe <mkoeppe@math.ucdavis.edu>
13
+ #
14
+ # This program is free software: you can redistribute it and/or modify
15
+ # it under the terms of the GNU General Public License as published by
16
+ # the Free Software Foundation, either version 2 of the License, or
17
+ # (at your option) any later version.
18
+ # https://www.gnu.org/licenses/
19
+ # ****************************************************************************
20
+
21
+
22
+ from sage.numerical.backends.generic_backend import GenericBackend
23
+
24
+
25
+ def _format_function_call(fn_name, *v, **k):
26
+ """
27
+ Return a Python function call as a string.
28
+
29
+ EXAMPLES::
30
+
31
+ sage: from sage.numerical.backends.logging_backend import _format_function_call
32
+ sage: _format_function_call('foo', 17, hellooooo='goodbyeeee')
33
+ "foo(17, hellooooo='goodbyeeee')"
34
+ """
35
+ args = [repr(a) for a in v] + ["%s=%r" % (arg, val) for arg, val in k.items()]
36
+ return "{}({})".format(fn_name, ", ".join(args))
37
+
38
+
39
+ def _make_wrapper(backend, attr):
40
+ """
41
+ Return a wrapper for the backend method named by ``attr`` that does the logging.
42
+
43
+ Documentation and other metadata is copied from the `backend` method named ``attr``.
44
+
45
+ EXAMPLES::
46
+
47
+ sage: from sage.numerical.backends.generic_backend import get_solver
48
+ sage: from sage.numerical.backends.logging_backend import _make_wrapper, LoggingBackend
49
+ sage: backend = get_solver(solver='GLPK')
50
+ sage: w = _make_wrapper(backend, 'ncols')
51
+ sage: logging_backend = LoggingBackend(backend)
52
+ sage: w(logging_backend)
53
+ # p.ncols()
54
+ # result: 0
55
+ 0
56
+ """
57
+ def m(self, *args, **kwdargs):
58
+ funcall = _format_function_call("p." + attr, *args, **kwdargs)
59
+ a = getattr(self._backend, attr)
60
+ if self._printing:
61
+ print("# {}".format(funcall))
62
+ if self._doctest:
63
+ self._doctest.write(" sage: {}\n".format(funcall))
64
+ try:
65
+ result = a(*args, **kwdargs)
66
+ except Exception as e:
67
+ if self._printing:
68
+ print("# exception: {}".format(e))
69
+ if self._doctest:
70
+ self._doctest.write(" Traceback (most recent call last):\n"
71
+ " ...\n"
72
+ " MIPSolverException: {}\n".format(e))
73
+ if self._test_method:
74
+ self._test_method.write((" with tester.assertRaises({}) as cm:\n" +
75
+ " {}\n").format(type(e).__name__, funcall))
76
+ raise
77
+ else:
78
+ if self._printing:
79
+ print("# result: {}".format(result))
80
+ if self._doctest:
81
+ self._doctest.write(" {}\n".format(result))
82
+ if self._test_method:
83
+ if result is None:
84
+ self._test_method.write(" tester.assertIsNone({})\n".format(funcall))
85
+ elif type(result) is float:
86
+ # TODO: by default assertAlmostEqual does 7 decimal places (not significant digits)
87
+ # better perhaps to compute an appropriate 'places' or 'delta' parameter from result.
88
+ self._test_method.write(" tester.assertAlmostEqual({}, {})\n".format(funcall, result))
89
+ else:
90
+ self._test_method.write(" tester.assertEqual({}, {})\n".format(funcall, result))
91
+ return result
92
+ from functools import update_wrapper
93
+ update_wrapper(m, getattr(backend, attr))
94
+ return m
95
+
96
+
97
+ class LoggingBackend(GenericBackend):
98
+ """
99
+ See :class:`LoggingBackendFactory` for documentation.
100
+
101
+ EXAMPLES::
102
+
103
+ sage: import sage.numerical.backends.logging_backend
104
+ sage: from sage.numerical.backends.logging_backend import LoggingBackend
105
+ sage: from sage.numerical.backends.generic_backend import get_solver
106
+ sage: b = get_solver(solver = "GLPK")
107
+ sage: lb = LoggingBackend(backend=b)
108
+ sage: lb.add_variable(obj=42, name='Helloooooo')
109
+ # p.add_variable(obj=42, name='Helloooooo')
110
+ # result: 0
111
+ 0
112
+ sage: lb.add_variable(obj=1789)
113
+ # p.add_variable(obj=1789)
114
+ # result: 1
115
+ 1
116
+
117
+ .. :no-undoc-members:
118
+ """
119
+
120
+ def __init__(self, backend, printing=True, doctest=None, test_method=None,
121
+ base_ring=None):
122
+ """
123
+ See :class:`LoggingBackendFactory` for documentation.
124
+
125
+ EXAMPLES::
126
+
127
+ sage: import sage.numerical.backends.logging_backend
128
+ sage: from sage.numerical.backends.logging_backend import LoggingBackend
129
+ sage: from sage.numerical.backends.generic_backend import get_solver
130
+ sage: b = get_solver(solver = "GLPK")
131
+ sage: lb = LoggingBackend(backend=b)
132
+ """
133
+ self._backend = backend
134
+ self._printing = printing
135
+ self._doctest = doctest
136
+ self._test_method = test_method
137
+ self._base_ring = base_ring
138
+
139
+ def __getattr__(self, attr):
140
+ """
141
+ Look up an attribute in the instance.
142
+
143
+ It is provided to dynamically create delegating methods for all methods of
144
+ the backend that are not part of the :class:`GenericBackend` interface,
145
+ from which :class:`LoggingBackend` inherits.
146
+
147
+ EXAMPLES::
148
+
149
+ sage: import sage.numerical.backends.logging_backend
150
+ sage: from sage.numerical.backends.logging_backend import LoggingBackend
151
+ sage: from sage.numerical.backends.generic_backend import get_solver
152
+ sage: b = get_solver(solver = "GLPK")
153
+ sage: lb = LoggingBackend(backend=b)
154
+ sage: lb.print_ranges
155
+ <bound method ...>
156
+ """
157
+ _a = getattr(self._backend, attr)
158
+ if callable(_a):
159
+ # make a bound method
160
+ import types
161
+ _mm = types.MethodType(_make_wrapper(self._backend, attr), self)
162
+ # cache it
163
+ setattr(self, attr, _mm)
164
+ return _mm
165
+ else:
166
+ return _a
167
+
168
+ def base_ring(self):
169
+ """
170
+ Return the base ring.
171
+
172
+ The backend's base ring can be overridden. It is best to run
173
+ the tests with GLPK and override the base ring to ``QQ``. Then
174
+ default input to backend methods, prepared by
175
+ :class:`MixedIntegerLinearProgram`, depends on the base ring.
176
+ This way input will be rational and so suitable for both exact
177
+ and inexact methods; whereas output will be float and will thus
178
+ trigger :func:`assertAlmostEqual` tests.
179
+
180
+ EXAMPLES::
181
+
182
+ sage: import sage.numerical.backends.logging_backend
183
+ sage: from sage.numerical.backends.logging_backend import LoggingBackend
184
+ sage: from sage.numerical.backends.generic_backend import get_solver
185
+ sage: b = get_solver(solver = "GLPK")
186
+ sage: lb = LoggingBackend(backend=b)
187
+ sage: lb.base_ring()
188
+ Real Double Field
189
+ sage: from sage.rings.rational_field import QQ
190
+ sage: lb = LoggingBackend(backend=b, base_ring=QQ)
191
+ sage: lb.base_ring()
192
+ Rational Field
193
+ """
194
+ if self._base_ring is not None:
195
+ return self._base_ring
196
+ else:
197
+ return self._backend.base_ring()
198
+
199
+
200
+ # Override all methods that we inherited from GenericBackend
201
+ # by delegating methods
202
+ def _override_attr(attr):
203
+ """
204
+ Override a method by a delegating method.
205
+ """
206
+ a = getattr(LoggingBackend, attr)
207
+ if callable(a):
208
+ m = _make_wrapper(GenericBackend(), attr)
209
+ setattr(LoggingBackend, attr, m)
210
+
211
+
212
+ for attr in dir(LoggingBackend):
213
+ if not attr.startswith("_") and attr not in ("zero", "base_ring"):
214
+ _override_attr(attr)
215
+
216
+ test_method_template = \
217
+ r'''
218
+ @classmethod
219
+ def _test_{name}(cls, tester=None, **options):
220
+ """
221
+ Run tests on ...
222
+
223
+ TESTS::
224
+
225
+ SAGE: from sage.numerical.backends.generic_backend import GenericBackend
226
+ SAGE: p = GenericBackend()
227
+ SAGE: p._test_{name}()
228
+ Traceback (most recent call last):
229
+ ...
230
+ NotImplementedError
231
+ """
232
+ p = cls() # fresh instance of the backend
233
+ if tester is None:
234
+ tester = p._tester(**options)
235
+ '''.replace("SAGE:", "sage:") # so that the above test does not get picked up by the doctester
236
+
237
+ from sage.rings.rational_field import QQ
238
+
239
+
240
+ def LoggingBackendFactory(solver=None, printing=True, doctest_file=None, test_method_file=None,
241
+ test_method=None, base_ring=QQ):
242
+ """
243
+ Factory that constructs a :class:`LoggingBackend` for debugging and testing.
244
+
245
+ An instance of it can be passed as the solver argument of
246
+ :func:`sage.numerical.backends.generic_backend.get_solver` and
247
+ :class:`MixedIntegerLinearProgram`.
248
+
249
+ EXAMPLES:
250
+
251
+ Assume that we have the following function that does some
252
+ computation using :class:`MixedIntegerLinearProgram` (or MIP
253
+ backend methods), and suppose we have observed that it works with
254
+ the GLPK backend, but not with the COIN backend::
255
+
256
+ sage: def compute_something(solver='GLPK'):
257
+ ....: from sage.numerical.mip import MIPSolverException
258
+ ....: mip = MixedIntegerLinearProgram(solver=solver)
259
+ ....: lb = mip.get_backend()
260
+ ....: lb.add_variable(obj=42, name='Helloooooo')
261
+ ....: lb.add_variable(obj=1789)
262
+ ....: try:
263
+ ....: lb.solve()
264
+ ....: except MIPSolverException:
265
+ ....: return 4711
266
+ ....: else:
267
+ ....: return 91
268
+
269
+ We can investigate what the backend methods are doing by running a
270
+ :class:`LoggingBackend` in its in-terminal logging mode::
271
+
272
+ sage: import sage.numerical.backends.logging_backend
273
+ sage: from sage.numerical.backends.logging_backend import LoggingBackendFactory
274
+ sage: compute_something(solver = LoggingBackendFactory(solver='GLPK'))
275
+ # p = get_solver(solver='GLPK')
276
+ # p.add_variable(obj=42, name='Helloooooo')
277
+ # result: 0
278
+ # p.add_variable(obj=1789)
279
+ # result: 1
280
+ # p.solve()
281
+ # exception: GLPK: The LP (relaxation) problem has no dual feasible solution
282
+ 4711
283
+
284
+ By replacing 'GLPK' by 'COIN' above, we can then compare the two
285
+ logs and see where they differ.
286
+
287
+ Imagine that we have now fixed the bug in the COIN backend, and we
288
+ want to add a doctest that documents this fact. We do not want to
289
+ call ``compute_something`` in the doctest, but rather just have a
290
+ sequence of calls to backend methods.
291
+
292
+ We can have the doctest autogenerated by running a
293
+ :class:`LoggingBackend` in its doctest-writing mode::
294
+
295
+ sage: fname = tmp_filename()
296
+ sage: compute_something(solver = LoggingBackendFactory(solver='GLPK', printing=False,
297
+ ....: doctest_file=fname))
298
+ 4711
299
+ sage: with open(fname) as f:
300
+ ....: for line in f.readlines(): _ = sys.stdout.write('|{}'.format(line))
301
+ | sage: p = get_solver(solver='GLPK')
302
+ | sage: p.add_variable(obj=42, name='Helloooooo')
303
+ | 0
304
+ | sage: p.add_variable(obj=1789)
305
+ | 1
306
+ | sage: p.solve()
307
+ | Traceback (most recent call last):
308
+ | ...
309
+ | MIPSolverException: GLPK: The LP (relaxation) problem has no dual feasible solution
310
+
311
+ We then copy from the generated file and paste into the source
312
+ code of the COIN backend.
313
+
314
+ If this test seems valuable enough that all backends should be
315
+ tested against it, we should create a test method instead of a
316
+ docstring.
317
+
318
+ We can have the test method autogenerated by running a
319
+ :class:`LoggingBackend` in its test-method-writing mode::
320
+
321
+ sage: fname = tmp_filename()
322
+ sage: compute_something(solver= LoggingBackendFactory(solver='GLPK', printing=False,
323
+ ....: test_method_file=fname,
324
+ ....: test_method='something'))
325
+ 4711
326
+ sage: with open(fname) as f:
327
+ ....: for line in f.readlines(): _ = sys.stdout.write('|{}'.format(line))
328
+ |
329
+ | @classmethod
330
+ | def _test_something(cls, tester=None, **options):
331
+ | ...
332
+ | Run tests on ...
333
+ |
334
+ | TESTS::
335
+ |
336
+ | sage: from sage.numerical.backends.generic_backend import GenericBackend
337
+ | sage: p = GenericBackend()
338
+ | sage: p._test_something()
339
+ | Traceback (most recent call last):
340
+ | ...
341
+ | NotImplementedError
342
+ | ...
343
+ | p = cls() # fresh instance of the backend
344
+ | if tester is None:
345
+ | tester = p._tester(**options)
346
+ | tester.assertEqual(p.add_variable(obj=42, name='Helloooooo'), 0)
347
+ | tester.assertEqual(p.add_variable(obj=1789), 1)
348
+ | with tester.assertRaises(MIPSolverException) as cm:
349
+ | p.solve()
350
+
351
+ We then copy from the generated file and paste into the source
352
+ code of the generic backend, where all test methods are defined.
353
+
354
+ If ``test_method_file`` is not provided, a default output file name
355
+ will be computed from ``test_method``.
356
+ """
357
+
358
+ if test_method is not None:
359
+ if test_method_file is None:
360
+ # Construct output file name from method name.
361
+ test_method_file = "test_{}.py".format(test_method)
362
+ else:
363
+ test_method = 'CHANGE'
364
+ # Will have to be edited by user in generated file.
365
+
366
+ if doctest_file is not None:
367
+ doctest = open(doctest_file, "w", 1) # line-buffered
368
+ else:
369
+ doctest = None
370
+ if test_method_file is not None:
371
+ test_method_output = open(test_method_file, "w", 1) # line-buffered
372
+ else:
373
+ test_method_output = None
374
+
375
+ def logging_solver(**kwds):
376
+ """
377
+ Create an instance of :class:`LoggingBackend`.
378
+ """
379
+ construct = "p = {}".format(_format_function_call('get_solver', solver=solver, **kwds))
380
+ if printing:
381
+ print("# {}".format(construct))
382
+ if doctest is not None:
383
+ doctest.write(" sage: {}\n".format(construct))
384
+ if test_method_output is not None:
385
+ test_method_output.write(test_method_template.format(name=test_method))
386
+ from sage.numerical.backends.generic_backend import get_solver
387
+ return LoggingBackend(backend=get_solver(solver=solver, **kwds),
388
+ printing=printing, doctest=doctest, test_method=test_method_output,
389
+ base_ring=base_ring)
390
+
391
+ return logging_solver
@@ -0,0 +1,15 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ from sage.numerical.backends.generic_sdp_backend cimport GenericSDPBackend
3
+
4
+
5
+ cdef class MatrixSDPBackend(GenericSDPBackend):
6
+
7
+ cdef list objective_function
8
+ cdef list coeffs_matrix
9
+ cdef bint is_maximize
10
+
11
+ cdef list row_name_var
12
+ cdef list col_name_var
13
+ cdef str name
14
+
15
+ cdef object _base_ring