# Morphisms of chain 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 chain complexes. The input is a dictionary whose keys are in the grading group of the chain complex and whose values are matrix morphisms.

EXAMPLES:

sage: # needs sage.graphs
sage: S = simplicial_complexes.Sphere(1); S
Minimal triangulation of the 1-sphere
sage: C = S.chain_complex()
sage: C.differential()
{0: [], 1: [-1 -1  0]
[ 1  0 -1]
[ 0  1  1], 2: []}
sage: f = {0: zero_matrix(ZZ,3,3), 1: zero_matrix(ZZ,3,3)}
sage: G = Hom(C, C)
sage: x = G(f); x
Chain complex endomorphism of
Chain complex with at most 2 nonzero terms over Integer Ring
sage: x._matrix_dictionary
{0: [0 0 0]
[0 0 0]
[0 0 0],
1: [0 0 0]
[0 0 0]
[0 0 0]}

>>> from sage.all import *
>>> # needs sage.graphs
>>> S = simplicial_complexes.Sphere(Integer(1)); S
Minimal triangulation of the 1-sphere
>>> C = S.chain_complex()
>>> C.differential()
{0: [], 1: [-1 -1  0]
[ 1  0 -1]
[ 0  1  1], 2: []}
>>> f = {Integer(0): zero_matrix(ZZ,Integer(3),Integer(3)), Integer(1): zero_matrix(ZZ,Integer(3),Integer(3))}
>>> G = Hom(C, C)
>>> x = G(f); x
Chain complex endomorphism of
Chain complex with at most 2 nonzero terms over Integer Ring
>>> x._matrix_dictionary
{0: [0 0 0]
[0 0 0]
[0 0 0],
1: [0 0 0]
[0 0 0]
[0 0 0]}

class sage.homology.chain_complex_morphism.ChainComplexMorphism(matrices, C, D, check=True)[source]#

Bases: Morphism

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

dual()[source]#

The dual chain map to this one.

That is, the map from the dual of the codomain of this one to the dual of its domain, represented in each degree by the transpose of the corresponding matrix.

EXAMPLES:

sage: # needs sage.graphs
sage: X = simplicial_complexes.Simplex(1)
sage: Y = simplicial_complexes.Simplex(0)
sage: g = Hom(X,Y)({0:0, 1:0})
sage: f = g.associated_chain_complex_morphism()
sage: f.in_degree(0)
[1 1]
sage: f.dual()
Chain complex morphism:
From: Chain complex with at most 1 nonzero terms over Integer Ring
To: Chain complex with at most 2 nonzero terms over Integer Ring
sage: f.dual().in_degree(0)
[1]
[1]
sage: ascii_art(f.domain())
[-1]
[ 1]
0 <-- C_0 <----- C_1 <-- 0
sage: ascii_art(f.dual().codomain())
[-1  1]
0 <-- C_1 <-------- C_0 <-- 0

>>> from sage.all import *
>>> # needs sage.graphs
>>> X = simplicial_complexes.Simplex(Integer(1))
>>> Y = simplicial_complexes.Simplex(Integer(0))
>>> g = Hom(X,Y)({Integer(0):Integer(0), Integer(1):Integer(0)})
>>> f = g.associated_chain_complex_morphism()
>>> f.in_degree(Integer(0))
[1 1]
>>> f.dual()
Chain complex morphism:
From: Chain complex with at most 1 nonzero terms over Integer Ring
To: Chain complex with at most 2 nonzero terms over Integer Ring
>>> f.dual().in_degree(Integer(0))
[1]
[1]
>>> ascii_art(f.domain())
[-1]
[ 1]
0 <-- C_0 <----- C_1 <-- 0
>>> ascii_art(f.dual().codomain())
[-1  1]
0 <-- C_1 <-------- C_0 <-- 0

in_degree(n)[source]#

The matrix representing this morphism in degree $$n$$.

INPUT:

• n – degree

EXAMPLES:

