Ticket #11625: trac_11625-remove-face.patch

File trac_11625-remove-face.patch, 6.2 KB (added by jhpalmieri, 11 years ago)
  • sage/homology/simplicial_complex.py

    # HG changeset patch
    # User J. H. Palmieri <palmieri@math.washington.edu>
    # Date 1311636440 25200
    # Node ID 68a710e7d343fb407da3a6f2afceef4d1373b37c
    # Parent  9dca3876f46be512d86d82dc0b43468f0ad2c8a4
    #11625: speed up (and simplify) remove_face for simplicial complexes
    
    diff --git a/sage/homology/simplicial_complex.py b/sage/homology/simplicial_complex.py
    a b class SimplicialComplex(GenericCellCompl 
    15921592            sage: circle = SimplicialComplex(2, [[0,1], [1,2], [0, 2]])
    15931593            sage: circle._homology_()
    15941594            {0: 0, 1: Z}
    1595             sage: sphere = SimplicialComplex(3, [[0,1,2,3]])
    1596             sage: sphere.remove_face([0,1,2,3])
     1595            sage: disk = SimplicialComplex(3, [[0,1,2,3]])
     1596            sage: sphere = disk.remove_face([0,1,2,3])
    15971597            sage: sphere
    15981598            Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)}
    15991599            sage: sphere._homology_()
    class SimplicialComplex(GenericCellCompl 
    16981698
    16991699        :param face: a subset of the vertex set
    17001700
    1701         This changes the simplicial complex, adding a new face and all
     1701        This *changes* the simplicial complex, adding a new face and all
    17021702        of its subfaces.
    17031703
    17041704        EXAMPLES::
    class SimplicialComplex(GenericCellCompl 
    17561756
    17571757    def remove_face(self, face):
    17581758        """
    1759         Remove a face from this simplicial complex
     1759        Remove a face from this simplicial complex and return the
     1760        resulting simplicial complex.
    17601761
    17611762        :param face: a face of the simplicial complex
    17621763
    1763         This changes the simplicial complex, removing the given face
    1764         any face which contains it.
    1765 
    1766         Algorithm: check if the face is a facet. If so, simply add its
    1767         faces and remove it. Otherwise, take the Alexander dual, add
    1768         the complement of ``face``, and then take the Alexander dual
    1769         again.
     1764        Algorithm: the facets of the new simplicial complex are
     1765        the facets of the original complex not containing ``face``,
     1766        together with those of ``link(face)*boundary(face)``.
    17701767
    17711768        EXAMPLES::
    17721769
    17731770            sage: S = range(1,5)
    17741771            sage: Z = SimplicialComplex(S, [S]); Z
    17751772            Simplicial complex with vertex set (1, 2, 3, 4) and facets {(1, 2, 3, 4)}
    1776             sage: Z.remove_face([1,2])
    1777             sage: Z
     1773            sage: Z2 = Z.remove_face([1,2])
     1774            sage: Z2
    17781775            Simplicial complex with vertex set (1, 2, 3, 4) and facets {(1, 3, 4), (2, 3, 4)}
    17791776
    17801777            sage: S = SimplicialComplex(4,[[0,1,2],[2,3]])
    17811778            sage: S
    17821779            Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {(0, 1, 2), (2, 3)}
    1783             sage: S.remove_face([0,1,2])
    1784             sage: S
     1780            sage: S2 = S.remove_face([0,1,2])
     1781            sage: S2
    17851782            Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {(1, 2), (2, 3), (0, 2), (0, 1)}
    17861783        """
    1787         face = Simplex(face)
    1788         if not Simplex(face).is_face(self.vertices()):
    1789             raise ValueError, "The face to be removed is not a subset of the vertex set."
    1790         else:
    1791             # first, we check if face is a maximal facet.
    1792             # if so, there is a faster method, which we use.
    1793             count = 0
    1794             ec = 0
    1795             for i in self.facets():
    1796                 if face == i:
    1797                     ec = ec+1
    1798                 if face.is_face(i):
    1799                     count = count+1
    1800             if ec == 1 and count == 1:
    1801                 F = SimplicialComplex(face.tuple(),[face])
    1802                 G = F.n_skeleton(face.dimension()-1)
    1803                 old_facets = self.facets().list()
    1804                 old_facets.remove(face)
    1805                 new_facets = old_facets + G.facets().list()
    1806                 self.__init__(self.vertices(),new_facets,maximality_check=True)
    1807             else:
    1808                 X = self.alexander_dual()
    1809                 X.add_face(self._complement(face))
    1810                 self._facets = X.alexander_dual()._facets
    1811                 if None in self._faces:
    1812                     s = Simplex(face)
    1813                     bad_faces = SimplicialComplex(self.vertices(), [s]).faces()
    1814                     for dim in range(0, s.dimension()+1):
    1815                         self._faces[None][dim] = self._faces[None][dim].difference(bad_faces[dim])
    1816             # update self._graph if necessary
    1817             if self._graph is None:
    1818                 pass
    1819             else:
    1820                 d = Simplex(face).dimension()
    1821                 if d==1:
    1822                     self._graph.delete_edge([face[0],face[1]])
    1823                 if d==0:
    1824                     self._graph.delete_vertex(face[0])
    1825             return None
     1784        simplex = Simplex(face)
     1785        facets = self.facets()
     1786        if all([not simplex.is_face(F) for F in facets]):
     1787            # face is not in self: nothing to remove
     1788            return self
     1789        link = self.link(simplex)
     1790        join_facets = []
     1791        for f in simplex.faces():
     1792            for g in link.facets():
     1793                join_facets.append(f.join(g, rename_vertices=False))
     1794        # join_facets is the list of facets in the join bdry(face) * link(face)
     1795        other_facets = [elem for elem in facets if not simplex.is_face(elem)]
     1796        return SimplicialComplex(self.vertices(), join_facets + other_facets)
    18261797
    18271798    def connected_sum(self, other):
    18281799        """
    class SimplicialComplex(GenericCellCompl 
    24162387
    24172388        EXAMPLES::
    24182389
    2419             sage: sphere = SimplicialComplex(3, [[0,1,2,3]])
    2420             sage: sphere.remove_face([0,1,2,3])
     2390            sage: disk = SimplicialComplex(3, [[0,1,2,3]])
     2391            sage: sphere = disk.remove_face([0,1,2,3])
    24212392            sage: sphere
    24222393            Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)}
    24232394            sage: L = sphere._contractible_subcomplex(); L
    2424             Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3)}
    2425 
     2395            Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (1, 2, 3), (0, 1, 3)}
     2396            sage: L.homology()
    24262397            {0: 0, 1: 0, 2: 0}
    24272398        """
    24282399        vertices = self.vertices()