1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
//! # LoPHAT
//! LoPHAT implements mutliple algorithms for computing persistent homology; in particular, the parallel, lockfree algorithm of Morozov and Nigmetov.
//! The algorithms implemented are:
//!
//! * [`SerialAlgorithm`](algorithms::SerialAlgorithm) - the standard left-to-right column additional algorithm of [Edelsbrunner et al.](https://doi.org/10.1109/SFCS.2000.892133).
//! * [`LockFreeAlgorithm`](algorithms::LockFreeAlgorithm) - the algorithm introduced by [Morozov and Nigmetov](https://doi.org/10.1145/3350755.3400244).
//! * [`LockingAlgorithm`](algorithms::LockingAlgorithm) - a locking variant of the above, in which each column is stored behind a [`RwLock`](std::sync::RwLock).
//!
//! The primary interface to each of these algorithms is the [`DecompositionAlgo`](algorithms::DecompositionAlgo) trait.
//! Once you have built up your input matrix in an implementor, you can decompose it via the [`decompose`](algorithms::DecompositionAlgo::decompose) method.
//! The output is a struct which implements [`Decomposition`](algorithms::Decomposition) -- a trait which contains methods for querying the resulting R=DV decomposition.
//! In particular, you can then compute the persistence pairings via the [`diagram`](algorithms::Decomposition::diagram) method.
//!
//! Each algorithm is generic over the underlying column representation.
//! A number of representations are available in the [`columns`] module.
//! For many applications, [`VecColumn`](columns::VecColumn) is a good choice.
//!
//! # Example
//!
//! ```
//! // Import the algorithm you want to use as well as the decomposition and algorithm traits
//! use lophat::algorithms::{LockFreeAlgorithm, DecompositionAlgo, Decomposition};
//! // Import the column representation we want to use
//! use lophat::columns::VecColumn;
//! use lophat::utils::PersistenceDiagram;
//! use hashbrown::HashSet;
//!
//! fn build_sphere_triangulation() -> impl Iterator<Item = VecColumn> {
//! vec![
//! (0, vec![]),
//! (0, vec![]),
//! (0, vec![]),
//! (0, vec![]),
//! (1, vec![0, 1]),
//! (1, vec![0, 2]),
//! (1, vec![1, 2]),
//! (1, vec![0, 3]),
//! (1, vec![1, 3]),
//! (1, vec![2, 3]),
//! (2, vec![4, 7, 8]),
//! (2, vec![5, 7, 9]),
//! (2, vec![6, 8, 9]),
//! (2, vec![4, 5, 6]),
//! ]
//! .into_iter()
//! .map(|col| col.into())
//! }
//!
//! // Build a simplicial representation of the 2-sphere
//! let matrix = build_sphere_triangulation();
//! // Decompose with the lockfree algorithm, using the default options
//! let decomposition = LockFreeAlgorithm::init(None).add_cols(matrix).decompose();
//! // Compute the persistence diagram
//! let computed_diagram = decomposition.diagram();
//! // Ensure we get the correct pairings
//! let correct_diagram = PersistenceDiagram {
//! unpaired: HashSet::from_iter(vec![0, 13]),
//! paired: HashSet::from_iter(vec![(1, 4), (2, 5), (3, 7), (6, 12), (8, 10), (9, 11)]),
//! };
//! assert_eq!(computed_diagram, correct_diagram)
//! ```
pub mod algorithms;
pub mod columns;
pub mod options;
pub mod utils;
#[cfg(feature = "python")]
mod bindings;