Path: blob/master/src/sage/geometry/polyhedron/face.py
8817 views
"""1A class to keep information about faces of a polyhedron23This module gives you a tool to work with the faces of a polyhedron4and their relative position. First, you need to find the faces. To get5the faces in a particular dimension, use the6:meth:`~sage.geometry.poylhedron.base.face` method::78sage: P = polytopes.cross_polytope(3)9sage: P.faces(3)10(<0,1,2,3,4,5>,)11sage: P.faces(2)12(<0,1,2>, <0,1,3>, <0,2,4>, <0,3,4>, <3,4,5>, <2,4,5>, <1,3,5>, <1,2,5>)13sage: P.faces(1)14(<0,1>, <0,2>, <1,2>, <0,3>, <1,3>, <0,4>, <2,4>, <3,4>, <2,5>, <3,5>, <4,5>, <1,5>)1516or :meth:`~sage.geometry.poylhedron.base.face_lattice` to get the17whole face lattice as a poset::1819sage: P.face_lattice()20Finite poset containing 28 elements2122The faces are printed in shorthand notation where each integer is the23index of a vertex/ray/line in the same order as the containing24Polyhedron's :meth:`~sage.geometry.polyhedron.base.Vrepresentation` ::2526sage: face = P.faces(1)[3]; face27<0,3>28sage: P.Vrepresentation(0)29A vertex at (-1, 0, 0)30sage: P.Vrepresentation(3)31A vertex at (0, 0, 1)32sage: face.vertices()33(A vertex at (-1, 0, 0), A vertex at (0, 0, 1))3435The face itself is not represented by Sage's36:func:`sage.geometry.polyhedron.constructor.Polyhedron` class, but by37an auxiliary class to keep the information. You can get the face as a38polyhedron with the :meth:`PolyhedronFace.as_polyhedron` method::3940sage: face.as_polyhedron()41A 1-dimensional polyhedron in ZZ^3 defined as the convex hull of 2 vertices42sage: _.equations()43(An equation (0, 1, 0) x + 0 == 0,44An equation (1, 0, -1) x + 1 == 0)45"""4647########################################################################48# Copyright (C) 2012 Volker Braun <[email protected]>49#50# Distributed under the terms of the GNU General Public License (GPL)51#52# http://www.gnu.org/licenses/53########################################################################545556from sage.structure.sage_object import SageObject57from sage.misc.all import cached_method58from sage.modules.free_module_element import vector59from sage.matrix.constructor import matrix60616263#########################################################################64class PolyhedronFace(SageObject):65r"""66A face of a polyhedron.6768This class is for use in69:meth:`~sage.geometry.polyhedron.base.Polyhedron_base.face_lattice`.7071INPUT:7273No checking is performed whether the H/V-representation indices74actually determine a face of the polyhedron. You should not75manually create :class:`PolyhedronFace` objects unless you know76what you are doing.7778OUTPUT:7980A :class:`PolyhedronFace`.8182EXAMPLES::8384sage: octahedron = polytopes.cross_polytope(3)85sage: inequality = octahedron.Hrepresentation(2)86sage: face_h = tuple([ inequality ])87sage: face_v = tuple( inequality.incident() )88sage: face_h_indices = [ h.index() for h in face_h ]89sage: face_v_indices = [ v.index() for v in face_v ]90sage: from sage.geometry.polyhedron.face import PolyhedronFace91sage: face = PolyhedronFace(octahedron, face_v_indices, face_h_indices)92sage: face93<0,1,2>94sage: face.dim()95296sage: face.ambient_Hrepresentation()97(An inequality (1, 1, 1) x + 1 >= 0,)98sage: face.ambient_Vrepresentation()99(A vertex at (-1, 0, 0), A vertex at (0, -1, 0), A vertex at (0, 0, -1))100"""101102def __init__(self, polyhedron, V_indices, H_indices):103r"""104The constructor.105106See :class:`PolyhedronFace` for more information.107108INPUT:109110- ``polyhedron`` -- a :class:`Polyhedron`. The ambient111polyhedron.112113- ``V_indices`` -- list of sorted integers. The indices of the114face-spanning V-representation objects in the ambient115polyhedron.116117- ``H_indices`` -- list of sorted integers. The indices of the118H-representation objects of the ambient polyhedron that are119saturated on the face.120121TESTS::122123sage: from sage.geometry.polyhedron.face import PolyhedronFace124sage: PolyhedronFace(Polyhedron(), [], []) # indirect doctest125<>126"""127self._polyhedron = polyhedron128self._ambient_Vrepresentation_indices = tuple(V_indices)129self._ambient_Hrepresentation_indices = tuple(H_indices)130self._ambient_Vrepresentation = tuple( polyhedron.Vrepresentation(i) for i in V_indices )131self._ambient_Hrepresentation = tuple( polyhedron.Hrepresentation(i) for i in H_indices )132133def vertex_generator(self):134"""135Return a generator for the vertices of the face.136137EXAMPLES::138139sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])140sage: face = triangle.faces(1)[0]141sage: for v in face.vertex_generator(): print(v)142A vertex at (0, 1)143A vertex at (1, 0)144sage: type(face.vertex_generator())145<type 'generator'>146"""147for V in self.ambient_Vrepresentation():148if V.is_vertex():149yield V150151@cached_method152def vertices(self):153"""154Return all vertices of the face.155156OUTPUT:157158A tuple of vertices.159160EXAMPLES::161162sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])163sage: face = triangle.faces(1)[0]164sage: face.vertices()165(A vertex at (0, 1), A vertex at (1, 0))166"""167return tuple(self.vertex_generator())168169def ray_generator(self):170"""171Return a generator for the rays of the face.172173EXAMPLES::174175sage: pi = Polyhedron(ieqs = [[1,1,0],[1,0,1]])176sage: face = pi.faces(1)[0]177sage: face.ray_generator().next()178A ray in the direction (1, 0)179"""180for V in self.ambient_Vrepresentation():181if V.is_ray():182yield V183184@cached_method185def rays(self):186"""187Return the rays of the face.188189OUTPUT:190191A tuple of rays.192193EXAMPLES::194195sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])196sage: face = p.faces(2)[0]197sage: face.rays()198(A ray in the direction (1, 0, 0), A ray in the direction (0, 1, 0))199"""200return tuple(self.ray_generator())201202def line_generator(self):203"""204Return a generator for the lines of the face.205206EXAMPLES::207208sage: pr = Polyhedron(rays = [[1,0],[-1,0],[0,1]], vertices = [[-1,-1]])209sage: face = pr.faces(1)[0]210sage: face.line_generator().next()211A line in the direction (1, 0)212"""213for V in self.ambient_Vrepresentation():214if V.is_line():215yield V216217@cached_method218def lines(self):219"""220Return all lines of the face.221222OUTPUT:223224A tuple of lines.225226EXAMPLES::227228sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])229sage: p.lines()230(A line in the direction (1, 0),)231"""232return tuple(self.line_generator())233234def __cmp__(self, other):235"""236Compare ``self`` and ``other``.237238INPUT:239240- ``other`` -- anything.241242OUTPUT:243244Two faces test equal if and only if they are faces of the same245(not just isomorphic) polyhedron and their generators have the246same indices.247248EXAMPLES::249250sage: square = polytopes.n_cube(2)251sage: f = square.faces(1)252sage: matrix(4,4, lambda i,j: cmp(f[i], f[j]))253[ 0 -1 -1 -1]254[ 1 0 -1 -1]255[ 1 1 0 -1]256[ 1 1 1 0]257"""258if not isinstance(other, PolyhedronFace):259return -1260if self._polyhedron is not other._polyhedron:261return -1262return cmp(self._ambient_Vrepresentation_indices,263other._ambient_Vrepresentation_indices)264265def ambient_Hrepresentation(self, index=None):266r"""267Return the H-representation objects of the ambient polytope268defining the face.269270INPUT:271272- ``index`` -- optional. Either an integer or ``None``273(default).274275OUTPUT:276277If the optional argument is not present, a tuple of278H-representation objects. Each entry is either an inequality279or an equation.280281If the optional integer ``index`` is specified, the282``index``-th element of the tuple is returned.283284EXAMPLES::285286sage: square = polytopes.n_cube(2)287sage: for face in square.face_lattice():288... print face.ambient_Hrepresentation()289(An inequality (1, 0) x + 1 >= 0, An inequality (0, 1) x + 1 >= 0,290An inequality (-1, 0) x + 1 >= 0, An inequality (0, -1) x + 1 >= 0)291(An inequality (1, 0) x + 1 >= 0, An inequality (0, 1) x + 1 >= 0)292(An inequality (1, 0) x + 1 >= 0, An inequality (0, -1) x + 1 >= 0)293(An inequality (0, 1) x + 1 >= 0, An inequality (-1, 0) x + 1 >= 0)294(An inequality (-1, 0) x + 1 >= 0, An inequality (0, -1) x + 1 >= 0)295(An inequality (1, 0) x + 1 >= 0,)296(An inequality (0, 1) x + 1 >= 0,)297(An inequality (-1, 0) x + 1 >= 0,)298(An inequality (0, -1) x + 1 >= 0,)299()300"""301if index==None:302return self._ambient_Hrepresentation303else:304return self._ambient_Hrepresentation[index]305306def ambient_Vrepresentation(self, index=None):307r"""308Return the V-representation objects of the ambient polytope309defining the face.310311INPUT:312313- ``index`` -- optional. Either an integer or ``None``314(default).315316OUTPUT:317318If the optional argument is not present, a tuple of319V-representation objects. Each entry is either a vertex, a320ray, or a line.321322If the optional integer ``index`` is specified, the323``index``-th element of the tuple is returned.324325EXAMPLES::326327sage: square = polytopes.n_cube(2)328sage: for fl in square.face_lattice():329... print fl.ambient_Vrepresentation()330...331()332(A vertex at (-1, -1),)333(A vertex at (-1, 1),)334(A vertex at (1, -1),)335(A vertex at (1, 1),)336(A vertex at (-1, -1), A vertex at (-1, 1))337(A vertex at (-1, -1), A vertex at (1, -1))338(A vertex at (1, -1), A vertex at (1, 1))339(A vertex at (-1, 1), A vertex at (1, 1))340(A vertex at (-1, -1), A vertex at (-1, 1),341A vertex at (1, -1), A vertex at (1, 1))342"""343if index==None:344return self._ambient_Vrepresentation345else:346return self._ambient_Vrepresentation[index]347348def n_ambient_Hrepresentation(self):349"""350Return the number of objects that make up the ambient351H-representation of the polyhedron.352353See also :meth:`ambient_Hrepresentation`.354355OUTPUT:356357Integer.358359EXAMPLES::360361sage: p = polytopes.cross_polytope(4)362sage: face = p.face_lattice()[10]363sage: face364<0,2>365sage: face.ambient_Hrepresentation()366(An inequality (1, -1, 1, -1) x + 1 >= 0,367An inequality (1, 1, 1, 1) x + 1 >= 0,368An inequality (1, 1, 1, -1) x + 1 >= 0,369An inequality (1, -1, 1, 1) x + 1 >= 0)370sage: face.n_ambient_Hrepresentation()3714372"""373return len(self.ambient_Hrepresentation())374375def n_ambient_Vrepresentation(self):376"""377Return the number of objects that make up the ambient378V-representation of the polyhedron.379380See also :meth:`ambient_Vrepresentation`.381382OUTPUT:383384Integer.385386EXAMPLES::387388sage: p = polytopes.cross_polytope(4)389sage: face = p.face_lattice()[10]390sage: face391<0,2>392sage: face.ambient_Vrepresentation()393(A vertex at (-1, 0, 0, 0), A vertex at (0, 0, -1, 0))394sage: face.n_ambient_Vrepresentation()3952396"""397return len(self.ambient_Vrepresentation())398399def ambient_dim(self):400r"""401Return the dimension of the containing polyhedron.402403EXAMPLES::404405sage: P = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])406sage: face = P.faces(1)[0]407sage: face.ambient_dim()4084409"""410return self._polyhedron.ambient_dim()411412@cached_method413def dim(self):414"""415Return the dimension of the face.416417OUTPUT:418419Integer.420421EXAMPLES::422423sage: fl = polytopes.dodecahedron().face_lattice()424sage: [ x.dim() for x in fl ]425[-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,4261, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,4271, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3]428"""429if self.n_ambient_Vrepresentation()==0:430return -1431else:432origin = vector(self.ambient_Vrepresentation(0))433v_list = [ vector(v)-origin for v in self.ambient_Vrepresentation() ]434return matrix(v_list).rank()435436def _repr_(self):437r"""438Return a string representation.439440OUTPUT:441442A string listing the V-representation indices of the face.443444EXAMPLES::445446sage: square = polytopes.n_cube(2)447sage: a_face = list( square.face_lattice() )[8]448sage: a_face.__repr__()449'<1,3>'450"""451s = '<'452s += ','.join([ str(v.index()) for v in self.ambient_Vrepresentation() ])453s += '>'454return s455456def polyhedron(self):457"""458Return the containing polyhedron.459460EXAMPLES::461462sage: P = polytopes.cross_polytope(3); P463A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices464sage: face = P.faces(2)[3]465sage: face466<0,3,4>467sage: face.polyhedron()468A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices469"""470return self._polyhedron471472@cached_method473def as_polyhedron(self):474"""475Return the face as an independent polyhedron.476477OUTPUT:478479A polyhedron.480481EXAMPLES::482483sage: P = polytopes.cross_polytope(3); P484A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices485sage: face = P.faces(2)[3]486sage: face487<0,3,4>488sage: face.as_polyhedron()489A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices490491sage: P.intersection(face.as_polyhedron()) == face.as_polyhedron()492True493"""494P = self._polyhedron495parent = P.parent()496Vrep = (self.vertices(), self.rays(), self.lines())497return P.__class__(parent, Vrep, None)498499500