use std::fmt;
use crate::{Bar, Diagram};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct IntervalGroupId([u8; 32]);
impl IntervalGroupId {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
pub fn from_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
}
}
impl fmt::Display for IntervalGroupId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.0 {
write!(f, "{byte:02x}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BasisClassId([u8; 32]);
impl BasisClassId {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
pub fn from_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
}
}
impl fmt::Display for BasisClassId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.0 {
write!(f, "{byte:02x}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct CocycleTerm {
pub u: usize,
pub v: usize,
pub coefficient: u32,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Cocycle {
pub modulus: u32,
pub scale: f64,
pub terms: Vec<CocycleTerm>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CriticalSimplex {
pub vertices: Vec<usize>,
pub value: f64,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CriticalPair {
pub birth: CriticalSimplex,
pub death: Option<CriticalSimplex>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct PersistentClassProvenance {
pub(crate) source_graph_digest: [u8; 32],
pub(crate) class_digest: [u8; 32],
pub(crate) interval: Bar,
pub(crate) modulus: u32,
pub(crate) scale: f64,
}
impl PersistentClassProvenance {
pub fn source_graph_digest(&self) -> &[u8; 32] {
&self.source_graph_digest
}
pub fn class_digest(&self) -> &[u8; 32] {
&self.class_digest
}
pub fn interval(&self) -> Bar {
self.interval
}
pub fn modulus(&self) -> u32 {
self.modulus
}
pub fn scale(&self) -> f64 {
self.scale
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct PersistentClass {
pub id: BasisClassId,
pub group_id: IntervalGroupId,
pub basis_index: usize,
pub interval: Bar,
pub cocycle: Cocycle,
pub provenance: Option<PersistentClassProvenance>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct PersistentClassSpace {
pub id: IntervalGroupId,
pub interval: Bar,
pub basis: Vec<PersistentClass>,
pub critical_pairs: Vec<CriticalPair>,
}
#[derive(Debug, Clone)]
pub struct ExplainedDiagram {
pub diagram: Diagram,
pub spaces: Vec<PersistentClassSpace>,
}
impl ExplainedDiagram {
pub fn class_count(&self) -> usize {
self.spaces.iter().map(|space| space.basis.len()).sum()
}
pub fn classes(&self) -> impl Iterator<Item = &PersistentClass> {
self.spaces.iter().flat_map(|space| &space.basis)
}
}