eryon_mem/features/
feature.rs

1/*
2    Appellation: features <module>
3    Contrib: @FL03
4*/
5use num_traits::{Float, FromPrimitive, ToPrimitive};
6
7/// Represents a topological feature that persists across transformations
8#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
9#[cfg_attr(
10    feature = "serde",
11    derive(serde_derive::Deserialize, serde_derive::Serialize)
12)]
13pub struct PersistentFeature<T = f32> {
14    pub(crate) id: usize,
15    pub(crate) birth: usize,
16    pub(crate) content: Vec<usize>,
17    pub(crate) death: Option<usize>,
18    pub(crate) dimension: usize,
19    pub(crate) importance: T,
20    pub(crate) occurrences: usize,
21}
22
23impl<T> PersistentFeature<T> {
24    pub fn from_parts(
25        id: usize,
26        birth: usize,
27        content: Vec<usize>,
28        dimension: usize,
29        importance: T,
30    ) -> Self {
31        Self {
32            id,
33            birth,
34            content: Vec::from_iter(content),
35            death: None,
36            dimension,
37            importance,
38            occurrences: 1,
39        }
40    }
41
42    scsys::gsw! {
43        id: usize,
44        birth: usize,
45        dimension: usize,
46        occurrences: usize,
47    }
48
49    scsys::gsw! {
50        importance: &T,
51    }
52    /// returns an immutable reference to the features content
53    pub const fn content(&self) -> &Vec<usize> {
54        &self.content
55    }
56    /// returns a mutable reference to the feature's content
57    pub fn content_mut(&mut self) -> &mut Vec<usize> {
58        &mut self.content
59    }
60    /// get the death time of this feature; None if still active
61    pub const fn death(&self) -> Option<usize> {
62        self.death
63    }
64    pub fn death_mut(&mut self) -> Option<&mut usize> {
65        self.death.as_mut()
66    }
67    /// scale the importance of the feature
68    pub fn importance_to_usize_by(&self, scale: T) -> usize
69    where
70        T: Copy + core::ops::Mul<T, Output = T> + ToPrimitive,
71    {
72        (self.importance * scale).to_usize().unwrap()
73    }
74    /// scale the importance of the feature
75    pub fn importance_to_usize_by_10(&self) -> usize
76    where
77        T: Copy + core::ops::Mul<Output = T> + FromPrimitive + ToPrimitive,
78    {
79        Self::importance_to_usize_by(self, T::from_usize(10).unwrap())
80    }
81
82    pub fn update_importance_by_occurrences(&mut self)
83    where
84        T: Float + FromPrimitive,
85    {
86        let ten = T::from_usize(10).unwrap();
87        let occurrences = T::from_usize(self.occurrences).unwrap();
88        self.set_importance(occurrences.min(ten) / ten);
89    }
90    /// set the content of the feature
91    pub fn set_content<I>(&mut self, content: I)
92    where
93        I: IntoIterator<Item = usize>,
94    {
95        self.content = Vec::from_iter(content);
96    }
97    /// set the death of the feature
98    pub fn set_death(&mut self, death: usize) {
99        self.death = Some(death);
100    }
101    /// consumes the current instance to create another with the given content
102    pub fn with_content<I>(self, iter: I) -> Self
103    where
104        I: IntoIterator<Item = usize>,
105    {
106        Self {
107            content: Vec::from_iter(iter),
108            ..self
109        }
110    }
111    /// consumes the current instance to create another with the given death time
112    pub fn with_death(self, death: Option<usize>) -> Self {
113        Self { death, ..self }
114    }
115    /// check if the feature contains a given content
116    pub fn contains(&self, content: &usize) -> bool {
117        self.content.contains(content)
118    }
119    /// check if the feature does not have a death time
120    pub fn is_alive(&self) -> bool {
121        self.death.is_none()
122    }
123    /// check if a feature has died
124    pub fn is_dead(&self) -> bool {
125        self.death.is_some()
126    }
127    /// returns the number of elements in the content
128    pub fn content_len(&self) -> usize {
129        self.content.len()
130    }
131    /// decrement the number of occurrences
132    pub fn decrement_occurrences(&mut self) {
133        self.occurrences -= 1;
134    }
135    /// Increment the occurrence count
136    pub fn increment_occurrences(&mut self) {
137        self.occurrences += 1;
138    }
139}
140
141impl<T> core::ops::Index<usize> for PersistentFeature<T> {
142    type Output = usize;
143
144    fn index(&self, index: usize) -> &Self::Output {
145        &self.content[index]
146    }
147}
148
149impl<T> core::ops::IndexMut<usize> for PersistentFeature<T> {
150    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
151        &mut self.content[index]
152    }
153}