passagemath-polyhedra 10.6.31rc3__cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_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 +206 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +6 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_polyhedra.libs/libgmp-6e109695.so.10.5.0 +0 -0
- passagemath_polyhedra.libs/libgomp-e985bcbb.so.1.0.0 +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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.so +0 -0
- sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
- sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-linux-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.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-gnu.so +0 -0
- sage/numerical/mip.pxd +40 -0
- sage/numerical/mip.pyx +3667 -0
- sage/numerical/sdp.cpython-314-x86_64-linux-gnu.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-gnu.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,202 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
"""
|
|
3
|
+
Construction of finite atomic and coatomic lattices from incidences
|
|
4
|
+
|
|
5
|
+
This module provides the function :func:`lattice_from_incidences` for
|
|
6
|
+
computing finite atomic and coatomic lattices in the sense of
|
|
7
|
+
partially ordered sets where any two elements have meet and joint. For
|
|
8
|
+
example, the face lattice of a polyhedron.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# ****************************************************************************
|
|
12
|
+
# Copyright (C) 2010 Andrey Novoseltsev <novoselt@gmail.com>
|
|
13
|
+
#
|
|
14
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
15
|
+
#
|
|
16
|
+
# https://www.gnu.org/licenses/
|
|
17
|
+
# ****************************************************************************
|
|
18
|
+
|
|
19
|
+
from sage.graphs.digraph import DiGraph
|
|
20
|
+
from sage.combinat.posets.lattices import FiniteLatticePoset
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def lattice_from_incidences(atom_to_coatoms, coatom_to_atoms,
|
|
24
|
+
face_constructor=None,
|
|
25
|
+
required_atoms=None,
|
|
26
|
+
key=None,
|
|
27
|
+
**kwds):
|
|
28
|
+
r"""
|
|
29
|
+
Compute an atomic and coatomic lattice from the incidence between
|
|
30
|
+
atoms and coatoms.
|
|
31
|
+
|
|
32
|
+
INPUT:
|
|
33
|
+
|
|
34
|
+
- ``atom_to_coatoms`` -- list; ``atom_to_coatom[i]`` should list all
|
|
35
|
+
coatoms over the ``i``-th atom
|
|
36
|
+
|
|
37
|
+
- ``coatom_to_atoms`` -- list; ``coatom_to_atom[i]`` should list all
|
|
38
|
+
atoms under the ``i``-th coatom
|
|
39
|
+
|
|
40
|
+
- ``face_constructor`` -- function or class taking as the first two
|
|
41
|
+
arguments sorted :class:`tuple` of integers and any keyword arguments.
|
|
42
|
+
It will be called to construct a face over atoms passed as the first
|
|
43
|
+
argument and under coatoms passed as the second argument. Default
|
|
44
|
+
implementation will just return these two tuples as a tuple;
|
|
45
|
+
|
|
46
|
+
- ``required_atoms`` -- list of atoms (default: ``None``); each
|
|
47
|
+
non-empty "face" requires at least one of the specified atoms
|
|
48
|
+
present. Used to ensure that each face has a vertex.
|
|
49
|
+
|
|
50
|
+
- ``key`` -- any hashable value (default: ``None``); it is passed down
|
|
51
|
+
to :class:`~sage.combinat.posets.posets.FinitePoset`
|
|
52
|
+
|
|
53
|
+
- all other keyword arguments will be passed to ``face_constructor`` on
|
|
54
|
+
each call
|
|
55
|
+
|
|
56
|
+
OUTPUT:
|
|
57
|
+
|
|
58
|
+
- :class:`finite poset <sage.combinat.posets.posets.FinitePoset>` with
|
|
59
|
+
elements constructed by ``face_constructor``.
|
|
60
|
+
|
|
61
|
+
.. NOTE::
|
|
62
|
+
|
|
63
|
+
In addition to the specified partial order, finite posets in Sage have
|
|
64
|
+
internal total linear order of elements which extends the partial one.
|
|
65
|
+
This function will try to make this internal order to start with the
|
|
66
|
+
bottom and atoms in the order corresponding to ``atom_to_coatoms`` and
|
|
67
|
+
to finish with coatoms in the order corresponding to
|
|
68
|
+
``coatom_to_atoms`` and the top. This may not be possible if atoms and
|
|
69
|
+
coatoms are the same, in which case the preference is given to the
|
|
70
|
+
first list.
|
|
71
|
+
|
|
72
|
+
ALGORITHM:
|
|
73
|
+
|
|
74
|
+
The detailed description of the used algorithm is given in [KP2002]_.
|
|
75
|
+
|
|
76
|
+
The code of this function follows the pseudo-code description in the
|
|
77
|
+
section 2.5 of the paper, although it is mostly based on frozen sets
|
|
78
|
+
instead of sorted lists - this makes the implementation easier and should
|
|
79
|
+
not cost a big performance penalty. (If one wants to make this function
|
|
80
|
+
faster, it should be probably written in Cython.)
|
|
81
|
+
|
|
82
|
+
While the title of the paper mentions only polytopes, the algorithm (and
|
|
83
|
+
the implementation provided here) is applicable to any atomic and coatomic
|
|
84
|
+
lattice if both incidences are given, see Section 3.4.
|
|
85
|
+
|
|
86
|
+
In particular, this function can be used for strictly convex cones and
|
|
87
|
+
complete fans.
|
|
88
|
+
|
|
89
|
+
REFERENCES: [KP2002]_
|
|
90
|
+
|
|
91
|
+
AUTHORS:
|
|
92
|
+
|
|
93
|
+
- Andrey Novoseltsev (2010-05-13) with thanks to Marshall Hampton for the
|
|
94
|
+
reference.
|
|
95
|
+
|
|
96
|
+
EXAMPLES:
|
|
97
|
+
|
|
98
|
+
Let us construct the lattice of subsets of {0, 1, 2}.
|
|
99
|
+
Our atoms are {0}, {1}, and {2}, while our coatoms are {0,1}, {0,2}, and
|
|
100
|
+
{1,2}. Then incidences are ::
|
|
101
|
+
|
|
102
|
+
sage: atom_to_coatoms = [(0,1), (0,2), (1,2)]
|
|
103
|
+
sage: coatom_to_atoms = [(0,1), (0,2), (1,2)]
|
|
104
|
+
|
|
105
|
+
and we can compute the lattice as ::
|
|
106
|
+
|
|
107
|
+
sage: from sage.geometry.cone import lattice_from_incidences
|
|
108
|
+
sage: L = lattice_from_incidences(atom_to_coatoms, coatom_to_atoms); L # needs sage.graphs
|
|
109
|
+
Finite lattice containing 8 elements with distinguished linear extension
|
|
110
|
+
sage: for level in L.level_sets(): print(level) # needs sage.graphs
|
|
111
|
+
[((), (0, 1, 2))]
|
|
112
|
+
[((0,), (0, 1)), ((1,), (0, 2)), ((2,), (1, 2))]
|
|
113
|
+
[((0, 1), (0,)), ((0, 2), (1,)), ((1, 2), (2,))]
|
|
114
|
+
[((0, 1, 2), ())]
|
|
115
|
+
|
|
116
|
+
For more involved examples see the *source code* of
|
|
117
|
+
:meth:`sage.geometry.cone.ConvexRationalPolyhedralCone.face_lattice` and
|
|
118
|
+
:meth:`sage.geometry.fan.RationalPolyhedralFan._compute_cone_lattice`.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
def default_face_constructor(atoms, coatoms, **kwds):
|
|
122
|
+
return (atoms, coatoms)
|
|
123
|
+
if face_constructor is None:
|
|
124
|
+
face_constructor = default_face_constructor
|
|
125
|
+
atom_to_coatoms = [frozenset(atc) for atc in atom_to_coatoms]
|
|
126
|
+
A = frozenset(range(len(atom_to_coatoms))) # All atoms
|
|
127
|
+
coatom_to_atoms = [frozenset(cta) for cta in coatom_to_atoms]
|
|
128
|
+
C = frozenset(range(len(coatom_to_atoms))) # All coatoms
|
|
129
|
+
# Comments with numbers correspond to steps in Section 2.5 of the article
|
|
130
|
+
L = DiGraph(1) # 3: initialize L
|
|
131
|
+
faces = {}
|
|
132
|
+
atoms = frozenset()
|
|
133
|
+
coatoms = C
|
|
134
|
+
faces[atoms, coatoms] = 0
|
|
135
|
+
next_index = 1
|
|
136
|
+
Q = [(atoms, coatoms)] # 4: initialize Q with the empty face
|
|
137
|
+
while Q: # 5
|
|
138
|
+
q_atoms, q_coatoms = Q.pop() # 6: remove some q from Q
|
|
139
|
+
q = faces[q_atoms, q_coatoms]
|
|
140
|
+
# 7: compute H = {closure(q+atom) : atom not in atoms of q}
|
|
141
|
+
H = {}
|
|
142
|
+
candidates = set(A.difference(q_atoms))
|
|
143
|
+
for atom in candidates:
|
|
144
|
+
coatoms = q_coatoms.intersection(atom_to_coatoms[atom])
|
|
145
|
+
atoms = A
|
|
146
|
+
for coatom in coatoms:
|
|
147
|
+
atoms = atoms.intersection(coatom_to_atoms[coatom])
|
|
148
|
+
H[atom] = (atoms, coatoms)
|
|
149
|
+
# 8: compute the set G of minimal sets in H
|
|
150
|
+
minimals = set()
|
|
151
|
+
while candidates:
|
|
152
|
+
candidate = candidates.pop()
|
|
153
|
+
atoms = H[candidate][0]
|
|
154
|
+
if atoms.isdisjoint(candidates) and atoms.isdisjoint(minimals):
|
|
155
|
+
minimals.add(candidate)
|
|
156
|
+
# Now G == {H[atom] : atom in minimals}
|
|
157
|
+
for atom in minimals: # 9: for g in G:
|
|
158
|
+
g_atoms, g_coatoms = H[atom]
|
|
159
|
+
if required_atoms is not None:
|
|
160
|
+
if g_atoms.isdisjoint(required_atoms):
|
|
161
|
+
continue
|
|
162
|
+
if (g_atoms, g_coatoms) in faces:
|
|
163
|
+
g = faces[g_atoms, g_coatoms]
|
|
164
|
+
else: # 11: if g was newly created
|
|
165
|
+
g = next_index
|
|
166
|
+
faces[g_atoms, g_coatoms] = g
|
|
167
|
+
next_index += 1
|
|
168
|
+
Q.append((g_atoms, g_coatoms)) # 12
|
|
169
|
+
L.add_edge(q, g) # 14
|
|
170
|
+
|
|
171
|
+
# End of algorithm, now construct a FiniteLatticePoset.
|
|
172
|
+
|
|
173
|
+
# In principle, it is recommended to use Poset or in this case perhaps
|
|
174
|
+
# even LatticePoset, but it seems to take several times more time
|
|
175
|
+
# than the above computation, makes unnecessary copies, and crashes.
|
|
176
|
+
# So for now we will mimic the relevant code from Poset.
|
|
177
|
+
|
|
178
|
+
# Enumeration of graph vertices must be a linear extension of the poset
|
|
179
|
+
new_order = L.topological_sort()
|
|
180
|
+
# Make sure that coatoms are in the end in proper order
|
|
181
|
+
tail = [faces[atomes, frozenset([coatom])]
|
|
182
|
+
for coatom, atomes in enumerate(coatom_to_atoms)]
|
|
183
|
+
tail.append(faces[A, frozenset()])
|
|
184
|
+
new_order = [n for n in new_order if n not in tail] + tail
|
|
185
|
+
# Make sure that atoms are in the beginning in proper order
|
|
186
|
+
head = [0] # We know that the empty face has index 0
|
|
187
|
+
head.extend(faces[frozenset([atom]), coatoms]
|
|
188
|
+
for atom, coatoms in enumerate(atom_to_coatoms)
|
|
189
|
+
if required_atoms is None or atom in required_atoms)
|
|
190
|
+
new_order = head + [n for n in new_order if n not in head]
|
|
191
|
+
# "Invert" this list to a dictionary
|
|
192
|
+
labels = {old: new for new, old in enumerate(new_order)}
|
|
193
|
+
L.relabel(labels)
|
|
194
|
+
# Construct the actual poset elements
|
|
195
|
+
elements = [None] * next_index
|
|
196
|
+
for face, index in faces.items():
|
|
197
|
+
atoms, coatoms = face
|
|
198
|
+
elements[labels[index]] = face_constructor(
|
|
199
|
+
tuple(sorted(atoms)), tuple(sorted(coatoms)), **kwds)
|
|
200
|
+
D = dict(enumerate(elements))
|
|
201
|
+
L.relabel(D)
|
|
202
|
+
return FiniteLatticePoset(L, elements, key=key)
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
"""
|
|
3
|
+
Affine Subspaces of a Vector Space
|
|
4
|
+
|
|
5
|
+
An affine subspace of a vector space is a translation of a linear
|
|
6
|
+
subspace. The affine subspaces here are only used internally in
|
|
7
|
+
hyperplane arrangements. You should not use them for interactive work
|
|
8
|
+
or return them to the user.
|
|
9
|
+
|
|
10
|
+
EXAMPLES::
|
|
11
|
+
|
|
12
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
13
|
+
sage: a = AffineSubspace([1,0,0,0], QQ^4)
|
|
14
|
+
sage: a.dimension()
|
|
15
|
+
4
|
|
16
|
+
sage: a.point()
|
|
17
|
+
(1, 0, 0, 0)
|
|
18
|
+
sage: a.linear_part()
|
|
19
|
+
Vector space of dimension 4 over Rational Field
|
|
20
|
+
sage: a
|
|
21
|
+
Affine space p + W where:
|
|
22
|
+
p = (1, 0, 0, 0)
|
|
23
|
+
W = Vector space of dimension 4 over Rational Field
|
|
24
|
+
sage: b = AffineSubspace((1,0,0,0), matrix(QQ, [[1,2,3,4]]).right_kernel())
|
|
25
|
+
sage: c = AffineSubspace((0,2,0,0), matrix(QQ, [[0,0,1,2]]).right_kernel())
|
|
26
|
+
sage: b.intersection(c)
|
|
27
|
+
Affine space p + W where:
|
|
28
|
+
p = (-3, 2, 0, 0)
|
|
29
|
+
W = Vector space of degree 4 and dimension 2 over Rational Field
|
|
30
|
+
Basis matrix:
|
|
31
|
+
[ 1 0 -1 1/2]
|
|
32
|
+
[ 0 1 -2 1]
|
|
33
|
+
sage: b < a
|
|
34
|
+
True
|
|
35
|
+
sage: c < b
|
|
36
|
+
False
|
|
37
|
+
sage: A = AffineSubspace([8,38,21,250], VectorSpace(GF(19),4))
|
|
38
|
+
sage: A
|
|
39
|
+
Affine space p + W where:
|
|
40
|
+
p = (8, 0, 2, 3)
|
|
41
|
+
W = Vector space of dimension 4 over Finite Field of size 19
|
|
42
|
+
|
|
43
|
+
TESTS::
|
|
44
|
+
|
|
45
|
+
sage: A = AffineSubspace([2], VectorSpace(QQ, 1))
|
|
46
|
+
sage: A.point()
|
|
47
|
+
(2)
|
|
48
|
+
sage: A.linear_part()
|
|
49
|
+
Vector space of dimension 1 over Rational Field
|
|
50
|
+
sage: A.linear_part().basis_matrix()
|
|
51
|
+
[1]
|
|
52
|
+
sage: A = AffineSubspace([], VectorSpace(QQ, 0))
|
|
53
|
+
sage: A.point()
|
|
54
|
+
()
|
|
55
|
+
sage: A.linear_part()
|
|
56
|
+
Vector space of dimension 0 over Rational Field
|
|
57
|
+
sage: A.linear_part().basis_matrix()
|
|
58
|
+
[]
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
#*****************************************************************************
|
|
62
|
+
# Copyright (C) 2013 David Perkinson <davidp@reed.edu>
|
|
63
|
+
# Volker Braun <vbraun.name@gmail.com>
|
|
64
|
+
#
|
|
65
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
66
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
67
|
+
# the License, or (at your option) any later version.
|
|
68
|
+
# http://www.gnu.org/licenses/
|
|
69
|
+
#*****************************************************************************
|
|
70
|
+
|
|
71
|
+
from sage.structure.sage_object import SageObject
|
|
72
|
+
from sage.matrix.constructor import vector
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class AffineSubspace(SageObject):
|
|
76
|
+
"""
|
|
77
|
+
An affine subspace.
|
|
78
|
+
|
|
79
|
+
INPUT:
|
|
80
|
+
|
|
81
|
+
- ``p`` -- list/tuple/iterable representing a point on the
|
|
82
|
+
affine space
|
|
83
|
+
|
|
84
|
+
- ``V`` -- vector subspace
|
|
85
|
+
|
|
86
|
+
OUTPUT: affine subspace parallel to ``V`` and passing through ``p``
|
|
87
|
+
|
|
88
|
+
EXAMPLES::
|
|
89
|
+
|
|
90
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
91
|
+
sage: a = AffineSubspace([1,0,0,0], VectorSpace(QQ,4))
|
|
92
|
+
sage: a
|
|
93
|
+
Affine space p + W where:
|
|
94
|
+
p = (1, 0, 0, 0)
|
|
95
|
+
W = Vector space of dimension 4 over Rational Field
|
|
96
|
+
"""
|
|
97
|
+
def __init__(self, p, V):
|
|
98
|
+
r"""
|
|
99
|
+
Construct an :class:`AffineSubspace`.
|
|
100
|
+
|
|
101
|
+
TESTS::
|
|
102
|
+
|
|
103
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
104
|
+
sage: a = AffineSubspace([1,0,0,0], VectorSpace(QQ,4))
|
|
105
|
+
sage: TestSuite(a).run()
|
|
106
|
+
sage: AffineSubspace(0, VectorSpace(QQ,4)).point()
|
|
107
|
+
(0, 0, 0, 0)
|
|
108
|
+
"""
|
|
109
|
+
R = V.base_ring()
|
|
110
|
+
from sage.categories.fields import Fields
|
|
111
|
+
if R not in Fields():
|
|
112
|
+
R = R.fraction_field()
|
|
113
|
+
V = V.change_ring(R)
|
|
114
|
+
self._base_ring = R
|
|
115
|
+
self._linear_part = V
|
|
116
|
+
p = V.ambient_vector_space()(p)
|
|
117
|
+
p.set_immutable()
|
|
118
|
+
self._point = p
|
|
119
|
+
|
|
120
|
+
def __hash__(self):
|
|
121
|
+
"""
|
|
122
|
+
Return a hash value.
|
|
123
|
+
|
|
124
|
+
EXAMPLES::
|
|
125
|
+
|
|
126
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
127
|
+
sage: a = AffineSubspace([1,0,0,0], VectorSpace(QQ,4))
|
|
128
|
+
sage: a.__hash__() # random output
|
|
129
|
+
-3713096828371451969
|
|
130
|
+
"""
|
|
131
|
+
# note that the point is not canonically chosen, but the linear part is
|
|
132
|
+
return hash(self._linear_part)
|
|
133
|
+
|
|
134
|
+
def _repr_(self):
|
|
135
|
+
r"""
|
|
136
|
+
String representation for an :class:`AffineSubspace`.
|
|
137
|
+
|
|
138
|
+
OUTPUT: string
|
|
139
|
+
|
|
140
|
+
EXAMPLES::
|
|
141
|
+
|
|
142
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
143
|
+
sage: a = AffineSubspace([1,0,0,0],VectorSpace(QQ,4))
|
|
144
|
+
sage: a
|
|
145
|
+
Affine space p + W where:
|
|
146
|
+
p = (1, 0, 0, 0)
|
|
147
|
+
W = Vector space of dimension 4 over Rational Field
|
|
148
|
+
"""
|
|
149
|
+
return "Affine space p + W where:\n p = "+str(self._point)+"\n W = "+str(self._linear_part)
|
|
150
|
+
|
|
151
|
+
def __eq__(self, other):
|
|
152
|
+
r"""
|
|
153
|
+
Test whether ``self`` is equal to ``other``.
|
|
154
|
+
|
|
155
|
+
INPUT:
|
|
156
|
+
|
|
157
|
+
- ``other`` -- an :class:`AffineSubspace`
|
|
158
|
+
|
|
159
|
+
OUTPUT: boolean
|
|
160
|
+
|
|
161
|
+
EXAMPLES::
|
|
162
|
+
|
|
163
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
164
|
+
sage: a = AffineSubspace([1,0,0], matrix([[1,0,0]]).right_kernel())
|
|
165
|
+
sage: b = AffineSubspace([2,0,0], matrix([[1,0,0]]).right_kernel())
|
|
166
|
+
sage: c = AffineSubspace([1,1,0], matrix([[1,0,0]]).right_kernel())
|
|
167
|
+
sage: a == b
|
|
168
|
+
False
|
|
169
|
+
sage: a == c
|
|
170
|
+
True
|
|
171
|
+
"""
|
|
172
|
+
V = self._linear_part
|
|
173
|
+
W = other._linear_part
|
|
174
|
+
return V == W and self._point - other._point in V
|
|
175
|
+
|
|
176
|
+
def __ne__(self, other):
|
|
177
|
+
r"""
|
|
178
|
+
Test whether ``self`` is not equal to ``other``.
|
|
179
|
+
|
|
180
|
+
INPUT:
|
|
181
|
+
|
|
182
|
+
- ``other`` -- an :class:`AffineSubspace`
|
|
183
|
+
|
|
184
|
+
OUTPUT: boolean
|
|
185
|
+
|
|
186
|
+
EXAMPLES::
|
|
187
|
+
|
|
188
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
189
|
+
sage: a = AffineSubspace([1,0,0],matrix([[1,0,0]]).right_kernel())
|
|
190
|
+
sage: b = AffineSubspace([2,0,0],matrix([[1,0,0]]).right_kernel())
|
|
191
|
+
sage: a == b
|
|
192
|
+
False
|
|
193
|
+
sage: a != b
|
|
194
|
+
True
|
|
195
|
+
sage: a != a
|
|
196
|
+
False
|
|
197
|
+
"""
|
|
198
|
+
return not self == other
|
|
199
|
+
|
|
200
|
+
def __le__(self, other):
|
|
201
|
+
r"""
|
|
202
|
+
Test whether ``self`` is an affine subspace of ``other``.
|
|
203
|
+
|
|
204
|
+
INPUT:
|
|
205
|
+
|
|
206
|
+
- ``other`` -- an :class:`AffineSubspace`
|
|
207
|
+
|
|
208
|
+
OUTPUT: boolean
|
|
209
|
+
|
|
210
|
+
EXAMPLES::
|
|
211
|
+
|
|
212
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
213
|
+
sage: V = VectorSpace(QQ, 3)
|
|
214
|
+
sage: W1 = V.subspace([[1,0,0],[0,1,0]])
|
|
215
|
+
sage: W2 = V.subspace([[1,0,0]])
|
|
216
|
+
sage: a = AffineSubspace([1,2,3], W1)
|
|
217
|
+
sage: b = AffineSubspace([1,2,3], W2)
|
|
218
|
+
sage: a <= b
|
|
219
|
+
False
|
|
220
|
+
sage: a <= a
|
|
221
|
+
True
|
|
222
|
+
sage: b <= a
|
|
223
|
+
True
|
|
224
|
+
"""
|
|
225
|
+
V = self._linear_part
|
|
226
|
+
W = other._linear_part
|
|
227
|
+
return V.is_subspace(W) and self._point-other._point in W
|
|
228
|
+
|
|
229
|
+
def __lt__(self, other):
|
|
230
|
+
r"""
|
|
231
|
+
Test whether ``self`` is a proper affine subspace of ``other``.
|
|
232
|
+
|
|
233
|
+
INPUT:
|
|
234
|
+
|
|
235
|
+
- ``other`` -- an :class:`AffineSubspace`
|
|
236
|
+
|
|
237
|
+
OUTPUT: boolean
|
|
238
|
+
|
|
239
|
+
EXAMPLES::
|
|
240
|
+
|
|
241
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
242
|
+
sage: V = VectorSpace(QQ, 3)
|
|
243
|
+
sage: W1 = V.subspace([[1,0,0], [0,1,0]])
|
|
244
|
+
sage: W2 = V.subspace([[1,0,0]])
|
|
245
|
+
sage: a = AffineSubspace([1,2,3], W1)
|
|
246
|
+
sage: b = AffineSubspace([1,2,3], W2)
|
|
247
|
+
sage: a < b
|
|
248
|
+
False
|
|
249
|
+
sage: a < a
|
|
250
|
+
False
|
|
251
|
+
sage: b < a
|
|
252
|
+
True
|
|
253
|
+
"""
|
|
254
|
+
if self._linear_part == other._linear_part:
|
|
255
|
+
return False
|
|
256
|
+
return self <= other
|
|
257
|
+
|
|
258
|
+
def __contains__(self, q):
|
|
259
|
+
r"""
|
|
260
|
+
Test whether the point ``q`` is in the affine space.
|
|
261
|
+
|
|
262
|
+
INPUT:
|
|
263
|
+
|
|
264
|
+
- ``q`` -- point as a list/tuple/iterable
|
|
265
|
+
|
|
266
|
+
OUTPUT: boolean
|
|
267
|
+
|
|
268
|
+
EXAMPLES::
|
|
269
|
+
|
|
270
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
271
|
+
sage: a = AffineSubspace([1,0,0], matrix([[1,0,0]]).right_kernel())
|
|
272
|
+
sage: (1,1,0) in a
|
|
273
|
+
True
|
|
274
|
+
sage: (0,0,0) in a
|
|
275
|
+
False
|
|
276
|
+
"""
|
|
277
|
+
q = vector(self._base_ring, q)
|
|
278
|
+
return self._point - q in self._linear_part
|
|
279
|
+
|
|
280
|
+
def linear_part(self):
|
|
281
|
+
r"""
|
|
282
|
+
Return the linear part of the affine space.
|
|
283
|
+
|
|
284
|
+
OUTPUT: a vector subspace of the ambient space
|
|
285
|
+
|
|
286
|
+
EXAMPLES::
|
|
287
|
+
|
|
288
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
289
|
+
sage: A = AffineSubspace([2,3,1], matrix(QQ, [[1,2,3]]).right_kernel())
|
|
290
|
+
sage: A.linear_part()
|
|
291
|
+
Vector space of degree 3 and dimension 2 over Rational Field
|
|
292
|
+
Basis matrix:
|
|
293
|
+
[ 1 0 -1/3]
|
|
294
|
+
[ 0 1 -2/3]
|
|
295
|
+
sage: A.linear_part().ambient_vector_space()
|
|
296
|
+
Vector space of dimension 3 over Rational Field
|
|
297
|
+
"""
|
|
298
|
+
return self._linear_part
|
|
299
|
+
|
|
300
|
+
def point(self):
|
|
301
|
+
r"""
|
|
302
|
+
Return a point ``p`` in the affine space.
|
|
303
|
+
|
|
304
|
+
OUTPUT: a point of the affine space as a vector in the ambient space
|
|
305
|
+
|
|
306
|
+
EXAMPLES::
|
|
307
|
+
|
|
308
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
309
|
+
sage: A = AffineSubspace([2,3,1], VectorSpace(QQ,3))
|
|
310
|
+
sage: A.point()
|
|
311
|
+
(2, 3, 1)
|
|
312
|
+
"""
|
|
313
|
+
return self._point
|
|
314
|
+
|
|
315
|
+
def dimension(self):
|
|
316
|
+
r"""
|
|
317
|
+
Return the dimension of the affine space.
|
|
318
|
+
|
|
319
|
+
OUTPUT: integer
|
|
320
|
+
|
|
321
|
+
EXAMPLES::
|
|
322
|
+
|
|
323
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
324
|
+
sage: a = AffineSubspace([1,0,0,0],VectorSpace(QQ,4))
|
|
325
|
+
sage: a.dimension()
|
|
326
|
+
4
|
|
327
|
+
"""
|
|
328
|
+
return self.linear_part().dimension()
|
|
329
|
+
|
|
330
|
+
def intersection(self, other):
|
|
331
|
+
r"""
|
|
332
|
+
Return the intersection of ``self`` with ``other``.
|
|
333
|
+
|
|
334
|
+
INPUT:
|
|
335
|
+
|
|
336
|
+
- ``other`` -- an :class:`AffineSubspace`
|
|
337
|
+
|
|
338
|
+
OUTPUT:
|
|
339
|
+
|
|
340
|
+
A new affine subspace, (or ``None`` if the intersection is
|
|
341
|
+
empty).
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
346
|
+
sage: V = VectorSpace(QQ,3)
|
|
347
|
+
sage: U = V.subspace([(1,0,0), (0,1,0)])
|
|
348
|
+
sage: W = V.subspace([(0,1,0), (0,0,1)])
|
|
349
|
+
sage: A = AffineSubspace((0,0,0), U)
|
|
350
|
+
sage: B = AffineSubspace((1,1,1), W)
|
|
351
|
+
sage: A.intersection(B)
|
|
352
|
+
Affine space p + W where:
|
|
353
|
+
p = (1, 1, 0)
|
|
354
|
+
W = Vector space of degree 3 and dimension 1 over Rational Field
|
|
355
|
+
Basis matrix:
|
|
356
|
+
[0 1 0]
|
|
357
|
+
sage: C = AffineSubspace((0,0,1), U)
|
|
358
|
+
sage: A.intersection(C)
|
|
359
|
+
sage: C = AffineSubspace((7,8,9), U.complement())
|
|
360
|
+
sage: A.intersection(C)
|
|
361
|
+
Affine space p + W where:
|
|
362
|
+
p = (7, 8, 0)
|
|
363
|
+
W = Vector space of degree 3 and dimension 0 over Rational Field
|
|
364
|
+
Basis matrix:
|
|
365
|
+
[]
|
|
366
|
+
sage: A.intersection(C).intersection(B)
|
|
367
|
+
|
|
368
|
+
sage: D = AffineSubspace([1,2,3], VectorSpace(GF(5),3))
|
|
369
|
+
sage: E = AffineSubspace([3,4,5], VectorSpace(GF(5),3))
|
|
370
|
+
sage: D.intersection(E)
|
|
371
|
+
Affine space p + W where:
|
|
372
|
+
p = (3, 4, 0)
|
|
373
|
+
W = Vector space of dimension 3 over Finite Field of size 5
|
|
374
|
+
"""
|
|
375
|
+
if self.linear_part().ambient_vector_space() != \
|
|
376
|
+
other.linear_part().ambient_vector_space():
|
|
377
|
+
raise ValueError('incompatible ambient vector spaces')
|
|
378
|
+
m = self.linear_part().matrix()
|
|
379
|
+
n = other.linear_part().matrix()
|
|
380
|
+
p = self.point()
|
|
381
|
+
q = other.point()
|
|
382
|
+
M = m.stack(n)
|
|
383
|
+
v = q - p
|
|
384
|
+
try:
|
|
385
|
+
t = M.solve_left(v)
|
|
386
|
+
except ValueError:
|
|
387
|
+
return None # empty intersection
|
|
388
|
+
new_p = p + t[:m.nrows()]*m
|
|
389
|
+
new_V = self.linear_part().intersection(other._linear_part)
|
|
390
|
+
return AffineSubspace(new_p, new_V)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|