Morphisms of simplicial complexes - Topology

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

# Morphisms of simplicial complexes

AUTHORS:

- Benjamin Antieau <d.ben.antieau@gmail.com> (2009.06)

- Travis Scrimshaw (2012-08-18): Made all simplicial complexes immutable to work with the homset cache.

This module implements morphisms of simplicial complexes. The input is given by a dictionary on the vertex set of a simplicial complex. The initialization checks that faces are sent to faces.

There is also the capability to create the fiber product of two morphisms with the same codomain.

EXAMPLES:

Sage

    sage: S = SimplicialComplex([[0,2],[1,5],[3,4]], immutable=True)
    sage: H = Hom(S,S.product(S, immutable=True))
    sage: H.diagonal_morphism()
    Simplicial complex morphism:
      From: Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(0, 2), (1, 5), (3, 4)}
      To: Simplicial complex with 36 vertices and 18 facets
      Defn: [0, 1, 2, 3, 4, 5] --> ['L0R0', 'L1R1', 'L2R2', 'L3R3', 'L4R4', 'L5R5']

    sage: S = SimplicialComplex([[0,2],[1,5],[3,4]], immutable=True)
    sage: T = SimplicialComplex([[0,2],[1,3]], immutable=True)
    sage: f = {0:0,1:1,2:2,3:1,4:3,5:3}
    sage: H = Hom(S,T)
    sage: x = H(f)
    sage: x.image()
    Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2), (1, 3)}
    sage: x.is_surjective()
    True
    sage: x.is_injective()
    False
    sage: x.is_identity()
    False

    sage: S = simplicial_complexes.Sphere(2)
    sage: H = Hom(S,S)
    sage: i = H.identity()
    sage: i.image()
    Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)}
    sage: i.is_surjective()
    True
    sage: i.is_injective()
    True
    sage: i.is_identity()
    True

    sage: S = simplicial_complexes.Sphere(2)
    sage: H = Hom(S,S)
    sage: i = H.identity()
    sage: j = i.fiber_product(i)
    sage: j
    Simplicial complex morphism:
      From: Simplicial complex with 4 vertices and 4 facets
      To:   Minimal triangulation of the 2-sphere
      Defn: L0R0 |--> 0
            L1R1 |--> 1
            L2R2 |--> 2
            L3R3 |--> 3
    sage: S = simplicial_complexes.Sphere(2)
    sage: T = S.product(SimplicialComplex([[0,1]]), rename_vertices = False, immutable=True)
    sage: H = Hom(T,S)
    sage: T
    Simplicial complex with 8 vertices and 12 facets
    sage: sorted(T.vertices())
    [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1)]
    sage: f = {(0, 0): 0, (0, 1): 0, (1, 0): 1, (1, 1): 1, (2, 0): 2, (2, 1): 2, (3, 0): 3, (3, 1): 3}
    sage: x = H(f)
    sage: U = simplicial_complexes.Sphere(1)
    sage: G = Hom(U,S)
    sage: U
    Minimal triangulation of the 1-sphere
    sage: g = {0:0,1:1,2:2}
    sage: y = G(g)
    sage: z = y.fiber_product(x)
    sage: z                                     # this is the mapping path space
    Simplicial complex morphism:
      From: Simplicial complex with 6 vertices and ... facets
      To:   Minimal triangulation of the 2-sphere
      Defn: ['L0R(0, 0)', 'L0R(0, 1)', 'L1R(1, 0)', 'L1R(1, 1)', 'L2R(2, 0)', 'L2R(2, 1)'] --> [0, 0, 1, 1, 2, 2]

