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

4. Apparent pairs

The boundary is the coboundary’s transpose, and attaching it costs one line:

    // Step 4: attach the transpose, so that apparent pairs need no reduction, and zero-length ones aren't recorded
    let delta_t = (&delta).with_transpose(Boundary(&volume));
    let apparent = timed("cohomology, clearing, apparent pairs", || {
        barcode::cohomology(&delta_t, Algorithm::Clearing(Clearing::new()))
    });

With the transpose the reduction can ask “which is the first column with an entry in row \(r\)?” (the smallest entry of column \(r\) of the transpose), and so recognise apparent pairs: pairs that need no reduction and no storage. In a lower-star filtration most pairs are apparent, and most of those have length zero (an edge and its brighter end appear together), which clearing then doesn’t even record.

But measure it:

A 40³ volume: 493039 cells

homology, standard algorithm                    5375.1 ms
cohomology, clearing                             156.7 ms
cohomology, clearing, apparent pairs             186.4 ms

Here it is 20% slower. Our columns have at most six entries, so reducing a column is cheap anyway, and the transpose’s generic answer (scan the column of the transpose, computing every entry’s filtration value from up to eight voxels) costs more than it saves. Apparent pairs pay off when a column is expensive to reduce, or, as in the next two steps, when they can be recognised more cheaply and used to avoid listing cells at all.

This is a general lesson: every optimisation in phlite has a cost, and the only way to know whether it pays on your matrix is to time it.