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}