Finite polyhedral complexes - Combinatorial and Discrete Geometry

Skip to content
Back to top
View this page
Edit this page

# Finite polyhedral complexes

This module implements the basic structure of finite polyhedral complexes. For more information, see `PolyhedralComplex`.

AUTHORS:

- Yuan Zhou (2021-05): initial implementation

## List of PolyhedralComplex methods

Maximal cells and cells

`maximal_cells()` | Return the dictionary of the maximal cells in this polyhedral complex.
`maximal_cell_iterator()` | Return an iterator over maximal cells in this polyhedral complex.
`maximal_cells_sorted()` | Return the sorted list of all maximal cells in this polyhedral complex.
`n_maximal_cells()` | List the maximal cells of dimension \(n\) in this polyhedral complex.
`_n_maximal_cells_sorted()` | Return the sorted list of maximal cells of dim \(n\) in this complex.
`is_maximal_cell()` | Return `True` if the given cell is a maximal cell in this complex.
`cells()` | Return the dictionary of the cells in this polyhedral complex.
`cell_iterator()` | Return an iterator over cells in this polyhedral complex.
`cells_sorted()` | Return the sorted list of all cells in this polyhedral complex.
`n_cells()` | List the cells of dimension \(n\) in this polyhedral complex.
`_n_cells_sorted()` | Return the sorted list of \(n\)-cells in this polyhedral complex.
`is_cell()` | Return `True` if the given cell is in this polyhedral complex.
`face_poset()` | Return the poset of nonempty cells in the polyhedral complex.
`relative_boundary_cells()` | List the maximal cells on the boundary of the polyhedral complex.

Properties of the polyhedral complex

`dimension()` | Return the dimension of the polyhedral complex.
`ambient_dimension()` | Return the ambient dimension of the polyhedral complex.
`is_pure()` | Return `True` if the polyhedral complex is pure.
`is_full_dimensional()` | Return `True` if the polyhedral complex is full dimensional.
`is_compact()` | Return `True` if the polyhedral complex is bounded.
`is_connected()` | Return `True` if the polyhedral complex is connected.
`is_subcomplex()` | Return `True` if this complex is a subcomplex of the other.
`is_convex()` | Return `True` if the polyhedral complex is convex.
`is_mutable()` | Return `True` if the polyhedral complex is mutable.
`is_immutable()` | Return `True` if the polyhedral complex is not mutable.
`is_simplicial_complex()` | Return `True` if the polyhedral complex is a simplicial complex.
`is_polyhedral_fan()` | Return `True` if the polyhedral complex is a fan.
`is_simplicial_fan()` | Return `True` if the polyhedral complex is a simplicial fan.

New polyhedral complexes from old ones

`connected_component()` | Return the connected component containing a cell as a subcomplex.
`connected_components()` | Return the connected components of this polyhedral complex.
`n_skeleton()` | Return the \(n\)-skeleton of this polyhedral complex.
`stratify()` | Return the (pure) subcomplex formed by the maximal cells of dim \(n\) in this complex.
`boundary_subcomplex()` | Return the boundary subcomplex of this polyhedral complex.
`product()` | Return the (Cartesian) product of this polyhedral complex with another one.
`disjoint_union()` | Return the disjoint union of this polyhedral complex with another one.
`union()` | Return the union of this polyhedral complex with another one.
`join()` | Return the join of this polyhedral complex with another one.
`subdivide()` | Return a new polyhedral complex (with option `make_simplicial`) subdividing this one.

Update polyhedral complex

`set_immutable()` | Make this polyhedral complex immutable.
`add_cell()` | Add a cell to this polyhedral complex.
`remove_cell()` | Remove a cell from this polyhedral complex.

Miscellaneous

`plot()` | Return a Graphic object showing the plot of polyhedral complex.
`graph()` | Return a directed graph corresponding to the 1-skeleton of this polyhedral complex, given that it is bounded.
`union_as_polyhedron()` | Return a `Polyhedron` which is the union of cells in this polyhedral complex, given that it is convex.

## Classes and functions