Python

    >>> from sage.all import *
    >>> S = SimplicialComplex([[Integer(0),Integer(2)],[Integer(1),Integer(5)],[Integer(3),Integer(4)]], immutable=True)
    >>> H = Hom(S,S.product(S, immutable=True))
    >>> H.diagonal_morphism()
    Simplicial complex morphism:
      From: Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(0, 2), (1, 5), (3, 4)}
      To: Simplicial complex with 36 vertices and 18 facets
      Defn: [0, 1, 2, 3, 4, 5] --> ['L0R0', 'L1R1', 'L2R2', 'L3R3', 'L4R4', 'L5R5']

    >>> S = SimplicialComplex([[Integer(0),Integer(2)],[Integer(1),Integer(5)],[Integer(3),Integer(4)]], immutable=True)
    >>> T = SimplicialComplex([[Integer(0),Integer(2)],[Integer(1),Integer(3)]], immutable=True)
    >>> f = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(2),Integer(3):Integer(1),Integer(4):Integer(3),Integer(5):Integer(3)}
    >>> H = Hom(S,T)
    >>> x = H(f)
    >>> x.image()
    Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2), (1, 3)}
    >>> x.is_surjective()
    True
    >>> x.is_injective()
    False
    >>> x.is_identity()
    False

    >>> S = simplicial_complexes.Sphere(Integer(2))
    >>> H = Hom(S,S)
    >>> i = H.identity()
    >>> i.image()
    Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)}
    >>> i.is_surjective()
    True
    >>> i.is_injective()
    True
    >>> i.is_identity()
    True

    >>> S = simplicial_complexes.Sphere(Integer(2))
    >>> H = Hom(S,S)
    >>> i = H.identity()
    >>> j = i.fiber_product(i)
    >>> j
    Simplicial complex morphism:
      From: Simplicial complex with 4 vertices and 4 facets
      To:   Minimal triangulation of the 2-sphere
      Defn: L0R0 |--> 0
            L1R1 |--> 1
            L2R2 |--> 2
            L3R3 |--> 3
    >>> S = simplicial_complexes.Sphere(Integer(2))
    >>> T = S.product(SimplicialComplex([[Integer(0),Integer(1)]]), rename_vertices = False, immutable=True)
    >>> H = Hom(T,S)
    >>> T
    Simplicial complex with 8 vertices and 12 facets
    >>> sorted(T.vertices())
    [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1)]
    >>> f = {(Integer(0), Integer(0)): Integer(0), (Integer(0), Integer(1)): Integer(0), (Integer(1), Integer(0)): Integer(1), (Integer(1), Integer(1)): Integer(1), (Integer(2), Integer(0)): Integer(2), (Integer(2), Integer(1)): Integer(2), (Integer(3), Integer(0)): Integer(3), (Integer(3), Integer(1)): Integer(3)}
    >>> x = H(f)
    >>> U = simplicial_complexes.Sphere(Integer(1))
    >>> G = Hom(U,S)
    >>> U
    Minimal triangulation of the 1-sphere
    >>> g = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(2)}
    >>> y = G(g)
    >>> z = y.fiber_product(x)
    >>> z                                     # this is the mapping path space
    Simplicial complex morphism:
      From: Simplicial complex with 6 vertices and ... facets
      To:   Minimal triangulation of the 2-sphere
      Defn: ['L0R(0, 0)', 'L0R(0, 1)', 'L1R(1, 0)', 'L1R(1, 1)', 'L2R(2, 0)', 'L2R(2, 1)'] --> [0, 0, 1, 1, 2, 2]

