Skip to content

Commit

Permalink
Trac #29898: vertex facet graph for trivial polyhedra fails
Browse files Browse the repository at this point in the history
The vertex facet graph of `CombinatorialPolyhedron` only works for
polyhedra of dimension at least one. With #29188 this makes it fail with
for `Polyhedron_base` as well.

We fix this to return
- the `Digraph` on 0 vertices for the empty polyhedron and
- the `Digraph` on 1 vertex for the 0-dimensional polyhedron (it was
misbehaved even before #29188).

We also "fix" the definition of facets to correspond to inequalities.
The `0`-dimensional polyhedron does not have facets in this case
anymore.
(Before this ticket `n_facets` and `facets` would use different
definitions of facets.)b

URL: https://trac.sagemath.org/29898
Reported by: gh-kliem
Ticket author(s): Jonathan Kliem
Reviewer(s): Matthias Koeppe
  • Loading branch information
Release Manager committed Jul 10, 2020
2 parents 66a0338 + 25cfaa0 commit 04219c9
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
13 changes: 12 additions & 1 deletion src/sage/geometry/polyhedron/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6449,8 +6449,11 @@ def facets(self):
r"""
Return the facets of the polyhedron.
Facets are the maximal nontrivial faces of polyhedra.
The empty face and the polyhedron itself are trivial.
A facet of a `d`-dimensional polyhedron is a face of dimension
`d-1`.
`d-1`. For `d \neq 0` the converse is true as well.
OUTPUT:
Expand Down Expand Up @@ -6490,7 +6493,15 @@ def facets(self):
A 3-dimensional face of a Polyhedron in ZZ^4 defined as the convex hull of 8 vertices,
A 3-dimensional face of a Polyhedron in ZZ^4 defined as the convex hull of 8 vertices,
A 3-dimensional face of a Polyhedron in ZZ^4 defined as the convex hull of 8 vertices)
The ``0``-dimensional polyhedron does not have facets::
sage: P = Polyhedron([[0]])
sage: P.facets()
()
"""
if self.dimension() == 0:
return ()
return self.faces(self.dimension()-1)

@cached_method(do_pickle=True)
Expand Down
47 changes: 42 additions & 5 deletions src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ cdef class CombinatorialPolyhedron(SageObject):
sage: P = Polyhedron(vertices=[[0,0]])
sage: C = CombinatorialPolyhedron(P)
sage: C._repr_()
'A 0-dimensional combinatorial polyhedron with 1 facet'
'A 0-dimensional combinatorial polyhedron with 0 facets'
sage: P = Polyhedron(lines=[[0,0,1],[0,1,0]])
sage: C = CombinatorialPolyhedron(P)
Expand Down Expand Up @@ -908,15 +908,18 @@ cdef class CombinatorialPolyhedron(SageObject):
sage: C.n_facets()
0
Facets are defined to be the maximal nontrivial faces.
The ``0``-dimensional polyhedron does not have nontrivial faces::
sage: C = CombinatorialPolyhedron(0)
sage: C.f_vector()
(1, 1)
sage: C.n_facets()
1
0
"""
if unlikely(self._dimension == 0):
# This trivial polyhedron needs special attention.
return smallInteger(1)
return smallInteger(0)
return smallInteger(self._n_facets)

def facets(self, names=True):
Expand All @@ -926,6 +929,8 @@ cdef class CombinatorialPolyhedron(SageObject):
If ``names`` is ``False``, then the Vrepresentatives in the facets
are given by their indices in the Vrepresentation.
The facets are the maximal nontrivial faces.
EXAMPLES::
sage: P = polytopes.cube()
Expand Down Expand Up @@ -962,11 +967,19 @@ cdef class CombinatorialPolyhedron(SageObject):
(4, 5, 6, 7),
(0, 1, 5, 6),
(0, 3, 4, 5))
The empty face is trivial and hence the ``0``-dimensional
polyhedron does not have facets::
sage: C = CombinatorialPolyhedron(0)
sage: C.facets()
()
"""
if unlikely(self.dimension() == 0):
# Special attention for this trivial case.
# There is actually one facet, but we have not initialized it.
return ((),)
# Facets are defined to be nontrivial faces of codimension 1.
# The empty face is trivial.
return ()

# It is essential to have the facets in the exact same order as
# on input, so that pickle/unpickle by :meth:`reduce` works.
Expand Down Expand Up @@ -1508,7 +1521,31 @@ cdef class CombinatorialPolyhedron(SageObject):
sage: C.vertex_facet_graph(names=False).vertices()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
TESTS:
Test that :trac:`29898` is fixed::
sage: Polyhedron().vertex_facet_graph()
Digraph on 0 vertices
sage: Polyhedron([[0]]).vertex_facet_graph()
Digraph on 1 vertex
sage: Polyhedron([[0]]).vertex_facet_graph(False)
Digraph on 1 vertex
"""
if self.dimension() == -1:
return DiGraph()
if self.dimension() == 0:
if not names:
return DiGraph(1)
else:
Vrep = self.Vrep()
if Vrep:
v = Vrep[0]
else:
v = ("V", 0)
return DiGraph([[v], []])

# The face iterator will iterate through the facets in opposite order.
facet_iter = self.face_iter(self.dimension() - 1, dual=False)
n_facets = self.n_facets()
Expand Down

0 comments on commit 04219c9

Please sign in to comment.