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:
object
Auxiliary 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:
CellComplexReference
,CombinatorialFreeModule
Class 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:
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:
CellComplexReference
,CombinatorialFreeModule
Class 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:
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'>