diff --git a/src/sage/geometry/polyhedron/base3.py b/src/sage/geometry/polyhedron/base3.py index 2f056dee15b..615816476e2 100644 --- a/src/sage/geometry/polyhedron/base3.py +++ b/src/sage/geometry/polyhedron/base3.py @@ -967,7 +967,7 @@ def vertex_adjacency_matrix(self): @cached_method def facet_adjacency_matrix(self): """ - Return the adjacency matrix for the facets and hyperplanes. + Return the adjacency matrix for the facets. EXAMPLES:: @@ -979,6 +979,13 @@ def facet_adjacency_matrix(self): [1 1 1 0 1] [1 1 1 1 0] + sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)]) + sage: p.facet_adjacency_matrix() + [0 1 1] + [1 0 1] + [1 1 0] + + The facet adjacency matrix has base ring integers. This way one can express various counting questions:: @@ -992,52 +999,18 @@ def facet_adjacency_matrix(self): Check that :trac:`28828` is fixed:: - sage: s4.facet_adjacency_matrix().is_immutable() - True - """ - return self._facet_adjacency_matrix() - - def _facet_adjacency_matrix(self): - """ - Compute the facet adjacency matrix in case it has not been - computed during initialization. - - EXAMPLES:: - - sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)]) - sage: p._facet_adjacency_matrix() - [0 1 1] - [1 0 1] - [1 1 0] + sage: s4.facet_adjacency_matrix().is_immutable() + True Checks that :trac:`22455` is fixed:: sage: s = polytopes.simplex(2) - sage: s._facet_adjacency_matrix() + sage: s.facet_adjacency_matrix() [0 1 1] [1 0 1] [1 1 0] - """ - # TODO: This implementation computes the whole face lattice, - # which is much more information than necessary. - M = matrix(ZZ, self.n_facets(), self.n_facets(), 0) - codim = self.ambient_dim()-self.dim() - - def set_adjacent(h1, h2): - if h1 is h2: - return - i = h1.index() - codim - j = h2.index() - codim - M[i, j] = 1 - M[j, i] = 1 - - for face in self.faces(self.dim()-2): - Hrep = face.ambient_Hrepresentation() - assert(len(Hrep) == codim+2) - set_adjacent(Hrep[-2], Hrep[-1]) - M.set_immutable() - return M + return self.combinatorial_polyhedron().facet_adjacency_matrix() def a_maximal_chain(self): r""" diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 6e795febc0e..fc0bb11ca9c 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -1467,6 +1467,51 @@ cdef class CombinatorialPolyhedron(SageObject): return tuple((facet_one(i), facet_two(i)) for i in range(n_ridges)) + @cached_method + def facet_adjacency_matrix(self): + """ + Return the binary matrix of facet adjacencies. + + .. SEEALSO:: + + :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.vertex_adjacency_matrix`. + + EXAMPLES:: + + sage: P = polytopes.cube() + sage: C = P.combinatorial_polyhedron() + sage: C.facet_adjacency_matrix() + [0 1 1 0 1 1] + [1 0 1 1 1 0] + [1 1 0 1 0 1] + [0 1 1 0 1 1] + [1 1 0 1 0 1] + [1 0 1 1 1 0] + + TESTS:: + + sage: CombinatorialPolyhedron(-1).facet_adjacency_matrix() + [] + sage: CombinatorialPolyhedron(0).facet_adjacency_matrix() + [] + sage: polytopes.cube().facet_adjacency_matrix().is_immutable() + True + """ + from sage.rings.integer_ring import ZZ + from sage.matrix.constructor import matrix + cdef Matrix_integer_dense adjacency_matrix = matrix( + ZZ, self.n_facets(), self.n_facets(), 0) + cdef size_t i, a, b + + self._compute_ridges(-1) + for i in range(self._n_ridges): + a = self._get_edge(self._ridges, i, 0) + b = self._get_edge(self._ridges, i, 1) + adjacency_matrix.set_unsafe_si(a, b, 1) + adjacency_matrix.set_unsafe_si(b, a, 1) + adjacency_matrix.set_immutable() + return adjacency_matrix + def facet_graph(self, names=True): r""" Return the facet graph.