Chains and cochains¶
This module implements formal linear combinations of cells of a given
cell complex (Chains) and their dual (Cochains). It
is closely related to the sage.topology.chain_complex
module. The main differences are that chains and cochains here are of
homogeneous dimension only, and that they reference their cell
complex.
- class sage.homology.chains.CellComplexReference(cell_complex, degree, cells=None)¶
Bases:
objectAuxiliary base class for chains and cochains
INPUT:
cell_complex– The cell complex to referencedegree– integer. The degree of the (co)chainscells– tuple of cells orNone. Does not necessarily have to be the cells in the given degree, for computational purposes this could also be any collection that is in one-to-one correspondence with the cells. IfNone, the cells of the complex in the given degree are used.
EXAMPLES:
sage: X = simplicial_complexes.Simplex(2) sage: from sage.homology.chains import CellComplexReference sage: c = CellComplexReference(X, 1) sage: c.cell_complex() is X True
- cell_complex()¶
Return the underlying cell complex
OUTPUT:
A cell complex.
EXAMPLES:
sage: X = simplicial_complexes.Simplex(2) sage: X.n_chains(1).cell_complex() is X True
- degree()¶
Return the dimension of the cells
OUTPUT:
Integer. The dimension of the cells.
EXAMPLES:
sage: X = simplicial_complexes.Simplex(2) sage: X.n_chains(1).degree() 1
- class sage.homology.chains.Chains(cell_complex, degree, cells=None, base_ring=None)¶
Bases:
sage.homology.chains.CellComplexReference,sage.combinat.free_module.CombinatorialFreeModuleClass for the free module of chains in a given degree.
INPUT:
n_cells– tuple of \(n\)-cells, which thus forms a basis for this modulebase_ring– optional (default \(\ZZ\))
One difference between chains and cochains is notation. In a simplicial complex, for example, a simplex
(0,1,2)is written as “(0,1,2)” in the group of chains but as “\chi_(0,1,2)” in the group of cochains.Also, since the free modules of chains and cochains are dual, there is a pairing \(\langle c, z \rangle\), sending a cochain \(c\) and a chain \(z\) to a scalar.
EXAMPLES:
sage: S2 = simplicial_complexes.Sphere(2) sage: C_2 = S2.n_chains(1) sage: C_2_co = S2.n_chains(1, cochains=True) sage: x = C_2.basis()[Simplex((0,2))] sage: y = C_2.basis()[Simplex((1,3))] sage: z = x+2*y sage: a = C_2_co.basis()[Simplex((1,3))] sage: b = C_2_co.basis()[Simplex((0,3))] sage: c = 3*a-2*b sage: z (0, 2) + 2*(1, 3) sage: c -2*\chi_(0, 3) + 3*\chi_(1, 3) sage: c.eval(z) 6
- class Element¶
Bases:
sage.modules.with_basis.indexed_element.IndexedFreeModuleElement- boundary()¶
Return the boundary of the chain
OUTPUT:
The boundary as a chain in one degree lower.
EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C1 = square.n_chains(1, QQ) sage: from sage.topology.cubical_complex import Cube sage: chain = C1(Cube([[1, 1], [0, 1]])) - 2 * C1(Cube([[0, 1], [0, 0]])) sage: chain -2*[0,1] x [0,0] + [1,1] x [0,1] sage: chain.boundary() 2*[0,0] x [0,0] - 3*[1,1] x [0,0] + [1,1] x [1,1]
- is_boundary()¶
Test whether the chain is a boundary
OUTPUT:
Boolean. Whether the chain is the
boundary()of a chain in one degree higher.EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C1 = square.n_chains(1, QQ) sage: from sage.topology.cubical_complex import Cube sage: chain = C1(Cube([[1, 1], [0, 1]])) - C1(Cube([[0, 1], [0, 0]])) sage: chain.is_boundary() False
- is_cycle()¶
Test whether the chain is a cycle
OUTPUT:
Boolean. Whether the
boundary()vanishes.EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C1 = square.n_chains(1, QQ) sage: from sage.topology.cubical_complex import Cube sage: chain = C1(Cube([[1, 1], [0, 1]])) - C1(Cube([[0, 1], [0, 0]])) sage: chain.is_cycle() False
- to_complex()¶
Return the corresponding chain complex element
OUTPUT:
An element of the chain complex, see
sage.homology.chain_complex.EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C1 = square.n_chains(1, QQ) sage: from sage.topology.cubical_complex import Cube sage: chain = C1(Cube([[1, 1], [0, 1]])) sage: chain.to_complex() Chain(1:(0, 0, 0, 1)) sage: ascii_art(_) d_0 [0] d_1 [0] d_2 d_3 0 <---- [0] <---- [0] <---- [0] <---- 0 [0] [0] [0] [1]
- chain_complex()¶
Return the chain complex.
OUTPUT:
Chain complex, see
sage.homology.chain_complex.EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: CC = square.n_chains(2, QQ).chain_complex(); CC Chain complex with at most 3 nonzero terms over Rational Field sage: ascii_art(CC) [-1 -1 0 0] [-1] [ 1 0 -1 0] [ 1] [ 0 1 0 -1] [-1] [ 0 0 1 1] [ 1] 0 <-- C_0 <-------------- C_1 <----- C_2 <-- 0
- dual()¶
Return the cochains.
OUTPUT:
The cochains of the same cells with the same base ring.
EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: chains = square.n_chains(1, ZZ); chains Free module generated by {[0,0] x [0,1], [0,1] x [0,0], [0,1] x [1,1], [1,1] x [0,1]} over Integer Ring sage: chains.dual() Free module generated by {[0,0] x [0,1], [0,1] x [0,0], [0,1] x [1,1], [1,1] x [0,1]} over Integer Ring sage: type(chains) <class 'sage.homology.chains.Chains_with_category'> sage: type(chains.dual()) <class 'sage.homology.chains.Cochains_with_category'>
- class sage.homology.chains.Cochains(cell_complex, degree, cells=None, base_ring=None)¶
Bases:
sage.homology.chains.CellComplexReference,sage.combinat.free_module.CombinatorialFreeModuleClass for the free module of cochains in a given degree.
INPUT:
n_cells– tuple of \(n\)-cells, which thus forms a basis for this modulebase_ring– optional (default \(\ZZ\))
One difference between chains and cochains is notation. In a simplicial complex, for example, a simplex
(0,1,2)is written as “(0,1,2)” in the group of chains but as “\chi_(0,1,2)” in the group of cochains.Also, since the free modules of chains and cochains are dual, there is a pairing \(\langle c, z \rangle\), sending a cochain \(c\) and a chain \(z\) to a scalar.
EXAMPLES:
sage: S2 = simplicial_complexes.Sphere(2) sage: C_2 = S2.n_chains(1) sage: C_2_co = S2.n_chains(1, cochains=True) sage: x = C_2.basis()[Simplex((0,2))] sage: y = C_2.basis()[Simplex((1,3))] sage: z = x+2*y sage: a = C_2_co.basis()[Simplex((1,3))] sage: b = C_2_co.basis()[Simplex((0,3))] sage: c = 3*a-2*b sage: z (0, 2) + 2*(1, 3) sage: c -2*\chi_(0, 3) + 3*\chi_(1, 3) sage: c.eval(z) 6
- class Element¶
Bases:
sage.modules.with_basis.indexed_element.IndexedFreeModuleElement- coboundary()¶
Return the coboundary of this cochain
OUTPUT:
The coboundary as a cochain in one degree higher.
EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C1 = square.n_chains(1, QQ, cochains=True) sage: from sage.topology.cubical_complex import Cube sage: cochain = C1(Cube([[1, 1], [0, 1]])) - 2 * C1(Cube([[0, 1], [0, 0]])) sage: cochain -2*\chi_[0,1] x [0,0] + \chi_[1,1] x [0,1] sage: cochain.coboundary() -\chi_[0,1] x [0,1]
- cup_product(cochain)¶
Return the cup product with another cochain.
INPUT:
cochain– cochain over the same cell complex
EXAMPLES:
sage: T2 = simplicial_complexes.Torus() sage: C1 = T2.n_chains(1, base_ring=ZZ, cochains=True) sage: def l(i, j): ....: return C1(Simplex([i, j])) sage: l1 = l(1, 3) + l(1, 4) + l(1, 6) + l(2, 4) - l(4, 5) + l(5, 6) sage: l2 = l(1, 6) - l(2, 3) - l(2, 5) + l(3, 6) - l(4, 5) + l(5, 6)
The two one-cocycles are cohomology generators:
sage: l1.is_cocycle(), l1.is_coboundary() (True, False) sage: l2.is_cocycle(), l2.is_coboundary() (True, False)
Their cup product is a two-cocycle that is again non-trivial in cohomology:
sage: l12 = l1.cup_product(l2) sage: l12 \chi_(1, 3, 6) - \chi_(2, 4, 5) - \chi_(4, 5, 6) sage: l1.parent().degree(), l2.parent().degree(), l12.parent().degree() (1, 1, 2) sage: l12.is_cocycle(), l12.is_coboundary() (True, False)
- eval(other)¶
Evaluate this cochain on the chain
other.INPUT:
other– a chain for the same cell complex in the same dimension with the same base ring
OUTPUT: scalar
EXAMPLES:
sage: S2 = simplicial_complexes.Sphere(2) sage: C_2 = S2.n_chains(1) sage: C_2_co = S2.n_chains(1, cochains=True) sage: x = C_2.basis()[Simplex((0,2))] sage: y = C_2.basis()[Simplex((1,3))] sage: z = x+2*y sage: a = C_2_co.basis()[Simplex((1,3))] sage: b = C_2_co.basis()[Simplex((0,3))] sage: c = 3*a-2*b sage: z (0, 2) + 2*(1, 3) sage: c -2*\chi_(0, 3) + 3*\chi_(1, 3) sage: c.eval(z) 6
- is_coboundary()¶
Test whether the cochain is a coboundary
OUTPUT:
Boolean. Whether the cochain is the
coboundary()of a cochain in one degree lower.EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C1 = square.n_chains(1, QQ, cochains=True) sage: from sage.topology.cubical_complex import Cube sage: cochain = C1(Cube([[1, 1], [0, 1]])) - C1(Cube([[0, 1], [0, 0]])) sage: cochain.is_coboundary() True
- is_cocycle()¶
Test whether the cochain is a cocycle
OUTPUT:
Boolean. Whether the
coboundary()vanishes.EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C1 = square.n_chains(1, QQ, cochains=True) sage: from sage.topology.cubical_complex import Cube sage: cochain = C1(Cube([[1, 1], [0, 1]])) - C1(Cube([[0, 1], [0, 0]])) sage: cochain.is_cocycle() True
- to_complex()¶
Return the corresponding cochain complex element
OUTPUT:
An element of the cochain complex, see
sage.homology.chain_complex.EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C1 = square.n_chains(1, QQ, cochains=True) sage: from sage.topology.cubical_complex import Cube sage: cochain = C1(Cube([[1, 1], [0, 1]])) sage: cochain.to_complex() Chain(1:(0, 0, 0, 1)) sage: ascii_art(_) d_2 d_1 [0] d_0 [0] d_-1 0 <---- [0] <---- [0] <---- [0] <----- 0 [0] [0] [1] [0]
- cochain_complex()¶
Return the cochain complex.
OUTPUT:
Cochain complex, see
sage.homology.chain_complex.EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: C2 = square.n_chains(2, QQ, cochains=True) sage: C2.cochain_complex() Chain complex with at most 3 nonzero terms over Rational Field sage: ascii_art(C2.cochain_complex()) [-1 1 0 0] [-1 0 1 0] [ 0 -1 0 1] [-1 1 -1 1] [ 0 0 -1 1] 0 <-- C_2 <-------------- C_1 <-------------- C_0 <-- 0
- dual()¶
Return the chains
OUTPUT:
The chains of the same cells with the same base ring.
EXAMPLES:
sage: square = cubical_complexes.Cube(2) sage: cochains = square.n_chains(1, ZZ, cochains=True); cochains Free module generated by {[0,0] x [0,1], [0,1] x [0,0], [0,1] x [1,1], [1,1] x [0,1]} over Integer Ring sage: cochains.dual() Free module generated by {[0,0] x [0,1], [0,1] x [0,0], [0,1] x [1,1], [1,1] x [0,1]} over Integer Ring sage: type(cochains) <class 'sage.homology.chains.Cochains_with_category'> sage: type(cochains.dual()) <class 'sage.homology.chains.Chains_with_category'>