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<
28        FS: OrderedRingStructure + FieldStructure,
29        SP: Borrow<AffineSpace<FS>> + Clone,
30        T: Eq + Clone,
31    > LabelledSimplexCollection<FS, SP, T> for LabelledPartialSimplicialComplex<FS, SP, T>
32where
33    FS::Set: Hash,
34{
35    type WithLabel<S: Eq + Clone> = LabelledPartialSimplicialComplex<FS, SP, S>;
36    type SubsetType = LabelledPartialSimplicialComplex<FS, SP, T>;
37
38    fn new_labelled(
39        ambient_space: SP,
40        simplexes: std::collections::HashMap<Simplex<FS, SP>, T>,
41    ) -> Result<Self, &'static str> {
42        Ok(Self {
43            ambient_space,
44            simplexes,
45        })
46    }
47
48    fn new_labelled_unchecked(
49        ambient_space: SP,
50        simplexes: std::collections::HashMap<Simplex<FS, SP>, T>,
51    ) -> Self {
52        Self::new_labelled(ambient_space, simplexes).unwrap()
53    }
54
55    fn ambient_space(&self) -> SP {
56        self.ambient_space.clone()
57    }
58
59    fn labelled_simplexes(&self) -> std::collections::HashMap<&Simplex<FS, SP>, &T> {
60        self.simplexes.iter().collect()
61    }
62
63    fn into_labelled_simplexes(self) -> std::collections::HashMap<Simplex<FS, SP>, T> {
64        self.simplexes
65    }
66
67    fn into_partial_simplicial_complex(self) -> LabelledPartialSimplicialComplex<FS, SP, T> {
68        self
69    }
70}
71
72impl<
73        FS: OrderedRingStructure + FieldStructure,
74        SP: Borrow<AffineSpace<FS>> + Clone,
75        T: Eq + Clone,
76    > LabelledPartialSimplicialComplex<FS, SP, T>
77where
78    FS::Set: Hash,
79{
80    pub fn try_as_simplicial_complex(
81        self,
82    ) -> Result<LabelledSimplicialComplex<FS, SP, T>, &'static str> {
83        LabelledSimplicialComplex::new_labelled(self.ambient_space, self.simplexes)
84    }
85
86    pub fn closure(&self) -> LabelledSimplicialComplex<FS, SP, Option<T>> {
87        let mut simplexes = HashSet::new();
88        for (spx, _label) in &self.simplexes {
89            for bdry in spx.sub_simplices_not_null() {
90                simplexes.insert(bdry);
91            }
92        }
93        LabelledSimplicialComplex::new_labelled(
94            self.ambient_space(),
95            simplexes
96                .into_iter()
97                .map(|spx| {
98                    let label = self.simplexes.get(&spx).cloned();
99                    (spx, label)
100                })
101                .collect(),
102        )
103        .unwrap()
104    }
105
106    pub fn simplify(&self) -> Self {
107        self.closure()
108            .simplify()
109            .subset_by_filter(|label| label.is_some())
110            .apply_label_function(|label| label.clone().unwrap())
111    }
112}