passagemath-polyhedra 10.6.31rc3__cp314-cp314-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-polyhedra might be problematic. Click here for more details.
- passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +367 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +369 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +208 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_polyhedra.libs/libgcc_s-0cd532bd.so.1 +0 -0
- passagemath_polyhedra.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_polyhedra.libs/libgomp-8949ffbe.so.1.0.0 +0 -0
- passagemath_polyhedra.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
- sage/all__sagemath_polyhedra.py +50 -0
- sage/game_theory/all.py +8 -0
- sage/game_theory/catalog.py +6 -0
- sage/game_theory/catalog_normal_form_games.py +923 -0
- sage/game_theory/cooperative_game.py +844 -0
- sage/game_theory/matching_game.py +1181 -0
- sage/game_theory/normal_form_game.py +2697 -0
- sage/game_theory/parser.py +275 -0
- sage/geometry/all__sagemath_polyhedra.py +22 -0
- sage/geometry/cone.py +6940 -0
- sage/geometry/cone_catalog.py +847 -0
- sage/geometry/cone_critical_angles.py +1027 -0
- sage/geometry/convex_set.py +1119 -0
- sage/geometry/fan.py +3743 -0
- sage/geometry/fan_isomorphism.py +389 -0
- sage/geometry/fan_morphism.py +1884 -0
- sage/geometry/hasse_diagram.py +202 -0
- sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
- sage/geometry/hyperplane_arrangement/all.py +1 -0
- sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
- sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
- sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
- sage/geometry/hyperplane_arrangement/library.py +825 -0
- sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
- sage/geometry/hyperplane_arrangement/plot.py +520 -0
- sage/geometry/integral_points.py +35 -0
- sage/geometry/integral_points_generic_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/integral_points_generic_dense.pyx +7 -0
- sage/geometry/lattice_polytope.py +5894 -0
- sage/geometry/linear_expression.py +773 -0
- sage/geometry/newton_polygon.py +767 -0
- sage/geometry/point_collection.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/point_collection.pyx +1008 -0
- sage/geometry/polyhedral_complex.py +2616 -0
- sage/geometry/polyhedron/all.py +8 -0
- sage/geometry/polyhedron/backend_cdd.py +460 -0
- sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
- sage/geometry/polyhedron/backend_field.py +347 -0
- sage/geometry/polyhedron/backend_normaliz.py +2503 -0
- sage/geometry/polyhedron/backend_number_field.py +168 -0
- sage/geometry/polyhedron/backend_polymake.py +765 -0
- sage/geometry/polyhedron/backend_ppl.py +582 -0
- sage/geometry/polyhedron/base.py +1206 -0
- sage/geometry/polyhedron/base0.py +1444 -0
- sage/geometry/polyhedron/base1.py +886 -0
- sage/geometry/polyhedron/base2.py +812 -0
- sage/geometry/polyhedron/base3.py +1845 -0
- sage/geometry/polyhedron/base4.py +1262 -0
- sage/geometry/polyhedron/base5.py +2700 -0
- sage/geometry/polyhedron/base6.py +1741 -0
- sage/geometry/polyhedron/base7.py +997 -0
- sage/geometry/polyhedron/base_QQ.py +1258 -0
- sage/geometry/polyhedron/base_RDF.py +98 -0
- sage/geometry/polyhedron/base_ZZ.py +934 -0
- sage/geometry/polyhedron/base_mutable.py +215 -0
- sage/geometry/polyhedron/base_number_field.py +122 -0
- sage/geometry/polyhedron/cdd_file_format.py +155 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
- sage/geometry/polyhedron/constructor.py +773 -0
- sage/geometry/polyhedron/double_description.py +753 -0
- sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
- sage/geometry/polyhedron/face.py +1060 -0
- sage/geometry/polyhedron/generating_function.py +1810 -0
- sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
- sage/geometry/polyhedron/library.py +3502 -0
- sage/geometry/polyhedron/misc.py +121 -0
- sage/geometry/polyhedron/modules/all.py +1 -0
- sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
- sage/geometry/polyhedron/palp_database.py +447 -0
- sage/geometry/polyhedron/parent.py +1279 -0
- sage/geometry/polyhedron/plot.py +1986 -0
- sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
- sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
- sage/geometry/polyhedron/representation.py +1723 -0
- sage/geometry/pseudolines.py +515 -0
- sage/geometry/relative_interior.py +445 -0
- sage/geometry/toric_plotter.py +1103 -0
- sage/geometry/triangulation/all.py +2 -0
- sage/geometry/triangulation/base.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/triangulation/base.pyx +963 -0
- sage/geometry/triangulation/data.h +147 -0
- sage/geometry/triangulation/data.pxd +4 -0
- sage/geometry/triangulation/element.py +914 -0
- sage/geometry/triangulation/functions.h +10 -0
- sage/geometry/triangulation/functions.pxd +4 -0
- sage/geometry/triangulation/point_configuration.py +2256 -0
- sage/geometry/triangulation/triangulations.h +49 -0
- sage/geometry/triangulation/triangulations.pxd +7 -0
- sage/geometry/voronoi_diagram.py +319 -0
- sage/interfaces/all__sagemath_polyhedra.py +1 -0
- sage/interfaces/polymake.py +2028 -0
- sage/numerical/all.py +13 -0
- sage/numerical/all__sagemath_polyhedra.py +11 -0
- sage/numerical/backends/all.py +1 -0
- sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
- sage/numerical/backends/cvxopt_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_backend.pyx +1006 -0
- sage/numerical/backends/cvxopt_backend_test.py +19 -0
- sage/numerical/backends/cvxopt_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
- sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/cvxpy_backend.pxd +41 -0
- sage/numerical/backends/cvxpy_backend.pyx +934 -0
- sage/numerical/backends/cvxpy_backend_test.py +13 -0
- sage/numerical/backends/generic_backend_test.py +24 -0
- sage/numerical/backends/interactivelp_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/interactivelp_backend.pxd +36 -0
- sage/numerical/backends/interactivelp_backend.pyx +1231 -0
- sage/numerical/backends/interactivelp_backend_test.py +12 -0
- sage/numerical/backends/logging_backend.py +391 -0
- sage/numerical/backends/matrix_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
- sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
- sage/numerical/backends/ppl_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/ppl_backend.pyx +1126 -0
- sage/numerical/backends/ppl_backend_test.py +13 -0
- sage/numerical/backends/scip_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/scip_backend.pxd +22 -0
- sage/numerical/backends/scip_backend.pyx +1289 -0
- sage/numerical/backends/scip_backend_test.py +13 -0
- sage/numerical/interactive_simplex_method.py +5338 -0
- sage/numerical/knapsack.py +665 -0
- sage/numerical/linear_functions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/linear_functions.pxd +31 -0
- sage/numerical/linear_functions.pyx +1648 -0
- sage/numerical/linear_tensor.py +470 -0
- sage/numerical/linear_tensor_constraints.py +448 -0
- sage/numerical/linear_tensor_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/linear_tensor_element.pxd +6 -0
- sage/numerical/linear_tensor_element.pyx +459 -0
- sage/numerical/mip.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/mip.pxd +40 -0
- sage/numerical/mip.pyx +3667 -0
- sage/numerical/sdp.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/sdp.pxd +39 -0
- sage/numerical/sdp.pyx +1433 -0
- sage/rings/all__sagemath_polyhedra.py +3 -0
- sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
- sage/rings/polynomial/omega.py +982 -0
- sage/schemes/all__sagemath_polyhedra.py +2 -0
- sage/schemes/toric/all.py +10 -0
- sage/schemes/toric/chow_group.py +1248 -0
- sage/schemes/toric/divisor.py +2082 -0
- sage/schemes/toric/divisor_class.cpython-314-x86_64-linux-musl.so +0 -0
- sage/schemes/toric/divisor_class.pyx +322 -0
- sage/schemes/toric/fano_variety.py +1606 -0
- sage/schemes/toric/homset.py +650 -0
- sage/schemes/toric/ideal.py +451 -0
- sage/schemes/toric/library.py +1322 -0
- sage/schemes/toric/morphism.py +1958 -0
- sage/schemes/toric/points.py +1032 -0
- sage/schemes/toric/sheaf/all.py +1 -0
- sage/schemes/toric/sheaf/constructor.py +302 -0
- sage/schemes/toric/sheaf/klyachko.py +921 -0
- sage/schemes/toric/toric_subscheme.py +905 -0
- sage/schemes/toric/variety.py +3460 -0
- sage/schemes/toric/weierstrass.py +1078 -0
- sage/schemes/toric/weierstrass_covering.py +457 -0
- sage/schemes/toric/weierstrass_higher.py +288 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
- sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
- sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
r"""
|
|
3
|
+
Double Description for Arbitrary Polyhedra
|
|
4
|
+
|
|
5
|
+
This module is part of the python backend for polyhedra. It uses the
|
|
6
|
+
double description method for cones
|
|
7
|
+
:mod:`~sage.geometry.polyhedron.double_description` to find minimal
|
|
8
|
+
H/V-representations of polyhedra. The latter works with cones
|
|
9
|
+
only. This is sufficient to treat general polyhedra by the following
|
|
10
|
+
construction: Any polyhedron can be embedded in one dimension higher
|
|
11
|
+
in the hyperplane `(1, *, \dots, *)`. The cone over the embedded
|
|
12
|
+
polyhedron will be called the *homogenized cone* in the
|
|
13
|
+
following. Conversely, intersecting the homogenized cone with the
|
|
14
|
+
hyperplane `x_0=1` gives you back the original polyhedron.
|
|
15
|
+
|
|
16
|
+
While slower than specialized C/C++ implementations, the
|
|
17
|
+
implementation is general and works with any field in Sage that allows
|
|
18
|
+
you to define polyhedra.
|
|
19
|
+
|
|
20
|
+
.. NOTE::
|
|
21
|
+
|
|
22
|
+
If you just want polyhedra over arbitrary fields then you should
|
|
23
|
+
just use the
|
|
24
|
+
:func:`~sage.geometry.polyhedron.constructor.Polyhedron`
|
|
25
|
+
constructor.
|
|
26
|
+
|
|
27
|
+
EXAMPLES::
|
|
28
|
+
|
|
29
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous \
|
|
30
|
+
....: import Hrep2Vrep, Vrep2Hrep
|
|
31
|
+
sage: Hrep2Vrep(QQ, 2, [(1,2,3), (2,4,3)], [])
|
|
32
|
+
[-1/2|-1/2 1/2|]
|
|
33
|
+
[ 0| 2/3 -1/3|]
|
|
34
|
+
|
|
35
|
+
Note that the columns of the printed matrix are the vertices, rays,
|
|
36
|
+
and lines of the minimal V-representation. Dually, the rows of the
|
|
37
|
+
following are the inequalities and equations::
|
|
38
|
+
|
|
39
|
+
sage: Vrep2Hrep(QQ, 2, [(-1/2,0)], [(-1/2,2/3), (1/2,-1/3)], [])
|
|
40
|
+
[1 2 3]
|
|
41
|
+
[2 4 3]
|
|
42
|
+
[-----]
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
# ****************************************************************************
|
|
46
|
+
# Copyright (C) 2014 Volker Braun <vbraun.name@gmail.com>
|
|
47
|
+
#
|
|
48
|
+
# This program is free software: you can redistribute it and/or modify
|
|
49
|
+
# it under the terms of the GNU General Public License as published by
|
|
50
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
51
|
+
# (at your option) any later version.
|
|
52
|
+
# https://www.gnu.org/licenses/
|
|
53
|
+
# ****************************************************************************
|
|
54
|
+
|
|
55
|
+
from sage.structure.sage_object import SageObject
|
|
56
|
+
from sage.matrix.constructor import matrix
|
|
57
|
+
from sage.modules.free_module_element import vector
|
|
58
|
+
from sage.geometry.polyhedron.double_description import StandardAlgorithm as Algorithm
|
|
59
|
+
|
|
60
|
+
# Compare with PPL if the base ring is QQ. Can be left enabled since
|
|
61
|
+
# we don't use the Python fallback for polyhedra over QQ unless you
|
|
62
|
+
# construct one by hand.
|
|
63
|
+
VERIFY_RESULT = True
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class PivotedInequalities(SageObject):
|
|
67
|
+
|
|
68
|
+
def __init__(self, base_ring, dim):
|
|
69
|
+
"""
|
|
70
|
+
Base class for inequalities that may contain linear subspaces.
|
|
71
|
+
|
|
72
|
+
INPUT:
|
|
73
|
+
|
|
74
|
+
- ``base_ring`` -- a field
|
|
75
|
+
|
|
76
|
+
- ``dim`` -- integer; the ambient space dimension
|
|
77
|
+
|
|
78
|
+
EXAMPLES::
|
|
79
|
+
|
|
80
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous \
|
|
81
|
+
....: import PivotedInequalities
|
|
82
|
+
sage: piv = PivotedInequalities(QQ, 2)
|
|
83
|
+
sage: piv._pivot_inequalities(matrix([(1,1,3), (5,5,7)]))
|
|
84
|
+
[1 3]
|
|
85
|
+
[5 7]
|
|
86
|
+
sage: piv._pivots
|
|
87
|
+
(0, 2)
|
|
88
|
+
sage: piv._linear_subspace
|
|
89
|
+
Free module of degree 3 and rank 1 over Integer Ring
|
|
90
|
+
Echelon basis matrix:
|
|
91
|
+
[ 1 -1 0]
|
|
92
|
+
"""
|
|
93
|
+
self.base_ring = base_ring
|
|
94
|
+
self.dim = dim
|
|
95
|
+
|
|
96
|
+
def _pivot_inequalities(self, A):
|
|
97
|
+
"""
|
|
98
|
+
Pick pivots for inequalities.
|
|
99
|
+
|
|
100
|
+
INPUT:
|
|
101
|
+
|
|
102
|
+
- ``A`` -- matrix; the inequalities
|
|
103
|
+
|
|
104
|
+
OUTPUT: the matrix of pivot columns
|
|
105
|
+
|
|
106
|
+
EXAMPLES::
|
|
107
|
+
|
|
108
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous \
|
|
109
|
+
....: import PivotedInequalities
|
|
110
|
+
sage: piv = PivotedInequalities(QQ, 2)
|
|
111
|
+
sage: piv._pivot_inequalities(matrix([(1,1,3), (5,5,7)]))
|
|
112
|
+
[1 3]
|
|
113
|
+
[5 7]
|
|
114
|
+
"""
|
|
115
|
+
self._linear_subspace = A.right_kernel()
|
|
116
|
+
self._pivots = A.pivots()
|
|
117
|
+
self._nonpivots = A.nonpivots()
|
|
118
|
+
return A.matrix_from_columns(self._pivots)
|
|
119
|
+
|
|
120
|
+
def _unpivot_ray(self, ray):
|
|
121
|
+
"""
|
|
122
|
+
Undo the pivoting to go back to the original inequalities
|
|
123
|
+
containing a linear subspace.
|
|
124
|
+
|
|
125
|
+
INPUT:
|
|
126
|
+
|
|
127
|
+
- ``ray`` -- ray in the pivoted coordinates
|
|
128
|
+
|
|
129
|
+
OUTPUT: ray in the original coordinates
|
|
130
|
+
|
|
131
|
+
EXAMPLES::
|
|
132
|
+
|
|
133
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous \
|
|
134
|
+
....: import PivotedInequalities
|
|
135
|
+
sage: piv = PivotedInequalities(QQ, 2)
|
|
136
|
+
sage: piv._pivot_inequalities(matrix([(1,1,3), (5,5,7)]))
|
|
137
|
+
[1 3]
|
|
138
|
+
[5 7]
|
|
139
|
+
sage: piv._unpivot_ray([1, 3])
|
|
140
|
+
(1, 0, 3)
|
|
141
|
+
"""
|
|
142
|
+
result = [self.base_ring.zero()] * (self.dim + 1)
|
|
143
|
+
for r, i in zip(ray, self._pivots):
|
|
144
|
+
result[i] = r
|
|
145
|
+
return vector(self.base_ring, result)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class Hrep2Vrep(PivotedInequalities):
|
|
149
|
+
|
|
150
|
+
def __init__(self, base_ring, dim, inequalities, equations):
|
|
151
|
+
"""
|
|
152
|
+
Convert H-representation to a minimal V-representation.
|
|
153
|
+
|
|
154
|
+
INPUT:
|
|
155
|
+
|
|
156
|
+
- ``base_ring`` -- a field
|
|
157
|
+
|
|
158
|
+
- ``dim`` -- integer; the ambient space dimension
|
|
159
|
+
|
|
160
|
+
- ``inequalities`` -- list of inequalities; each inequality
|
|
161
|
+
is given as constant term, ``dim`` coefficients
|
|
162
|
+
|
|
163
|
+
- ``equations`` -- list of equations; same notation as for
|
|
164
|
+
inequalities
|
|
165
|
+
|
|
166
|
+
EXAMPLES::
|
|
167
|
+
|
|
168
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Hrep2Vrep
|
|
169
|
+
sage: Hrep2Vrep(QQ, 2, [(1,2,3), (2,4,3)], [])
|
|
170
|
+
[-1/2|-1/2 1/2|]
|
|
171
|
+
[ 0| 2/3 -1/3|]
|
|
172
|
+
sage: Hrep2Vrep(QQ, 2, [(1,2,3), (2,-2,-3)], [])
|
|
173
|
+
[ 1 -1/2|| 1]
|
|
174
|
+
[ 0 0||-2/3]
|
|
175
|
+
sage: Hrep2Vrep(QQ, 2, [(1,2,3), (2,2,3)], [])
|
|
176
|
+
[-1/2| 1/2| 1]
|
|
177
|
+
[ 0| 0|-2/3]
|
|
178
|
+
sage: Hrep2Vrep(QQ, 2, [(8,7,-2), (1,-4,3), (4,-3,-1)], [])
|
|
179
|
+
[ 1 0 -2||]
|
|
180
|
+
[ 1 4 -3||]
|
|
181
|
+
sage: Hrep2Vrep(QQ, 2, [(1,2,3), (2,4,3), (5,-1,-2)], [])
|
|
182
|
+
[-19/5 -1/2| 2/33 1/11|]
|
|
183
|
+
[ 22/5 0|-1/33 -2/33|]
|
|
184
|
+
sage: Hrep2Vrep(QQ, 2, [(0,2,3), (0,4,3), (0,-1,-2)], [])
|
|
185
|
+
[ 0| 1/2 1/3|]
|
|
186
|
+
[ 0|-1/3 -1/6|]
|
|
187
|
+
sage: Hrep2Vrep(QQ, 2, [], [(1,2,3), (7,8,9)])
|
|
188
|
+
[-2||]
|
|
189
|
+
[ 1||]
|
|
190
|
+
sage: Hrep2Vrep(QQ, 2, [(1,0,0)], []) # universe
|
|
191
|
+
[0||1 0]
|
|
192
|
+
[0||0 1]
|
|
193
|
+
sage: Hrep2Vrep(QQ, 2, [(-1,0,0)], []) # empty
|
|
194
|
+
[]
|
|
195
|
+
sage: Hrep2Vrep(QQ, 2, [], []) # universe
|
|
196
|
+
[0||1 0]
|
|
197
|
+
[0||0 1]
|
|
198
|
+
"""
|
|
199
|
+
super().__init__(base_ring, dim)
|
|
200
|
+
inequalities = [list(x) for x in inequalities]
|
|
201
|
+
equations = [list(x) for x in equations]
|
|
202
|
+
if not inequalities and not equations:
|
|
203
|
+
# Adding a trivial inequality, so that the ambient dimension is passed to the algorithm.
|
|
204
|
+
inequalities = [[self.base_ring.one()] + [self.base_ring.zero()] * self.dim]
|
|
205
|
+
A = self._init_Vrep(inequalities, equations)
|
|
206
|
+
DD = Algorithm(A).run()
|
|
207
|
+
self._extract_Vrep(DD)
|
|
208
|
+
if VERIFY_RESULT:
|
|
209
|
+
self.verify(inequalities, equations)
|
|
210
|
+
|
|
211
|
+
def _init_Vrep(self, inequalities, equations):
|
|
212
|
+
"""
|
|
213
|
+
Split off the linear subspace from the inequalities and select pivots.
|
|
214
|
+
|
|
215
|
+
INPUT:
|
|
216
|
+
|
|
217
|
+
- ``inequalities``, ``equations`` -- see :class:`Vrep2Hrep`
|
|
218
|
+
|
|
219
|
+
OUTPUT: the pivoted inequalities
|
|
220
|
+
|
|
221
|
+
TESTS::
|
|
222
|
+
|
|
223
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Hrep2Vrep
|
|
224
|
+
sage: H2V = Hrep2Vrep(QQ, 2, [], [])
|
|
225
|
+
sage: H2V._init_Vrep([(1,0,3), (3,0,1)], [])
|
|
226
|
+
[1 3]
|
|
227
|
+
[3 1]
|
|
228
|
+
"""
|
|
229
|
+
neg_eqns = [[-e for e in eqn] for eqn in equations]
|
|
230
|
+
A = matrix(self.base_ring, equations + neg_eqns + inequalities)
|
|
231
|
+
return self._pivot_inequalities(A)
|
|
232
|
+
|
|
233
|
+
def _split_linear_subspace(self):
|
|
234
|
+
r"""
|
|
235
|
+
Split the linear subspace in a generator with `x_0\not=0` and the
|
|
236
|
+
remaining generators with `x_0=0`.
|
|
237
|
+
|
|
238
|
+
OUTPUT:
|
|
239
|
+
|
|
240
|
+
Pair consisting of a line generator with its first coordinate
|
|
241
|
+
scaled to one (if it exists, otherwise ``None``) and a list of
|
|
242
|
+
remaining line generators whose first coordinate has been
|
|
243
|
+
chosen to be zero.
|
|
244
|
+
|
|
245
|
+
EXAMPLES::
|
|
246
|
+
|
|
247
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Hrep2Vrep
|
|
248
|
+
sage: H = Hrep2Vrep(QQ, 2, [(1,2,3)], [])
|
|
249
|
+
sage: H._split_linear_subspace()
|
|
250
|
+
((1, 0, -1/3), [(0, 1, -2/3)])
|
|
251
|
+
sage: H = Hrep2Vrep(QQ, 2, [(1,0,0)], [])
|
|
252
|
+
sage: H._split_linear_subspace()
|
|
253
|
+
(None, [(0, 1, 0), (0, 0, 1)])
|
|
254
|
+
"""
|
|
255
|
+
lines = self._linear_subspace.basis_matrix().rows()
|
|
256
|
+
L0 = []
|
|
257
|
+
L1 = []
|
|
258
|
+
zero = self.base_ring.zero()
|
|
259
|
+
for l in lines:
|
|
260
|
+
if l[0] == zero:
|
|
261
|
+
L0.append(l)
|
|
262
|
+
else:
|
|
263
|
+
l = l / l[0]
|
|
264
|
+
L1.append(l)
|
|
265
|
+
if len(L1) == 0:
|
|
266
|
+
return None, L0
|
|
267
|
+
else:
|
|
268
|
+
l1 = L1.pop()
|
|
269
|
+
return l1, L0 + [l - l[0] * l1 for l in L1]
|
|
270
|
+
|
|
271
|
+
def _extract_Vrep(self, DD):
|
|
272
|
+
r"""
|
|
273
|
+
Extract the V-representation from the extremal rays
|
|
274
|
+
of the homogeneous cone.
|
|
275
|
+
|
|
276
|
+
The V-representation is the intersection of the cone generated
|
|
277
|
+
by the rays `R` and ``self._linear_subspace`` with the
|
|
278
|
+
hyperplane `(1, *, *, \ldots, *)`.
|
|
279
|
+
|
|
280
|
+
INPUT:
|
|
281
|
+
|
|
282
|
+
- ``DD`` -- a
|
|
283
|
+
:class:`~sage.geometry.polyhedron.double_description.DoubleDescriptionPair`
|
|
284
|
+
|
|
285
|
+
TESTS::
|
|
286
|
+
|
|
287
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Hrep2Vrep
|
|
288
|
+
sage: H = Hrep2Vrep(QQ, 1, [(1,2)], [])
|
|
289
|
+
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
|
|
290
|
+
sage: DD = StandardAlgorithm(matrix([[1,2], [3,5]])).run()
|
|
291
|
+
sage: H._extract_Vrep(DD)
|
|
292
|
+
sage: H.vertices
|
|
293
|
+
[(-1/2)]
|
|
294
|
+
"""
|
|
295
|
+
R = [self._unpivot_ray(_) for _ in DD.R]
|
|
296
|
+
|
|
297
|
+
line1, L0 = self._split_linear_subspace()
|
|
298
|
+
if line1:
|
|
299
|
+
# we can shift all rays to have x_0 = 0, stay extremal
|
|
300
|
+
L1 = [line1]
|
|
301
|
+
R1 = []
|
|
302
|
+
R0 = [r - r[0] * line1 for r in R]
|
|
303
|
+
else:
|
|
304
|
+
# have to really intersect with x_0 = 0
|
|
305
|
+
L1 = []
|
|
306
|
+
zero = self.base_ring.zero()
|
|
307
|
+
R1 = [r / r[0] for r in R if r[0] > zero]
|
|
308
|
+
DD0 = DD.first_coordinate_plane()
|
|
309
|
+
R0 = [self._unpivot_ray(_) for _ in DD0.R]
|
|
310
|
+
|
|
311
|
+
vertices = []
|
|
312
|
+
one = self.base_ring.one()
|
|
313
|
+
for v in R1 + L1:
|
|
314
|
+
assert v[0] == one
|
|
315
|
+
vertices.append(v[1:])
|
|
316
|
+
self.vertices = vertices
|
|
317
|
+
if len(vertices) > 0:
|
|
318
|
+
self.rays = [r[1:] for r in R0]
|
|
319
|
+
self.lines = [l[1:] for l in L0]
|
|
320
|
+
else:
|
|
321
|
+
# empty polyhedron
|
|
322
|
+
self.rays = self.lines = []
|
|
323
|
+
|
|
324
|
+
def _repr_(self):
|
|
325
|
+
"""
|
|
326
|
+
Return a string representation.
|
|
327
|
+
|
|
328
|
+
EXAMPLES::
|
|
329
|
+
|
|
330
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Hrep2Vrep
|
|
331
|
+
sage: H = Hrep2Vrep(QQ, 1, [(1,2)], [])
|
|
332
|
+
sage: H._repr_()
|
|
333
|
+
'[-1/2| 1/2|]'
|
|
334
|
+
"""
|
|
335
|
+
from sage.matrix.constructor import block_matrix
|
|
336
|
+
|
|
337
|
+
def make_matrix(rows):
|
|
338
|
+
return matrix(self.base_ring, len(rows), self.dim, rows).transpose()
|
|
339
|
+
V = make_matrix(self.vertices)
|
|
340
|
+
R = make_matrix(self.rays)
|
|
341
|
+
L = make_matrix(self.lines)
|
|
342
|
+
return str(block_matrix([[V, R, L]]))
|
|
343
|
+
|
|
344
|
+
def verify(self, inequalities, equations):
|
|
345
|
+
"""
|
|
346
|
+
Compare result to PPL if the base ring is QQ.
|
|
347
|
+
|
|
348
|
+
This method is for debugging purposes and compares the
|
|
349
|
+
computation with another backend if available.
|
|
350
|
+
|
|
351
|
+
INPUT:
|
|
352
|
+
|
|
353
|
+
- ``inequalities``, ``equations`` -- see :class:`Hrep2Vrep`
|
|
354
|
+
|
|
355
|
+
EXAMPLES::
|
|
356
|
+
|
|
357
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Hrep2Vrep
|
|
358
|
+
sage: H = Hrep2Vrep(QQ, 1, [(1,2)], [])
|
|
359
|
+
sage: H.verify([(1,2)], [])
|
|
360
|
+
"""
|
|
361
|
+
from sage.rings.rational_field import QQ
|
|
362
|
+
from sage.geometry.polyhedron.constructor import Polyhedron
|
|
363
|
+
if self.base_ring is not QQ:
|
|
364
|
+
return
|
|
365
|
+
P = Polyhedron(vertices=self.vertices, rays=self.rays, lines=self.lines,
|
|
366
|
+
base_ring=QQ, ambient_dim=self.dim, backend='ppl')
|
|
367
|
+
Q = Polyhedron(ieqs=inequalities, eqns=equations,
|
|
368
|
+
base_ring=QQ, ambient_dim=self.dim, backend='ppl')
|
|
369
|
+
if (P != Q) or \
|
|
370
|
+
(len(self.vertices) != P.n_vertices()) or \
|
|
371
|
+
(len(self.rays) != P.n_rays()) or \
|
|
372
|
+
(len(self.lines) != P.n_lines()):
|
|
373
|
+
print('incorrect!', end="")
|
|
374
|
+
print(Q.Vrepresentation())
|
|
375
|
+
print(P.Hrepresentation())
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
class Vrep2Hrep(PivotedInequalities):
|
|
379
|
+
|
|
380
|
+
def __init__(self, base_ring, dim, vertices, rays, lines):
|
|
381
|
+
"""
|
|
382
|
+
Convert V-representation to a minimal H-representation.
|
|
383
|
+
|
|
384
|
+
INPUT:
|
|
385
|
+
|
|
386
|
+
- ``base_ring`` -- a field
|
|
387
|
+
|
|
388
|
+
- ``dim`` -- integer; the ambient space dimension
|
|
389
|
+
|
|
390
|
+
- ``vertices`` -- list of vertices; each vertex is given as
|
|
391
|
+
list of ``dim`` coordinates
|
|
392
|
+
|
|
393
|
+
- ``rays`` -- list of rays; each ray is given as
|
|
394
|
+
list of ``dim`` coordinates, not all zero
|
|
395
|
+
|
|
396
|
+
- ``lines`` -- list of line generators; each line is given as
|
|
397
|
+
list of ``dim`` coordinates, not all zero
|
|
398
|
+
|
|
399
|
+
EXAMPLES::
|
|
400
|
+
|
|
401
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Vrep2Hrep
|
|
402
|
+
sage: Vrep2Hrep(QQ, 2, [(-1/2,0)], [(-1/2,2/3), (1/2,-1/3)], [])
|
|
403
|
+
[1 2 3]
|
|
404
|
+
[2 4 3]
|
|
405
|
+
[-----]
|
|
406
|
+
|
|
407
|
+
sage: Vrep2Hrep(QQ, 2, [(1,0), (-1/2,0)], [], [(1,-2/3)])
|
|
408
|
+
[ 1/3 2/3 1]
|
|
409
|
+
[ 2/3 -2/3 -1]
|
|
410
|
+
[--------------]
|
|
411
|
+
|
|
412
|
+
sage: Vrep2Hrep(QQ, 2, [(-1/2,0)], [(1/2,0)], [(1,-2/3)])
|
|
413
|
+
[1 2 3]
|
|
414
|
+
[-----]
|
|
415
|
+
|
|
416
|
+
sage: Vrep2Hrep(QQ, 2, [(1,1), (0,4), (-2,-3)], [], [])
|
|
417
|
+
[ 8/13 7/13 -2/13]
|
|
418
|
+
[ 1/13 -4/13 3/13]
|
|
419
|
+
[ 4/13 -3/13 -1/13]
|
|
420
|
+
[-----------------]
|
|
421
|
+
|
|
422
|
+
sage: Vrep2Hrep(QQ, 2, [(-19/5,22/5), (-1/2,0)], [(2/33,-1/33), (1/11,-2/33)], [])
|
|
423
|
+
[10/11 -2/11 -4/11]
|
|
424
|
+
[ 66/5 132/5 99/5]
|
|
425
|
+
[ 2/11 4/11 6/11]
|
|
426
|
+
[-----------------]
|
|
427
|
+
|
|
428
|
+
sage: Vrep2Hrep(QQ, 2, [(0,0)], [(1/2,-1/3), (1/3,-1/6)], [])
|
|
429
|
+
[ 0 -6 -12]
|
|
430
|
+
[ 0 12 18]
|
|
431
|
+
[-----------]
|
|
432
|
+
|
|
433
|
+
sage: Vrep2Hrep(QQ, 2, [(-1/2,0)], [], [(1,-2/3)])
|
|
434
|
+
[-----]
|
|
435
|
+
[1 2 3]
|
|
436
|
+
|
|
437
|
+
sage: Vrep2Hrep(QQ, 2, [(-1/2,0)], [], [(1,-2/3), (1,0)])
|
|
438
|
+
[]
|
|
439
|
+
"""
|
|
440
|
+
super().__init__(base_ring, dim)
|
|
441
|
+
if rays or lines:
|
|
442
|
+
assert len(vertices) > 0
|
|
443
|
+
if not vertices and not rays and not lines:
|
|
444
|
+
# The algorithm does not work, as the ambient dimension cannot be passed.
|
|
445
|
+
# Manually setting a single equality in this case.
|
|
446
|
+
one = self.base_ring.one()
|
|
447
|
+
zero = self.base_ring.zero()
|
|
448
|
+
self.equations = [[one] + [zero]*self.dim]
|
|
449
|
+
self.inequalities = []
|
|
450
|
+
else:
|
|
451
|
+
A = self._init_Vrep(vertices, rays, lines)
|
|
452
|
+
DD = Algorithm(A).run()
|
|
453
|
+
self._extract_Hrep(DD)
|
|
454
|
+
if VERIFY_RESULT:
|
|
455
|
+
self.verify(vertices, rays, lines)
|
|
456
|
+
|
|
457
|
+
def _init_Vrep(self, vertices, rays, lines):
|
|
458
|
+
"""
|
|
459
|
+
Split off the linear subspace from the inequalities and select pivots.
|
|
460
|
+
|
|
461
|
+
INPUT:
|
|
462
|
+
|
|
463
|
+
- ``vertices``, ``rays``, ``lines`` -- see :class:`Vrep2Hrep`
|
|
464
|
+
|
|
465
|
+
OUTPUT: matrix of pivoted inequalities for the dual homogenized cone
|
|
466
|
+
|
|
467
|
+
TESTS::
|
|
468
|
+
|
|
469
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Vrep2Hrep
|
|
470
|
+
sage: V2H = Vrep2Hrep(QQ, 2, [(-1/2,0)], [(-1/2,2/3), (1/2,-1/3)], [])
|
|
471
|
+
sage: V2H._init_Vrep([(-1/2,0)], [(-1/2,2/3), (1/2,-1/3)], [])
|
|
472
|
+
[ 1 -1/2 0]
|
|
473
|
+
[ 0 -1/2 2/3]
|
|
474
|
+
[ 0 1/2 -1/3]
|
|
475
|
+
"""
|
|
476
|
+
one = self.base_ring.one()
|
|
477
|
+
zero = self.base_ring.zero()
|
|
478
|
+
homogeneous = \
|
|
479
|
+
[[one] + list(v) for v in vertices] + \
|
|
480
|
+
[[zero] + list(r) for r in rays] + \
|
|
481
|
+
[[zero] + list(l) for l in lines] + \
|
|
482
|
+
[[zero] + [-x for x in l] for l in lines]
|
|
483
|
+
A = matrix(self.base_ring, homogeneous)
|
|
484
|
+
return self._pivot_inequalities(A)
|
|
485
|
+
|
|
486
|
+
def _extract_Hrep(self, DD):
|
|
487
|
+
"""
|
|
488
|
+
Extract generators from the dual description of the homogenized cone.
|
|
489
|
+
|
|
490
|
+
INPUT:
|
|
491
|
+
|
|
492
|
+
- ``DD`` -- a
|
|
493
|
+
:class:`~sage.geometry.polyhedron.double_description.DoubleDescriptionPair`
|
|
494
|
+
|
|
495
|
+
EXAMPLES::
|
|
496
|
+
|
|
497
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Vrep2Hrep
|
|
498
|
+
sage: V2H = Vrep2Hrep(QQ, 1, [(-1/2,), (2/3)], [], [])
|
|
499
|
+
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
|
|
500
|
+
sage: DD = StandardAlgorithm(matrix([[1,2], [3,5]])).run()
|
|
501
|
+
sage: V2H._extract_Hrep(DD)
|
|
502
|
+
"""
|
|
503
|
+
zero = self.base_ring.zero()
|
|
504
|
+
|
|
505
|
+
def is_trivial(ray):
|
|
506
|
+
# trivial Hrep output 1 >= 0
|
|
507
|
+
return ray[0] > zero and all(r == zero for r in ray[1:])
|
|
508
|
+
ieqs = (self._unpivot_ray(ra) for ra in DD.R)
|
|
509
|
+
self.inequalities = [r for r in ieqs if not is_trivial(r)]
|
|
510
|
+
self.equations = self._linear_subspace.matrix().rows()
|
|
511
|
+
|
|
512
|
+
def _repr_(self):
|
|
513
|
+
r"""
|
|
514
|
+
Return a string representation.
|
|
515
|
+
|
|
516
|
+
OUTPUT: string
|
|
517
|
+
|
|
518
|
+
EXAMPLES::
|
|
519
|
+
|
|
520
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Vrep2Hrep
|
|
521
|
+
sage: V2H = Vrep2Hrep(QQ, 2, [(-1/2,0)], [(-1/2,2/3), (1/2,-1/3)], [])
|
|
522
|
+
sage: V2H._repr_()
|
|
523
|
+
'[1 2 3]\n[2 4 3]\n[-----]'
|
|
524
|
+
"""
|
|
525
|
+
from sage.matrix.constructor import block_matrix
|
|
526
|
+
|
|
527
|
+
def make_matrix(cols):
|
|
528
|
+
return matrix(self.base_ring, len(cols), self.dim + 1, cols)
|
|
529
|
+
I = make_matrix(self.inequalities)
|
|
530
|
+
E = make_matrix(self.equations)
|
|
531
|
+
return str(block_matrix([[I], [E]]))
|
|
532
|
+
|
|
533
|
+
def verify(self, vertices, rays, lines):
|
|
534
|
+
"""
|
|
535
|
+
Compare result to PPL if the base ring is QQ.
|
|
536
|
+
|
|
537
|
+
This method is for debugging purposes and compares the
|
|
538
|
+
computation with another backend if available.
|
|
539
|
+
|
|
540
|
+
INPUT:
|
|
541
|
+
|
|
542
|
+
- ``vertices``, ``rays``, ``lines`` -- see :class:`Vrep2Hrep`
|
|
543
|
+
|
|
544
|
+
EXAMPLES::
|
|
545
|
+
|
|
546
|
+
sage: from sage.geometry.polyhedron.double_description_inhomogeneous import Vrep2Hrep
|
|
547
|
+
sage: vertices = [(-1/2,0)]
|
|
548
|
+
sage: rays = [(-1/2,2/3), (1/2,-1/3)]
|
|
549
|
+
sage: lines = []
|
|
550
|
+
sage: V2H = Vrep2Hrep(QQ, 2, vertices, rays, lines)
|
|
551
|
+
sage: V2H.verify(vertices, rays, lines)
|
|
552
|
+
"""
|
|
553
|
+
from sage.rings.rational_field import QQ
|
|
554
|
+
from sage.geometry.polyhedron.constructor import Polyhedron
|
|
555
|
+
if self.base_ring is not QQ:
|
|
556
|
+
return
|
|
557
|
+
P = Polyhedron(vertices=vertices, rays=rays, lines=lines,
|
|
558
|
+
base_ring=QQ, ambient_dim=self.dim)
|
|
559
|
+
Q = Polyhedron(ieqs=self.inequalities, eqns=self.equations,
|
|
560
|
+
base_ring=QQ, ambient_dim=self.dim)
|
|
561
|
+
if not P == Q:
|
|
562
|
+
print('incorrect!', P, Q)
|
|
563
|
+
print(Q.Vrepresentation())
|
|
564
|
+
print(P.Hrepresentation())
|