diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd index b5e914514f4..06dbbd0900e 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd @@ -7,7 +7,7 @@ from .face_data_structure cimport face_t from .polyhedron_face_lattice cimport PolyhedronFaceLattice @cython.final -cdef class CombinatorialPolyhedron(Element): +cdef class CombinatorialPolyhedron_class(Element): cdef public dict __cached_methods # Do not assume any of those attributes to be initialized, use the corresponding methods instead. @@ -53,8 +53,8 @@ cdef class CombinatorialPolyhedron(Element): cdef tuple far_face_tuple(self) # Methods to obtain a different combinatorial polyhedron. - cpdef CombinatorialPolyhedron dual(self) - cpdef CombinatorialPolyhedron pyramid(self, new_vertex=*, new_facet=*) + cpdef CombinatorialPolyhedron_class dual(self) + cpdef CombinatorialPolyhedron_class pyramid(self, new_vertex=*, new_facet=*) # Space for edges, ridges, etc. is allocated with ``MemoryAllocators``. # Upon success they are copied to ``_mem_tuple``. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 61933862abf..145107a3230 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -113,9 +113,10 @@ cdef extern from "Python.h": from .parent import CombinatorialPolyhedra cdef Parent unspecific_parent = CombinatorialPolyhedra() -cdef class CombinatorialPolyhedron(Element): +cpdef CombinatorialPolyhedron(data, Vrep=None, facets=None, unbounded=False, + far_face=None, Vrepr=None, parent=None): r""" - The class of the Combinatorial Type of a Polyhedron, a Polytope. + Construct a combinatorial polyhedron, the labeled combinatorial type of a polyhedron. INPUT: @@ -317,8 +318,15 @@ cdef class CombinatorialPolyhedron(Element): sage: CombinatorialPolyhedron(LatticePolytope([], lattice=ToricLattice(3))) A -1-dimensional combinatorial polyhedron with 0 facets """ - def __init__(self, data, Vrep=None, facets=None, unbounded=False, - far_face=None, Vrepr=None, parent=None): + if parent is None: + parent = unspecific_parent + return CombinatorialPolyhedron_class(parent, data, Vrep, facets, + unbounded, far_face, Vrepr) + +cdef class CombinatorialPolyhedron_class(Element): + + def __init__(self, parent, data, Vrep=None, facets=None, unbounded=False, + far_face=None, Vrepr=None): r""" Initialize :class:`CombinatorialPolyhedron`. @@ -2788,9 +2796,9 @@ cdef class CombinatorialPolyhedron(Element): r""" Return whether ``self`` and ``other`` are equal. """ - if not isinstance(other, CombinatorialPolyhedron): + if not isinstance(other, CombinatorialPolyhedron_class): return False - cdef CombinatorialPolyhedron other_C = other + cdef CombinatorialPolyhedron_class other_C = other return (self.n_facets() == other.n_facets() and self.Vrepresentation() == other.Vrepresentation() and self.facet_names() == other_C.facet_names() @@ -2802,7 +2810,7 @@ cdef class CombinatorialPolyhedron(Element): # Methods to obtain a different combinatorial polyhedron. - cpdef CombinatorialPolyhedron dual(self): + cpdef CombinatorialPolyhedron_class dual(self): r""" Return the dual/polar of self. @@ -2845,7 +2853,7 @@ cdef class CombinatorialPolyhedron(Element): polar = dual - cpdef CombinatorialPolyhedron pyramid(self, new_vertex=None, new_facet=None): + cpdef CombinatorialPolyhedron_class pyramid(self, new_vertex=None, new_facet=None): r""" Return the pyramid of ``self``. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx index 8d068de872c..6aed786dedc 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx @@ -69,7 +69,7 @@ from sage.misc.superseded import deprecated_function_alias import numbers from sage.rings.integer cimport smallInteger from .conversions cimport bit_rep_to_Vrep_list -from .base cimport CombinatorialPolyhedron +from .base import CombinatorialPolyhedron from .face_iterator cimport FaceIterator_base from .polyhedron_face_lattice cimport PolyhedronFaceLattice from .face_data_structure cimport face_len_atoms, face_init, face_copy diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index fc4929bf29f..a2330621430 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -1,4 +1,4 @@ -r""" +""" Face iterator for polyhedra This iterator in principle works on every graded lattice, where @@ -178,7 +178,7 @@ from sage.rings.integer cimport smallInteger from cysignals.signals cimport sig_check from .conversions cimport bit_rep_to_Vrep_list from .conversions import facets_tuple_to_bit_rep_of_facets -from .base cimport CombinatorialPolyhedron +from .base cimport CombinatorialPolyhedron_class from sage.geometry.polyhedron.face import combinatorial_face_to_polyhedral_face, PolyhedronFace from .face_list_data_structure cimport * @@ -195,7 +195,7 @@ cdef class FaceIterator_base(SageObject): See :class:`FaceIterator`. """ - def __init__(self, CombinatorialPolyhedron C, bint dual, output_dimension=None): + def __init__(self, CombinatorialPolyhedron_class C, bint dual, output_dimension=None): r""" Initialize :class:`FaceIterator_base`. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/morphism.py b/src/sage/geometry/polyhedron/combinatorial_polyhedron/morphism.py index 4cc82f3dfed..43f4e26d216 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/morphism.py +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/morphism.py @@ -17,3 +17,49 @@ def __init__(self, Vrep_dict=None, parent=None, domain=None, codomain=None, chec def _repr_type(self): return "Combinatorial polyhedral set" + + def __call__(self, p): + """ + Apply the morphism to a combinatorial polyhedron. + + EXAMPLES:: + + sage: C = polytopes.cube().combinatorial_polyhedron() + sage: C.Vrepresentation() + (A vertex at (1, -1, -1), + A vertex at (1, 1, -1), + A vertex at (1, 1, 1), + A vertex at (1, -1, 1), + A vertex at (-1, -1, 1), + A vertex at (-1, -1, -1), + A vertex at (-1, 1, -1), + A vertex at (-1, 1, 1)) + sage: C.Hrepresentation() + (An inequality (-1, 0, 0) x + 1 >= 0, + An inequality (0, -1, 0) x + 1 >= 0, + An inequality (0, 0, -1) x + 1 >= 0, + An inequality (1, 0, 0) x + 1 >= 0, + An inequality (0, 0, 1) x + 1 >= 0, + An inequality (0, 1, 0) x + 1 >= 0) + + Abstraction morphism:: + + sage: Vrep_dict = {vertex: index for index, vertex in enumerate(C.vertices())} + sage: phi = C.parent().hom(Vrep_dict) + sage: phi_C = phi(C); phi_C + A 3-dimensional combinatorial polyhedron with 6 facets + sage: phi_C.Vrepresentation() + (0, 1, 2, 3, 4, 5, 6, 7) + sage: phi_C.Hrepresentation() + (0, 1, 2, 3, 4, 5) + + """ + # For now, degenerations are not implemented + incidence_matrix = p.incidence_matrix() + + Vrep = p.Vrepresentation() + def map_vrep_element(v): + return self._Vrep_dict[v] + Vrep = [map_vrep_element(v) for v in Vrep] + + return self.codomain()(incidence_matrix, Vrep=Vrep) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/parent.py b/src/sage/geometry/polyhedron/combinatorial_polyhedron/parent.py index bc1380056f8..6d20242265e 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/parent.py +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/parent.py @@ -14,6 +14,7 @@ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation +from .base import CombinatorialPolyhedron_class class CombinatorialPolyhedra(UniqueRepresentation, Parent): @@ -21,6 +22,8 @@ class CombinatorialPolyhedra(UniqueRepresentation, Parent): Parent class for combinatorial polyhedra """ + Element = CombinatorialPolyhedron_class + def __init__(self): """ Construct the parent of class ``CombinatorialPolyhedra``. @@ -60,7 +63,10 @@ def hom(self, Vrep_dict, codomain=None, check=True, category=None): sage: C = polytopes.cube().combinatorial_polyhedron() sage: C.parent().hom({1: 2, 2: 2}, C.parent()) + Combinatorial polyhedral set endomorphism of Combinatorial polyhedra """ + if codomain is None: + codomain = self homset = self.Hom(codomain) return homset(Vrep_dict, check=check) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx index f01b38b94eb..09afa0f9c89 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx @@ -66,7 +66,8 @@ from .conversions \ from .conversions cimport bit_rep_to_Vrep_list from sage.rings.integer cimport smallInteger -from .base cimport CombinatorialPolyhedron +from .base import CombinatorialPolyhedron +from .base cimport CombinatorialPolyhedron_class from .face_iterator cimport FaceIterator from .face_list_data_structure cimport * @@ -110,7 +111,7 @@ cdef class PolyhedronFaceLattice: by intersecting with all coatoms. Then each intersection is looked up in the sorted level sets. """ - def __init__(self, CombinatorialPolyhedron C): + def __init__(self, CombinatorialPolyhedron_class C): r""" Initialize :class:`PolyhedronFaceLattice`.