class sage.geometry.polyhedral_complex.PolyhedralComplex(maximal_cells=None, backend=None, maximality_check=True, face_to_face_check=False, immutable=False, ambient_dim=None)

  Bases: `GenericCellComplex`

  A polyhedral complex.

  A polyhedral complex \(PC\) is a collection of polyhedra in a certain ambient space \(\RR^n\) such that the following hold.

  - If a polyhedron \(P\) is in \(PC\), then all the faces of \(P\) are in \(PC\).

  - If polyhedra \(P\) and \(Q\) are in \(PC\), then \(P \cap Q\) is either empty or a face of both \(P\) and \(Q\).

  In this context, a “polyhedron” means the geometric realization of a polyhedron. This is in contrast to `simplicial complex`, whose cells are abstract simplices. The concept of a polyhedral complex generalizes that of a geometric simplicial complex.

  Note

  This class derives from `GenericCellComplex`, and so inherits its methods. Some of those methods are not listed here; see the `Generic Cell Complex` page instead.

  INPUT:

  - `maximal_cells` – list, tuple, or dictionary (indexed by dimension) of cells of the Complex. Each cell is of class `Polyhedron` of the same ambient dimension. To set up a :class:PolyhedralComplex, it is sufficient to provide the maximal faces. Use keyword argument `partial=True` to set up a partial polyhedral complex, which is a subset of the faces (viewed as relatively open) of a polyhedral complex that is not necessarily closed under taking intersection.

  - `maximality_check` – boolean (default: `True`); if `True`, then the constructor checks that each given maximal cell is indeed maximal, and ignores those that are not

  - `face_to_face_check` – boolean (default: `False`); if `True`, then the constructor checks whether the cells are face-to-face, and it raises a `ValueError` if they are not

  - `immutable` – boolean (default: `False`); set `immutable=True` to make this polyhedral complex immutable

  - `backend` – string (optional); the name of the backend used for computations on Sage polyhedra; if it is not given, then each cell has its own backend; otherwise it must be one of the following:

    - `'ppl'` – the Parma Polyhedra Library

    - `'cdd'` – CDD

    - `'normaliz'` – normaliz

    - `'polymake'` – polymake

    - `'field'` – a generic Sage implementation

  - `ambient_dim` – integer (optional); used to set up an empty complex in the intended ambient space

  EXAMPLES:

  Sage

      sage: pc = PolyhedralComplex([
      ....:         Polyhedron(vertices=[(1/3, 1/3), (0, 0), (1/7, 2/7)]),
      ....:         Polyhedron(vertices=[(1/7, 2/7), (0, 0), (0, 1/4)])])
      sage: [p.Vrepresentation() for p in pc.cells_sorted()]
      [(A vertex at (0, 0), A vertex at (0, 1/4), A vertex at (1/7, 2/7)),
       (A vertex at (0, 0), A vertex at (1/3, 1/3), A vertex at (1/7, 2/7)),
       (A vertex at (0, 0), A vertex at (0, 1/4)),
       (A vertex at (0, 0), A vertex at (1/7, 2/7)),
       (A vertex at (0, 0), A vertex at (1/3, 1/3)),
       (A vertex at (0, 1/4), A vertex at (1/7, 2/7)),
       (A vertex at (1/3, 1/3), A vertex at (1/7, 2/7)),
       (A vertex at (0, 0),),
       (A vertex at (0, 1/4),),
       (A vertex at (1/7, 2/7),),
       (A vertex at (1/3, 1/3),)]
      sage: pc.plot()                                                                 # needs sage.plot
      Graphics object consisting of 10 graphics primitives
      sage: pc.is_pure()
      True
      sage: pc.is_full_dimensional()
      True
      sage: pc.is_compact()
      True
      sage: pc.boundary_subcomplex()
      Polyhedral complex with 4 maximal cells
      sage: pc.is_convex()
      True
      sage: pc.union_as_polyhedron().Hrepresentation()
      (An inequality (1, -4) x + 1 >= 0,
       An inequality (-1, 1) x + 0 >= 0,
       An inequality (1, 0) x + 0 >= 0)
      sage: pc.face_poset()
      Finite poset containing 11 elements
      sage: pc.is_connected()
      True
      sage: pc.connected_component() == pc
      True

  Python

      >>> from sage.all import *
      >>> pc = PolyhedralComplex([
      ...         Polyhedron(vertices=[(Integer(1)/Integer(3), Integer(1)/Integer(3)), (Integer(0), Integer(0)), (Integer(1)/Integer(7), Integer(2)/Integer(7))]),
      ...         Polyhedron(vertices=[(Integer(1)/Integer(7), Integer(2)/Integer(7)), (Integer(0), Integer(0)), (Integer(0), Integer(1)/Integer(4))])])
      >>> [p.Vrepresentation() for p in pc.cells_sorted()]
      [(A vertex at (0, 0), A vertex at (0, 1/4), A vertex at (1/7, 2/7)),
       (A vertex at (0, 0), A vertex at (1/3, 1/3), A vertex at (1/7, 2/7)),
       (A vertex at (0, 0), A vertex at (0, 1/4)),
       (A vertex at (0, 0), A vertex at (1/7, 2/7)),
       (A vertex at (0, 0), A vertex at (1/3, 1/3)),
       (A vertex at (0, 1/4), A vertex at (1/7, 2/7)),
       (A vertex at (1/3, 1/3), A vertex at (1/7, 2/7)),
       (A vertex at (0, 0),),
       (A vertex at (0, 1/4),),
       (A vertex at (1/7, 2/7),),
       (A vertex at (1/3, 1/3),)]
      >>> pc.plot()                                                                 # needs sage.plot
      Graphics object consisting of 10 graphics primitives
      >>> pc.is_pure()
      True
      >>> pc.is_full_dimensional()
      True
      >>> pc.is_compact()
      True
      >>> pc.boundary_subcomplex()
      Polyhedral complex with 4 maximal cells
      >>> pc.is_convex()
      True
      >>> pc.union_as_polyhedron().Hrepresentation()
      (An inequality (1, -4) x + 1 >= 0,
       An inequality (-1, 1) x + 0 >= 0,
       An inequality (1, 0) x + 0 >= 0)
      >>> pc.face_poset()
      Finite poset containing 11 elements
      >>> pc.is_connected()
      True
      >>> pc.connected_component() == pc
      True

  add_cell(cell)

    Add a cell to this polyhedral complex.

    INPUT:

    - `cell` – a polyhedron

    This changes the polyhedral complex, by adding a new cell and all of its subfaces.

    EXAMPLES:

    Set up an empty complex in the intended ambient space, then add a cell:

    Sage

        sage: pc = PolyhedralComplex(ambient_dim=2)
        sage: pc.add_cell(Polyhedron(vertices=[(1, 2), (0, 2)]))
        sage: pc
        Polyhedral complex with 1 maximal cell

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex(ambient_dim=Integer(2))
        >>> pc.add_cell(Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))]))
        >>> pc
        Polyhedral complex with 1 maximal cell

    If you add a cell which is already present, there is no effect:

    Sage

        sage: pc.add_cell(Polyhedron(vertices=[(1, 2)]))
        sage: pc
        Polyhedral complex with 1 maximal cell
        sage: pc.dimension()
        1

    [Python]

        >>> from sage.all import *
        >>> pc.add_cell(Polyhedron(vertices=[(Integer(1), Integer(2))]))
        >>> pc
        Polyhedral complex with 1 maximal cell
        >>> pc.dimension()
        1

    Add a cell and check that dimension is correctly updated:

    Sage

        sage: pc.add_cell(Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)]))
        sage: pc.dimension()
        2
        sage: pc.maximal_cells()
        {2: {A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices}}
        sage: pc.is_convex()
        True

    Python

        >>> from sage.all import *
        >>> pc.add_cell(Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))]))
        >>> pc.dimension()
        2
        >>> pc.maximal_cells()
        {2: {A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices}}
        >>> pc.is_convex()
        True

    Add another cell and check that the properties are correctly updated:

    Sage

        sage: pc.add_cell(Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]))
        sage: pc
        Polyhedral complex with 2 maximal cells
        sage: len(pc._cells[1])
        5
        sage: pc._face_poset
        Finite poset containing 11 elements
        sage: pc._is_convex
        True
        sage: pc._polyhedron.vertices_list()
        [[0, 0], [0, 2], [1, 1], [1, 2]]

    [Python]

        >>> from sage.all import *
        >>> pc.add_cell(Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]))
        >>> pc
        Polyhedral complex with 2 maximal cells
        >>> len(pc._cells[Integer(1)])
        5
        >>> pc._face_poset
        Finite poset containing 11 elements
        >>> pc._is_convex
        True
        >>> pc._polyhedron.vertices_list()
        [[0, 0], [0, 2], [1, 1], [1, 2]]

    Add a ray which makes the complex non convex:

    Sage

        sage: pc.add_cell(Polyhedron(rays=[(1, 0)]))
        sage: pc
        Polyhedral complex with 3 maximal cells
        sage: len(pc._cells[1])
        6
        sage: (pc._is_convex is False) and (pc._polyhedron is None)
        True

    Python

        >>> from sage.all import *
        >>> pc.add_cell(Polyhedron(rays=[(Integer(1), Integer(0))]))
        >>> pc
        Polyhedral complex with 3 maximal cells
        >>> len(pc._cells[Integer(1)])
        6
        >>> (pc._is_convex is False) and (pc._polyhedron is None)
        True

  alexander_whitney(cell, dim_left)

    The decomposition of `cell` in this complex into left and right factors, suitable for computing cup products.

    Todo

    Implement `alexander_whitney()` of a polyhedral complex.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])])
        sage: pc.alexander_whitney(None, 1)
        Traceback (most recent call last):
        ...
        NotImplementedError: alexander_whitney is not implemented for polyhedral complex

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])])
        >>> pc.alexander_whitney(None, Integer(1))
        Traceback (most recent call last):
        ...
        NotImplementedError: alexander_whitney is not implemented for polyhedral complex

  ambient_dimension()

    The ambient dimension of this cell complex: the ambient dimension of each of its cells.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([Polyhedron(vertices=[(1, 2, 3)])])
        sage: pc.ambient_dimension()
        3
        sage: empty_pc = PolyhedralComplex([])
        sage: empty_pc.ambient_dimension()
        -1
        sage: pc0 = PolyhedralComplex(ambient_dim=2)
        sage: pc0.ambient_dimension()
        2

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([Polyhedron(vertices=[(Integer(1), Integer(2), Integer(3))])])
        >>> pc.ambient_dimension()
        3
        >>> empty_pc = PolyhedralComplex([])
        >>> empty_pc.ambient_dimension()
        -1
        >>> pc0 = PolyhedralComplex(ambient_dim=Integer(2))
        >>> pc0.ambient_dimension()
        2

  boundary_subcomplex()

    Return the sub-polyhedral complex that is the boundary of `self`.

    A point \(P\) is on the boundary of a set \(S\) if \(P\) is in the closure of \(S\) but not in the interior of \(S\).

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: bd = PolyhedralComplex([p1, p2]).boundary_subcomplex()
        sage: len(bd.n_maximal_cells(2))
        0
        sage: len(bd.n_maximal_cells(1))
        4
        sage: pt = PolyhedralComplex([p3])
        sage: pt.boundary_subcomplex() == pt
        True

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> bd = PolyhedralComplex([p1, p2]).boundary_subcomplex()
        >>> len(bd.n_maximal_cells(Integer(2)))
        0
        >>> len(bd.n_maximal_cells(Integer(1)))
        4
        >>> pt = PolyhedralComplex([p3])
        >>> pt.boundary_subcomplex() == pt
        True

    Test on polyhedral complex which is not pure:

    Sage

        sage: pc_non_pure = PolyhedralComplex([p1, p3])
        sage: pc_non_pure.boundary_subcomplex() == pc_non_pure.n_skeleton(1)
        True

    [Python]

        >>> from sage.all import *
        >>> pc_non_pure = PolyhedralComplex([p1, p3])
        >>> pc_non_pure.boundary_subcomplex() == pc_non_pure.n_skeleton(Integer(1))
        True

    Test with `maximality_check == False`:

    Sage

        sage: pc_invalid = PolyhedralComplex([p2, p3],
        ....:                                maximality_check=False)
        sage: pc_invalid.boundary_subcomplex() == pc_invalid.n_skeleton(1)
        True

    Python

        >>> from sage.all import *
        >>> pc_invalid = PolyhedralComplex([p2, p3],
        ...                                maximality_check=False)
        >>> pc_invalid.boundary_subcomplex() == pc_invalid.n_skeleton(Integer(1))
        True

    Test unbounded cases:

    Sage

        sage: pc1 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[[1,0], [0,1]], rays=[[1,0], [0,1]])])
        sage: pc1.boundary_subcomplex() == pc1.n_skeleton(1)
        True
        sage: pc1b = PolyhedralComplex([Polyhedron(
        ....:         vertices=[[1,0,0], [0,1,0]], rays=[[1,0,0],[0,1,0]])])
        sage: pc1b.boundary_subcomplex() == pc1b
        True
        sage: pc2 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[[-1,0], [1,0]], lines=[[0,1]])])
        sage: pc2.boundary_subcomplex() == pc2.n_skeleton(1)
        True
        sage: pc3 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[[1,0], [0,1]], rays=[[1,0], [0,1]]),
        ....:         Polyhedron(vertices=[[1,0], [0,-1]], rays=[[1,0], [0,-1]])])
        sage: pc3.boundary_subcomplex() == pc3.n_skeleton(1)
        False

    [Python]

        >>> from sage.all import *
        >>> pc1 = PolyhedralComplex([
        ...         Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]], rays=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]])])
        >>> pc1.boundary_subcomplex() == pc1.n_skeleton(Integer(1))
        True
        >>> pc1b = PolyhedralComplex([Polyhedron(
        ...         vertices=[[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)]], rays=[[Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(0)]])])
        >>> pc1b.boundary_subcomplex() == pc1b
        True
        >>> pc2 = PolyhedralComplex([
        ...         Polyhedron(vertices=[[-Integer(1),Integer(0)], [Integer(1),Integer(0)]], lines=[[Integer(0),Integer(1)]])])
        >>> pc2.boundary_subcomplex() == pc2.n_skeleton(Integer(1))
        True
        >>> pc3 = PolyhedralComplex([
        ...         Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]], rays=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]]),
        ...         Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),-Integer(1)]], rays=[[Integer(1),Integer(0)], [Integer(0),-Integer(1)]])])
        >>> pc3.boundary_subcomplex() == pc3.n_skeleton(Integer(1))
        False

  cell_iterator(increasing=True)

    An iterator for the cells in this polyhedral complex.

    INPUT:

    - `increasing` – boolean (default: `True`); if `True`, return cells in increasing order of dimension, thus starting with the zero-dimensional cells; otherwise it returns cells in decreasing order of dimension

    Note

    Among the cells of a fixed dimension, there is no sorting.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])])
        sage: len(list(pc.cell_iterator()))
        11

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])])
        >>> len(list(pc.cell_iterator()))
        11

  cells(subcomplex=None)

    The cells of this polyhedral complex, in the form of a dictionary: the keys are integers, representing dimension, and the value associated to an integer \(d\) is the set of \(d\)-cells.

    INPUT:

    - `subcomplex` – (optional) if a subcomplex is given then return the cells which are not in this subcomplex

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])])
        sage: list(pc.cells().keys())
        [2, 1, 0]

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])])
        >>> list(pc.cells().keys())
        [2, 1, 0]

  cells_sorted(subcomplex=None)

    The sorted list of the cells of this polyhedral complex in non-increasing dimensions.

    INPUT:

    - `subcomplex` – (optional) if a subcomplex is given then return the cells which are not in this subcomplex

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([
        ....: Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....: Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])])
        sage: len(pc.cells_sorted())
        11
        sage: pc.cells_sorted()[0].Vrepresentation()
        (A vertex at (0, 0), A vertex at (0, 2), A vertex at (1, 2))

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ... Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ... Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])])
        >>> len(pc.cells_sorted())
        11
        >>> pc.cells_sorted()[Integer(0)].Vrepresentation()
        (A vertex at (0, 0), A vertex at (0, 2), A vertex at (1, 2))

  chain_complex(subcomplex=None, augmented=False, verbose=False, check=True, dimensions=None, base_ring=Integer Ring, cochain=False)

    The chain complex associated to this polyhedral complex.

    Todo

    Implement chain complexes of a polyhedral complex.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])])
        sage: pc.chain_complex()
        Traceback (most recent call last):
        ...
        NotImplementedError: chain_complex is not implemented for polyhedral complex

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])])
        >>> pc.chain_complex()
        Traceback (most recent call last):
        ...
        NotImplementedError: chain_complex is not implemented for polyhedral complex

  connected_component(cell=None)

    Return the connected component of this polyhedral complex containing a given cell.

    INPUT:

    - `cell` – (default: `self.an_element()`) a cell of `self`

    OUTPUT:

    The connected component containing `cell`. If the polyhedral complex is empty or if it does not contain the given cell, raise an error.

    EXAMPLES:

    Sage

        sage: t1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: t2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: v1 = Polyhedron(vertices=[(1, 1)])
        sage: v2 = Polyhedron(vertices=[(0, 2)])
        sage: v3 = Polyhedron(vertices=[(-1, 0)])
        sage: o =  Polyhedron(vertices=[(0, 0)])
        sage: r = Polyhedron(rays=[(1, 0)])
        sage: l = Polyhedron(vertices=[(-1, 0)], lines=[(1, -1)])
        sage: pc1 = PolyhedralComplex([t1, t2])
        sage: pc1.connected_component() == pc1
        True
        sage: pc1.connected_component(v1) == pc1
        True
        sage: pc2 = PolyhedralComplex([t1, v2])
        sage: pc2.connected_component(t1) == PolyhedralComplex([t1])
        True
        sage: pc2.connected_component(o) == PolyhedralComplex([t1])
        True
        sage: pc2.connected_component(v3)
        Traceback (most recent call last):
        ...
        ValueError: the polyhedral complex does not contain the given cell
        sage: pc2.connected_component(r)
        Traceback (most recent call last):
        ...
        ValueError: the polyhedral complex does not contain the given cell
        sage: pc3 = PolyhedralComplex([t1, t2, r])
        sage: pc3.connected_component(v2) == pc3
        True
        sage: pc4 = PolyhedralComplex([t1, t2, r, l])
        sage: pc4.connected_component(o) == pc3
        True
        sage: pc4.connected_component(v3)
        Traceback (most recent call last):
        ...
        ValueError: the polyhedral complex does not contain the given cell
        sage: pc5 = PolyhedralComplex([t1, t2, r, l, v3])
        sage: pc5.connected_component(v3) == PolyhedralComplex([v3])
        True
        sage: PolyhedralComplex([]).connected_component()
        Traceback (most recent call last):
        ...
        ValueError: the empty polyhedral complex has no connected components

    Python

        >>> from sage.all import *
        >>> t1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> t2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> v1 = Polyhedron(vertices=[(Integer(1), Integer(1))])
        >>> v2 = Polyhedron(vertices=[(Integer(0), Integer(2))])
        >>> v3 = Polyhedron(vertices=[(-Integer(1), Integer(0))])
        >>> o =  Polyhedron(vertices=[(Integer(0), Integer(0))])
        >>> r = Polyhedron(rays=[(Integer(1), Integer(0))])
        >>> l = Polyhedron(vertices=[(-Integer(1), Integer(0))], lines=[(Integer(1), -Integer(1))])
        >>> pc1 = PolyhedralComplex([t1, t2])
        >>> pc1.connected_component() == pc1
        True
        >>> pc1.connected_component(v1) == pc1
        True
        >>> pc2 = PolyhedralComplex([t1, v2])
        >>> pc2.connected_component(t1) == PolyhedralComplex([t1])
        True
        >>> pc2.connected_component(o) == PolyhedralComplex([t1])
        True
        >>> pc2.connected_component(v3)
        Traceback (most recent call last):
        ...
        ValueError: the polyhedral complex does not contain the given cell
        >>> pc2.connected_component(r)
        Traceback (most recent call last):
        ...
        ValueError: the polyhedral complex does not contain the given cell
        >>> pc3 = PolyhedralComplex([t1, t2, r])
        >>> pc3.connected_component(v2) == pc3
        True
        >>> pc4 = PolyhedralComplex([t1, t2, r, l])
        >>> pc4.connected_component(o) == pc3
        True
        >>> pc4.connected_component(v3)
        Traceback (most recent call last):
        ...
        ValueError: the polyhedral complex does not contain the given cell
        >>> pc5 = PolyhedralComplex([t1, t2, r, l, v3])
        >>> pc5.connected_component(v3) == PolyhedralComplex([v3])
        True
        >>> PolyhedralComplex([]).connected_component()
        Traceback (most recent call last):
        ...
        ValueError: the empty polyhedral complex has no connected components

  connected_components()

    Return the connected components of this polyhedral complex, as list of (sub-)PolyhedralComplexes.

    EXAMPLES:

    Sage

        sage: t1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: t2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: v1 = Polyhedron(vertices=[(1, 1)])
        sage: v2 = Polyhedron(vertices=[(0, 2)])
        sage: v3 = Polyhedron(vertices=[(-1, 0)])
        sage: o =  Polyhedron(vertices=[(0, 0)])
        sage: r = Polyhedron(rays=[(1, 0)])
        sage: l = Polyhedron(vertices=[(-1, 0)], lines=[(1, -1)])
        sage: pc1 = PolyhedralComplex([t1, t2])
        sage: len(pc1.connected_components())
        1
        sage: pc2 = PolyhedralComplex([t1, v2])
        sage: len(pc2.connected_components())
        2
        sage: pc3 = PolyhedralComplex([t1, t2, r])
        sage: len(pc3.connected_components())
        1
        sage: pc4 = PolyhedralComplex([t1, t2, r, l])
        sage: len(pc4.connected_components())
        2
        sage: pc5 = PolyhedralComplex([t1, t2, r, l, v3])
        sage: len(pc5.connected_components())
        3
        sage: PolyhedralComplex([]).connected_components()
        Traceback (most recent call last):
        ...
        ValueError: the empty polyhedral complex has no connected components

    Python

        >>> from sage.all import *
        >>> t1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> t2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> v1 = Polyhedron(vertices=[(Integer(1), Integer(1))])
        >>> v2 = Polyhedron(vertices=[(Integer(0), Integer(2))])
        >>> v3 = Polyhedron(vertices=[(-Integer(1), Integer(0))])
        >>> o =  Polyhedron(vertices=[(Integer(0), Integer(0))])
        >>> r = Polyhedron(rays=[(Integer(1), Integer(0))])
        >>> l = Polyhedron(vertices=[(-Integer(1), Integer(0))], lines=[(Integer(1), -Integer(1))])
        >>> pc1 = PolyhedralComplex([t1, t2])
        >>> len(pc1.connected_components())
        1
        >>> pc2 = PolyhedralComplex([t1, v2])
        >>> len(pc2.connected_components())
        2
        >>> pc3 = PolyhedralComplex([t1, t2, r])
        >>> len(pc3.connected_components())
        1
        >>> pc4 = PolyhedralComplex([t1, t2, r, l])
        >>> len(pc4.connected_components())
        2
        >>> pc5 = PolyhedralComplex([t1, t2, r, l, v3])
        >>> len(pc5.connected_components())
        3
        >>> PolyhedralComplex([]).connected_components()
        Traceback (most recent call last):
        ...
        ValueError: the empty polyhedral complex has no connected components

  dimension()

    The dimension of this cell complex: the maximum dimension of its cells.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 2)]) ])
        sage: pc.dimension()
        2
        sage: empty_pc = PolyhedralComplex([])
        sage: empty_pc.dimension()
        -1

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))]) ])
        >>> pc.dimension()
        2
        >>> empty_pc = PolyhedralComplex([])
        >>> empty_pc.dimension()
        -1

  disjoint_union(right)

    The disjoint union of this polyhedral complex with another one.

    INPUT:

    - `right` – the other polyhedral complex (the right-hand factor)

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(-1, 0), (0, 0), (0, 1)])
        sage: p2 = Polyhedron(vertices=[(0, -1), (0, 0), (1, 0)])
        sage: p3 = Polyhedron(vertices=[(0, -1), (1, -1), (1, 0)])
        sage: pc = PolyhedralComplex([p1]).disjoint_union(PolyhedralComplex([p3]))
        sage: set(pc.maximal_cell_iterator()) == set([p1, p3])
        True
        sage: pc.disjoint_union(PolyhedralComplex([p2]))
        Traceback (most recent call last):
        ...
        ValueError: the two complexes are not disjoint

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(-Integer(1), Integer(0)), (Integer(0), Integer(0)), (Integer(0), Integer(1))])
        >>> p2 = Polyhedron(vertices=[(Integer(0), -Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(0))])
        >>> p3 = Polyhedron(vertices=[(Integer(0), -Integer(1)), (Integer(1), -Integer(1)), (Integer(1), Integer(0))])
        >>> pc = PolyhedralComplex([p1]).disjoint_union(PolyhedralComplex([p3]))
        >>> set(pc.maximal_cell_iterator()) == set([p1, p3])
        True
        >>> pc.disjoint_union(PolyhedralComplex([p2]))
        Traceback (most recent call last):
        ...
        ValueError: the two complexes are not disjoint

  face_poset()

    The face poset of this polyhedral complex, the poset of nonempty cells, ordered by inclusion.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1/3, 1/3), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 1/2)])])
        sage: poset = pc.face_poset()
        sage: poset
        Finite poset containing 11 elements
        sage: d = {i: i.vertices_matrix() for i in poset}
        sage: poset.plot(element_labels=d)                                          # needs sage.plot
        Graphics object consisting of 28 graphics primitives

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1)/Integer(3), Integer(1)/Integer(3)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(1)/Integer(2))])])
        >>> poset = pc.face_poset()
        >>> poset
        Finite poset containing 11 elements
        >>> d = {i: i.vertices_matrix() for i in poset}
        >>> poset.plot(element_labels=d)                                          # needs sage.plot
        Graphics object consisting of 28 graphics primitives

    For a nonbounded polyhedral complex:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1/3, 1/3), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 1/2)]),
        ....:         Polyhedron(vertices=[(-1/2, -1/2)], lines=[(1, -1)]),
        ....:         Polyhedron(rays=[(1, 0)])])
        sage: poset = pc.face_poset()
        sage: poset
        Finite poset containing 13 elements
        sage: d = {i:''.join([str(v)+'\n'
        ....:      for v in i.Vrepresentation()]) for i in poset}
        sage: poset.show(element_labels=d, figsize=15)        # not tested
        sage: pc = PolyhedralComplex([
        ....: Polyhedron(rays=[(1,0),(0,1)]),
        ....: Polyhedron(rays=[(-1,0),(0,1)]),
        ....: Polyhedron(rays=[(-1,0),(0,-1)]),
        ....: Polyhedron(rays=[(1,0),(0,-1)])])
        sage: pc.face_poset()
        Finite poset containing 9 elements

    [Python]

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1)/Integer(3), Integer(1)/Integer(3)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(1)/Integer(2))]),
        ...         Polyhedron(vertices=[(-Integer(1)/Integer(2), -Integer(1)/Integer(2))], lines=[(Integer(1), -Integer(1))]),
        ...         Polyhedron(rays=[(Integer(1), Integer(0))])])
        >>> poset = pc.face_poset()
        >>> poset
        Finite poset containing 13 elements
        >>> d = {i:''.join([str(v)+'\n'
        ...      for v in i.Vrepresentation()]) for i in poset}
        >>> poset.show(element_labels=d, figsize=Integer(15))        # not tested
        >>> pc = PolyhedralComplex([
        ... Polyhedron(rays=[(Integer(1),Integer(0)),(Integer(0),Integer(1))]),
        ... Polyhedron(rays=[(-Integer(1),Integer(0)),(Integer(0),Integer(1))]),
        ... Polyhedron(rays=[(-Integer(1),Integer(0)),(Integer(0),-Integer(1))]),
        ... Polyhedron(rays=[(Integer(1),Integer(0)),(Integer(0),-Integer(1))])])
        >>> pc.face_poset()
        Finite poset containing 9 elements

  graph(immutable=False)

    Return the 1-skeleton of this polyhedral complex, as a graph.

    The vertices of the graph are of type `vector`. This raises a `NotImplementedError` if the polyhedral complex is unbounded.

    Warning

    This may give the wrong answer if the polyhedral complex was constructed with `maximality_check` set to `False`.

    INPUT:

    - `immutable` – boolean (default: `False`); whether to return an immutable or a mutable graph

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])])
        sage: g = pc.graph(); g
        Graph on 4 vertices
        sage: g.vertices(sort=True)
        [(0, 0), (0, 2), (1, 1), (1, 2)]
        sage: g.edges(sort=True, labels=False)
        [((0, 0), (0, 2)), ((0, 0), (1, 1)), ((0, 0), (1, 2)), ((0, 2), (1, 2)), ((1, 1), (1, 2))]
        sage: PolyhedralComplex([Polyhedron(rays=[(1,1)])]).graph()
        Traceback (most recent call last):
        ...
        NotImplementedError: the polyhedral complex is unbounded

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])])
        >>> g = pc.graph(); g
        Graph on 4 vertices
        >>> g.vertices(sort=True)
        [(0, 0), (0, 2), (1, 1), (1, 2)]
        >>> g.edges(sort=True, labels=False)
        [((0, 0), (0, 2)), ((0, 0), (1, 1)), ((0, 0), (1, 2)), ((0, 2), (1, 2)), ((1, 1), (1, 2))]
        >>> PolyhedralComplex([Polyhedron(rays=[(Integer(1),Integer(1))])]).graph()
        Traceback (most recent call last):
        ...
        NotImplementedError: the polyhedral complex is unbounded

    Wrong answer due to `maximality_check=False`:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: PolyhedralComplex([p1, p2]).is_pure()
        True
        sage: PolyhedralComplex([p2, p3], maximality_check=True).is_pure()
        True
        sage: PolyhedralComplex([p2, p3], maximality_check=False).is_pure()
        False

    [Python]

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> PolyhedralComplex([p1, p2]).is_pure()
        True
        >>> PolyhedralComplex([p2, p3], maximality_check=True).is_pure()
        True
        >>> PolyhedralComplex([p2, p3], maximality_check=False).is_pure()
        False

    Check the behavior of parameter immutable:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])])
        sage: pc.graph(immutable=False).is_immutable()
        False
        sage: pc.graph(immutable=True).is_immutable()
        True

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])])
        >>> pc.graph(immutable=False).is_immutable()
        False
        >>> pc.graph(immutable=True).is_immutable()
        True

  is_cell(c)

    Return whether the given cell `c` is a cell of `self`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: pc = PolyhedralComplex([p1, p2])
        sage: pc.is_cell(p3)
        True
        sage: pc.is_cell(Polyhedron(vertices=[(0, 0)]))
        True

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2])
        >>> pc.is_cell(p3)
        True
        >>> pc.is_cell(Polyhedron(vertices=[(Integer(0), Integer(0))]))
        True

  is_compact()

    Test for boundedness of the polyhedral complex.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 1/2)])
        sage: p2 = Polyhedron(rays=[(1, 0)])
        sage: PolyhedralComplex([p1]).is_compact()
        True
        sage: PolyhedralComplex([p1, p2]).is_compact()
        False

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(1)/Integer(2))])
        >>> p2 = Polyhedron(rays=[(Integer(1), Integer(0))])
        >>> PolyhedralComplex([p1]).is_compact()
        True
        >>> PolyhedralComplex([p1, p2]).is_compact()
        False

  is_connected()

    Return whether `self` is connected.

    EXAMPLES:

    Sage

        sage: pc1 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])])
        sage: pc1.is_connected()
        True
        sage: pc2 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(0, 2)])])
        sage: pc2.is_connected()
        False
        sage: pc3 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1/3, 1/3), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 1/2)]),
        ....:         Polyhedron(vertices=[(-1/2, -1/2)], lines=[(1, -1)]),
        ....:         Polyhedron(rays=[(1, 0)])])
        sage: pc3.is_connected()
        False
        sage: pc4 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1/3, 1/3), (0, 0), (1, 2)]),
        ....:         Polyhedron(rays=[(1, 0)])])
        sage: pc4.is_connected()
        True

    Python

        >>> from sage.all import *
        >>> pc1 = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])])
        >>> pc1.is_connected()
        True
        >>> pc2 = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(0), Integer(2))])])
        >>> pc2.is_connected()
        False
        >>> pc3 = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1)/Integer(3), Integer(1)/Integer(3)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(1)/Integer(2))]),
        ...         Polyhedron(vertices=[(-Integer(1)/Integer(2), -Integer(1)/Integer(2))], lines=[(Integer(1), -Integer(1))]),
        ...         Polyhedron(rays=[(Integer(1), Integer(0))])])
        >>> pc3.is_connected()
        False
        >>> pc4 = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1)/Integer(3), Integer(1)/Integer(3)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(rays=[(Integer(1), Integer(0))])])
        >>> pc4.is_connected()
        True

  is_convex()

    Return whether the set of points in `self` is a convex set.

    When `self` is convex, the union of its cells is a Polyhedron.

    See also

    `union_as_polyhedron()`

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(0, 0), (1, 1), (2, 0)])
        sage: p4 = Polyhedron(vertices=[(2, 2)])
        sage: PolyhedralComplex([p1, p2]).is_convex()
        True
        sage: PolyhedralComplex([p1, p3]).is_convex()
        False
        sage: PolyhedralComplex([p1, p4]).is_convex()
        False

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(1), Integer(1)), (Integer(2), Integer(0))])
        >>> p4 = Polyhedron(vertices=[(Integer(2), Integer(2))])
        >>> PolyhedralComplex([p1, p2]).is_convex()
        True
        >>> PolyhedralComplex([p1, p3]).is_convex()
        False
        >>> PolyhedralComplex([p1, p4]).is_convex()
        False

    Test unbounded cases:

    Sage

        sage: pc1 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[[1,0], [0,1]], rays=[[1,0], [0,1]])])
        sage: pc1.is_convex()
        True
        sage: pc2 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[[-1,0], [1,0]], lines=[[0,1]])])
        sage: pc2.is_convex()
        True
        sage: pc3 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[[1,0], [0,1]], rays=[[1,0], [0,1]]),
        ....:         Polyhedron(vertices=[[1,0], [0,-1]], rays=[[1,0], [0,-1]])])
        sage: pc3.is_convex()
        False
        sage: pc4 = PolyhedralComplex([Polyhedron(rays=[[1,0], [-1,1]]),
        ....:                          Polyhedron(rays=[[1,0], [-1,-1]])])
        sage: pc4.is_convex()
        False

    [Python]

        >>> from sage.all import *
        >>> pc1 = PolyhedralComplex([
        ...         Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]], rays=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]])])
        >>> pc1.is_convex()
        True
        >>> pc2 = PolyhedralComplex([
        ...         Polyhedron(vertices=[[-Integer(1),Integer(0)], [Integer(1),Integer(0)]], lines=[[Integer(0),Integer(1)]])])
        >>> pc2.is_convex()
        True
        >>> pc3 = PolyhedralComplex([
        ...         Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]], rays=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]]),
        ...         Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),-Integer(1)]], rays=[[Integer(1),Integer(0)], [Integer(0),-Integer(1)]])])
        >>> pc3.is_convex()
        False
        >>> pc4 = PolyhedralComplex([Polyhedron(rays=[[Integer(1),Integer(0)], [-Integer(1),Integer(1)]]),
        ...                          Polyhedron(rays=[[Integer(1),Integer(0)], [-Integer(1),-Integer(1)]])])
        >>> pc4.is_convex()
        False

    The whole 3d space minus the first orthant is not convex:

    Sage

        sage: pc5 = PolyhedralComplex([
        ....:         Polyhedron(rays=[[1,0,0], [0,1,0], [0,0,-1]]),
        ....:         Polyhedron(rays=[[1,0,0], [0,-1,0], [0,0,-1]]),
        ....:         Polyhedron(rays=[[1,0,0], [0,-1,0], [0,0,1]]),
        ....:         Polyhedron(rays=[[-1,0,0], [0,-1,0], [0,0,-1]]),
        ....:         Polyhedron(rays=[[-1,0,0], [0,-1,0], [0,0,1]]),
        ....:         Polyhedron(rays=[[-1,0,0], [0,1,0], [0,0,-1]]),
        ....:         Polyhedron(rays=[[-1,0,0], [0,1,0], [0,0,1]])])
        sage: pc5.is_convex()
        False

    Python

        >>> from sage.all import *
        >>> pc5 = PolyhedralComplex([
        ...         Polyhedron(rays=[[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]]),
        ...         Polyhedron(rays=[[Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]]),
        ...         Polyhedron(rays=[[Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]]),
        ...         Polyhedron(rays=[[-Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]]),
        ...         Polyhedron(rays=[[-Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]]),
        ...         Polyhedron(rays=[[-Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]]),
        ...         Polyhedron(rays=[[-Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]])])
        >>> pc5.is_convex()
        False

    Test some non-full-dimensional examples:

    Sage

        sage: l = PolyhedralComplex([Polyhedron(vertices=[(1, 2), (0, 2)])])
        sage: l.is_convex()
        True
        sage: pc1b = PolyhedralComplex([Polyhedron(
        ....:         vertices=[[1,0,0], [0,1,0]], rays=[[1,0,0],[0,1,0]])])
        sage: pc1b.is_convex()
        True
        sage: pc4b = PolyhedralComplex([
        ....:         Polyhedron(rays=[[1,0,0], [-1,1,0]]),
        ....:         Polyhedron(rays=[[1,0,0], [-1,-1,0]])])
        sage: pc4b.is_convex()
        False

    [Python]

        >>> from sage.all import *
        >>> l = PolyhedralComplex([Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])])
        >>> l.is_convex()
        True
        >>> pc1b = PolyhedralComplex([Polyhedron(
        ...         vertices=[[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)]], rays=[[Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(0)]])])
        >>> pc1b.is_convex()
        True
        >>> pc4b = PolyhedralComplex([
        ...         Polyhedron(rays=[[Integer(1),Integer(0),Integer(0)], [-Integer(1),Integer(1),Integer(0)]]),
        ...         Polyhedron(rays=[[Integer(1),Integer(0),Integer(0)], [-Integer(1),-Integer(1),Integer(0)]])])
        >>> pc4b.is_convex()
        False

  is_full_dimensional()

    Return whether this polyhedral complex is full-dimensional.

    This means that its dimension is equal to its ambient dimension.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: pc = PolyhedralComplex([p1, p2, p3])
        sage: pc.is_full_dimensional()
        True
        sage: PolyhedralComplex([p3]).is_full_dimensional()
        False

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2, p3])
        >>> pc.is_full_dimensional()
        True
        >>> PolyhedralComplex([p3]).is_full_dimensional()
        False

  is_immutable()

    Return whether `self` is immutable.

    EXAMPLES:

    Sage

        sage: pc1 = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])])
        sage: pc1.is_immutable()
        False
        sage: pc2 = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])],
        ....:                         immutable=True)
        sage: pc2.is_immutable()
        True
        sage: pc3 = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])],
        ....:                         immutable=True)
        sage: pc3.is_immutable()
        True

    Python

        >>> from sage.all import *
        >>> pc1 = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])])
        >>> pc1.is_immutable()
        False
        >>> pc2 = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])],
        ...                         immutable=True)
        >>> pc2.is_immutable()
        True
        >>> pc3 = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])],
        ...                         immutable=True)
        >>> pc3.is_immutable()
        True

  is_maximal_cell(c)

    Return whether the given cell `c` is a maximal cell of `self`.

    Warning

    This may give the wrong answer if the polyhedral complex was constructed with `maximality_check` set to `False`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: pc = PolyhedralComplex([p1, p2, p3])
        sage: pc.is_maximal_cell(p1)
        True
        sage: pc.is_maximal_cell(p3)
        False

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2, p3])
        >>> pc.is_maximal_cell(p1)
        True
        >>> pc.is_maximal_cell(p3)
        False

    Wrong answer due to `maximality_check=False`:

    Sage

        sage: pc_invalid = PolyhedralComplex([p1, p2, p3],
        ....:              maximality_check=False)
        sage: pc_invalid.is_maximal_cell(p3)
        True

    [Python]

        >>> from sage.all import *
        >>> pc_invalid = PolyhedralComplex([p1, p2, p3],
        ...              maximality_check=False)
        >>> pc_invalid.is_maximal_cell(p3)
        True

  is_mutable()

    Return whether `self` is mutable.

    EXAMPLES:

    Sage

        sage: pc1 = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])])
        sage: pc1.is_mutable()
        True
        sage: pc2 = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])],
        ....:                         immutable=True)
        sage: pc2.is_mutable()
        False
        sage: pc1 == pc2
        True
        sage: pc3 = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])],
        ....:                         immutable=True)
        sage: pc3.is_mutable()
        False
        sage: pc2 == pc3
        True

    Python

        >>> from sage.all import *
        >>> pc1 = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])])
        >>> pc1.is_mutable()
        True
        >>> pc2 = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])],
        ...                         immutable=True)
        >>> pc2.is_mutable()
        False
        >>> pc1 == pc2
        True
        >>> pc3 = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])],
        ...                         immutable=True)
        >>> pc3.is_mutable()
        False
        >>> pc2 == pc3
        True

  is_polyhedral_fan()

    Test if this polyhedral complex is a polyhedral fan.

    A polyhedral complex is a fan if all of its (maximal) cells are cones.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(0, 0), (1, 1), (1, 2)])
        sage: p2 = Polyhedron(rays=[(1, 0)])
        sage: PolyhedralComplex([p1]).is_polyhedral_fan()
        False
        sage: PolyhedralComplex([p2]).is_polyhedral_fan()
        True
        sage: halfplane = Polyhedron(rays=[(1, 0), (-1, 0), (0, 1)])
        sage: PolyhedralComplex([halfplane]).is_polyhedral_fan()
        True

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(1), Integer(1)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(rays=[(Integer(1), Integer(0))])
        >>> PolyhedralComplex([p1]).is_polyhedral_fan()
        False
        >>> PolyhedralComplex([p2]).is_polyhedral_fan()
        True
        >>> halfplane = Polyhedron(rays=[(Integer(1), Integer(0)), (-Integer(1), Integer(0)), (Integer(0), Integer(1))])
        >>> PolyhedralComplex([halfplane]).is_polyhedral_fan()
        True

  is_pure()

    Test if this polyhedral complex is pure.

    A polyhedral complex is pure if and only if all of its maximal cells have the same dimension.

    Warning

    This may give the wrong answer if the polyhedral complex was constructed with `maximality_check` set to `False`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: pc = PolyhedralComplex([p1, p2, p3])
        sage: pc.is_pure()
        True

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2, p3])
        >>> pc.is_pure()
        True

    Wrong answer due to `maximality_check=False`:

    Sage

        sage: pc_invalid = PolyhedralComplex([p1, p2, p3],
        ....:              maximality_check=False)
        sage: pc_invalid.is_pure()
        False

    [Python]

        >>> from sage.all import *
        >>> pc_invalid = PolyhedralComplex([p1, p2, p3],
        ...              maximality_check=False)
        >>> pc_invalid.is_pure()
        False

  is_simplicial_complex()

    Test if this polyhedral complex is a simplicial complex.

    A polyhedral complex is simplicial if all of its (maximal) cells are simplices, i.e., every cell is a bounded polytope with \(d+1\) vertices, where \(d\) is the dimension of the polytope.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(0, 0), (1, 1), (1, 2)])
        sage: p2 = Polyhedron(rays=[(1, 0)])
        sage: PolyhedralComplex([p1]).is_simplicial_complex()
        True
        sage: PolyhedralComplex([p2]).is_simplicial_complex()
        False

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(1), Integer(1)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(rays=[(Integer(1), Integer(0))])
        >>> PolyhedralComplex([p1]).is_simplicial_complex()
        True
        >>> PolyhedralComplex([p2]).is_simplicial_complex()
        False

  is_simplicial_fan()

    Test if this polyhedral complex is a simplicial fan.

    A polyhedral complex is a simplicial fan if all of its (maximal) cells are simplicial cones, i.e., every cell is a pointed cone (with vertex being the origin) generated by \(d\) linearly independent rays, where \(d\) is the dimension of the cone.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(0, 0), (1, 1), (1, 2)])
        sage: p2 = Polyhedron(rays=[(1, 0)])
        sage: PolyhedralComplex([p1]).is_simplicial_fan()
        False
        sage: PolyhedralComplex([p2]).is_simplicial_fan()
        True
        sage: halfplane = Polyhedron(rays=[(1, 0), (-1, 0), (0, 1)])
        sage: PolyhedralComplex([halfplane]).is_simplicial_fan()
        False

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(1), Integer(1)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(rays=[(Integer(1), Integer(0))])
        >>> PolyhedralComplex([p1]).is_simplicial_fan()
        False
        >>> PolyhedralComplex([p2]).is_simplicial_fan()
        True
        >>> halfplane = Polyhedron(rays=[(Integer(1), Integer(0)), (-Integer(1), Integer(0)), (Integer(0), Integer(1))])
        >>> PolyhedralComplex([halfplane]).is_simplicial_fan()
        False

  is_subcomplex(other)

    Return whether `self` is a subcomplex of `other`.

    INPUT:

    - `other` – a polyhedral complex

    Each maximal cell of `self` must be a cell of `other` for this to be `True`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1/3, 1/3), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 1/2)])
        sage: p3 = Polyhedron(vertices=[(0, 0), (1, 0)])
        sage: pc = PolyhedralComplex([p1, Polyhedron(vertices=[(1, 0)])])
        sage: pc.is_subcomplex(PolyhedralComplex([p1, p2, p3]))
        True
        sage: pc.is_subcomplex(PolyhedralComplex([p1, p2]))
        False

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1)/Integer(3), Integer(1)/Integer(3)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(1)/Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(1), Integer(0))])
        >>> pc = PolyhedralComplex([p1, Polyhedron(vertices=[(Integer(1), Integer(0))])])
        >>> pc.is_subcomplex(PolyhedralComplex([p1, p2, p3]))
        True
        >>> pc.is_subcomplex(PolyhedralComplex([p1, p2]))
        False

  join(right)

    The join of this polyhedral complex with another one.

    INPUT:

    - `right` – the other polyhedral complex (the right-hand factor)

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])])
        sage: pc_join = pc.join(pc)
        sage: pc_join
        Polyhedral complex with 1 maximal cell
        sage: next(pc_join.maximal_cell_iterator()).vertices()
        (A vertex at (0, 0, 0),
         A vertex at (0, 0, 1),
         A vertex at (0, 1, 1),
         A vertex at (1, 0, 0))

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])])
        >>> pc_join = pc.join(pc)
        >>> pc_join
        Polyhedral complex with 1 maximal cell
        >>> next(pc_join.maximal_cell_iterator()).vertices()
        (A vertex at (0, 0, 0),
         A vertex at (0, 0, 1),
         A vertex at (0, 1, 1),
         A vertex at (1, 0, 0))

  maximal_cell_iterator(increasing=False)

    An iterator for the maximal cells in this polyhedral complex.

    INPUT:

    - `increasing` – boolean (default: `False`); if `True`, return maximal cells in increasing order of dimension. Otherwise it returns cells in decreasing order of dimension.

    Note

    Among the cells of a fixed dimension, there is no sorting.

    Warning

    This may give the wrong answer if the polyhedral complex was constructed with `maximality_check` set to `False`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: pc = PolyhedralComplex([p1, p2, p3])
        sage: len(list(pc.maximal_cell_iterator()))
        2

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2, p3])
        >>> len(list(pc.maximal_cell_iterator()))
        2

    Wrong answer due to `maximality_check=False`:

    Sage

        sage: pc_invalid = PolyhedralComplex([p1, p2, p3],
        ....:              maximality_check=False)
        sage: len(list(pc_invalid.maximal_cell_iterator()))
        3

    [Python]

        >>> from sage.all import *
        >>> pc_invalid = PolyhedralComplex([p1, p2, p3],
        ...              maximality_check=False)
        >>> len(list(pc_invalid.maximal_cell_iterator()))
        3

  maximal_cells()

    The maximal cells of this polyhedral complex, in the form of a dictionary: the keys are integers, representing dimension, and the value associated to an integer \(d\) is the set of \(d\)-maximal cells.

    Warning

    This may give the wrong answer if the polyhedral complex was constructed with `maximality_check` set to `False`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: pc = PolyhedralComplex([p1, p2, p3])
        sage: len(pc.maximal_cells()[2])
        2
        sage: 1 in pc.maximal_cells()
        False

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2, p3])
        >>> len(pc.maximal_cells()[Integer(2)])
        2
        >>> Integer(1) in pc.maximal_cells()
        False

    Wrong answer due to `maximality_check=False`:

    Sage

        sage: pc_invalid = PolyhedralComplex([p1, p2, p3],
        ....:              maximality_check=False)
        sage: len(pc_invalid.maximal_cells()[1])
        1

    [Python]

        >>> from sage.all import *
        >>> pc_invalid = PolyhedralComplex([p1, p2, p3],
        ...              maximality_check=False)
        >>> len(pc_invalid.maximal_cells()[Integer(1)])
        1

  maximal_cells_sorted()

    Return the sorted list of the maximal cells of this polyhedral complex by non-increasing dimensions.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])])
        sage: [p.vertices_list() for p in pc.maximal_cells_sorted()]
        [[[0, 0], [0, 2], [1, 2]], [[0, 0], [1, 1], [1, 2]]]

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])])
        >>> [p.vertices_list() for p in pc.maximal_cells_sorted()]
        [[[0, 0], [0, 2], [1, 2]], [[0, 0], [1, 1], [1, 2]]]

  n_maximal_cells(n)

    List of maximal cells of dimension `n` of this polyhedral complex.

    INPUT:

    - `n` – nonnegative integer; the dimension

    Note

    The resulting list need not be sorted. If you want a sorted list of \(n\)-cells, use `_n_maximal_cells_sorted()`.

    Warning

    This may give the wrong answer if the polyhedral complex was constructed with `maximality_check` set to `False`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: pc = PolyhedralComplex([p1, p2, p3])
        sage: len(pc.n_maximal_cells(2))
        2
        sage: len(pc.n_maximal_cells(1))
        0

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2, p3])
        >>> len(pc.n_maximal_cells(Integer(2)))
        2
        >>> len(pc.n_maximal_cells(Integer(1)))
        0

    Wrong answer due to `maximality_check=False`:

    Sage

        sage: pc_invalid = PolyhedralComplex([p1, p2, p3],
        ....:              maximality_check=False)
        sage: len(pc_invalid.n_maximal_cells(1))
        1

    [Python]

        >>> from sage.all import *
        >>> pc_invalid = PolyhedralComplex([p1, p2, p3],
        ...              maximality_check=False)
        >>> len(pc_invalid.n_maximal_cells(Integer(1)))
        1

  n_skeleton(n)

    The \(n\)-skeleton of this polyhedral complex.

    The \(n\)-skeleton of a polyhedral complex is obtained by discarding all of the cells in dimensions larger than \(n\).

    INPUT:

    - `n` – nonnegative integer; the dimension

    See also

    `stratify()`

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]),
        ....:         Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])])
        sage: pc.n_skeleton(2)
        Polyhedral complex with 2 maximal cells
        sage: pc.n_skeleton(1)
        Polyhedral complex with 5 maximal cells
        sage: pc.n_skeleton(0)
        Polyhedral complex with 4 maximal cells

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))]),
        ...         Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])])
        >>> pc.n_skeleton(Integer(2))
        Polyhedral complex with 2 maximal cells
        >>> pc.n_skeleton(Integer(1))
        Polyhedral complex with 5 maximal cells
        >>> pc.n_skeleton(Integer(0))
        Polyhedral complex with 4 maximal cells

  plot(**kwds)

    Return a plot of the polyhedral complex, if it is of dim at most 3.

    INPUT:

    - `explosion_factor` – (default: 0) if positive, separate the cells of the complex by extra space. In this case, the following keyword arguments can be passed to `exploded_plot()`:

      - `center` – (default: `None`, denoting the origin) the center of explosion

      - `sticky_vertices` – (default: `False`) boolean or dict; whether to draw line segments between shared vertices of the given polyhedra. A dict gives options for `sage.plot.line()`.

      - `sticky_center` – (default: `True`) boolean or dict. When `center` is a vertex of some of the polyhedra, whether to draw line segments connecting the `center` to the shifted copies of these vertices. A dict gives options for `sage.plot.line()`.

    - `color` – (default: `None`) if `'rainbow'`, assign a different color to every maximal cell; otherwise, passed on to `plot()`.

    - other keyword arguments are passed on to `plot()`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(0, 0), (0, 2), (-1, 1)])
        sage: pc1 = PolyhedralComplex([p1, p2, p3, -p1, -p2, -p3])
        sage: bb = dict(xmin=-2, xmax=2, ymin=-3, ymax=3, axes=False)
        sage: g0 = pc1.plot(color='rainbow', **bb)                                  # needs sage.plot
        sage: g1 = pc1.plot(explosion_factor=0.5, **bb)                             # needs sage.plot
        sage: g2 = pc1.plot(explosion_factor=1, color='rainbow', alpha=0.5, **bb)   # needs sage.plot
        sage: graphics_array([g0, g1, g2]).show(axes=False)                        # not tested

        sage: pc2 = PolyhedralComplex([polytopes.hypercube(3)])
        sage: pc3 = pc2.subdivide(new_vertices=[(0, 0, 0)])
        sage: g3 = pc3.plot(explosion_factor=1, color='rainbow',                    # needs sage.plot
        ....:               alpha=0.5, axes=False, online=True)
        sage: pc4 = pc2.subdivide(make_simplicial=True)
        sage: g4 = pc4.plot(explosion_factor=1, center=(1, -1, 1), fill='blue',     # needs sage.plot
        ....:              wireframe='white', point={'color':'red', 'size':10},
        ....:              alpha=0.6, online=True)
        sage: pc5 = PolyhedralComplex([
        ....:         Polyhedron(rays=[[1,0,0], [0,1,0], [0,0,-1]]),
        ....:         Polyhedron(rays=[[1,0,0], [0,-1,0], [0,0,-1]]),
        ....:         Polyhedron(rays=[[1,0,0], [0,-1,0], [0,0,1]]),
        ....:         Polyhedron(rays=[[-1,0,0], [0,-1,0], [0,0,-1]]),
        ....:         Polyhedron(rays=[[-1,0,0], [0,-1,0], [0,0,1]]),
        ....:         Polyhedron(rays=[[-1,0,0], [0,1,0], [0,0,-1]]),
        ....:         Polyhedron(rays=[[-1,0,0], [0,1,0], [0,0,1]])])
        sage: g5 = pc5.plot(explosion_factor=0.3, color='rainbow', alpha=0.8,       # needs sage.plot
        ....:               point={'size': 20}, axes=False, online=True)

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(0), Integer(2)), (-Integer(1), Integer(1))])
        >>> pc1 = PolyhedralComplex([p1, p2, p3, -p1, -p2, -p3])
        >>> bb = dict(xmin=-Integer(2), xmax=Integer(2), ymin=-Integer(3), ymax=Integer(3), axes=False)
        >>> g0 = pc1.plot(color='rainbow', **bb)                                  # needs sage.plot
        >>> g1 = pc1.plot(explosion_factor=RealNumber('0.5'), **bb)                             # needs sage.plot
        >>> g2 = pc1.plot(explosion_factor=Integer(1), color='rainbow', alpha=RealNumber('0.5'), **bb)   # needs sage.plot
        >>> graphics_array([g0, g1, g2]).show(axes=False)                        # not tested

        >>> pc2 = PolyhedralComplex([polytopes.hypercube(Integer(3))])
        >>> pc3 = pc2.subdivide(new_vertices=[(Integer(0), Integer(0), Integer(0))])
        >>> g3 = pc3.plot(explosion_factor=Integer(1), color='rainbow',                    # needs sage.plot
        ...               alpha=RealNumber('0.5'), axes=False, online=True)
        >>> pc4 = pc2.subdivide(make_simplicial=True)
        >>> g4 = pc4.plot(explosion_factor=Integer(1), center=(Integer(1), -Integer(1), Integer(1)), fill='blue',     # needs sage.plot
        ...              wireframe='white', point={'color':'red', 'size':Integer(10)},
        ...              alpha=RealNumber('0.6'), online=True)
        >>> pc5 = PolyhedralComplex([
        ...         Polyhedron(rays=[[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]]),
        ...         Polyhedron(rays=[[Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]]),
        ...         Polyhedron(rays=[[Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]]),
        ...         Polyhedron(rays=[[-Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]]),
        ...         Polyhedron(rays=[[-Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]]),
        ...         Polyhedron(rays=[[-Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]]),
        ...         Polyhedron(rays=[[-Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]])])
        >>> g5 = pc5.plot(explosion_factor=RealNumber('0.3'), color='rainbow', alpha=RealNumber('0.8'),       # needs sage.plot
        ...               point={'size': Integer(20)}, axes=False, online=True)

  product(right)

    The (Cartesian) product of this polyhedral complex with another one.

    INPUT:

    - `right` – the other polyhedral complex (the right-hand factor)

    OUTPUT: the product `self x right`

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])])
        sage: pc_square = pc.product(pc)
        sage: pc_square
        Polyhedral complex with 1 maximal cell
        sage: next(pc_square.maximal_cell_iterator()).vertices()
        (A vertex at (0, 0),
         A vertex at (0, 1),
         A vertex at (1, 0),
         A vertex at (1, 1))

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])])
        >>> pc_square = pc.product(pc)
        >>> pc_square
        Polyhedral complex with 1 maximal cell
        >>> next(pc_square.maximal_cell_iterator()).vertices()
        (A vertex at (0, 0),
         A vertex at (0, 1),
         A vertex at (1, 0),
         A vertex at (1, 1))

  relative_boundary_cells()

    Return the maximal cells of the relative-boundary sub-complex.

    A point \(P\) is in the relative boundary of a set \(S\) if \(P\) is in the closure of \(S\) but not in the relative interior of \(S\).

    Warning

    This may give the wrong answer if the polyhedral complex was constructed with `maximality_check` set to `False`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: p4 = Polyhedron(vertices=[(2, 2)])
        sage: pc = PolyhedralComplex([p1, p2])
        sage: rbd_cells = pc.relative_boundary_cells()
        sage: len(rbd_cells)
        4
        sage: all(p.dimension() == 1 for p in rbd_cells)
        True
        sage: pc_lower_dim = PolyhedralComplex([p3])
        sage: sorted([p.vertices() for p in pc_lower_dim.relative_boundary_cells()])
        [(A vertex at (0, 2),), (A vertex at (1, 2),)]

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> p4 = Polyhedron(vertices=[(Integer(2), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2])
        >>> rbd_cells = pc.relative_boundary_cells()
        >>> len(rbd_cells)
        4
        >>> all(p.dimension() == Integer(1) for p in rbd_cells)
        True
        >>> pc_lower_dim = PolyhedralComplex([p3])
        >>> sorted([p.vertices() for p in pc_lower_dim.relative_boundary_cells()])
        [(A vertex at (0, 2),), (A vertex at (1, 2),)]

    Test on polyhedral complex which is not pure:

    Sage

        sage: pc_non_pure = PolyhedralComplex([p1, p3, p4])
        sage: (set(pc_non_pure.relative_boundary_cells())
        ....:  == set([f.as_polyhedron() for f in p1.faces(1)] + [p3, p4]))
        True

    [Python]

        >>> from sage.all import *
        >>> pc_non_pure = PolyhedralComplex([p1, p3, p4])
        >>> (set(pc_non_pure.relative_boundary_cells())
        ...  == set([f.as_polyhedron() for f in p1.faces(Integer(1))] + [p3, p4]))
        True

    Test with `maximality_check == False`:

    Sage

        sage: pc_invalid = PolyhedralComplex([p2, p3],
        ....:                                maximality_check=False)
        sage: (set(pc_invalid.relative_boundary_cells())
        ....:  == set([f.as_polyhedron() for f in p2.faces(1)]))
        True

    Python

        >>> from sage.all import *
        >>> pc_invalid = PolyhedralComplex([p2, p3],
        ...                                maximality_check=False)
        >>> (set(pc_invalid.relative_boundary_cells())
        ...  == set([f.as_polyhedron() for f in p2.faces(Integer(1))]))
        True

    Test unbounded case:

    Sage

        sage: pc3 = PolyhedralComplex([
        ....:         Polyhedron(vertices=[[1,0], [0,1]], rays=[[1,0], [0,1]]),
        ....:         Polyhedron(vertices=[[1,0], [0,-1]], rays=[[1,0], [0,-1]])])
        sage: len(pc3.relative_boundary_cells())
        4

    [Python]

        >>> from sage.all import *
        >>> pc3 = PolyhedralComplex([
        ...         Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]], rays=[[Integer(1),Integer(0)], [Integer(0),Integer(1)]]),
        ...         Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),-Integer(1)]], rays=[[Integer(1),Integer(0)], [Integer(0),-Integer(1)]])])
        >>> len(pc3.relative_boundary_cells())
        4

  remove_cell(cell, check=False)

    Remove `cell` from `self` and all the cells that contain `cell` as a subface.

    INPUT:

    - `cell` – a cell of the polyhedral complex

    - `check` – boolean (default: `False`); if `True`, raise an error if `cell` is not a cell of this complex

    This does not return anything; instead, it changes the polyhedral complex.

    EXAMPLES:

    If you add a cell which is already present, there is no effect:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: r = Polyhedron(rays=[(1, 0)])
        sage: pc = PolyhedralComplex([p1, p2, r])
        sage: pc.dimension()
        2
        sage: pc.remove_cell(Polyhedron(vertices=[(0, 0), (1, 2)]))
        sage: pc.dimension()
        1
        sage: pc
        Polyhedral complex with 5 maximal cells
        sage: pc.remove_cell(Polyhedron(vertices=[(1, 2)]))
        sage: pc.dimension()
        1
        sage: pc
        Polyhedral complex with 3 maximal cells
        sage: pc.remove_cell(Polyhedron(vertices=[(0, 0)]))
        sage: pc.dimension()
        0

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> r = Polyhedron(rays=[(Integer(1), Integer(0))])
        >>> pc = PolyhedralComplex([p1, p2, r])
        >>> pc.dimension()
        2
        >>> pc.remove_cell(Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(1), Integer(2))]))
        >>> pc.dimension()
        1
        >>> pc
        Polyhedral complex with 5 maximal cells
        >>> pc.remove_cell(Polyhedron(vertices=[(Integer(1), Integer(2))]))
        >>> pc.dimension()
        1
        >>> pc
        Polyhedral complex with 3 maximal cells
        >>> pc.remove_cell(Polyhedron(vertices=[(Integer(0), Integer(0))]))
        >>> pc.dimension()
        0

  set_immutable()

    Make this polyhedral complex immutable.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])])
        sage: pc.is_mutable()
        True
        sage: pc.set_immutable()
        sage: pc.is_mutable()
        False

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])])
        >>> pc.is_mutable()
        True
        >>> pc.set_immutable()
        >>> pc.is_mutable()
        False

  stratify(n)

    Return the pure sub-polyhedral complex which is constructed from the \(n\)-dimensional maximal cells of this polyhedral complex.

    See also

    `n_skeleton()`

    Warning

    This may give the wrong answer if the polyhedral complex was constructed with `maximality_check` set to `False`.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(1, 2), (0, 2)])
        sage: pc = PolyhedralComplex([p1, p2, p3])
        sage: pc.stratify(2) == pc
        True
        sage: pc.stratify(1)
        Polyhedral complex with 0 maximal cells

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(2))])
        >>> pc = PolyhedralComplex([p1, p2, p3])
        >>> pc.stratify(Integer(2)) == pc
        True
        >>> pc.stratify(Integer(1))
        Polyhedral complex with 0 maximal cells

    Wrong answer due to `maximality_check=False`:

    Sage

        sage: pc_invalid = PolyhedralComplex([p1, p2, p3],
        ....:                                maximality_check=False)
        sage: pc_invalid.stratify(1)
        Polyhedral complex with 1 maximal cell

    [Python]

        >>> from sage.all import *
        >>> pc_invalid = PolyhedralComplex([p1, p2, p3],
        ...                                maximality_check=False)
        >>> pc_invalid.stratify(Integer(1))
        Polyhedral complex with 1 maximal cell

  subdivide(make_simplicial=False, new_vertices=None, new_rays=None)

    Construct a new polyhedral complex by iterative stellar subdivision of `self` for each new vertex/ray given.

    Currently, subdivision is only supported for bounded polyhedral complex or polyhedral fan.

    INPUT:

    - `make_simplicial` – boolean (default: `False`); if `True`, the returned polyhedral complex is simplicial

    - `new_vertices`, `new_rays` – list (optional); new generators to be added during subdivision

    EXAMPLES:

    Sage

        sage: square_vertices = [(1, 1, 1), (-1, 1, 1), (-1, -1, 1), (1, -1, 1)]
        sage: pc = PolyhedralComplex([
        ....:         Polyhedron(vertices=[(0, 0, 0)] + square_vertices),
        ....:         Polyhedron(vertices=[(0, 0, 2)] + square_vertices)])
        sage: pc.is_compact() and not pc.is_simplicial_complex()
        True
        sage: subdivided_pc = pc.subdivide(new_vertices=[(0, 0, 1)])
        sage: subdivided_pc
        Polyhedral complex with 8 maximal cells
        sage: subdivided_pc.is_simplicial_complex()
        True
        sage: simplicial_pc = pc.subdivide(make_simplicial=True)
        sage: simplicial_pc
        Polyhedral complex with 4 maximal cells
        sage: simplicial_pc.is_simplicial_complex()
        True

        sage: fan = PolyhedralComplex([Polyhedron(rays=square_vertices)])
        sage: fan.is_polyhedral_fan() and not fan.is_simplicial_fan()
        True
        sage: fan.subdivide(new_vertices=[(0, 0, 1)])
        Traceback (most recent call last):
        ...
        ValueError: new vertices cannot be used for subdivision
        sage: subdivided_fan = fan.subdivide(new_rays=[(0, 0, 1)])
        sage: subdivided_fan
        Polyhedral complex with 4 maximal cells
        sage: subdivided_fan.is_simplicial_fan()
        True
        sage: simplicial_fan = fan.subdivide(make_simplicial=True)
        sage: simplicial_fan
        Polyhedral complex with 2 maximal cells
        sage: simplicial_fan.is_simplicial_fan()
        True

        sage: halfspace = PolyhedralComplex([Polyhedron(rays=[(0, 0, 1)],
        ....:             lines=[(1, 0, 0), (0, 1, 0)])])
        sage: halfspace.is_simplicial_fan()
        False
        sage: subdiv_halfspace = halfspace.subdivide(make_simplicial=True)
        sage: subdiv_halfspace
        Polyhedral complex with 4 maximal cells
        sage: subdiv_halfspace.is_simplicial_fan()
        True

    Python

        >>> from sage.all import *
        >>> square_vertices = [(Integer(1), Integer(1), Integer(1)), (-Integer(1), Integer(1), Integer(1)), (-Integer(1), -Integer(1), Integer(1)), (Integer(1), -Integer(1), Integer(1))]
        >>> pc = PolyhedralComplex([
        ...         Polyhedron(vertices=[(Integer(0), Integer(0), Integer(0))] + square_vertices),
        ...         Polyhedron(vertices=[(Integer(0), Integer(0), Integer(2))] + square_vertices)])
        >>> pc.is_compact() and not pc.is_simplicial_complex()
        True
        >>> subdivided_pc = pc.subdivide(new_vertices=[(Integer(0), Integer(0), Integer(1))])
        >>> subdivided_pc
        Polyhedral complex with 8 maximal cells
        >>> subdivided_pc.is_simplicial_complex()
        True
        >>> simplicial_pc = pc.subdivide(make_simplicial=True)
        >>> simplicial_pc
        Polyhedral complex with 4 maximal cells
        >>> simplicial_pc.is_simplicial_complex()
        True

        >>> fan = PolyhedralComplex([Polyhedron(rays=square_vertices)])
        >>> fan.is_polyhedral_fan() and not fan.is_simplicial_fan()
        True
        >>> fan.subdivide(new_vertices=[(Integer(0), Integer(0), Integer(1))])
        Traceback (most recent call last):
        ...
        ValueError: new vertices cannot be used for subdivision
        >>> subdivided_fan = fan.subdivide(new_rays=[(Integer(0), Integer(0), Integer(1))])
        >>> subdivided_fan
        Polyhedral complex with 4 maximal cells
        >>> subdivided_fan.is_simplicial_fan()
        True
        >>> simplicial_fan = fan.subdivide(make_simplicial=True)
        >>> simplicial_fan
        Polyhedral complex with 2 maximal cells
        >>> simplicial_fan.is_simplicial_fan()
        True

        >>> halfspace = PolyhedralComplex([Polyhedron(rays=[(Integer(0), Integer(0), Integer(1))],
        ...             lines=[(Integer(1), Integer(0), Integer(0)), (Integer(0), Integer(1), Integer(0))])])
        >>> halfspace.is_simplicial_fan()
        False
        >>> subdiv_halfspace = halfspace.subdivide(make_simplicial=True)
        >>> subdiv_halfspace
        Polyhedral complex with 4 maximal cells
        >>> subdiv_halfspace.is_simplicial_fan()
        True

  union(right)

    The union of this polyhedral complex with another one.

    INPUT:

    - `right` – the other polyhedral complex (the right-hand factor)

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(-1, 0), (0, 0), (0, 1)])
        sage: p2 = Polyhedron(vertices=[(0, -1), (0, 0), (1, 0)])
        sage: p3 = Polyhedron(vertices=[(0, -1), (1, -1), (1, 0)])
        sage: pc = PolyhedralComplex([p1]).union(PolyhedralComplex([p3]))
        sage: set(pc.maximal_cell_iterator()) == set([p1, p3])
        True
        sage: pc.union(PolyhedralComplex([p2]))
        Polyhedral complex with 3 maximal cells
        sage: p4 = Polyhedron(vertices=[(0, -1), (0, 0), (1, 0), (1, -1)])
        sage: pc.union(PolyhedralComplex([p4]))
        Traceback (most recent call last):
        ...
        ValueError: the given cells are not face-to-face

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(-Integer(1), Integer(0)), (Integer(0), Integer(0)), (Integer(0), Integer(1))])
        >>> p2 = Polyhedron(vertices=[(Integer(0), -Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(0))])
        >>> p3 = Polyhedron(vertices=[(Integer(0), -Integer(1)), (Integer(1), -Integer(1)), (Integer(1), Integer(0))])
        >>> pc = PolyhedralComplex([p1]).union(PolyhedralComplex([p3]))
        >>> set(pc.maximal_cell_iterator()) == set([p1, p3])
        True
        >>> pc.union(PolyhedralComplex([p2]))
        Polyhedral complex with 3 maximal cells
        >>> p4 = Polyhedron(vertices=[(Integer(0), -Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(0)), (Integer(1), -Integer(1))])
        >>> pc.union(PolyhedralComplex([p4]))
        Traceback (most recent call last):
        ...
        ValueError: the given cells are not face-to-face

  union_as_polyhedron()

    Return `self` as a `Polyhedron` if `self` is convex.

    EXAMPLES:

    Sage

        sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
        sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
        sage: p3 = Polyhedron(vertices=[(0, 0), (1, 1), (2, 0)])
        sage: P = PolyhedralComplex([p1, p2]).union_as_polyhedron()
        sage: P.vertices_list()
        [[0, 0], [0, 2], [1, 1], [1, 2]]
        sage: PolyhedralComplex([p1, p3]).union_as_polyhedron()
        Traceback (most recent call last):
        ...
        ValueError: the polyhedral complex is not convex

    Python

        >>> from sage.all import *
        >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
        >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
        >>> p3 = Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(1), Integer(1)), (Integer(2), Integer(0))])
        >>> P = PolyhedralComplex([p1, p2]).union_as_polyhedron()
        >>> P.vertices_list()
        [[0, 0], [0, 2], [1, 1], [1, 2]]
        >>> PolyhedralComplex([p1, p3]).union_as_polyhedron()
        Traceback (most recent call last):
        ...
        ValueError: the polyhedral complex is not convex

  wedge(right)

    The wedge (one-point union) of `self` with `right`.

    Todo

    Implement the wedge product of two polyhedral complexes.

    EXAMPLES:

    Sage

        sage: pc = PolyhedralComplex([Polyhedron(vertices=[[0], [1]])])
        sage: pc.wedge(pc)
        Traceback (most recent call last):
        ...
        NotImplementedError: wedge is not implemented for polyhedral complex

    Python

        >>> from sage.all import *
        >>> pc = PolyhedralComplex([Polyhedron(vertices=[[Integer(0)], [Integer(1)]])])
        >>> pc.wedge(pc)
        Traceback (most recent call last):
        ...
        NotImplementedError: wedge is not implemented for polyhedral complex

