Skip to main content

algebraeon_geometry/
simplex_collection.rs

1use super::*;
2use crate::{
3    ambient_space::AffineSpace, partial_simplicial_complex::LabelledPartialSimplicialComplex,
4    simplex::Simplex, simplicial_disjoint_union::LabelledSimplicialDisjointUnion,
5};
6use std::collections::{HashMap, HashSet};
7
8/// A collection of disjoint simplices labelled by T
9pub trait LabelledSimplexCollection<
10    'f,
11    FS: OrderedRingSignature + FieldSignature + 'f,
12    T: Eq + Clone + Send + Sync,
13>: Sized where
14    FS::Set: Hash,
15{
16    type WithLabel<S: Eq + Clone + Send + Sync>: LabelledSimplexCollection<'f, FS, S>;
17    type SubsetType: LabelledSimplexCollection<'f, FS, T>;
18
19    fn try_new(
20        ambient_space: AffineSpace<'f, FS>,
21        simplexes: HashSet<Simplex<'f, FS>>,
22    ) -> Result<Self::WithLabel<()>, &'static str> {
23        Self::WithLabel::<()>::try_new_labelled(
24            ambient_space,
25            simplexes.into_iter().map(|spx| (spx, ())).collect(),
26        )
27    }
28    fn new_unchecked(
29        ambient_space: AffineSpace<'f, FS>,
30        simplexes: HashSet<Simplex<'f, FS>>,
31    ) -> Self::WithLabel<()> {
32        Self::WithLabel::<()>::new_labelled_unchecked(
33            ambient_space,
34            simplexes.into_iter().map(|spx| (spx, ())).collect(),
35        )
36    }
37
38    fn try_new_labelled(
39        ambient_space: AffineSpace<'f, FS>,
40        simplexes: HashMap<Simplex<'f, FS>, T>,
41    ) -> Result<Self, &'static str>;
42    fn new_labelled_unchecked(
43        ambient_space: AffineSpace<'f, FS>,
44        simplexes: HashMap<Simplex<'f, FS>, T>,
45    ) -> Self;
46
47    fn ambient_space(&self) -> AffineSpace<'f, FS>;
48
49    fn simplexes<'a>(&'a self) -> HashSet<&'a Simplex<'f, FS>>
50    where
51        T: 'a,
52    {
53        self.labelled_simplexes().into_keys().collect()
54    }
55    fn into_simplexes(self) -> HashSet<Simplex<'f, FS>> {
56        self.into_labelled_simplexes().into_keys().collect()
57    }
58
59    fn labelled_simplexes(&self) -> HashMap<&Simplex<'f, FS>, &T>;
60    fn into_labelled_simplexes(self) -> HashMap<Simplex<'f, FS>, T>;
61
62    fn subset_by_label(
63        &self,
64        label: &T,
65    ) -> <Self::SubsetType as LabelledSimplexCollection<'f, FS, T>>::WithLabel<()> {
66        self.subset_by_filter(|spx_label| spx_label == label)
67            .forget_labels()
68    }
69    fn into_subset_by_label(
70        self,
71        label: &T,
72    ) -> <Self::SubsetType as LabelledSimplexCollection<'f, FS, T>>::WithLabel<()> {
73        self.into_subset_by_filter(|spx_label| spx_label == label)
74            .forget_labels()
75    }
76    fn subset_by_filter(&self, f: impl Fn(&T) -> bool) -> Self::SubsetType {
77        Self::SubsetType::new_labelled_unchecked(
78            self.ambient_space(),
79            self.labelled_simplexes()
80                .into_iter()
81                .filter(|(_spx, label)| f(label))
82                .map(|(spx, label)| (spx.clone(), label.clone()))
83                .collect(),
84        )
85    }
86    fn into_subset_by_filter(self, f: impl Fn(&T) -> bool) -> Self::SubsetType {
87        Self::SubsetType::new_labelled_unchecked(
88            self.ambient_space(),
89            self.into_labelled_simplexes()
90                .into_iter()
91                .filter(|(_spx, label)| f(label))
92                .collect(),
93        )
94    }
95
96    fn into_partial_simplicial_complex(self) -> LabelledPartialSimplicialComplex<'f, FS, T>;
97    fn to_partial_simplicial_complex(&self) -> LabelledPartialSimplicialComplex<'f, FS, T>;
98
99    fn into_simplicial_disjoint_union(self) -> LabelledSimplicialDisjointUnion<'f, FS, T>;
100    fn to_simplicial_disjoint_union(&self) -> LabelledSimplicialDisjointUnion<'f, FS, T>;
101
102    fn apply_label_function<S: Eq + Clone + Send + Sync>(
103        &self,
104        f: impl Fn(&T) -> S,
105    ) -> Self::WithLabel<S> {
106        LabelledSimplexCollection::new_labelled_unchecked(
107            self.ambient_space(),
108            self.labelled_simplexes()
109                .into_iter()
110                .map(|(spx, label)| (spx.clone(), f(label)))
111                .collect(),
112        )
113    }
114    fn into_apply_label_function<S: Eq + Clone + Send + Sync>(
115        self,
116        f: impl Fn(T) -> S,
117    ) -> Self::WithLabel<S> {
118        LabelledSimplexCollection::new_labelled_unchecked(
119            self.ambient_space(),
120            self.into_labelled_simplexes()
121                .into_iter()
122                .map(|(spx, label)| (spx, f(label)))
123                .collect(),
124        )
125    }
126    fn forget_labels(&self) -> Self::WithLabel<()> {
127        self.apply_label_function(|_| ())
128    }
129    fn into_forget_labels(self) -> Self::WithLabel<()> {
130        self.into_apply_label_function(|_| ())
131    }
132
133    fn common_label<'a>(
134        &'a self,
135        simplexes: impl Iterator<Item = &'a Simplex<'f, FS>>,
136    ) -> Option<&'a T>
137    where
138        FS: 'a,
139        'f: 'a,
140        AffineSpace<'f, FS>: 'a,
141    {
142        let mut label = None;
143        for spx in simplexes {
144            let spx_label = *self.labelled_simplexes().get(&spx).unwrap();
145            match label {
146                Some(label) => {
147                    if label != spx_label {
148                        return None;
149                    }
150                }
151                None => {
152                    label = Some(spx_label);
153                }
154            }
155        }
156        label
157    }
158}
159
160#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
161pub enum InteriorOrBoundary {
162    Interior,
163    Boundary,
164}
165
166pub trait InteriorOrBoundarySimplexCollection<'f, FS: OrderedRingSignature + FieldSignature + 'f>:
167    LabelledSimplexCollection<'f, FS, InteriorOrBoundary>
168where
169    FS::Set: Hash,
170{
171    fn interior(
172        &self,
173    ) -> <Self::SubsetType as LabelledSimplexCollection<'f, FS, InteriorOrBoundary>>::WithLabel<()>
174    {
175        self.subset_by_label(&InteriorOrBoundary::Interior)
176    }
177
178    fn boundary(
179        &self,
180    ) -> <Self::SubsetType as LabelledSimplexCollection<'f, FS, InteriorOrBoundary>>::WithLabel<()>
181    {
182        self.subset_by_label(&InteriorOrBoundary::Boundary)
183    }
184}
185
186impl<
187    'f,
188    FS: OrderedRingSignature + FieldSignature + 'f,
189    S: LabelledSimplexCollection<'f, FS, InteriorOrBoundary>,
190> InteriorOrBoundarySimplexCollection<'f, FS> for S
191where
192    FS::Set: Hash,
193{
194}