algebraeon_geometry/simplexes/
partial_simplicial_complex.rs

1use std::collections::{HashMap, HashSet};
2
3use super::*;
4
5#[derive(Clone)]
6pub struct LabelledPartialSimplicialComplex<
7    FS: OrderedRingStructure + FieldStructure,
8    SP: Borrow<AffineSpace<FS>> + Clone,
9    T: Eq + Clone,
10> {
11    ambient_space: SP,
12    simplexes: HashMap<Simplex<FS, SP>, T>,
13}
14
15pub type PartialSimplicialComplex<FS, SP> = LabelledPartialSimplicialComplex<FS, SP, ()>;
16
17impl<FS: OrderedRingStructure + FieldStructure, SP: Borrow<AffineSpace<FS>> + Clone> std::fmt::Debug
18    for PartialSimplicialComplex<FS, SP>
19{
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        f.debug_struct("PartialSimplicialComplex")
22            .field("simplexes", &self.simplexes)
23            .finish()
24    }
25}
26
27impl<FS: OrderedRingStructure + FieldStructure, SP: Borrow<AffineSpace<FS>> + Clone, T: Eq + Clone>
28    LabelledSimplexCollection<FS, SP, T> for LabelledPartialSimplicialComplex<FS, SP, T>
29where
30    FS::Set: Hash,
31{
32    type WithLabel<S: Eq + Clone> = LabelledPartialSimplicialComplex<FS, SP, S>;
33    type SubsetType = LabelledPartialSimplicialComplex<FS, SP, T>;
34
35    fn new_labelled(
36        ambient_space: SP,
37        simplexes: std::collections::HashMap<Simplex<FS, SP>, T>,
38    ) -> Result<Self, &'static str> {
39        Ok(Self {
40            ambient_space,
41            simplexes,
42        })
43    }
44
45    fn new_labelled_unchecked(
46        ambient_space: SP,
47        simplexes: std::collections::HashMap<Simplex<FS, SP>, T>,
48    ) -> Self {
49        Self::new_labelled(ambient_space, simplexes).unwrap()
50    }
51
52    fn ambient_space(&self) -> SP {
53        self.ambient_space.clone()
54    }
55
56    fn labelled_simplexes(&self) -> std::collections::HashMap<&Simplex<FS, SP>, &T> {
57        self.simplexes.iter().collect()
58    }
59
60    fn into_labelled_simplexes(self) -> std::collections::HashMap<Simplex<FS, SP>, T> {
61        self.simplexes
62    }
63
64    fn into_partial_simplicial_complex(self) -> LabelledPartialSimplicialComplex<FS, SP, T> {
65        self
66    }
67}
68
69impl<FS: OrderedRingStructure + FieldStructure, SP: Borrow<AffineSpace<FS>> + Clone, T: Eq + Clone>
70    LabelledPartialSimplicialComplex<FS, SP, T>
71where
72    FS::Set: Hash,
73{
74    pub fn try_as_simplicial_complex(
75        self,
76    ) -> Result<LabelledSimplicialComplex<FS, SP, T>, &'static str> {
77        LabelledSimplicialComplex::new_labelled(self.ambient_space, self.simplexes)
78    }
79
80    pub fn closure(&self) -> LabelledSimplicialComplex<FS, SP, Option<T>> {
81        let mut simplexes = HashSet::new();
82        for (spx, _label) in &self.simplexes {
83            for bdry in spx.sub_simplices_not_null() {
84                simplexes.insert(bdry);
85            }
86        }
87        LabelledSimplicialComplex::new_labelled(
88            self.ambient_space(),
89            simplexes
90                .into_iter()
91                .map(|spx| {
92                    let label = self.simplexes.get(&spx).cloned();
93                    (spx, label)
94                })
95                .collect(),
96        )
97        .unwrap()
98    }
99
100    pub fn simplify(&self) -> Self {
101        self.closure()
102            .simplify()
103            .subset_by_filter(|label| label.is_some())
104            .apply_label_function(|label| label.clone().unwrap())
105    }
106}