holos_tda/persistent_coordinate_artifact/
model.rs1use std::fmt;
2
3use crate::circular::SelectedCircularCoordinate;
4use crate::{
5 Bar, CriticalPair, IntegralCocycleTerm, PersistenceCycleTerm, PersistenceTriangleTerm,
6 PersistentClass, PersistentClassArtifact, SparseDistanceMatrix,
7};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct PersistentCoordinateArtifactError {
12 pub(super) message: String,
13}
14
15impl PersistentCoordinateArtifactError {
16 pub(crate) fn new(message: impl Into<String>) -> Self {
17 Self {
18 message: message.into(),
19 }
20 }
21
22 pub fn message(&self) -> &str {
24 &self.message
25 }
26}
27
28impl fmt::Display for PersistentCoordinateArtifactError {
29 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
30 write!(
31 formatter,
32 "persistent coordinate artifact: {}",
33 self.message
34 )
35 }
36}
37
38impl std::error::Error for PersistentCoordinateArtifactError {}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub struct PersistentCoordinateArtifactSummary {
43 pub vertices: usize,
45 pub source_edges: usize,
47 pub integral_terms: usize,
49 pub potential_values: usize,
51}
52
53#[derive(Debug, Clone)]
59pub struct PersistentCoordinateArtifact {
60 pub(super) class_artifact: PersistentClassArtifact,
61 pub(super) coordinate: SelectedCircularCoordinate,
62}
63
64impl PersistentCoordinateArtifact {
65 pub fn class_artifact(&self) -> &PersistentClassArtifact {
67 &self.class_artifact
68 }
69
70 pub fn source(&self) -> &SparseDistanceMatrix {
72 self.class_artifact.source()
73 }
74
75 pub fn class(&self) -> &PersistentClass {
77 self.class_artifact.class()
78 }
79
80 pub fn interval(&self) -> Bar {
82 self.class().interval
83 }
84
85 pub fn critical_pair(&self) -> &CriticalPair {
87 self.class_artifact.critical_pair()
88 }
89
90 pub fn cycle(&self) -> &[PersistenceCycleTerm] {
92 self.class_artifact.cycle()
93 }
94
95 pub fn bounding_chain(&self) -> &[PersistenceTriangleTerm] {
97 self.class_artifact.bounding_chain()
98 }
99
100 pub fn modulus(&self) -> u32 {
102 self.coordinate.modulus
103 }
104
105 pub fn scale(&self) -> f64 {
107 self.coordinate.scale
108 }
109
110 pub fn field_multiplier(&self) -> u32 {
112 self.coordinate.field_multiplier
113 }
114
115 pub fn integral(&self) -> &[IntegralCocycleTerm] {
117 &self.coordinate.integral
118 }
119
120 pub fn divisibility(&self) -> u64 {
122 self.coordinate.divisibility
123 }
124
125 pub fn potential(&self) -> &[f64] {
127 &self.coordinate.potential
128 }
129
130 pub fn phase(&self) -> &[f64] {
132 &self.coordinate.phase
133 }
134
135 pub fn energy(&self) -> f64 {
137 self.coordinate.energy
138 }
139
140 pub fn max_residual(&self) -> f64 {
142 self.coordinate.max_residual
143 }
144
145 pub fn relative_residual(&self) -> f64 {
147 self.coordinate.relative_residual
148 }
149
150 pub fn iterations(&self) -> usize {
152 self.coordinate.iterations
153 }
154
155 pub fn tolerance(&self) -> f64 {
157 self.coordinate.tolerance
158 }
159
160 pub fn summary(&self) -> PersistentCoordinateArtifactSummary {
162 PersistentCoordinateArtifactSummary {
163 vertices: self.source().len(),
164 source_edges: self.source().num_edges(),
165 integral_terms: self.integral().len(),
166 potential_values: self.potential().len(),
167 }
168 }
169}