Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

3. Cohomology and clearing

The coboundary lists each cell’s cofaces. Its oracle mirrors the boundary’s:

/// Step 3: the coboundary matrix (the transpose of the boundary), with the same filtration.
#[derive(Clone, Copy)]
pub struct Coboundary<'a>(pub &'a Volume);

impl MatrixOracle for Coboundary<'_> {
    type CoefficientField = Z2;
    type ColT = Cell;
    type RowT = Cell;

    fn column(&self, col: Cell) -> impl Iterator<Item = (Z2, Cell)> {
        self.0.cofaces(col.0).map(|coface| (Z2::one(), Cell(coface)))
    }
}

impl HasRowFiltration for Coboundary<'_> {
    type FiltrationT = NotNan<f32>;

    fn filtration_value(&self, row: Cell) -> NotNan<f32> {
        NotNan::new(self.0.value(row.0)).unwrap()
    }
}

and now cohomology with clearing is available:

    // Step 3: cohomology with clearing. Columns stop at the squares (for H0, H1 and H2): the cubes only ever appear
    // as rows, cofaces of squares, and are never enumerated
    let delta = Coboundary(&volume).with_basis(basis(&volume, 2));
    let cohomology = timed("cohomology, clearing", || {
        barcode::cohomology(&delta, Algorithm::Clearing(Clearing::new()))
    });

Two things changed:

  • The basis stops at the squares. For \(H_0\), \(H_1\) and \(H_2\) by cohomology the columns are vertices, edges and squares; cubes only appear as rows, produced by the oracle as cofaces of squares. They are never listed.
  • Clearing. barcode::cohomology reverses the coboundary (the anti-transpose) and reduces it dimension by dimension, skipping every column that the previous dimension’s pairs show to be zero. The basis must be split by dimension, which SplitBasis is.

On the 40³ volume this takes 157 ms, against 5.4 s for the standard algorithm on the boundary: 34× faster.

You can now use every algorithm in phlite that doesn’t need extra information about the matrix.