algebraeon_geometry/
ambient_space.rs1use super::*;
2use crate::{
3 simplex_collection::LabelledSimplexCollection,
4 simplicial_disjoint_union::SimplicialDisjointUnion, vector::Vector,
5};
6use std::sync::atomic::AtomicUsize;
7
8#[derive(Debug, Clone)]
15pub struct AffineSpace<'f, FS: FieldSignature> {
16 field: &'f FS,
17 affine_dimension: usize,
19 ident: usize,
20}
21
22impl<'f, FS: FieldSignature> Copy for AffineSpace<'f, FS> {}
23
24impl<'f, FS: FieldSignature> PartialEq for AffineSpace<'f, FS> {
25 fn eq(&self, other: &Self) -> bool {
26 #[cfg(debug_assertions)]
27 if self.ident == other.ident {
28 assert_eq!(self.affine_dimension, other.affine_dimension);
29 assert_eq!(self.field(), other.field());
30 }
31 self.ident == other.ident
32 }
33}
34
35impl<'f, FS: FieldSignature> Eq for AffineSpace<'f, FS> {}
36
37impl<'f, FS: FieldSignature + Hash> Hash for AffineSpace<'f, FS> {
38 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
39 self.ident.hash(state);
40 }
41}
42
43impl<'f, FS: FieldSignature> AffineSpace<'f, FS> {
44 pub fn new_affine(field: &'f FS, affine_dimension: usize) -> Self {
45 static COUNTER: AtomicUsize = AtomicUsize::new(0);
46 Self {
47 field,
48 affine_dimension,
49 ident: COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed),
50 }
51 }
52
53 pub fn new_empty(field: &'f FS) -> Self {
54 Self::new_affine(field, 0)
55 }
56
57 pub fn new_linear(field: &'f FS, linear_dimension: usize) -> Self {
58 Self::new_affine(field, linear_dimension + 1)
59 }
60
61 pub fn field(&self) -> &'f FS {
62 self.field
63 }
64
65 pub fn origin(&self) -> Option<Vector<'f, FS>> {
66 Some(Vector::construct(*self, |_| self.field().zero()))
67 }
68
69 pub fn empty_subset(&self) -> impl LabelledSimplexCollection<'f, FS, ()>
70 where
71 FS: OrderedRingSignature,
72 FS::Set: Hash,
73 {
74 SimplicialDisjointUnion::new_unchecked(*self, std::collections::HashSet::new())
75 }
76
77 pub fn linear_dimension(&self) -> Option<usize> {
78 if self.affine_dimension == 0 {
79 None
80 } else {
81 Some(self.affine_dimension - 1)
82 }
83 }
84
85 pub fn affine_dimension(&self) -> usize {
86 self.affine_dimension
87 }
88}
89
90pub fn common_space<'s, 'f, FS: FieldSignature + 'f>(
91 space1: AffineSpace<'f, FS>,
92 space2: AffineSpace<'f, FS>,
93) -> Option<AffineSpace<'f, FS>> {
94 if space1 == space2 { Some(space1) } else { None }
95}