Sun, 27 Apr 2025 20:29:43 -0500
Fix build with stable rust.
For optimisations, build.rs now automatically sets a nightly cfg flag,
so problems with the nightly feature are avoided. It is still used for
required for additional nightly-only features.
| 5 | 1 | /*! |
| 2 | This module provides various sets and traits for them. | |
| 3 | */ | |
| 4 | ||
| 0 | 5 | use std::ops::{RangeFull,RangeFrom,Range,RangeInclusive,RangeTo,RangeToInclusive}; |
| 6 | use crate::types::*; | |
| 5 | 7 | use crate::loc::Loc; |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
8 | use crate::euclidean::Euclidean; |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
9 | use crate::instance::{Space, Instance}; |
| 0 | 10 | use serde::Serialize; |
| 11 | ||
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
12 | pub mod cube; |
| 5 | 13 | pub use cube::Cube; |
| 0 | 14 | |
| 15 | /// Trait for arbitrary sets. The parameter `U` is the element type. | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
16 | pub trait Set<U> where U : Space { |
| 5 | 17 | /// Check for element containment |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
18 | fn contains<I : Instance<U>>(&self, item : I) -> bool; |
| 0 | 19 | } |
| 20 | ||
| 5 | 21 | /// Additional ordering (besides [`PartialOrd`]) of a subfamily of sets: |
| 22 | /// greatest lower bound and least upper bound. | |
| 0 | 23 | pub trait SetOrd : Sized { |
| 24 | /// Returns the smallest set of same class contain both parameters. | |
| 25 | fn common(&self, other : &Self) -> Self; | |
| 26 | ||
| 27 | /// Returns the greatest set of same class contaied by n both parameter sets. | |
| 28 | fn intersect(&self, other : &Self) -> Option<Self>; | |
| 29 | } | |
| 30 | ||
| 31 | impl<U, const N : usize> Set<Loc<U, N>> | |
| 32 | for Cube<U,N> | |
| 33 | where U : Num + PartialOrd + Sized { | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
34 | fn contains<I : Instance<Loc<U, N>>>(&self, item : I) -> bool { |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
35 | self.0.iter().zip(item.ref_instance().iter()).all(|(s, x)| s.contains(x)) |
| 0 | 36 | } |
| 37 | } | |
| 38 | ||
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
39 | impl<U : Space> Set<U> for RangeFull { |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
40 | fn contains<I : Instance<U>>(&self, _item : I) -> bool { true } |
| 0 | 41 | } |
| 42 | ||
| 43 | macro_rules! impl_ranges { | |
| 44 | ($($range:ident),*) => { $( | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
45 | impl<U,Idx> Set<U> for $range<Idx> |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
46 | where |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
47 | Idx : PartialOrd<U>, |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
48 | U : PartialOrd<Idx> + Space, |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
49 | Idx : PartialOrd |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
50 | { |
| 0 | 51 | #[inline] |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
52 | fn contains<I : Instance<U>>(&self, item : I) -> bool { |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
53 | item.eval(|x| $range::contains(&self, x)) |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
54 | } |
| 0 | 55 | } |
| 56 | )* } | |
| 57 | } | |
| 58 | ||
| 59 | impl_ranges!(RangeFrom,Range,RangeInclusive,RangeTo,RangeToInclusive); | |
| 60 | ||
| 5 | 61 | /// Halfspaces described by an orthogonal vector and an offset. |
| 62 | /// | |
| 63 | /// The halfspace is $H = \\{ t v + a \mid a^⊤ v = 0 \\}$, where $v$ is the orthogonal | |
| 64 | /// vector and $t$ the offset. | |
| 0 | 65 | #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
66 | pub struct Halfspace<A, F> where A : Euclidean<F>, F : Float { |
| 0 | 67 | pub orthogonal : A, |
| 68 | pub offset : F, | |
| 69 | } | |
| 70 | ||
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
71 | impl<A,F> Halfspace<A,F> where A : Euclidean<F>, F : Float { |
| 0 | 72 | #[inline] |
| 73 | pub fn new(orthogonal : A, offset : F) -> Self { | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
74 | Halfspace{ orthogonal : orthogonal, offset : offset } |
| 0 | 75 | } |
| 76 | } | |
| 77 | ||
| 5 | 78 | /// Trait for generating a halfspace spanned by another set `Self` of elements of type `U`. |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
79 | pub trait SpannedHalfspace<F> where F : Float { |
| 5 | 80 | /// Type of the orthogonal vector describing the halfspace. |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
81 | type A : Euclidean<F>; |
| 5 | 82 | /// Returns the halfspace spanned by this set. |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
83 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F>; |
| 0 | 84 | } |
| 85 | ||
| 86 | // TODO: Gram-Schmidt for higher N. | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
87 | impl<F : Float> SpannedHalfspace<F> for [Loc<F, 1>; 2] { |
| 0 | 88 | type A = Loc<F, 1>; |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
89 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F> { |
| 0 | 90 | let (x0, x1) = (self[0], self[1]); |
| 91 | Halfspace::new(x1-x0, x0[0]) | |
| 92 | } | |
| 93 | } | |
| 94 | ||
| 95 | // TODO: Gram-Schmidt for higher N. | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
96 | impl<F : Float> SpannedHalfspace<F> for [Loc<F, 2>; 2] { |
| 0 | 97 | type A = Loc<F, 2>; |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
98 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F> { |
| 0 | 99 | let (x0, x1) = (&self[0], &self[1]); |
| 100 | let d = x1 - x0; | |
| 101 | let orthog = loc![d[1], -d[0]]; // We don't normalise for efficiency | |
| 102 | let offset = x0.dot(&orthog); | |
| 103 | Halfspace::new(orthog, offset) | |
| 104 | } | |
| 105 | } | |
| 106 | ||
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
107 | impl<A,F> Set<A> for Halfspace<A,F> |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
108 | where |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
109 | A : Euclidean<F>, |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
110 | F : Float, |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
111 | { |
| 0 | 112 | #[inline] |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
113 | fn contains<I : Instance<A>>(&self, item : I) -> bool { |
| 0 | 114 | self.orthogonal.dot(item) >= self.offset |
| 115 | } | |
| 116 | } | |
| 117 | ||
| 118 | /// Polygons defined by `N` `Halfspace`s. | |
| 119 | #[derive(Clone,Copy,Debug,Eq,PartialEq)] | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
120 | pub struct NPolygon<A, F, const N : usize>(pub [Halfspace<A,F>; N]) |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
121 | where A : Euclidean<F>, F : Float; |
| 0 | 122 | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
123 | impl<A,F,const N : usize> Set<A> for NPolygon<A,F,N> |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
124 | where |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
125 | A : Euclidean<F>, |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
126 | F : Float, |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
127 | { |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
128 | fn contains<I : Instance<A>>(&self, item : I) -> bool { |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
129 | let r = item.ref_instance(); |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
130 | self.0.iter().all(|halfspace| halfspace.contains(r)) |
| 0 | 131 | } |
| 132 | } |