Thu, 01 May 2025 13:06:58 -0500
Transpose loc parameters to allow f64 defaults
| 5 | 1 | /*! |
| 2 | Multi-dimensional cubes. | |
| 3 | ||
| 4 | This module provides the [`Cube`] type for multi-dimensional cubes $∏_{i=1}^N [a_i, b_i)$. | |
| 5 | ||
| 6 | As an example, to create a the two-dimensional cube $[0, 1] × [-1, 1]$, you can | |
| 7 | ``` | |
| 8 | # use alg_tools::sets::cube::Cube; | |
| 9 | let cube = Cube::new([[0.0, 1.0], [-1.0, 1.0]]); | |
| 10 | ``` | |
| 11 | or | |
| 12 | ``` | |
| 13 | # use alg_tools::sets::cube::Cube; | |
| 14 | # use alg_tools::types::float; | |
| 15 | let cube : Cube<float, 2> = [[0.0, 1.0], [-1.0, 1.0]].into(); | |
| 16 | ``` | |
| 17 | */ | |
| 0 | 18 | |
| 19 | use crate::loc::Loc; | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
20 | use crate::maputil::{map1, map1_indexed, map2, FixedLength, FixedLengthMut}; |
| 0 | 21 | use crate::sets::SetOrd; |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
22 | use crate::types::*; |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
23 | use serde::ser::{Serialize, SerializeTupleStruct, Serializer}; |
| 0 | 24 | |
| 5 | 25 | /// A multi-dimensional cube $∏_{i=1}^N [a_i, b_i)$ with the starting and ending points |
| 26 | /// along $a_i$ and $b_i$ along each dimension of type `U`. | |
| 0 | 27 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
28 | pub struct Cube<const N: usize, U: Num = f64>(pub(super) [[U; 2]; N]); |
| 0 | 29 | |
| 30 | // Need to manually implement as [F; N] serialisation is provided only for some N. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
31 | impl<F: Num + Serialize, const N: usize> Serialize for Cube<N, F> |
| 0 | 32 | where |
| 33 | F: Serialize, | |
| 34 | { | |
| 35 | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
| 36 | where | |
| 37 | S: Serializer, | |
| 38 | { | |
| 39 | let mut ts = serializer.serialize_tuple_struct("Cube", N)?; | |
| 40 | for e in self.0.iter() { | |
| 41 | ts.serialize_field(e)?; | |
| 42 | } | |
| 43 | ts.end() | |
| 44 | } | |
| 45 | } | |
| 46 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
47 | impl<A: Num, const N: usize> FixedLength<N> for Cube<N, A> { |
| 0 | 48 | type Iter = std::array::IntoIter<[A; 2], N>; |
| 49 | type Elem = [A; 2]; | |
| 50 | #[inline] | |
| 51 | fn fl_iter(self) -> Self::Iter { | |
| 52 | self.0.into_iter() | |
| 53 | } | |
| 54 | } | |
| 55 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
56 | impl<A: Num, const N: usize> FixedLengthMut<N> for Cube<N, A> { |
| 0 | 57 | type IterMut<'a> = std::slice::IterMut<'a, [A; 2]>; |
| 58 | #[inline] | |
| 59 | fn fl_iter_mut(&mut self) -> Self::IterMut<'_> { | |
| 60 | self.0.iter_mut() | |
| 61 | } | |
| 62 | } | |
| 63 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
64 | impl<'a, A: Num, const N: usize> FixedLength<N> for &'a Cube<N, A> { |
| 0 | 65 | type Iter = std::slice::Iter<'a, [A; 2]>; |
| 66 | type Elem = &'a [A; 2]; | |
| 67 | #[inline] | |
| 68 | fn fl_iter(self) -> Self::Iter { | |
| 69 | self.0.iter() | |
| 70 | } | |
| 71 | } | |
| 72 | ||
| 73 | /// Iterator for [`Cube`] corners. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
74 | pub struct CubeCornersIter<'a, U: Num, const N: usize> { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
75 | index: usize, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
76 | cube: &'a Cube<N, U>, |
| 0 | 77 | } |
| 78 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
79 | impl<'a, U: Num, const N: usize> Iterator for CubeCornersIter<'a, U, N> { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
80 | type Item = Loc<N, U>; |
| 0 | 81 | #[inline] |
| 82 | fn next(&mut self) -> Option<Self::Item> { | |
| 83 | if self.index >= N { | |
| 84 | None | |
| 85 | } else { | |
| 86 | let i = self.index; | |
| 87 | self.index += 1; | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
88 | let arr = self |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
89 | .cube |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
90 | .map_indexed(|k, a, b| if (i >> k) & 1 == 0 { a } else { b }); |
| 0 | 91 | Some(arr.into()) |
| 92 | } | |
| 93 | } | |
| 94 | } | |
| 95 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
96 | impl<U: Num, const N: usize> Cube<N, U> { |
| 5 | 97 | /// Maps `f` over the triples $\\{(i, a\_i, b\_i)\\}\_{i=1}^N$ |
| 98 | /// of the cube $∏_{i=1}^N [a_i, b_i)$. | |
| 0 | 99 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
100 | pub fn map_indexed<T>(&self, f: impl Fn(usize, U, U) -> T) -> [T; N] { |
| 0 | 101 | map1_indexed(self, |i, &[a, b]| f(i, a, b)) |
| 102 | } | |
| 103 | ||
| 5 | 104 | /// Maps `f` over the tuples $\\{(a\_i, b\_i)\\}\_{i=1}^N$ |
| 105 | /// of the cube $∏_{i=1}^N [a_i, b_i)$. | |
| 0 | 106 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
107 | pub fn map<T>(&self, f: impl Fn(U, U) -> T) -> [T; N] { |
| 0 | 108 | map1(self, |&[a, b]| f(a, b)) |
| 109 | } | |
| 110 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
111 | /// Iterates over the start and end coordinates $\{(a_i, b_i)\}_{i=1}^N$ of the cube along |
| 5 | 112 | /// each dimension. |
| 0 | 113 | #[inline] |
| 114 | pub fn iter_coords(&self) -> std::slice::Iter<'_, [U; 2]> { | |
| 115 | self.0.iter() | |
| 116 | } | |
| 117 | ||
| 5 | 118 | /// Returns the “start” coordinate $a_i$ of the cube $∏_{i=1}^N [a_i, b_i)$. |
| 0 | 119 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
120 | pub fn start(&self, i: usize) -> U { |
| 0 | 121 | self.0[i][0] |
| 122 | } | |
| 123 | ||
| 5 | 124 | /// Returns the end coordinate $a_i$ of the cube $∏_{i=1}^N [a_i, b_i)$. |
| 0 | 125 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
126 | pub fn end(&self, i: usize) -> U { |
| 0 | 127 | self.0[i][1] |
| 128 | } | |
| 5 | 129 | |
| 130 | /// Returns the “start” $(a_1, … ,a_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$ | |
| 131 | /// spanned between $(a_1, … ,a_N)$ and $(b_1, … ,b_N)$. | |
| 0 | 132 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
133 | pub fn span_start(&self) -> Loc<N, U> { |
| 0 | 134 | Loc::new(self.map(|a, _b| a)) |
| 135 | } | |
| 136 | ||
| 5 | 137 | /// Returns the end $(b_1, … ,b_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$ |
| 138 | /// spanned between $(a_1, … ,a_N)$ and $(b_1, … ,b_N)$. | |
| 0 | 139 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
140 | pub fn span_end(&self) -> Loc<N, U> { |
| 0 | 141 | Loc::new(self.map(|_a, b| b)) |
| 142 | } | |
| 143 | ||
| 5 | 144 | /// Iterates over the corners $\{(c_1, … ,c_N) | c_i ∈ \{a_i, b_i\}\}$ of the cube |
| 145 | /// $∏_{i=1}^N [a_i, b_i)$. | |
| 0 | 146 | #[inline] |
| 147 | pub fn iter_corners(&self) -> CubeCornersIter<'_, U, N> { | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
148 | CubeCornersIter { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
149 | index: 0, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
150 | cube: self, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
151 | } |
| 0 | 152 | } |
| 153 | ||
| 5 | 154 | /// Returns the width-`N`-tuple $(b_1-a_1, … ,b_N-a_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$. |
| 0 | 155 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
156 | pub fn width(&self) -> Loc<N, U> { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
157 | Loc::new(self.map(|a, b| b - a)) |
| 0 | 158 | } |
| 159 | ||
| 5 | 160 | /// Translates the cube $∏_{i=1}^N [a_i, b_i)$ by the `shift` $(s_1, … , s_N)$ to |
| 161 | /// $∏_{i=1}^N [a_i+s_i, b_i+s_i)$. | |
| 0 | 162 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
163 | pub fn shift(&self, shift: &Loc<N, U>) -> Self { |
| 0 | 164 | let mut cube = self.clone(); |
| 165 | for i in 0..N { | |
| 166 | cube.0[i][0] += shift[i]; | |
| 167 | cube.0[i][1] += shift[i]; | |
| 168 | } | |
| 169 | cube | |
| 170 | } | |
| 171 | ||
| 5 | 172 | /// Creates a new cube from an array. |
| 0 | 173 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
174 | pub fn new(data: [[U; 2]; N]) -> Self { |
| 0 | 175 | Cube(data) |
| 176 | } | |
| 177 | } | |
| 178 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
179 | impl<F: Float, const N: usize> Cube<N, F> { |
| 0 | 180 | /// Returns the centre of the cube |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
181 | pub fn center(&self) -> Loc<N, F> { |
| 0 | 182 | map1(self, |&[a, b]| (a + b) / F::TWO).into() |
| 183 | } | |
| 184 | } | |
| 185 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
186 | impl<U: Num> Cube<1, U> { |
| 0 | 187 | /// Get the corners of the cube. |
| 5 | 188 | /// |
| 0 | 189 | /// TODO: generic implementation once const-generics can be involved in |
| 190 | /// calculations. | |
| 191 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
192 | pub fn corners(&self) -> [Loc<1, U>; 2] { |
| 0 | 193 | let [[a, b]] = self.0; |
| 194 | [a.into(), b.into()] | |
| 195 | } | |
| 196 | } | |
| 197 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
198 | impl<U: Num> Cube<2, U> { |
| 0 | 199 | /// Get the corners of the cube in counter-clockwise order. |
| 5 | 200 | /// |
| 0 | 201 | /// TODO: generic implementation once const-generics can be involved in |
| 202 | /// calculations. | |
| 203 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
204 | pub fn corners(&self) -> [Loc<2, U>; 4] { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
205 | let [[a1, b1], [a2, b2]] = self.0; |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
206 | [ |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
207 | [a1, a2].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
208 | [b1, a2].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
209 | [b1, b2].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
210 | [a1, b2].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
211 | ] |
| 0 | 212 | } |
| 213 | } | |
| 214 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
215 | impl<U: Num> Cube<3, U> { |
| 0 | 216 | /// Get the corners of the cube. |
| 5 | 217 | /// |
| 0 | 218 | /// TODO: generic implementation once const-generics can be involved in |
| 219 | /// calculations. | |
| 220 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
221 | pub fn corners(&self) -> [Loc<3, U>; 8] { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
222 | let [[a1, b1], [a2, b2], [a3, b3]] = self.0; |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
223 | [ |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
224 | [a1, a2, a3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
225 | [b1, a2, a3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
226 | [b1, b2, a3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
227 | [a1, b2, a3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
228 | [a1, b2, b3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
229 | [b1, b2, b3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
230 | [b1, a2, b3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
231 | [a1, a2, b3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
232 | ] |
| 0 | 233 | } |
| 234 | } | |
| 235 | ||
| 236 | // TODO: Implement Add and Sub of Loc to Cube, and Mul and Div by U : Num. | |
| 237 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
238 | impl<U: Num, const N: usize> From<[[U; 2]; N]> for Cube<N, U> { |
| 0 | 239 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
240 | fn from(data: [[U; 2]; N]) -> Self { |
| 0 | 241 | Cube(data) |
| 242 | } | |
| 243 | } | |
| 244 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
245 | impl<U: Num, const N: usize> From<Cube<N, U>> for [[U; 2]; N] { |
| 0 | 246 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
247 | fn from(Cube(data): Cube<N, U>) -> Self { |
| 0 | 248 | data |
| 249 | } | |
| 250 | } | |
| 251 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
252 | impl<U, const N: usize> Cube<N, U> |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
253 | where |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
254 | U: Num + PartialOrd, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
255 | { |
| 0 | 256 | /// Checks whether the cube is non-degenerate, i.e., the start coordinate |
| 257 | /// of each axis is strictly less than the end coordinate. | |
| 258 | #[inline] | |
| 259 | pub fn nondegenerate(&self) -> bool { | |
| 260 | self.0.iter().all(|range| range[0] < range[1]) | |
| 261 | } | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
262 | |
| 0 | 263 | /// Checks whether the cube intersects some `other` cube. |
| 264 | /// Matching boundary points are not counted, so `U` is ideally a [`Float`]. | |
| 265 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
266 | pub fn intersects(&self, other: &Cube<N, U>) -> bool { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
267 | self.iter_coords() |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
268 | .zip(other.iter_coords()) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
269 | .all(|([a1, b1], [a2, b2])| a1 < b2 && a2 < b1) |
| 0 | 270 | } |
| 271 | ||
| 272 | /// Checks whether the cube contains some `other` cube. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
273 | pub fn contains_set(&self, other: &Cube<N, U>) -> bool { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
274 | self.iter_coords() |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
275 | .zip(other.iter_coords()) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
276 | .all(|([a1, b1], [a2, b2])| a1 <= a2 && b1 >= b2) |
| 0 | 277 | } |
| 278 | ||
| 279 | /// Produces the point of minimum $ℓ^p$-norm within the cube `self` for any $p$-norm. | |
| 280 | /// This is the point where each coordinate is closest to zero. | |
| 281 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
282 | pub fn minnorm_point(&self) -> Loc<N, U> { |
| 0 | 283 | let z = U::ZERO; |
| 284 | // As always, we assume that a ≤ b. | |
| 285 | self.map(|a, b| { | |
| 286 | debug_assert!(a <= b); | |
| 287 | match (a < z, z < b) { | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
288 | (false, _) => a, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
289 | (_, false) => b, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
290 | (true, true) => z, |
| 0 | 291 | } |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
292 | }) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
293 | .into() |
| 0 | 294 | } |
| 295 | ||
| 296 | /// Produces the point of maximum $ℓ^p$-norm within the cube `self` for any $p$-norm. | |
| 297 | /// This is the point where each coordinate is furthest from zero. | |
| 298 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
299 | pub fn maxnorm_point(&self) -> Loc<N, U> { |
| 0 | 300 | let z = U::ZERO; |
| 301 | // As always, we assume that a ≤ b. | |
| 302 | self.map(|a, b| { | |
| 303 | debug_assert!(a <= b); | |
| 304 | match (a < z, z < b) { | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
305 | (false, _) => b, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
306 | (_, false) => a, |
| 0 | 307 | // A this stage we must have a < 0 (so U must be signed), and want to check |
| 308 | // whether |a| > |b|. We can do this without assuming U to actually implement | |
| 309 | // `Neg` by comparing whether 0 > a + b. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
310 | (true, true) => { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
311 | if z > a + b { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
312 | a |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
313 | } else { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
314 | b |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
315 | } |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
316 | } |
| 0 | 317 | } |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
318 | }) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
319 | .into() |
| 0 | 320 | } |
| 321 | } | |
| 322 | ||
| 323 | macro_rules! impl_common { | |
| 324 | ($($t:ty)*, $min:ident, $max:ident) => { $( | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
325 | impl<const N : usize> SetOrd for Cube<N, $t> { |
| 0 | 326 | #[inline] |
| 327 | fn common(&self, other : &Self) -> Self { | |
| 328 | map2(self, other, |&[a1, b1], &[a2, b2]| { | |
| 329 | debug_assert!(a1 <= b1 && a2 <= b2); | |
| 330 | [a1.$min(a2), b1.$max(b2)] | |
| 331 | }).into() | |
| 332 | } | |
| 333 | ||
| 334 | #[inline] | |
| 335 | fn intersect(&self, other : &Self) -> Option<Self> { | |
| 336 | let arr = map2(self, other, |&[a1, b1], &[a2, b2]| { | |
| 337 | debug_assert!(a1 <= b1 && a2 <= b2); | |
| 338 | [a1.$max(a2), b1.$min(b2)] | |
| 339 | }); | |
| 340 | arr.iter().all(|&[a, b]| a >= b).then(|| arr.into()) | |
| 341 | } | |
| 342 | } | |
| 343 | )* } | |
| 344 | } | |
| 345 | ||
| 346 | impl_common!(u8 u16 u32 u64 u128 usize | |
| 347 | i8 i16 i32 i64 i128 isize, min, max); | |
|
55
7b2ee3e84c5f
Add "nightly" feature and provide alternative low-performance implementations of several things when not available.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
348 | |
| 0 | 349 | // Any NaN yields NaN |
|
55
7b2ee3e84c5f
Add "nightly" feature and provide alternative low-performance implementations of several things when not available.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
350 | #[cfg(feature = "nightly")] |
| 0 | 351 | impl_common!(f32 f64, minimum, maximum); |
| 352 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
353 | impl<U: Num, const N: usize> std::ops::Index<usize> for Cube<N, U> { |
| 0 | 354 | type Output = [U; 2]; |
| 355 | #[inline] | |
| 356 | fn index(&self, index: usize) -> &Self::Output { | |
| 357 | &self.0[index] | |
| 358 | } | |
| 359 | } | |
| 360 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
361 | impl<U: Num, const N: usize> std::ops::IndexMut<usize> for Cube<N, U> { |
| 0 | 362 | #[inline] |
| 363 | fn index_mut(&mut self, index: usize) -> &mut Self::Output { | |
| 364 | &mut self.0[index] | |
| 365 | } | |
| 366 | } |