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: S = SimplicialComplex([[0,2],[1,5],[3,4]], is_mutable=False)
sage: H = Hom(S,S.product(S, is_mutable=False))
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]], is_mutable=False)
sage: T = SimplicialComplex([[0,2],[1,3]], is_mutable=False)
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, is_mutable=False)
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]
- 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: # 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
Some simplicial maps which reverse the orientation of a few simplices:
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]], is_mutable=False) sage: Hom(X,X)({0:1, 1:0}).associated_chain_complex_morphism()._matrix_dictionary {0: [0 1] [1 0], 1: [-1]}
- fiber_product(other, rename_vertices=True)#
Fiber product of
self
andother
. 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: S = SimplicialComplex([[0,1],[1,2]], is_mutable=False) sage: T = SimplicialComplex([[0,2],[1]], is_mutable=False) sage: U = SimplicialComplex([[0,1],[2]], is_mutable=False) 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
- image()#
Computes the image simplicial complex of \(f\).
EXAMPLES:
sage: S = SimplicialComplex([[0,1],[2,3]], is_mutable=False) sage: T = SimplicialComplex([[0,1]], is_mutable=False) 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(is_mutable=False) 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]], is_mutable=False) sage: T = SimplicialComplex([[0,1], [0,2]], is_mutable=False) 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)}
- induced_homology_morphism(base_ring=None, cohomology=False)#
The map in (co)homology induced by this map
INPUT:
base_ring
– must be a field (optional, defaultQQ
)cohomology
– boolean (optional, defaultFalse
). IfTrue
, the map induced in cohomology rather than homology.
EXAMPLES:
sage: S = simplicial_complexes.Sphere(1) sage: T = S.product(S, is_mutable=False) 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
We can view the matrix form for the homomorphism:
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]
The map on cohomology should be dual to the map on homology:
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
We can evaluate the map on (co)homology classes:
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}
Note that the complexes must be immutable for this to work. Many, but not all, complexes are immutable when constructed:
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
- is_contiguous_to(other)#
Return
True
ifself
is contiguous toother
.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 asself
EXAMPLES:
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
- is_identity()#
If
self
is an identity morphism, returnsTrue
. Otherwise,False
.EXAMPLES:
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
- is_injective()#
Return
True
if and only ifself
is injective.EXAMPLES:
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
- is_surjective()#
Return
True
if and only ifself
is surjective.EXAMPLES:
sage: S = SimplicialComplex([(0,1,2)], is_mutable=False) sage: S Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)} sage: T = SimplicialComplex([(0,1)], is_mutable=False) 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]], is_mutable=False) sage: T = SimplicialComplex([[0,1]], is_mutable=False) sage: f = {0:0,1:1,2:0,3:1} sage: H = Hom(S,T) sage: x = H(f) sage: 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: 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
- sage.topology.simplicial_complex_morphism.is_SimplicialComplexMorphism(x)#
Return
True
if and only ifx
is a morphism of simplicial complexes.EXAMPLES:
sage: from sage.topology.simplicial_complex_morphism import is_SimplicialComplexMorphism sage: S = SimplicialComplex([[0,1],[3,4]], is_mutable=False) sage: H = Hom(S,S) sage: f = {0:0,1:1,3:3,4:4} sage: x = H(f) sage: is_SimplicialComplexMorphism(x) True