Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
added simplicity and simpliciality to CombinatorialPolyhedron
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Kliem committed Oct 28, 2019
1 parent e44a557 commit 8e8ac4e
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ from .polyhedron_face_lattice cimport PolyhedronFaceLattice

@cython.final
cdef class CombinatorialPolyhedron(SageObject):
cdef public dict __cached_methods

# Do not assume any of those attributes to be initialized, use the corresponding methods instead.
cdef tuple _V # the names of VRep, if they exist
cdef tuple _H # the names of HRep, if they exist
Expand Down
141 changes: 141 additions & 0 deletions src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ from .conversions \
incidence_matrix_to_bit_repr_of_Vrepr, \
facets_tuple_to_bit_repr_of_facets, \
facets_tuple_to_bit_repr_of_Vrepr
from sage.misc.cachefunc import cached_method

from sage.rings.integer cimport smallInteger
from cysignals.signals cimport sig_check, sig_block, sig_unblock
Expand Down Expand Up @@ -1229,6 +1230,146 @@ cdef class CombinatorialPolyhedron(SageObject):
from sage.rings.all import ZZ
return vector(ZZ, self._f_vector)

@cached_method
def simpliciality(self):
r"""
Return the largest `k` such that the polytope is `k`-simplicial.
Return the dimension in case of a simplex.
A polytope is `k`-simplicial, if every `k`-face is a simplex.
EXAMPLES::
sage: cyclic = polytopes.cyclic_polytope(10,4)
sage: CombinatorialPolyhedron(cyclic).simpliciality()
3
sage: hypersimplex = polytopes.hypersimplex(5,2)
sage: CombinatorialPolyhedron(hypersimplex).simpliciality()
2
sage: cross = polytopes.cross_polytope(4)
sage: P = cross.join(cross)
sage: CombinatorialPolyhedron(P).simpliciality()
3
sage: P = polytopes.simplex(3)
sage: CombinatorialPolyhedron(P).simpliciality()
3
sage: P = polytopes.simplex(1)
sage: CombinatorialPolyhedron(P).simpliciality()
1
TESTS::
sage: P = polytopes.cube()
sage: C = CombinatorialPolyhedron(P)
sage: C.simpliciality is C.simpliciality
True
"""
if not self.is_bounded():
raise NotImplementedError("must be bounded")
cdef FaceIterator face_iter = self._face_iter(False, -2)
cdef int d
cdef int dim = self.dimension()

if self.n_facets() == self.dimension() + 1:
# A simplex.
return self.dimension()

cdef simpliciality = dim - 1

# For each face in the iterator, check if its a simplex.
face_iter.lowest_dimension = 2 # every 1-face is a simplex
d = face_iter.next_dimension()
while (d < dim):
sig_check()
if face_iter.length_atom_repr() == d + 1:
# The current face is a simplex.
face_iter.ignore_subfaces()
else:
# Current face is not a simplex.
if simpliciality > d - 1:
simpliciality = d - 1
d = face_iter.next_dimension()
if simpliciality == 1:
# Every polytope is 1-simplicial.
d = dim
return smallInteger(simpliciality)

@cached_method
def simplicity(self):
r"""
Return the largest `k` such that the polytope is `k`-simple.
Return the dimension in case of a simplex.
A polytope `P` is `k`-simple, if for every face `F`
of codimension `k` the polytope `P/F` is simple.
Equivalently it is `k`-simple if the polar/dual polytope is `k`-simplicial.
EXAMPLES::
sage: hyper4 = polytopes.hypersimplex(4,2)
sage: CombinatorialPolyhedron(hyper4).simplicity()
1
sage: hyper5 = polytopes.hypersimplex(5,2)
sage: CombinatorialPolyhedron(hyper5).simplicity()
2
sage: hyper6 = polytopes.hypersimplex(6,2)
sage: CombinatorialPolyhedron(hyper6).simplicity()
3
sage: P = polytopes.simplex(3)
sage: CombinatorialPolyhedron(P).simplicity()
3
sage: P = polytopes.simplex(1)
sage: CombinatorialPolyhedron(P).simplicity()
1
TESTS::
sage: P = polytopes.cube()
sage: C = CombinatorialPolyhedron(P)
sage: C.simplicity is C.simplicity
True
"""
if not self.is_bounded():
raise NotImplementedError("must be bounded")
cdef FaceIterator face_iter = self._face_iter(True, -2)
cdef int d
cdef int dim = self.dimension()

if self.n_facets() == self.dimension() + 1:
# A simplex.
return self.dimension()

cdef simplicity = dim - 1

# For each coface in the iterator, check if its a simplex.
face_iter.lowest_dimension = 2 # every coface of dimension 1 is a simplex
d = face_iter.next_dimension()
while (d < dim):
sig_check()
if face_iter.length_atom_repr() == d + 1:
# The current face is a simplex.
face_iter.ignore_supfaces()
else:
# Current coface is not a simplex.
if simplicity > d - 1:
simplicity = d - 1
d = face_iter.next_dimension()
if simplicity == 1:
# Every polytope is 1-simple.
d = dim
return smallInteger(simplicity)

def face_iter(self, dimension=None, dual=None):
r"""
Iterator over all proper faces of specified dimension.
Expand Down

0 comments on commit 8e8ac4e

Please sign in to comment.