Skip to main content

algebraeon_geometry/
partial_simplicial_complex.rs

1use super::*;
2use crate::{
3    ambient_space::AffineSpace,
4    simplex::Simplex,
5    simplex_collection::LabelledSimplexCollection,
6    simplicial_complex::{LabelledSimplicialComplex, SimplicialComplex},
7    simplicial_disjoint_union::LabelledSimplicialDisjointUnion,
8};
9use std::collections::{HashMap, HashSet};
10
11#[derive(Clone)]
12pub struct LabelledPartialSimplicialComplex<
13    'f,
14    FS: OrderedRingSignature + FieldSignature,
15    T: Eq + Clone + Send + Sync,
16> {
17    ambient_space: AffineSpace<'f, FS>,
18    simplexes: HashMap<Simplex<'f, FS>, T>,
19}
20
21pub type PartialSimplicialComplex<'f, FS> = LabelledPartialSimplicialComplex<'f, FS, ()>;
22
23impl<'f, FS: OrderedRingSignature + FieldSignature> std::fmt::Debug
24    for PartialSimplicialComplex<'f, FS>
25{
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        f.debug_struct("PartialSimplicialComplex")
28            .field("simplexes", &self.simplexes)
29            .finish()
30    }
31}
32
33impl<'f, FS: OrderedRingSignature + FieldSignature, T: Eq + Clone + Send + Sync>
34    LabelledSimplexCollection<'f, FS, T> for LabelledPartialSimplicialComplex<'f, FS, T>
35where
36    FS::Set: Hash,
37{
38    type WithLabel<S: Eq + Clone + Send + Sync> = LabelledPartialSimplicialComplex<'f, FS, S>;
39    type SubsetType = LabelledPartialSimplicialComplex<'f, FS, T>;
40
41    fn try_new_labelled(
42        ambient_space: AffineSpace<'f, FS>,
43        simplexes: std::collections::HashMap<Simplex<'f, FS>, T>,
44    ) -> Result<Self, &'static str> {
45        Ok(Self {
46            ambient_space,
47            simplexes,
48        })
49    }
50
51    fn new_labelled_unchecked(
52        ambient_space: AffineSpace<'f, FS>,
53        simplexes: std::collections::HashMap<Simplex<'f, FS>, T>,
54    ) -> Self {
55        Self::try_new_labelled(ambient_space, simplexes).unwrap()
56    }
57
58    fn ambient_space(&self) -> AffineSpace<'f, FS> {
59        self.ambient_space
60    }
61
62    fn labelled_simplexes(&self) -> std::collections::HashMap<&Simplex<'f, FS>, &T> {
63        self.simplexes.iter().collect()
64    }
65
66    fn into_labelled_simplexes(self) -> std::collections::HashMap<Simplex<'f, FS>, T> {
67        self.simplexes
68    }
69
70    fn into_partial_simplicial_complex(self) -> LabelledPartialSimplicialComplex<'f, FS, T> {
71        self
72    }
73
74    fn to_partial_simplicial_complex(&self) -> LabelledPartialSimplicialComplex<'f, FS, T> {
75        self.clone()
76    }
77
78    fn into_simplicial_disjoint_union(self) -> LabelledSimplicialDisjointUnion<'f, FS, T> {
79        LabelledSimplicialDisjointUnion::new_labelled_unchecked(self.ambient_space, self.simplexes)
80    }
81
82    fn to_simplicial_disjoint_union(&self) -> LabelledSimplicialDisjointUnion<'f, FS, T> {
83        self.clone().into_simplicial_disjoint_union()
84    }
85}
86
87impl<'f, FS: OrderedRingSignature + FieldSignature, T: Eq + Clone + Send + Sync>
88    LabelledPartialSimplicialComplex<'f, FS, T>
89where
90    FS::Set: Hash,
91{
92    pub fn try_into_simplicial_complex(
93        self,
94    ) -> Result<LabelledSimplicialComplex<'f, FS, T>, &'static str> {
95        LabelledSimplicialComplex::try_new_labelled(self.ambient_space, self.simplexes)
96    }
97
98    pub fn into_labelled_simplicial_complex(&self) -> LabelledSimplicialComplex<'f, FS, Option<T>> {
99        let mut simplexes = HashSet::new();
100        for spx in self.simplexes.keys() {
101            for bdry in spx.sub_simplices_not_null() {
102                simplexes.insert(bdry);
103            }
104        }
105        LabelledSimplicialComplex::try_new_labelled(
106            self.ambient_space(),
107            simplexes
108                .into_iter()
109                .map(|spx| {
110                    let label = self.simplexes.get(&spx).cloned();
111                    (spx, label)
112                })
113                .collect(),
114        )
115        .unwrap()
116    }
117
118    pub fn simplify(&self) -> Self {
119        self.into_labelled_simplicial_complex()
120            .simplify()
121            .subset_by_filter(|label| label.is_some())
122            .apply_label_function(|label| label.clone().unwrap())
123    }
124}
125
126impl<'f, FS: OrderedRingSignature + FieldSignature> PartialSimplicialComplex<'f, FS>
127where
128    FS::Set: Hash,
129{
130    pub fn closure(&self) -> SimplicialComplex<'f, FS> {
131        self.into_labelled_simplicial_complex().forget_labels()
132    }
133}