sage: C = ChainComplex({0: identity_matrix(ZZ, 1)})
sage: D = ChainComplex({0: zero_matrix(ZZ, 1), 1: zero_matrix(ZZ, 1)})
sage: f = Hom(C,D)({0: identity_matrix(ZZ, 1), 1: zero_matrix(ZZ, 1)})
sage: f.in_degree(0)
[1]

>>> from sage.all import *
>>> C = ChainComplex({Integer(0): identity_matrix(ZZ, Integer(1))})
>>> D = ChainComplex({Integer(0): zero_matrix(ZZ, Integer(1)), Integer(1): zero_matrix(ZZ, Integer(1))})
>>> f = Hom(C,D)({Integer(0): identity_matrix(ZZ, Integer(1)), Integer(1): zero_matrix(ZZ, Integer(1))})
>>> f.in_degree(Integer(0))
[1]


Note that if the matrix is not specified in the definition of the map, it is assumed to be zero:

sage: f.in_degree(2)
[]
sage: f.in_degree(2).nrows(), f.in_degree(2).ncols()
(1, 0)
sage: C.free_module(2)
Ambient free module of rank 0 over the principal ideal domain Integer Ring
sage: D.free_module(2)
Ambient free module of rank 1 over the principal ideal domain Integer Ring

>>> from sage.all import *
>>> f.in_degree(Integer(2))
[]
>>> f.in_degree(Integer(2)).nrows(), f.in_degree(Integer(2)).ncols()
(1, 0)
>>> C.free_module(Integer(2))
Ambient free module of rank 0 over the principal ideal domain Integer Ring
>>> D.free_module(Integer(2))
Ambient free module of rank 1 over the principal ideal domain Integer Ring

is_identity()[source]#

Return True if this is the identity map.

EXAMPLES:

sage: # needs sage.graphs
sage: S = SimplicialComplex(is_mutable=False)
sage: H = Hom(S,S)
sage: i = H.identity()
sage: x = i.associated_chain_complex_morphism()
sage: x.is_identity()
True

>>> from sage.all import *
>>> # needs sage.graphs
>>> S = SimplicialComplex(is_mutable=False)
>>> H = Hom(S,S)
>>> i = H.identity()
>>> x = i.associated_chain_complex_morphism()
>>> x.is_identity()
True

is_injective()[source]#

Return True if this map is injective.

EXAMPLES:

sage: # needs sage.graphs
sage: S1 = simplicial_complexes.Sphere(1)
sage: H = Hom(S1, S1)
sage: flip = H({0:0, 1:2, 2:1})
sage: flip.associated_chain_complex_morphism().is_injective()
True

sage: # needs sage.graphs
sage: pt = simplicial_complexes.Simplex(0)
sage: inclusion = Hom(pt, S1)({0:2})
sage: inclusion.associated_chain_complex_morphism().is_injective()
True
sage: inclusion.associated_chain_complex_morphism(cochain=True).is_injective()
False

>>> from sage.all import *
>>> # needs sage.graphs
>>> S1 = simplicial_complexes.Sphere(Integer(1))
>>> H = Hom(S1, S1)
>>> flip = H({Integer(0):Integer(0), Integer(1):Integer(2), Integer(2):Integer(1)})
>>> flip.associated_chain_complex_morphism().is_injective()
True

>>> # needs sage.graphs
>>> pt = simplicial_complexes.Simplex(Integer(0))
>>> inclusion = Hom(pt, S1)({Integer(0):Integer(2)})
>>> inclusion.associated_chain_complex_morphism().is_injective()
True
>>> inclusion.associated_chain_complex_morphism(cochain=True).is_injective()
False

is_surjective()[source]#

Return True if this map is surjective.

EXAMPLES:

sage: # needs sage.graphs
sage: S1 = simplicial_complexes.Sphere(1)
sage: H = Hom(S1, S1)
sage: flip = H({0:0, 1:2, 2:1})
sage: flip.associated_chain_complex_morphism().is_surjective()
True

sage: # needs sage.graphs
sage: pt = simplicial_complexes.Simplex(0)
sage: inclusion = Hom(pt, S1)({0:2})
sage: inclusion.associated_chain_complex_morphism().is_surjective()
False
sage: inclusion.associated_chain_complex_morphism(cochain=True).is_surjective()
True

