Skip to content

Commit

Permalink
Trac #33586: Triangulation.polyhedral_complex, boundary_simplicial_co…
Browse files Browse the repository at this point in the history
…mplex, boundary_polyhedral_complex

`polyhedral_complex` creates a geometric polyhedral complex
corresponding to the triangulation.

`boundary_simplicial_complex` and `boundary_polyhedral_complex` are
combinations of `boundary` (which gives a set of simplices) with
`simplicial_complex` (which gives an abstract simplicial complex) and
`polyhedral_complex`, respectively

URL: https://trac.sagemath.org/33586
Reported by: mkoeppe
Ticket author(s): Matthias Koeppe
Reviewer(s): Yuan Zhou, John Palmieri
  • Loading branch information
Release Manager committed Aug 8, 2022
2 parents 5247961 + 65134f1 commit e9efc9c
Showing 1 changed file with 128 additions and 14 deletions.
142 changes: 128 additions & 14 deletions src/sage/geometry/triangulation/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,21 +227,21 @@ class Triangulation(Element):
"""
def __init__(self, triangulation, parent, check=True):
"""
The constructor of a ``Triangulation`` object. Note that an
internal reference to the underlying ``PointConfiguration`` is
The constructor of a ``Triangulation`` object.
Note that an internal reference to the underlying ``PointConfiguration`` is
kept.
INPUT:
- ``parent`` -- a
:class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`
- ``triangulation`` -- an iterable of integers or iterable of
iterables (e.g. a list of lists). In the first case, the
integers specify simplices via
:meth:`PointConfiguration.simplex_to_int`. In the second
case, the point indices of the maximal simplices of the
triangulation.
- ``triangulation`` -- an iterable of integers or an iterable of
iterables (e.g. a list of lists), specifying the maximal simplices
of the triangulation. In the first case, each integer specifies a simplex
by the correspondence :meth:`PointConfiguration.simplex_to_int`. In the second
case, a simplex is specified by listing the indices of the included points.
- ``check`` -- boolean. Whether to perform checks that the
triangulation is, indeed, a triangulation of the point
Expand Down Expand Up @@ -370,7 +370,7 @@ def __getitem__(self, i):

def __len__(self):
"""
Returns the length of the triangulation.
Return the length of the triangulation.
TESTS::
Expand Down Expand Up @@ -572,8 +572,7 @@ def fan(self, origin=None):
@cached_method
def simplicial_complex(self):
r"""
Return a simplicial complex from a triangulation of the point
configuration.
Return ``self`` as an (abstract) simplicial complex.
OUTPUT:
Expand All @@ -598,7 +597,7 @@ def simplicial_complex(self):
@cached_method
def _boundary_simplex_dictionary(self):
"""
Return facets and the simplices they bound
Return facets and the simplices they bound.
TESTS::
Expand Down Expand Up @@ -675,6 +674,38 @@ def boundary(self):
in self._boundary_simplex_dictionary().items()
if len(bounded_simplices) == 1)

@cached_method
def boundary_simplicial_complex(self):
r"""
Return the boundary of ``self`` as an (abstract) simplicial complex.
OUTPUT:
A :class:`~sage.topology.simplicial_complex.SimplicialComplex`.
EXAMPLES::
sage: p = polytopes.cuboctahedron()
sage: triangulation = p.triangulate(engine='internal')
sage: bd_sc = triangulation.boundary_simplicial_complex()
sage: bd_sc
Simplicial complex with 12 vertices and 20 facets
The boundary of every convex set is a topological sphere, so it has
spherical homology::
sage: bd_sc.homology()
{0: 0, 1: 0, 2: Z}
It is a subcomplex of ``self`` as a :meth:`simplicial_complex`::
sage: sc = triangulation.simplicial_complex()
sage: all(f in sc for f in bd_sc.maximal_faces())
True
"""
from sage.topology.simplicial_complex import SimplicialComplex
return SimplicialComplex(self.boundary(), maximality_check=False)

@cached_method
def interior_facets(self):
"""
Expand Down Expand Up @@ -711,6 +742,90 @@ def interior_facets(self):
in self._boundary_simplex_dictionary().items()
if len(bounded_simplices) == 2)

def polyhedral_complex(self, **kwds):
"""
Return ``self`` as a :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex`.
OUTPUT:
A :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex` whose maximal cells
are the simplices of the triangulation.
EXAMPLES::
sage: P = polytopes.cube()
sage: pc = PointConfiguration(P.vertices())
sage: T = pc.placing_triangulation(); T
(<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>)
sage: C = T.polyhedral_complex(); C
Polyhedral complex with 6 maximal cells
sage: [P.vertices_list() for P in C.maximal_cells_sorted()]
[[[-1, -1, -1], [-1, -1, 1], [-1, 1, 1], [1, -1, -1]],
[[-1, -1, -1], [-1, 1, -1], [-1, 1, 1], [1, 1, -1]],
[[-1, -1, -1], [-1, 1, 1], [1, -1, -1], [1, 1, -1]],
[[-1, -1, 1], [-1, 1, 1], [1, -1, -1], [1, -1, 1]],
[[-1, 1, 1], [1, -1, -1], [1, -1, 1], [1, 1, 1]],
[[-1, 1, 1], [1, -1, -1], [1, 1, -1], [1, 1, 1]]]
"""
from sage.geometry.polyhedral_complex import PolyhedralComplex
from sage.geometry.polyhedron.constructor import Polyhedron
ambient_dim = self.point_configuration().ambient_dim()
points = self.point_configuration().points()
return PolyhedralComplex([Polyhedron(vertices=[points[i] for i in simplex])
for simplex in self],
ambient_dim=ambient_dim,
maximality_check=False,
face_to_face_check=False,
**kwds)

def boundary_polyhedral_complex(self, **kwds):
r"""
Return the boundary of ``self`` as a :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex`.
OUTPUT:
A :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex` whose maximal cells
are the simplices of the boundary of ``self``.
EXAMPLES::
sage: P = polytopes.cube()
sage: pc = PointConfiguration(P.vertices())
sage: T = pc.placing_triangulation(); T
(<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>)
sage: bd_C = T.boundary_polyhedral_complex(); bd_C
Polyhedral complex with 12 maximal cells
sage: [P.vertices_list() for P in bd_C.maximal_cells_sorted()]
[[[-1, -1, -1], [-1, -1, 1], [-1, 1, 1]],
[[-1, -1, -1], [-1, -1, 1], [1, -1, -1]],
[[-1, -1, -1], [-1, 1, -1], [-1, 1, 1]],
[[-1, -1, -1], [-1, 1, -1], [1, 1, -1]],
[[-1, -1, -1], [1, -1, -1], [1, 1, -1]],
[[-1, -1, 1], [-1, 1, 1], [1, -1, 1]],
[[-1, -1, 1], [1, -1, -1], [1, -1, 1]],
[[-1, 1, -1], [-1, 1, 1], [1, 1, -1]],
[[-1, 1, 1], [1, -1, 1], [1, 1, 1]],
[[-1, 1, 1], [1, 1, -1], [1, 1, 1]],
[[1, -1, -1], [1, -1, 1], [1, 1, 1]],
[[1, -1, -1], [1, 1, -1], [1, 1, 1]]]
It is a subcomplex of ``self`` as a :meth:`polyhedral_complex`::
sage: C = T.polyhedral_complex()
sage: bd_C.is_subcomplex(C)
True
"""
from sage.geometry.polyhedral_complex import PolyhedralComplex
from sage.geometry.polyhedron.constructor import Polyhedron
ambient_dim = self.point_configuration().ambient_dim()
points = self.point_configuration().points()
return PolyhedralComplex([Polyhedron(vertices=[points[i] for i in simplex])
for simplex in self.boundary()],
ambient_dim=ambient_dim,
maximality_check=False,
face_to_face_check=False,
**kwds)

@cached_method
def normal_cone(self):
r"""
Expand Down Expand Up @@ -798,8 +913,7 @@ def normal_cone(self):

def adjacency_graph(self):
"""
Returns a graph showing which simplices are adjacent in the
triangulation
Return a graph showing which simplices are adjacent in the triangulation.
OUTPUT:
Expand Down

0 comments on commit e9efc9c

Please sign in to comment.