sage.geometry.polyhedral_complex.cells_list_to_cells_dict(cells_list)

  Helper function that returns the dictionary whose keys are the dimensions, and the value associated to an integer \(d\) is the set of \(d\)-dimensional polyhedra in the given list.

  EXAMPLES:

  Sage

      sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
      sage: p2 = Polyhedron(vertices=[(1, 1), (0, 0)])
      sage: p3 = Polyhedron(vertices=[(0, 0)])
      sage: p4 = Polyhedron(vertices=[(1, 1)])
      sage: sage.geometry.polyhedral_complex.cells_list_to_cells_dict([p1, p2, p3, p4])
      {0: {A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex,
        A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex},
       1: {A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices},
       2: {A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices}}

  Python

      >>> from sage.all import *
      >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
      >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0))])
      >>> p3 = Polyhedron(vertices=[(Integer(0), Integer(0))])
      >>> p4 = Polyhedron(vertices=[(Integer(1), Integer(1))])
      >>> sage.geometry.polyhedral_complex.cells_list_to_cells_dict([p1, p2, p3, p4])
      {0: {A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex,
        A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex},
       1: {A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices},
       2: {A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices}}

sage.geometry.polyhedral_complex.exploded_plot(polyhedra, center, explosion_factor, sticky_vertices, sticky_center, point, **kwds)

  Return a plot of several `polyhedra` in one figure with extra space between them.

  INPUT:

  - `polyhedra` – an iterable of `Polyhedron_base` objects

  - `center` – (default: `None`, denoting the origin) the center of explosion

  - `explosion_factor` – (default: 1) a nonnegative number; translate polyhedra by this factor of the distance from `center` to their center

  - `sticky_vertices` – (default: `False`) boolean or dict; whether to draw line segments between shared vertices of the given polyhedra. A dict gives options for `sage.plot.line()`.

  - `sticky_center` – (default: `True`) boolean or dict. When `center` is a vertex of some of the polyhedra, whether to draw line segments connecting the `center` to the shifted copies of these vertices. A dict gives options for `sage.plot.line()`.

  - `color` – (default: `None`) if `'rainbow'`, assign a different color to every maximal cell and every vertex; otherwise, passed on to `plot()`

  - other keyword arguments are passed on to `plot()`

  EXAMPLES:

  Sage

      sage: from sage.geometry.polyhedral_complex import exploded_plot
      sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)])
      sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)])
      sage: p3 = Polyhedron(vertices=[(0, 0), (1, 1), (2, 0)])
      sage: exploded_plot([p1, p2, p3])                                               # needs sage.plot
      Graphics object consisting of 20 graphics primitives
      sage: exploded_plot([p1, p2, p3], center=(1, 1))                                # needs sage.plot
      Graphics object consisting of 19 graphics primitives
      sage: exploded_plot([p1, p2, p3], center=(1, 1), sticky_vertices=True)          # needs sage.plot
      Graphics object consisting of 23 graphics primitives

  Python

      >>> from sage.all import *
      >>> from sage.geometry.polyhedral_complex import exploded_plot
      >>> p1 = Polyhedron(vertices=[(Integer(1), Integer(1)), (Integer(0), Integer(0)), (Integer(1), Integer(2))])
      >>> p2 = Polyhedron(vertices=[(Integer(1), Integer(2)), (Integer(0), Integer(0)), (Integer(0), Integer(2))])
      >>> p3 = Polyhedron(vertices=[(Integer(0), Integer(0)), (Integer(1), Integer(1)), (Integer(2), Integer(0))])
      >>> exploded_plot([p1, p2, p3])                                               # needs sage.plot
      Graphics object consisting of 20 graphics primitives
      >>> exploded_plot([p1, p2, p3], center=(Integer(1), Integer(1)))                                # needs sage.plot
      Graphics object consisting of 19 graphics primitives
      >>> exploded_plot([p1, p2, p3], center=(Integer(1), Integer(1)), sticky_vertices=True)          # needs sage.plot
      Graphics object consisting of 23 graphics primitives