>>> from sage.all import *
>>> # needs sage.graphs
>>> S1 = simplicial_complexes.Sphere(Integer(1))
>>> H = Hom(S1, S1)
>>> flip = H({Integer(0):Integer(0), Integer(1):Integer(2), Integer(2):Integer(1)})
>>> flip.associated_chain_complex_morphism().is_surjective()
True

>>> # needs sage.graphs
>>> pt = simplicial_complexes.Simplex(Integer(0))
>>> inclusion = Hom(pt, S1)({Integer(0):Integer(2)})
>>> inclusion.associated_chain_complex_morphism().is_surjective()
False
>>> inclusion.associated_chain_complex_morphism(cochain=True).is_surjective()
True

to_matrix(deg=None)[source]#

The matrix representing this chain map.

If the degree deg is specified, return the matrix in that degree; otherwise, return the (block) matrix for the whole chain map.

INPUT:

• deg – (default: None) the degree

EXAMPLES:

sage: C = ChainComplex({0: identity_matrix(ZZ, 1)})
sage: D = ChainComplex({0: zero_matrix(ZZ, 1), 1: zero_matrix(ZZ, 1)})
sage: f = Hom(C,D)({0: identity_matrix(ZZ, 1), 1: zero_matrix(ZZ, 1)})
sage: f.to_matrix(0)
[1]
sage: f.to_matrix()
[1|0|]
[-+-+]
[0|0|]
[-+-+]
[0|0|]

>>> from sage.all import *
>>> C = ChainComplex({Integer(0): identity_matrix(ZZ, Integer(1))})
>>> D = ChainComplex({Integer(0): zero_matrix(ZZ, Integer(1)), Integer(1): zero_matrix(ZZ, Integer(1))})
>>> f = Hom(C,D)({Integer(0): identity_matrix(ZZ, Integer(1)), Integer(1): zero_matrix(ZZ, Integer(1))})
>>> f.to_matrix(Integer(0))
[1]
>>> f.to_matrix()
[1|0|]
[-+-+]
[0|0|]
[-+-+]
[0|0|]

sage.homology.chain_complex_morphism.is_ChainComplexMorphism(x)[source]#

Return True if and only if x is a chain complex morphism.

EXAMPLES:

sage: # needs sage.graphs
sage: from sage.homology.chain_complex_morphism import is_ChainComplexMorphism
sage: S = simplicial_complexes.Sphere(14)
sage: H = Hom(S,S)
sage: i = H.identity()                  # long time (8s on sage.math, 2011)
sage: S = simplicial_complexes.Sphere(6)
sage: H = Hom(S,S)
sage: i = H.identity()
sage: x = i.associated_chain_complex_morphism()
sage: x # indirect doctest
Chain complex morphism:
From: Chain complex with at most 7 nonzero terms over Integer Ring
To: Chain complex with at most 7 nonzero terms over Integer Ring
sage: is_ChainComplexMorphism(x)
doctest:warning...
DeprecationWarning: The function is_ChainComplexMorphism is deprecated;
See https://github.com/sagemath/sage/issues/38103 for details.
True

>>> from sage.all import *
>>> # needs sage.graphs
>>> from sage.homology.chain_complex_morphism import is_ChainComplexMorphism
>>> S = simplicial_complexes.Sphere(Integer(14))
>>> H = Hom(S,S)
>>> i = H.identity()                  # long time (8s on sage.math, 2011)
>>> S = simplicial_complexes.Sphere(Integer(6))
>>> H = Hom(S,S)
>>> i = H.identity()
>>> x = i.associated_chain_complex_morphism()
>>> x # indirect doctest
Chain complex morphism:
From: Chain complex with at most 7 nonzero terms over Integer Ring
To: Chain complex with at most 7 nonzero terms over Integer Ring
>>> is_ChainComplexMorphism(x)
doctest:warning...
DeprecationWarning: The function is_ChainComplexMorphism is deprecated;