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,8 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
|
|
3
|
+
from sage.misc.lazy_import import lazy_import
|
|
4
|
+
lazy_import('sage.geometry.polyhedron.constructor', 'Polyhedron')
|
|
5
|
+
lazy_import('sage.geometry.polyhedron.library', 'polytopes')
|
|
6
|
+
lazy_import('sage.geometry.polyhedron.combinatorial_polyhedron.base',
|
|
7
|
+
'CombinatorialPolyhedron')
|
|
8
|
+
del lazy_import
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
# sage.doctest: needs cddexec_gmp
|
|
3
|
+
r"""
|
|
4
|
+
The cdd backend for polyhedral computations
|
|
5
|
+
"""
|
|
6
|
+
# ****************************************************************************
|
|
7
|
+
# Copyright (C) 2011-2014 Volker Braun <vbraun.name@gmail.com>
|
|
8
|
+
# 2018 Timo Kaufmann <timokau@zoho.com>
|
|
9
|
+
# 2018 Julian Rüth <julian.rueth@fsfe.org>
|
|
10
|
+
#
|
|
11
|
+
# This program is free software: you can redistribute it and/or modify
|
|
12
|
+
# it under the terms of the GNU General Public License as published by
|
|
13
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
14
|
+
# (at your option) any later version.
|
|
15
|
+
# https://www.gnu.org/licenses/
|
|
16
|
+
# ****************************************************************************
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
from subprocess import Popen, PIPE
|
|
20
|
+
from sage.rings.integer_ring import ZZ
|
|
21
|
+
from sage.matrix.constructor import matrix
|
|
22
|
+
from sage.features.cddlib import CddExecutable
|
|
23
|
+
|
|
24
|
+
from .base import Polyhedron_base
|
|
25
|
+
from .base_QQ import Polyhedron_QQ
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Polyhedron_cdd(Polyhedron_base):
|
|
29
|
+
r"""
|
|
30
|
+
Base class for the cdd backend.
|
|
31
|
+
"""
|
|
32
|
+
def _init_from_Vrepresentation(self, vertices, rays, lines, verbose=False):
|
|
33
|
+
"""
|
|
34
|
+
Construct polyhedron from V-representation data.
|
|
35
|
+
|
|
36
|
+
INPUT:
|
|
37
|
+
|
|
38
|
+
- ``vertices`` -- list of point. Each point can be specified
|
|
39
|
+
as any iterable container of
|
|
40
|
+
:meth:`~sage.geometry.polyhedron.base.base_ring` elements.
|
|
41
|
+
|
|
42
|
+
- ``rays`` -- list of rays. Each ray can be specified as any
|
|
43
|
+
iterable container of
|
|
44
|
+
:meth:`~sage.geometry.polyhedron.base.base_ring` elements.
|
|
45
|
+
|
|
46
|
+
- ``lines`` -- list of lines. Each line can be specified as
|
|
47
|
+
any iterable container of
|
|
48
|
+
:meth:`~sage.geometry.polyhedron.base.base_ring` elements.
|
|
49
|
+
|
|
50
|
+
- ``verbose`` -- boolean (default: ``False``); whether to print
|
|
51
|
+
verbose output for debugging purposes
|
|
52
|
+
|
|
53
|
+
EXAMPLES::
|
|
54
|
+
|
|
55
|
+
sage: Polyhedron(vertices=[(0,0)], rays=[(1,1)], # indirect doctest
|
|
56
|
+
....: lines=[(1,-1)], backend='cdd', base_ring=QQ)
|
|
57
|
+
A 2-dimensional polyhedron in QQ^2 defined as the
|
|
58
|
+
convex hull of 1 vertex, 1 ray, 1 line
|
|
59
|
+
"""
|
|
60
|
+
from .cdd_file_format import cdd_Vrepresentation
|
|
61
|
+
s = cdd_Vrepresentation(self._cdd_type, vertices, rays, lines)
|
|
62
|
+
s = self._run_cdd(s, '--redcheck', verbose=verbose)
|
|
63
|
+
s = self._run_cdd(s, '--repall', verbose=verbose)
|
|
64
|
+
self._init_from_cdd_output(s)
|
|
65
|
+
if not self.base_ring().is_exact():
|
|
66
|
+
# cdd's parser cannot handle the full output of --repall, so we
|
|
67
|
+
# need to extract the first block before we feed it back into cdd
|
|
68
|
+
s = s.splitlines()
|
|
69
|
+
s = s[:s.index('end')+1]
|
|
70
|
+
s = '\n'.join(s)
|
|
71
|
+
t = self._run_cdd(s, '--rep', verbose=verbose)
|
|
72
|
+
|
|
73
|
+
def parse(intro, data):
|
|
74
|
+
count = int(data[0][0])
|
|
75
|
+
if count != len(self._cdd_V_to_sage_V):
|
|
76
|
+
# Upstream claims that nothing can be done about these
|
|
77
|
+
# cases/that they are features not bugs. Imho, cddlib is
|
|
78
|
+
# not really suitable for automatic parsing of its output,
|
|
79
|
+
# the implementation backed by doubles has not really been
|
|
80
|
+
# optimized for numerical stability, and makes some
|
|
81
|
+
# somewhat random numerical choices. (But I am not an
|
|
82
|
+
# expert in that field by any means.) See also
|
|
83
|
+
# https://github.com/cddlib/cddlib/pull/7.
|
|
84
|
+
from warnings import warn
|
|
85
|
+
warn("This polyhedron data is numerically complicated; cdd could not convert between the inexact V and H representation without loss of data. The resulting object might show inconsistencies.")
|
|
86
|
+
Polyhedron_cdd._parse_block(t.splitlines(), 'V-representation', parse)
|
|
87
|
+
|
|
88
|
+
def _init_from_Hrepresentation(self, ieqs, eqns, verbose=False):
|
|
89
|
+
"""
|
|
90
|
+
Construct polyhedron from H-representation data.
|
|
91
|
+
|
|
92
|
+
INPUT:
|
|
93
|
+
|
|
94
|
+
- ``ieqs`` -- list of inequalities. Each line can be specified
|
|
95
|
+
as any iterable container of
|
|
96
|
+
:meth:`~sage.geometry.polyhedron.base.base_ring` elements.
|
|
97
|
+
|
|
98
|
+
- ``eqns`` -- list of equalities. Each line can be specified
|
|
99
|
+
as any iterable container of
|
|
100
|
+
:meth:`~sage.geometry.polyhedron.base.base_ring` elements.
|
|
101
|
+
|
|
102
|
+
- ``verbose`` -- boolean (default: ``False``); whether to print
|
|
103
|
+
verbose output for debugging purposes
|
|
104
|
+
|
|
105
|
+
EXAMPLES::
|
|
106
|
+
|
|
107
|
+
sage: Polyhedron(ieqs=[(0,1,1)], eqns=[(0,1,-1)], # indirect doctest
|
|
108
|
+
....: backend='cdd', base_ring=QQ)
|
|
109
|
+
A 1-dimensional polyhedron in QQ^2 defined as the
|
|
110
|
+
convex hull of 1 vertex and 1 ray
|
|
111
|
+
|
|
112
|
+
TESTS:
|
|
113
|
+
|
|
114
|
+
The polyhedron with zero inequalities can be initialized from Hrepresentation;
|
|
115
|
+
see :issue:`29899`::
|
|
116
|
+
|
|
117
|
+
sage: Polyhedron(ieqs=[], ambient_dim=5, backend='cdd')
|
|
118
|
+
A 5-dimensional polyhedron in QQ^5 defined as the convex hull of 1 vertex and 5 lines
|
|
119
|
+
"""
|
|
120
|
+
from .cdd_file_format import cdd_Hrepresentation
|
|
121
|
+
# We have to add a trivial inequality, in case the polyhedron is the universe.
|
|
122
|
+
ieqs = tuple(ieqs) + ((1,) + tuple(0 for _ in range(self.ambient_dim())),)
|
|
123
|
+
s = cdd_Hrepresentation(self._cdd_type, ieqs, eqns)
|
|
124
|
+
s = self._run_cdd(s, '--redcheck', verbose=verbose)
|
|
125
|
+
s = self._run_cdd(s, '--repall', verbose=verbose)
|
|
126
|
+
self._init_from_cdd_output(s)
|
|
127
|
+
if not self.base_ring().is_exact():
|
|
128
|
+
if len(self._Vrepresentation) == 0:
|
|
129
|
+
# cdd (reasonably) refuses to handle empty polyhedra, so we
|
|
130
|
+
# skip this check
|
|
131
|
+
return
|
|
132
|
+
# cdd's parser cannot handle the full output of --repall, so we
|
|
133
|
+
# need to extract the first block before we feed it back into cdd
|
|
134
|
+
s = s.splitlines()
|
|
135
|
+
s = s[:s.index('end')+1]
|
|
136
|
+
s = '\n'.join(s)
|
|
137
|
+
t = self._run_cdd(s, '--rep', verbose=verbose)
|
|
138
|
+
|
|
139
|
+
def parse(intro, data):
|
|
140
|
+
count = int(data[0][0])
|
|
141
|
+
infinite_count = len([d for d in data[1:] if d[0] == '1' and all(c == '0' for c in d[1:])])
|
|
142
|
+
if count - infinite_count != len(self._Hrepresentation):
|
|
143
|
+
# Upstream claims that nothing can be done about these
|
|
144
|
+
# cases/that they are features not bugs. Imho, cddlib is
|
|
145
|
+
# not really suitable for automatic parsing of its output,
|
|
146
|
+
# the implementation backed by doubles has not really been
|
|
147
|
+
# optimized for numerical stability, and makes some
|
|
148
|
+
# somewhat random numerical choices. (But I am not an
|
|
149
|
+
# expert in that field by any means.)
|
|
150
|
+
from warnings import warn
|
|
151
|
+
warn("This polyhedron data is numerically complicated; cdd could not convert between the inexact V and H representation without loss of data. The resulting object might show inconsistencies.")
|
|
152
|
+
Polyhedron_cdd._parse_block(t.splitlines(), 'H-representation', parse)
|
|
153
|
+
|
|
154
|
+
def _run_cdd(self, cdd_input_string, cmdline_arg, verbose=False):
|
|
155
|
+
if verbose:
|
|
156
|
+
print('---- CDD input -----')
|
|
157
|
+
print(cdd_input_string)
|
|
158
|
+
|
|
159
|
+
cdd_proc = Popen([CddExecutable(self._cdd_executable).absolute_filename(), cmdline_arg],
|
|
160
|
+
stdin=PIPE, stdout=PIPE, stderr=PIPE,
|
|
161
|
+
encoding='latin-1')
|
|
162
|
+
ans, err = cdd_proc.communicate(input=cdd_input_string)
|
|
163
|
+
|
|
164
|
+
if verbose:
|
|
165
|
+
print('---- CDD output -----')
|
|
166
|
+
print(ans)
|
|
167
|
+
print(err)
|
|
168
|
+
if 'Error:' in ans + err:
|
|
169
|
+
# cdd reports errors on stdout and misc information on stderr
|
|
170
|
+
raise ValueError(ans.strip())
|
|
171
|
+
return ans
|
|
172
|
+
|
|
173
|
+
@classmethod
|
|
174
|
+
def _parse_block(cls, cddout, header, parser):
|
|
175
|
+
r"""
|
|
176
|
+
Parse a block of cdd data identified by ``header`` by invoking
|
|
177
|
+
``parser`` on it.
|
|
178
|
+
|
|
179
|
+
EXAMPLES::
|
|
180
|
+
|
|
181
|
+
sage: cddout = r'''
|
|
182
|
+
....: unrelated
|
|
183
|
+
....: HEADER
|
|
184
|
+
....: intro 0 1 2
|
|
185
|
+
....: begin
|
|
186
|
+
....: data 0 1 2
|
|
187
|
+
....: data 3 4 5
|
|
188
|
+
....: end
|
|
189
|
+
....: unrelated
|
|
190
|
+
....: '''.splitlines()
|
|
191
|
+
sage: from sage.geometry.polyhedron.backend_cdd import Polyhedron_cdd
|
|
192
|
+
sage: def parser(intro, data):
|
|
193
|
+
....: print("INTRO:", intro)
|
|
194
|
+
....: print("DATA:", data)
|
|
195
|
+
sage: Polyhedron_cdd._parse_block(cddout, 'HEADER', parser)
|
|
196
|
+
INTRO: [['intro', '0', '1', '2']]
|
|
197
|
+
DATA: [['data', '0', '1', '2'], ['data', '3', '4', '5']]
|
|
198
|
+
"""
|
|
199
|
+
try:
|
|
200
|
+
block = cddout[cddout.index(header)+1:]
|
|
201
|
+
except ValueError:
|
|
202
|
+
# section is missing in the cdd output
|
|
203
|
+
return
|
|
204
|
+
|
|
205
|
+
intro = block[:block.index('begin')]
|
|
206
|
+
intro = [i.strip().split() for i in intro]
|
|
207
|
+
data = block[block.index('begin')+1:block.index('end')]
|
|
208
|
+
data = [d.strip().split() for d in data]
|
|
209
|
+
parser(intro, data)
|
|
210
|
+
|
|
211
|
+
def _init_from_cdd_output(self, cddout):
|
|
212
|
+
"""
|
|
213
|
+
Initialize ourselves with the output from cdd.
|
|
214
|
+
|
|
215
|
+
TESTS::
|
|
216
|
+
|
|
217
|
+
sage: p = Polyhedron(vertices = [[0,0],[1,0],[0,1],[1,1]], backend='cdd', base_ring=QQ) # indirect doctest
|
|
218
|
+
sage: p.vertices()
|
|
219
|
+
(A vertex at (0, 0), A vertex at (1, 0), A vertex at (0, 1), A vertex at (1, 1))
|
|
220
|
+
|
|
221
|
+
Check that :issue:`29176` is fixed::
|
|
222
|
+
|
|
223
|
+
sage: e = [[11582947.657000002, 5374.38, 4177.06, 1.0], [11562795.9322, 5373.62, 4168.38, 1.0]]
|
|
224
|
+
sage: p = Polyhedron(ieqs=e); p
|
|
225
|
+
A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 1 vertex, 2 rays, 1 line
|
|
226
|
+
sage: p.incidence_matrix()
|
|
227
|
+
[1 1]
|
|
228
|
+
[1 0]
|
|
229
|
+
[0 1]
|
|
230
|
+
[1 1]
|
|
231
|
+
|
|
232
|
+
sage: P = [[-2687.19, -2088.53], [-2686.81, -2084.19]]
|
|
233
|
+
sage: V = VoronoiDiagram(P)
|
|
234
|
+
sage: R = V.regions()
|
|
235
|
+
sage: V.points()[0], R[V.points()[0]]
|
|
236
|
+
(P(-2687.19000000000, -2088.53000000000),
|
|
237
|
+
A 2-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex, 1 ray, 1 line)
|
|
238
|
+
sage: V.points()[1], R[V.points()[1]]
|
|
239
|
+
(P(-2686.81000000000, -2084.19000000000),
|
|
240
|
+
A 2-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex, 1 ray, 1 line)
|
|
241
|
+
|
|
242
|
+
Check that :issue:`31253` is fixed::
|
|
243
|
+
|
|
244
|
+
sage: P = polytopes.permutahedron(2, backend='cdd')
|
|
245
|
+
sage: P.Hrepresentation()
|
|
246
|
+
(An inequality (0, 1) x - 1 >= 0,
|
|
247
|
+
An inequality (1, 0) x - 1 >= 0,
|
|
248
|
+
An equation (1, 1) x - 3 == 0)
|
|
249
|
+
sage: Q = Polyhedron(P.vertices(), backend='cdd')
|
|
250
|
+
sage: Q.Hrepresentation()
|
|
251
|
+
(An inequality (-1, 0) x + 2 >= 0,
|
|
252
|
+
An inequality (1, 0) x - 1 >= 0,
|
|
253
|
+
An equation (1, 1) x - 3 == 0)
|
|
254
|
+
sage: [x.ambient_Hrepresentation() for x in P.facets()]
|
|
255
|
+
[(An inequality (1, 0) x - 1 >= 0, An equation (1, 1) x - 3 == 0),
|
|
256
|
+
(An inequality (0, 1) x - 1 >= 0, An equation (1, 1) x - 3 == 0)]
|
|
257
|
+
"""
|
|
258
|
+
cddout = cddout.splitlines()
|
|
259
|
+
|
|
260
|
+
def parse_indices(count, cdd_indices, cdd_indices_to_sage_indices=None):
|
|
261
|
+
cdd_indices = [int(x) for x in cdd_indices]
|
|
262
|
+
if cdd_indices_to_sage_indices is None:
|
|
263
|
+
cdd_indices_to_sage_indices = {i: i-1 for i in cdd_indices}
|
|
264
|
+
if count < 0:
|
|
265
|
+
assert cdd_indices_to_sage_indices is not None, "Did not expect negative counts here"
|
|
266
|
+
count = -count
|
|
267
|
+
cdd_indices = list(set(cdd_indices_to_sage_indices.keys()) - set(cdd_indices))
|
|
268
|
+
assert count in [len(cdd_indices), len(cdd_indices) - 1]
|
|
269
|
+
assert count == len(cdd_indices)
|
|
270
|
+
return [cdd_indices_to_sage_indices[i] for i in cdd_indices if cdd_indices_to_sage_indices[i] is not None]
|
|
271
|
+
|
|
272
|
+
def parse_linearities(intro):
|
|
273
|
+
for entries in intro:
|
|
274
|
+
if entries and entries.pop(0) == 'linearity':
|
|
275
|
+
return parse_indices(int(entries.pop(0)), entries)
|
|
276
|
+
return []
|
|
277
|
+
|
|
278
|
+
def parse_H_representation(intro, data):
|
|
279
|
+
if '_Hrepresentation' in self.__dict__:
|
|
280
|
+
raise NotImplementedError("cannot replace internal representation as this breaks caching")
|
|
281
|
+
self._Hrepresentation = []
|
|
282
|
+
# we drop some entries in cdd's output and this changes the numbering; this dict keeps track of that
|
|
283
|
+
self._cdd_H_to_sage_H = {}
|
|
284
|
+
equations = parse_linearities(intro)
|
|
285
|
+
data[0].pop(2) # ignore data type, we know the base ring already
|
|
286
|
+
count, dimension = map(int, data.pop(0))
|
|
287
|
+
assert self.ambient_dim() == dimension - 1, "Unexpected ambient dimension"
|
|
288
|
+
assert len(data) == count, "Unexpected number of lines"
|
|
289
|
+
R = self.base_ring()
|
|
290
|
+
from itertools import chain
|
|
291
|
+
# We add equations to the end of the Hrepresentation.
|
|
292
|
+
for i in chain(
|
|
293
|
+
(j for j in range(len(data)) if j not in equations),
|
|
294
|
+
equations):
|
|
295
|
+
line = data[i]
|
|
296
|
+
coefficients = [R(x) for x in line]
|
|
297
|
+
if coefficients[0] != 0 and all(e == 0 for e in coefficients[1:]):
|
|
298
|
+
# cddlib sometimes includes an implicit plane at infinity: 1 0 0 ... 0
|
|
299
|
+
# We do not care about this entry.
|
|
300
|
+
self._cdd_H_to_sage_H[i+1] = None
|
|
301
|
+
continue
|
|
302
|
+
|
|
303
|
+
self._cdd_H_to_sage_H[i+1] = len(self._Hrepresentation)
|
|
304
|
+
if i in equations:
|
|
305
|
+
self.parent()._make_Equation(self, coefficients)
|
|
306
|
+
else:
|
|
307
|
+
self.parent()._make_Inequality(self, coefficients)
|
|
308
|
+
|
|
309
|
+
self._Hrepresentation = tuple(self._Hrepresentation)
|
|
310
|
+
|
|
311
|
+
def parse_V_representation(intro, data):
|
|
312
|
+
if '_Vrepresentation' in self.__dict__:
|
|
313
|
+
raise NotImplementedError("cannot replace internal representation as this breaks caching")
|
|
314
|
+
self._Vrepresentation = []
|
|
315
|
+
# we drop some entries in cdd's output and this changes the numbering; this dict keeps track of that
|
|
316
|
+
self._cdd_V_to_sage_V = {}
|
|
317
|
+
lines = parse_linearities(intro)
|
|
318
|
+
data[0].pop(2) # ignore data type, we know the base ring already
|
|
319
|
+
count, dimension = map(int, data.pop(0))
|
|
320
|
+
assert self.ambient_dim() == dimension - 1, "Unexpected ambient dimension"
|
|
321
|
+
assert len(data) == count, "Unexpected number of lines"
|
|
322
|
+
has_vertex = False
|
|
323
|
+
for i, line in enumerate(data):
|
|
324
|
+
kind = line.pop(0)
|
|
325
|
+
coefficients = map(self.base_ring(), line)
|
|
326
|
+
self._cdd_V_to_sage_V[i+1] = len(self._Vrepresentation)
|
|
327
|
+
if i in lines:
|
|
328
|
+
self.parent()._make_Line(self, coefficients)
|
|
329
|
+
elif kind == '0':
|
|
330
|
+
self.parent()._make_Ray(self, coefficients)
|
|
331
|
+
else:
|
|
332
|
+
self.parent()._make_Vertex(self, coefficients)
|
|
333
|
+
has_vertex = True
|
|
334
|
+
if self._Vrepresentation and not has_vertex:
|
|
335
|
+
# when the Polyhedron consists only of lines/rays from the
|
|
336
|
+
# origin, cddlib does not output the single vertex at the
|
|
337
|
+
# origin so we have to add it here as the Polyhedron class
|
|
338
|
+
# expects it to be there.
|
|
339
|
+
self.parent()._make_Vertex(self, [self.base_ring().zero()] * self.ambient_dim())
|
|
340
|
+
self._Vrepresentation = tuple(self._Vrepresentation)
|
|
341
|
+
|
|
342
|
+
def parse_adjacency(intro, data, M, N, cdd_indices_to_sage_indices, cdd_indices_to_sage_indices2=None):
|
|
343
|
+
# This function is also used to parse the incidence matrix.
|
|
344
|
+
if cdd_indices_to_sage_indices2 is None:
|
|
345
|
+
cdd_indices_to_sage_indices2 = cdd_indices_to_sage_indices
|
|
346
|
+
ret = matrix(ZZ, M, N, 0)
|
|
347
|
+
data.pop(0)
|
|
348
|
+
data.reverse()
|
|
349
|
+
for adjacencies in data:
|
|
350
|
+
assert adjacencies[2] == ':', "Not a line of adjacency data"
|
|
351
|
+
cdd_vertex = int(adjacencies[0])
|
|
352
|
+
count = int(adjacencies[1])
|
|
353
|
+
|
|
354
|
+
# cdd sometimes prints implicit adjacencies for the plane at
|
|
355
|
+
# infinity at the end of the output (even though it's not part
|
|
356
|
+
# of the V/H representation) so we ignore indices that we do
|
|
357
|
+
# not know about.
|
|
358
|
+
if cdd_vertex not in cdd_indices_to_sage_indices:
|
|
359
|
+
cdd_indices_to_sage_indices[cdd_vertex] = None
|
|
360
|
+
v = cdd_indices_to_sage_indices[cdd_vertex]
|
|
361
|
+
if v is None:
|
|
362
|
+
continue
|
|
363
|
+
for w in parse_indices(count, adjacencies[3:], cdd_indices_to_sage_indices2):
|
|
364
|
+
if w is None:
|
|
365
|
+
continue
|
|
366
|
+
ret[v, w] = 1
|
|
367
|
+
return ret
|
|
368
|
+
|
|
369
|
+
def parse_vertex_adjacency(intro, data):
|
|
370
|
+
if '_V_adjacency_matrix' in self.__dict__:
|
|
371
|
+
raise NotImplementedError("cannot replace internal representation as this breaks caching")
|
|
372
|
+
N = len(self._Vrepresentation)
|
|
373
|
+
self._V_adjacency_matrix = parse_adjacency(intro, data, N, N, self._cdd_V_to_sage_V)
|
|
374
|
+
for i, v in enumerate(self._Vrepresentation):
|
|
375
|
+
# cdd reports that lines are never adjacent to anything.
|
|
376
|
+
# we disagree, they are adjacent to everything.
|
|
377
|
+
if v.is_line():
|
|
378
|
+
for j in range(len(self._Vrepresentation)):
|
|
379
|
+
self._V_adjacency_matrix[i ,j] = 1
|
|
380
|
+
self._V_adjacency_matrix[j, i] = 1
|
|
381
|
+
self._V_adjacency_matrix[i,i] = 0
|
|
382
|
+
self._V_adjacency_matrix.set_immutable()
|
|
383
|
+
self.vertex_adjacency_matrix.set_cache(self._V_adjacency_matrix)
|
|
384
|
+
|
|
385
|
+
def parse_facet_adjacency(intro, data):
|
|
386
|
+
if '_H_adjacency_matrix' in self.__dict__:
|
|
387
|
+
raise NotImplementedError("cannot replace internal representation as this breaks caching")
|
|
388
|
+
N = len(self._Hrepresentation)
|
|
389
|
+
self._H_adjacency_matrix = parse_adjacency(intro, data, N, N, self._cdd_H_to_sage_H)
|
|
390
|
+
self._H_adjacency_matrix.set_immutable()
|
|
391
|
+
self.facet_adjacency_matrix.set_cache(self._H_adjacency_matrix)
|
|
392
|
+
|
|
393
|
+
def parse_incidence_matrix(intro, data):
|
|
394
|
+
if 'incidence_matrix' in self.__dict__:
|
|
395
|
+
raise NotImplementedError("cannot replace internal representation as this breaks caching")
|
|
396
|
+
N = len(self._Hrepresentation)
|
|
397
|
+
M = len(self._Vrepresentation)
|
|
398
|
+
inc_mat = parse_adjacency(intro, data, M, N, self._cdd_V_to_sage_V, self._cdd_H_to_sage_H)
|
|
399
|
+
inc_mat.set_immutable()
|
|
400
|
+
self.incidence_matrix.set_cache(inc_mat)
|
|
401
|
+
|
|
402
|
+
Polyhedron_cdd._parse_block(cddout, 'H-representation', parse_H_representation)
|
|
403
|
+
Polyhedron_cdd._parse_block(cddout, 'V-representation', parse_V_representation)
|
|
404
|
+
Polyhedron_cdd._parse_block(cddout, 'Facet adjacency', parse_facet_adjacency)
|
|
405
|
+
Polyhedron_cdd._parse_block(cddout, 'Vertex adjacency', parse_vertex_adjacency)
|
|
406
|
+
Polyhedron_cdd._parse_block(cddout, 'Vertex incidence', parse_incidence_matrix)
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class Polyhedron_QQ_cdd(Polyhedron_cdd, Polyhedron_QQ):
|
|
410
|
+
"""
|
|
411
|
+
Polyhedra over QQ with cdd.
|
|
412
|
+
|
|
413
|
+
INPUT:
|
|
414
|
+
|
|
415
|
+
- ``parent`` -- the parent, an instance of
|
|
416
|
+
:class:`~sage.geometry.polyhedron.parent.Polyhedra`
|
|
417
|
+
|
|
418
|
+
- ``Vrep`` -- list ``[vertices, rays, lines]`` or ``None``
|
|
419
|
+
|
|
420
|
+
- ``Hrep`` -- list ``[ieqs, eqns]`` or ``None``
|
|
421
|
+
|
|
422
|
+
EXAMPLES::
|
|
423
|
+
|
|
424
|
+
sage: from sage.geometry.polyhedron.parent import Polyhedra
|
|
425
|
+
sage: parent = Polyhedra(QQ, 2, backend='cdd')
|
|
426
|
+
sage: from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd
|
|
427
|
+
sage: Polyhedron_QQ_cdd(parent, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
|
|
428
|
+
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
|
|
429
|
+
|
|
430
|
+
TESTS:
|
|
431
|
+
|
|
432
|
+
Check that :issue:`19803` is fixed::
|
|
433
|
+
|
|
434
|
+
sage: from sage.geometry.polyhedron.parent import Polyhedra
|
|
435
|
+
sage: P_cdd = Polyhedra(QQ, 3, 'cdd')
|
|
436
|
+
sage: P_cdd([[],[],[]], None)
|
|
437
|
+
The empty polyhedron in QQ^3
|
|
438
|
+
sage: Polyhedron(vertices=[], backend='cdd', base_ring=QQ)
|
|
439
|
+
The empty polyhedron in QQ^0
|
|
440
|
+
"""
|
|
441
|
+
|
|
442
|
+
_cdd_type = 'rational'
|
|
443
|
+
|
|
444
|
+
_cdd_executable = 'cddexec_gmp'
|
|
445
|
+
|
|
446
|
+
def __init__(self, parent, Vrep, Hrep, **kwds):
|
|
447
|
+
"""
|
|
448
|
+
The Python constructor.
|
|
449
|
+
|
|
450
|
+
See :class:`Polyhedron_base` for a description of the input
|
|
451
|
+
data.
|
|
452
|
+
|
|
453
|
+
TESTS::
|
|
454
|
+
|
|
455
|
+
sage: p = Polyhedron(backend='cdd', base_ring=QQ)
|
|
456
|
+
sage: type(p)
|
|
457
|
+
<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_cdd_with_category.element_class'>
|
|
458
|
+
sage: TestSuite(p).run()
|
|
459
|
+
"""
|
|
460
|
+
Polyhedron_cdd.__init__(self, parent, Vrep, Hrep, **kwds)
|