Skip to main content

holos_tda/kinetic/
model.rs

1use crate::{
2    CohomologyRelation, CohomologyRestriction, CohomologySpaceId, SparseDistanceMatrix,
3    ZigzagBarcode, ZigzagDirection,
4};
5
6/// Resource limits for an affine kinetic schedule.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[non_exhaustive]
9pub struct KineticLimits {
10    /// Largest accepted edge trajectory count.
11    pub max_edges: usize,
12    /// Largest accepted pairwise equality test count.
13    pub max_pair_tests: usize,
14    /// Largest accepted distinct event count.
15    pub max_events: usize,
16}
17
18impl Default for KineticLimits {
19    fn default() -> Self {
20        Self {
21            max_edges: 100_000,
22            max_pair_tests: 20_000_000,
23            max_events: 1_000_000,
24        }
25    }
26}
27
28/// Canonical unordered edge key.
29#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
30pub struct KineticEdgeKey {
31    /// Lower endpoint.
32    pub u: usize,
33    /// Higher endpoint.
34    pub v: usize,
35}
36
37impl KineticEdgeKey {
38    /// Construct a key and sort its endpoints.
39    pub fn new(u: usize, v: usize) -> Self {
40        Self {
41            u: u.min(v),
42            v: u.max(v),
43        }
44    }
45}
46
47/// One affine edge weight `intercept + velocity * time`.
48#[derive(Debug, Clone, Copy, PartialEq)]
49pub struct KineticEdge {
50    /// First endpoint.
51    pub u: usize,
52    /// Second endpoint.
53    pub v: usize,
54    /// Weight at time zero.
55    pub intercept: f64,
56    /// Constant weight derivative.
57    pub velocity: f64,
58}
59
60impl KineticEdge {
61    /// Canonical unordered edge key.
62    pub fn key(&self) -> KineticEdgeKey {
63        KineticEdgeKey::new(self.u, self.v)
64    }
65}
66
67/// One isolated change in the affine filtration arrangement.
68#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
69pub enum KineticEventKind {
70    /// An edge crosses the requested fixed scale.
71    ThresholdCrossing {
72        /// Crossing edge.
73        edge: KineticEdgeKey,
74    },
75    /// Two edge weights exchange their strict order.
76    EdgeOrderSwap {
77        /// First edge in canonical order.
78        first: KineticEdgeKey,
79        /// Second edge in canonical order.
80        second: KineticEdgeKey,
81    },
82}
83
84/// Adjacent-`f64` enclosure of one kinetic event time.
85#[derive(Debug, Clone, PartialEq)]
86pub struct KineticEvent {
87    /// Best `f64` approximation to the exact rational time.
88    pub time: f64,
89    /// Lower adjacent-`f64` enclosure endpoint.
90    pub lower: f64,
91    /// Upper adjacent-`f64` enclosure endpoint.
92    pub upper: f64,
93    /// Simultaneous changes at this exact time.
94    pub kinds: Vec<KineticEventKind>,
95}
96
97/// Complete event schedule on one closed time interval.
98#[derive(Debug, Clone, PartialEq)]
99pub struct KineticSchedule {
100    /// First time in the interval.
101    pub start: f64,
102    /// Last time in the interval.
103    pub end: f64,
104    /// Isolated events in exact time order.
105    pub events: Vec<KineticEvent>,
106    /// Edge pairs equal throughout the time interval.
107    pub persistent_ties: usize,
108}
109
110/// Exact class relation immediately before and after one kinetic event.
111#[derive(Debug, Clone, PartialEq)]
112pub struct KineticCohomologyEvent {
113    /// Certified event time and simultaneous changes.
114    pub event: KineticEvent,
115    /// Space on the open cell before the event.
116    pub before_space: CohomologySpaceId,
117    /// Space on the open cell after the event.
118    pub after_space: CohomologySpaceId,
119    /// Rank before the event.
120    pub before_rank: usize,
121    /// Rank after the event.
122    pub after_rank: usize,
123    /// Exact cohomology relation across the event.
124    pub relation: CohomologyRelation,
125}
126
127/// Position represented by one node in a kinetic cohomology zigzag.
128#[derive(Debug, Clone, PartialEq)]
129pub enum KineticZigzagNodeKind {
130    /// One open time cell between exact events.
131    OpenCell {
132        /// Sample time inside the open cell.
133        sample: f64,
134    },
135    /// The active complex at one exact event time.
136    Event(KineticEvent),
137}
138
139/// One canonical cohomology space in a kinetic zigzag.
140#[derive(Debug, Clone, PartialEq)]
141pub struct KineticZigzagNode {
142    /// Open cell or exact event represented by this node.
143    pub kind: KineticZigzagNodeKind,
144    /// Content identifier of the canonical cohomology space.
145    pub space: CohomologySpaceId,
146    /// Rank of the cohomology space at this node.
147    pub rank: usize,
148    /// Active edge count in the flag complex.
149    pub active_edges: usize,
150}
151
152/// One exact restriction arrow adjacent to a kinetic event.
153#[derive(Debug, Clone, PartialEq)]
154pub struct KineticZigzagArrow {
155    /// Direction relative to the left and right node order.
156    pub direction: ZigzagDirection,
157    /// Restriction from the event complex to the adjacent open-cell complex.
158    pub restriction: CohomologyRestriction,
159}
160
161/// Exact fixed-scale cohomology zigzag over a kinetic trajectory.
162#[derive(Debug, Clone, PartialEq)]
163pub struct KineticZigzag {
164    /// Cohomology dimension.
165    pub dimension: usize,
166    /// Fixed filtration scale.
167    pub scale: f64,
168    /// Prime coefficient modulus.
169    pub modulus: u32,
170    /// Edge pairs equal throughout the time interval.
171    pub persistent_ties: usize,
172    /// Alternating open-cell and exact-event spaces.
173    pub nodes: Vec<KineticZigzagNode>,
174    /// Exact maps between adjacent nodes.
175    pub arrows: Vec<KineticZigzagArrow>,
176    /// Interval decomposition of the zigzag module.
177    pub barcode: ZigzagBarcode,
178}
179
180/// Position represented by one graph in a fixed-scale schedule.
181#[derive(Debug, Clone, PartialEq)]
182pub enum KineticGraphStateKind {
183    /// Exact first time of the closed interval.
184    Start,
185    /// One open time cell between exact events.
186    OpenCell {
187        /// Sample time inside the open cell.
188        sample: f64,
189    },
190    /// Active graph at one exact event time.
191    Event(KineticEvent),
192    /// Exact last time of the closed interval.
193    End,
194}
195
196/// One active graph in a fixed-scale kinetic schedule.
197#[derive(Debug, Clone)]
198pub struct KineticGraphState {
199    /// Endpoint, open cell, or exact event represented by this state.
200    pub kind: KineticGraphStateKind,
201    /// Active graph at the represented time or open cell.
202    pub graph: SparseDistanceMatrix,
203}
204
205/// Fixed-envelope affine edge-weight trajectory.
206#[derive(Debug, Clone)]
207pub struct KineticFiltration {
208    pub(super) vertex_count: usize,
209    pub(super) edges: Vec<KineticEdge>,
210    pub(super) start: f64,
211    pub(super) end: f64,
212    pub(super) limits: KineticLimits,
213}