Thu, 01 May 2025 13:06:58 -0500
Transpose loc parameters to allow f64 defaults
| 5 | 1 | /*! |
| 2 | This module provides various sets and traits for them. | |
| 3 | */ | |
| 4 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
5 | use crate::euclidean::Euclidean; |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
6 | use crate::instance::{Instance, Space}; |
| 5 | 7 | use crate::loc::Loc; |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
8 | use crate::types::*; |
| 0 | 9 | use serde::Serialize; |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
10 | use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}; |
| 0 | 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. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
16 | pub trait Set<U> |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
17 | where |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
18 | U: Space, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
19 | { |
| 5 | 20 | /// Check for element containment |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
21 | fn contains<I: Instance<U>>(&self, item: I) -> bool; |
| 0 | 22 | } |
| 23 | ||
| 5 | 24 | /// Additional ordering (besides [`PartialOrd`]) of a subfamily of sets: |
| 25 | /// greatest lower bound and least upper bound. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
26 | pub trait SetOrd: Sized { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
27 | /// Returns the smallest set of same class contain both parameters. |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
28 | fn common(&self, other: &Self) -> Self; |
| 0 | 29 | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
30 | /// Returns the greatest set of same class contaied by n both parameter sets. |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
31 | fn intersect(&self, other: &Self) -> Option<Self>; |
| 0 | 32 | } |
| 33 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
34 | impl<U, const N: usize> Set<Loc<N, U>> for Cube<N, U> |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
35 | where |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
36 | U: Num + PartialOrd + Sized, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
37 | { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
38 | fn contains<I: Instance<Loc<N, U>>>(&self, item: I) -> bool { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
39 | self.0 |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
40 | .iter() |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
41 | .zip(item.ref_instance().iter()) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
42 | .all(|(s, x)| s.contains(x)) |
| 0 | 43 | } |
| 44 | } | |
| 45 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
46 | impl<U: Space> Set<U> for RangeFull { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
47 | fn contains<I: Instance<U>>(&self, _item: I) -> bool { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
48 | true |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
49 | } |
| 0 | 50 | } |
| 51 | ||
| 52 | macro_rules! impl_ranges { | |
| 53 | ($($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
|
54 | 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
|
55 | where |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
56 | 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
|
57 | 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
|
58 | Idx : PartialOrd |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
59 | { |
| 0 | 60 | #[inline] |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
61 | 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
|
62 | 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
|
63 | } |
| 0 | 64 | } |
| 65 | )* } | |
| 66 | } | |
| 67 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
68 | impl_ranges!(RangeFrom, Range, RangeInclusive, RangeTo, RangeToInclusive); |
| 0 | 69 | |
| 5 | 70 | /// Halfspaces described by an orthogonal vector and an offset. |
| 71 | /// | |
| 72 | /// The halfspace is $H = \\{ t v + a \mid a^⊤ v = 0 \\}$, where $v$ is the orthogonal | |
| 73 | /// vector and $t$ the offset. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
74 | #[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
75 | pub struct Halfspace<A, F> |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
76 | where |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
77 | A: Euclidean<F>, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
78 | F: Float, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
79 | { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
80 | pub orthogonal: A, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
81 | pub offset: F, |
| 0 | 82 | } |
| 83 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
84 | impl<A, F> Halfspace<A, F> |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
85 | where |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
86 | A: Euclidean<F>, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
87 | F: Float, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
88 | { |
| 0 | 89 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
90 | pub fn new(orthogonal: A, offset: F) -> Self { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
91 | Halfspace { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
92 | orthogonal: orthogonal, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
93 | offset: offset, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
94 | } |
| 0 | 95 | } |
| 96 | } | |
| 97 | ||
| 5 | 98 | /// Trait for generating a halfspace spanned by another set `Self` of elements of type `U`. |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
99 | pub trait SpannedHalfspace<F> |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
100 | where |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
101 | F: Float, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
102 | { |
| 5 | 103 | /// Type of the orthogonal vector describing the halfspace. |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
104 | type A: Euclidean<F>; |
| 5 | 105 | /// 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
|
106 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F>; |
| 0 | 107 | } |
| 108 | ||
| 109 | // TODO: Gram-Schmidt for higher N. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
110 | impl<F: Float> SpannedHalfspace<F> for [Loc<1, F>; 2] { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
111 | type A = Loc<1, F>; |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
112 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F> { |
| 0 | 113 | let (x0, x1) = (self[0], self[1]); |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
114 | Halfspace::new(x1 - x0, x0[0]) |
| 0 | 115 | } |
| 116 | } | |
| 117 | ||
| 118 | // TODO: Gram-Schmidt for higher N. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
119 | impl<F: Float> SpannedHalfspace<F> for [Loc<2, F>; 2] { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
120 | type A = Loc<2, F>; |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
121 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F> { |
| 0 | 122 | let (x0, x1) = (&self[0], &self[1]); |
| 123 | let d = x1 - x0; | |
| 124 | let orthog = loc![d[1], -d[0]]; // We don't normalise for efficiency | |
| 125 | let offset = x0.dot(&orthog); | |
| 126 | Halfspace::new(orthog, offset) | |
| 127 | } | |
| 128 | } | |
| 129 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
130 | impl<A, F> Set<A> for Halfspace<A, F> |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
131 | where |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
132 | A: Euclidean<F>, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
133 | F: Float, |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
134 | { |
| 0 | 135 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
136 | fn contains<I: Instance<A>>(&self, item: I) -> bool { |
| 0 | 137 | self.orthogonal.dot(item) >= self.offset |
| 138 | } | |
| 139 | } | |
| 140 | ||
| 141 | /// Polygons defined by `N` `Halfspace`s. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
142 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
143 | pub struct NPolygon<A, const N: usize, F = f64>(pub [Halfspace<A, F>; N]) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
144 | where |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
145 | A: Euclidean<F>, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
146 | F: Float; |
| 0 | 147 | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
148 | impl<A, F, const N: usize> Set<A> for NPolygon<A, N, F> |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
149 | where |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
150 | A: Euclidean<F>, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
151 | F: Float, |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
152 | { |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
153 | fn contains<I: Instance<A>>(&self, item: I) -> bool { |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
41
diff
changeset
|
154 | 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
|
155 | self.0.iter().all(|halfspace| halfspace.contains(r)) |
| 0 | 156 | } |
| 157 | } |