class sage.topology.simplicial_complex_morphism.SimplicialComplexMorphism(f, X, Y)

  Bases: `Morphism`

  An element of this class is a morphism of simplicial complexes.

  associated_chain_complex_morphism(base_ring=Integer Ring, augmented=False, cochain=False)

    Return the associated chain complex morphism of `self`.

    EXAMPLES:

    Sage

        sage: # needs sage.modules
        sage: S = simplicial_complexes.Sphere(1)
        sage: T = simplicial_complexes.Sphere(2)
        sage: H = Hom(S, T)
        sage: f = {0:0, 1:1, 2:2}
        sage: x = H(f); x
        Simplicial complex morphism:
          From: Minimal triangulation of the 1-sphere
          To:   Minimal triangulation of the 2-sphere
          Defn: 0 |--> 0
                1 |--> 1
                2 |--> 2
        sage: a = x.associated_chain_complex_morphism(); a
        Chain complex morphism:
          From: Chain complex with at most 2 nonzero terms over Integer Ring
          To:   Chain complex with at most 3 nonzero terms over Integer Ring
        sage: a._matrix_dictionary
        {0: [1 0 0]
            [0 1 0]
            [0 0 1]
            [0 0 0],
         1: [1 0 0]
            [0 1 0]
            [0 0 0]
            [0 0 1]
            [0 0 0]
            [0 0 0],
         2: []}
        sage: x.associated_chain_complex_morphism(augmented=True)
        Chain complex morphism:
          From: Chain complex with at most 3 nonzero terms over Integer Ring
          To:   Chain complex with at most 4 nonzero terms over Integer Ring
        sage: x.associated_chain_complex_morphism(cochain=True)
        Chain complex morphism:
          From: Chain complex with at most 3 nonzero terms over Integer Ring
          To:   Chain complex with at most 2 nonzero terms over Integer Ring
        sage: x.associated_chain_complex_morphism(augmented=True, cochain=True)
        Chain complex morphism:
          From: Chain complex with at most 4 nonzero terms over Integer Ring
          To:   Chain complex with at most 3 nonzero terms over Integer Ring
        sage: x.associated_chain_complex_morphism(base_ring=GF(11))
        Chain complex morphism:
          From: Chain complex with at most 2 nonzero terms over Finite Field of size 11
          To:   Chain complex with at most 3 nonzero terms over Finite Field of size 11

    Python

        >>> from sage.all import *
        >>> # needs sage.modules
        >>> S = simplicial_complexes.Sphere(Integer(1))
        >>> T = simplicial_complexes.Sphere(Integer(2))
        >>> H = Hom(S, T)
        >>> f = {Integer(0):Integer(0), Integer(1):Integer(1), Integer(2):Integer(2)}
        >>> x = H(f); x
        Simplicial complex morphism:
          From: Minimal triangulation of the 1-sphere
          To:   Minimal triangulation of the 2-sphere
          Defn: 0 |--> 0
                1 |--> 1
                2 |--> 2
        >>> a = x.associated_chain_complex_morphism(); a
        Chain complex morphism:
          From: Chain complex with at most 2 nonzero terms over Integer Ring
          To:   Chain complex with at most 3 nonzero terms over Integer Ring
        >>> a._matrix_dictionary
        {0: [1 0 0]
            [0 1 0]
            [0 0 1]
            [0 0 0],
         1: [1 0 0]
            [0 1 0]
            [0 0 0]
            [0 0 1]
            [0 0 0]
            [0 0 0],
         2: []}
        >>> x.associated_chain_complex_morphism(augmented=True)
        Chain complex morphism:
          From: Chain complex with at most 3 nonzero terms over Integer Ring
          To:   Chain complex with at most 4 nonzero terms over Integer Ring
        >>> x.associated_chain_complex_morphism(cochain=True)
        Chain complex morphism:
          From: Chain complex with at most 3 nonzero terms over Integer Ring
          To:   Chain complex with at most 2 nonzero terms over Integer Ring
        >>> x.associated_chain_complex_morphism(augmented=True, cochain=True)
        Chain complex morphism:
          From: Chain complex with at most 4 nonzero terms over Integer Ring
          To:   Chain complex with at most 3 nonzero terms over Integer Ring
        >>> x.associated_chain_complex_morphism(base_ring=GF(Integer(11)))
        Chain complex morphism:
          From: Chain complex with at most 2 nonzero terms over Finite Field of size 11
          To:   Chain complex with at most 3 nonzero terms over Finite Field of size 11

    Some simplicial maps which reverse the orientation of a few simplices:

    Sage

        sage: # needs sage.modules
        sage: g = {0:1, 1:2, 2:0}
        sage: H(g).associated_chain_complex_morphism()._matrix_dictionary
        {0: [0 0 1]
            [1 0 0]
            [0 1 0]
            [0 0 0],
         1: [ 0 -1  0]
            [ 0  0 -1]
            [ 0  0  0]
            [ 1  0  0]
            [ 0  0  0]
            [ 0  0  0],
         2: []}
        sage: X = SimplicialComplex([[0, 1]], immutable=True)
        sage: Hom(X,X)({0:1, 1:0}).associated_chain_complex_morphism()._matrix_dictionary
        {0: [0 1]
            [1 0],
         1: [-1]}

    [Python]

        >>> from sage.all import *
        >>> # needs sage.modules
        >>> g = {Integer(0):Integer(1), Integer(1):Integer(2), Integer(2):Integer(0)}
        >>> H(g).associated_chain_complex_morphism()._matrix_dictionary
        {0: [0 0 1]
            [1 0 0]
            [0 1 0]
            [0 0 0],
         1: [ 0 -1  0]
            [ 0  0 -1]
            [ 0  0  0]
            [ 1  0  0]
            [ 0  0  0]
            [ 0  0  0],
         2: []}
        >>> X = SimplicialComplex([[Integer(0), Integer(1)]], immutable=True)
        >>> Hom(X,X)({Integer(0):Integer(1), Integer(1):Integer(0)}).associated_chain_complex_morphism()._matrix_dictionary
        {0: [0 1]
            [1 0],
         1: [-1]}

  fiber_product(other, rename_vertices=True)

    Fiber product of `self` and `other`.

    Both morphisms should have the same codomain. The method returns a morphism of simplicial complexes, which is the morphism from the space of the fiber product to the codomain.

    EXAMPLES:

    Sage

        sage: S = SimplicialComplex([[0,1],[1,2]], immutable=True)
        sage: T = SimplicialComplex([[0,2],[1]], immutable=True)
        sage: U = SimplicialComplex([[0,1],[2]], immutable=True)
        sage: H = Hom(S,U)
        sage: G = Hom(T,U)
        sage: f = {0:0,1:1,2:0}
        sage: g = {0:0,1:1,2:1}
        sage: x = H(f)
        sage: y = G(g)
        sage: z = x.fiber_product(y)
        sage: z
        Simplicial complex morphism:
          From: Simplicial complex with 4 vertices and facets {...}
          To:   Simplicial complex with vertex set (0, 1, 2) and facets {(2,), (0, 1)}
          Defn: L0R0 |--> 0
                L1R1 |--> 1
                L1R2 |--> 1
                L2R0 |--> 0

    Python

        >>> from sage.all import *
        >>> S = SimplicialComplex([[Integer(0),Integer(1)],[Integer(1),Integer(2)]], immutable=True)
        >>> T = SimplicialComplex([[Integer(0),Integer(2)],[Integer(1)]], immutable=True)
        >>> U = SimplicialComplex([[Integer(0),Integer(1)],[Integer(2)]], immutable=True)
        >>> H = Hom(S,U)
        >>> G = Hom(T,U)
        >>> f = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(0)}
        >>> g = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(1)}
        >>> x = H(f)
        >>> y = G(g)
        >>> z = x.fiber_product(y)
        >>> z
        Simplicial complex morphism:
          From: Simplicial complex with 4 vertices and facets {...}
          To:   Simplicial complex with vertex set (0, 1, 2) and facets {(2,), (0, 1)}
          Defn: L0R0 |--> 0
                L1R1 |--> 1
                L1R2 |--> 1
                L2R0 |--> 0

  image()

    Compute the image simplicial complex of \(f\).

    EXAMPLES:

    Sage

        sage: S = SimplicialComplex([[0,1],[2,3]], immutable=True)
        sage: T = SimplicialComplex([[0,1]], immutable=True)
        sage: f = {0:0,1:1,2:0,3:1}
        sage: H = Hom(S,T)
        sage: x = H(f)
        sage: x.image()
        Simplicial complex with vertex set (0, 1) and facets {(0, 1)}

        sage: S = SimplicialComplex(immutable=True)
        sage: H = Hom(S,S)
        sage: i = H.identity()
        sage: i.image()
        Simplicial complex with vertex set () and facets {()}
        sage: i.is_surjective()
        True
        sage: S = SimplicialComplex([[0,1]], immutable=True)
        sage: T = SimplicialComplex([[0,1], [0,2]], immutable=True)
        sage: f = {0:0,1:1}
        sage: g = {0:0,1:1}
        sage: k = {0:0,1:2}
        sage: H = Hom(S,T)
        sage: x = H(f)
        sage: y = H(g)
        sage: z = H(k)
        sage: x == y
        True
        sage: x == z
        False
        sage: x.image()
        Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
        sage: y.image()
        Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
        sage: z.image()
        Simplicial complex with vertex set (0, 2) and facets {(0, 2)}

    Python

        >>> from sage.all import *
        >>> S = SimplicialComplex([[Integer(0),Integer(1)],[Integer(2),Integer(3)]], immutable=True)
        >>> T = SimplicialComplex([[Integer(0),Integer(1)]], immutable=True)
        >>> f = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(0),Integer(3):Integer(1)}
        >>> H = Hom(S,T)
        >>> x = H(f)
        >>> x.image()
        Simplicial complex with vertex set (0, 1) and facets {(0, 1)}

        >>> S = SimplicialComplex(immutable=True)
        >>> H = Hom(S,S)
        >>> i = H.identity()
        >>> i.image()
        Simplicial complex with vertex set () and facets {()}
        >>> i.is_surjective()
        True
        >>> S = SimplicialComplex([[Integer(0),Integer(1)]], immutable=True)
        >>> T = SimplicialComplex([[Integer(0),Integer(1)], [Integer(0),Integer(2)]], immutable=True)
        >>> f = {Integer(0):Integer(0),Integer(1):Integer(1)}
        >>> g = {Integer(0):Integer(0),Integer(1):Integer(1)}
        >>> k = {Integer(0):Integer(0),Integer(1):Integer(2)}
        >>> H = Hom(S,T)
        >>> x = H(f)
        >>> y = H(g)
        >>> z = H(k)
        >>> x == y
        True
        >>> x == z
        False
        >>> x.image()
        Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
        >>> y.image()
        Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
        >>> z.image()
        Simplicial complex with vertex set (0, 2) and facets {(0, 2)}

  induced_homology_morphism(base_ring=None, cohomology=False)

    Return the map in (co)homology induced by this map.

    INPUT:

    - `base_ring` – must be a field (default: `QQ`)

    - `cohomology` – boolean (default: `False`); if `True`, the map induced in cohomology rather than homology

    EXAMPLES:

    Sage

        sage: S = simplicial_complexes.Sphere(1)
        sage: T = S.product(S, immutable=True)
        sage: H = Hom(S,T)
        sage: diag = H.diagonal_morphism()
        sage: h = diag.induced_homology_morphism(QQ); h                             # needs sage.modules
        Graded vector space morphism:
          From: Homology module of
                Minimal triangulation of the 1-sphere over Rational Field
          To:   Homology module of
                Simplicial complex with 9 vertices and 18 facets over Rational Field
          Defn: induced by:
            Simplicial complex morphism:
              From: Minimal triangulation of the 1-sphere
              To:   Simplicial complex with 9 vertices and 18 facets
              Defn: 0 |--> L0R0
                    1 |--> L1R1
                    2 |--> L2R2

    Python

        >>> from sage.all import *
        >>> S = simplicial_complexes.Sphere(Integer(1))
        >>> T = S.product(S, immutable=True)
        >>> H = Hom(S,T)
        >>> diag = H.diagonal_morphism()
        >>> h = diag.induced_homology_morphism(QQ); h                             # needs sage.modules
        Graded vector space morphism:
          From: Homology module of
                Minimal triangulation of the 1-sphere over Rational Field
          To:   Homology module of
                Simplicial complex with 9 vertices and 18 facets over Rational Field
          Defn: induced by:
            Simplicial complex morphism:
              From: Minimal triangulation of the 1-sphere
              To:   Simplicial complex with 9 vertices and 18 facets
              Defn: 0 |--> L0R0
                    1 |--> L1R1
                    2 |--> L2R2

    We can view the matrix form for the homomorphism:

    Sage

        sage: h.to_matrix(0)  # in degree 0                                         # needs sage.modules
        [1]
        sage: h.to_matrix(1)  # in degree 1                                         # needs sage.modules
        [1]
        [1]
        sage: h.to_matrix()   # the entire homomorphism                             # needs sage.modules
        [1|0]
        [-+-]
        [0|1]
        [0|1]
        [-+-]
        [0|0]

    [Python]

        >>> from sage.all import *
        >>> h.to_matrix(Integer(0))  # in degree 0                                         # needs sage.modules
        [1]
        >>> h.to_matrix(Integer(1))  # in degree 1                                         # needs sage.modules
        [1]
        [1]
        >>> h.to_matrix()   # the entire homomorphism                             # needs sage.modules
        [1|0]
        [-+-]
        [0|1]
        [0|1]
        [-+-]
        [0|0]

    The map on cohomology should be dual to the map on homology:

    Sage

        sage: coh = diag.induced_homology_morphism(QQ, cohomology=True)             # needs sage.modules
        sage: coh.to_matrix(1)                                                      # needs sage.modules
        [1 1]
        sage: h.to_matrix() == coh.to_matrix().transpose()                          # needs sage.modules
        True

    Python

        >>> from sage.all import *
        >>> coh = diag.induced_homology_morphism(QQ, cohomology=True)             # needs sage.modules
        >>> coh.to_matrix(Integer(1))                                                      # needs sage.modules
        [1 1]
        >>> h.to_matrix() == coh.to_matrix().transpose()                          # needs sage.modules
        True

    We can evaluate the map on (co)homology classes:

    Sage

        sage: x,y = list(T.cohomology_ring(QQ).basis(1))                            # needs sage.modules
        sage: coh(x)                                                                # needs sage.modules
        h^{1,0}
        sage: coh(2*x + 3*y)                                                        # needs sage.modules
        5*h^{1,0}

    [Python]

        >>> from sage.all import *
        >>> x,y = list(T.cohomology_ring(QQ).basis(Integer(1)))                            # needs sage.modules
        >>> coh(x)                                                                # needs sage.modules
        h^{1,0}
        >>> coh(Integer(2)*x + Integer(3)*y)                                                        # needs sage.modules
        5*h^{1,0}

    Note that the complexes must be immutable for this to work. Many, but not all, complexes are immutable when constructed:

    Sage

        sage: S.is_immutable()
        True
        sage: S.barycentric_subdivision().is_immutable()
        False
        sage: S2 = S.suspension()
        sage: S2.is_immutable()
        False
        sage: h = Hom(S, S2)({0: 0, 1: 1, 2: 2}).induced_homology_morphism()        # needs sage.modules
        Traceback (most recent call last):
        ...
        ValueError: the domain and codomain complexes must be immutable
        sage: S2.set_immutable(); S2.is_immutable()
        True
        sage: h = Hom(S, S2)({0: 0, 1: 1, 2: 2}).induced_homology_morphism()        # needs sage.modules

    Python

        >>> from sage.all import *
        >>> S.is_immutable()
        True
        >>> S.barycentric_subdivision().is_immutable()
        False
        >>> S2 = S.suspension()
        >>> S2.is_immutable()
        False
        >>> h = Hom(S, S2)({Integer(0): Integer(0), Integer(1): Integer(1), Integer(2): Integer(2)}).induced_homology_morphism()        # needs sage.modules
        Traceback (most recent call last):
        ...
        ValueError: the domain and codomain complexes must be immutable
        >>> S2.set_immutable(); S2.is_immutable()
        True
        >>> h = Hom(S, S2)({Integer(0): Integer(0), Integer(1): Integer(1), Integer(2): Integer(2)}).induced_homology_morphism()        # needs sage.modules

  is_contiguous_to(other)

    Return `True` if `self` is contiguous to `other`.

    Two morphisms \(f_0, f_1: K \to L\) are contiguous if for any simplex \(\sigma \in K\), the union \(f_0(\sigma) \cup f_1(\sigma)\) is a simplex in \(L\). This is not a transitive relation, but it induces an equivalence relation on simplicial maps: \(f\) is equivalent to \(g\) if there is a finite sequence \(f_0 = f\), \(f_1\), …, \(f_n = g\) such that \(f_i\) and \(f_{i+1}\) are contiguous for each \(i\).

    This is related to maps being homotopic: if they are contiguous, then they induce homotopic maps on the geometric realizations. Given two homotopic maps on the geometric realizations, then after barycentrically subdividing \(n\) times for some \(n\), the maps have simplicial approximations which are in the same contiguity class. (This last fact is only true if the domain is a finite simplicial complex, by the way.)

    See Section 3.5 of Spanier [Spa1966] for details.

    ALGORITHM:

    It is enough to check when \(\sigma\) ranges over the facets.

    INPUT:

    - `other` – a simplicial complex morphism with the same domain and codomain as `self`

    EXAMPLES:

    Sage

        sage: K = simplicial_complexes.Simplex(1)
        sage: L = simplicial_complexes.Sphere(1)
        sage: H = Hom(K, L)
        sage: f = H({0: 0, 1: 1})
        sage: g = H({0: 0, 1: 0})
        sage: f.is_contiguous_to(f)
        True
        sage: f.is_contiguous_to(g)
        True
        sage: h = H({0: 1, 1: 2})
        sage: f.is_contiguous_to(h)
        False

    Python

        >>> from sage.all import *
        >>> K = simplicial_complexes.Simplex(Integer(1))
        >>> L = simplicial_complexes.Sphere(Integer(1))
        >>> H = Hom(K, L)
        >>> f = H({Integer(0): Integer(0), Integer(1): Integer(1)})
        >>> g = H({Integer(0): Integer(0), Integer(1): Integer(0)})
        >>> f.is_contiguous_to(f)
        True
        >>> f.is_contiguous_to(g)
        True
        >>> h = H({Integer(0): Integer(1), Integer(1): Integer(2)})
        >>> f.is_contiguous_to(h)
        False

  is_identity()

    If `self` is an identity morphism, returns `True`. Otherwise, `False`.

    EXAMPLES:

    Sage

        sage: T = simplicial_complexes.Sphere(1)
        sage: G = Hom(T,T)
        sage: T
        Minimal triangulation of the 1-sphere
        sage: j = G({0:0,1:1,2:2})
        sage: j.is_identity()
        True

        sage: S = simplicial_complexes.Sphere(2)
        sage: T = simplicial_complexes.Sphere(3)
        sage: H = Hom(S,T)
        sage: f = {0:0,1:1,2:2,3:3}
        sage: x = H(f)
        sage: x
        Simplicial complex morphism:
          From: Minimal triangulation of the 2-sphere
          To:   Minimal triangulation of the 3-sphere
          Defn: 0 |--> 0
                1 |--> 1
                2 |--> 2
                3 |--> 3
        sage: x.is_identity()
        False

    Python

        >>> from sage.all import *
        >>> T = simplicial_complexes.Sphere(Integer(1))
        >>> G = Hom(T,T)
        >>> T
        Minimal triangulation of the 1-sphere
        >>> j = G({Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(2)})
        >>> j.is_identity()
        True

        >>> S = simplicial_complexes.Sphere(Integer(2))
        >>> T = simplicial_complexes.Sphere(Integer(3))
        >>> H = Hom(S,T)
        >>> f = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(2),Integer(3):Integer(3)}
        >>> x = H(f)
        >>> x
        Simplicial complex morphism:
          From: Minimal triangulation of the 2-sphere
          To:   Minimal triangulation of the 3-sphere
          Defn: 0 |--> 0
                1 |--> 1
                2 |--> 2
                3 |--> 3
        >>> x.is_identity()
        False

  is_injective()

    Return `True` if and only if `self` is injective.

    EXAMPLES:

    Sage

        sage: S = simplicial_complexes.Sphere(1)
        sage: T = simplicial_complexes.Sphere(2)
        sage: U = simplicial_complexes.Sphere(3)
        sage: H = Hom(T,S)
        sage: G = Hom(T,U)
        sage: f = {0:0,1:1,2:0,3:1}
        sage: x = H(f)
        sage: g = {0:0,1:1,2:2,3:3}
        sage: y = G(g)
        sage: x.is_injective()
        False
        sage: y.is_injective()
        True

    Python

        >>> from sage.all import *
        >>> S = simplicial_complexes.Sphere(Integer(1))
        >>> T = simplicial_complexes.Sphere(Integer(2))
        >>> U = simplicial_complexes.Sphere(Integer(3))
        >>> H = Hom(T,S)
        >>> G = Hom(T,U)
        >>> f = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(0),Integer(3):Integer(1)}
        >>> x = H(f)
        >>> g = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(2),Integer(3):Integer(3)}
        >>> y = G(g)
        >>> x.is_injective()
        False
        >>> y.is_injective()
        True

  is_surjective()

    Return `True` if and only if `self` is surjective.

    EXAMPLES:

    Sage

        sage: S = SimplicialComplex([(0,1,2)], immutable=True)
        sage: S
        Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}
        sage: T = SimplicialComplex([(0,1)], immutable=True)
        sage: T
        Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
        sage: H = Hom(S,T)
        sage: x = H({0:0,1:1,2:1})
        sage: x.is_surjective()
        True

        sage: S = SimplicialComplex([[0,1],[2,3]], immutable=True)
        sage: T = SimplicialComplex([[0,1]], immutable=True)
        sage: f = {0:0,1:1,2:0,3:1}
        sage: H = Hom(S,T)
        sage: x = H(f)
        sage: x.is_surjective()
        True

    Python

        >>> from sage.all import *
        >>> S = SimplicialComplex([(Integer(0),Integer(1),Integer(2))], immutable=True)
        >>> S
        Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}
        >>> T = SimplicialComplex([(Integer(0),Integer(1))], immutable=True)
        >>> T
        Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
        >>> H = Hom(S,T)
        >>> x = H({Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(1)})
        >>> x.is_surjective()
        True

        >>> S = SimplicialComplex([[Integer(0),Integer(1)],[Integer(2),Integer(3)]], immutable=True)
        >>> T = SimplicialComplex([[Integer(0),Integer(1)]], immutable=True)
        >>> f = {Integer(0):Integer(0),Integer(1):Integer(1),Integer(2):Integer(0),Integer(3):Integer(1)}
        >>> H = Hom(S,T)
        >>> x = H(f)
        >>> x.is_surjective()
        True

  mapping_torus()

    The mapping torus of a simplicial complex endomorphism.

    The mapping torus is the simplicial complex formed by taking the product of the domain of `self` with a \(4\) point interval \([I_0, I_1, I_2, I_3]\) and identifying vertices of the form \((I_0, v)\) with \((I_3, w)\) where \(w\) is the image of \(v\) under the given morphism.

    See Wikipedia article Mapping torus

    EXAMPLES:

    Sage

        sage: C = simplicial_complexes.Sphere(1)            # Circle
        sage: T = Hom(C,C).identity().mapping_torus() ; T   # Torus
        Simplicial complex with 9 vertices and 18 facets
        sage: T.homology() == simplicial_complexes.Torus().homology()               # needs sage.modules
        True

        sage: f = Hom(C,C)({0:0, 1:2, 2:1})
        sage: K = f.mapping_torus(); K                      # Klein Bottle
        Simplicial complex with 9 vertices and 18 facets
        sage: K.homology() == simplicial_complexes.KleinBottle().homology()         # needs sage.modules
        True

    Python

        >>> from sage.all import *
        >>> C = simplicial_complexes.Sphere(Integer(1))            # Circle
        >>> T = Hom(C,C).identity().mapping_torus() ; T   # Torus
        Simplicial complex with 9 vertices and 18 facets
        >>> T.homology() == simplicial_complexes.Torus().homology()               # needs sage.modules
        True

        >>> f = Hom(C,C)({Integer(0):Integer(0), Integer(1):Integer(2), Integer(2):Integer(1)})
        >>> K = f.mapping_torus(); K                      # Klein Bottle
        Simplicial complex with 9 vertices and 18 facets
        >>> K.homology() == simplicial_complexes.KleinBottle().homology()         # needs sage.modules
        True