Thu, 03 Sep 2026 10:59:13 -0500
Possible p2 model solution fixes
| 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] |
| 204 | 100 | pub fn map_indexed<T>(&self, mut f: impl FnMut(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] |
| 204 | 107 | pub fn map<T>(&self, mut f: impl FnMut(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> { | |
| 204 | 148 | CubeCornersIter { index: 0, cube: self } |
| 0 | 149 | } |
| 150 | ||
| 5 | 151 | /// Returns the width-`N`-tuple $(b_1-a_1, … ,b_N-a_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$. |
| 0 | 152 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
153 | pub fn width(&self) -> Loc<N, U> { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
154 | Loc::new(self.map(|a, b| b - a)) |
| 0 | 155 | } |
| 156 | ||
| 5 | 157 | /// Translates the cube $∏_{i=1}^N [a_i, b_i)$ by the `shift` $(s_1, … , s_N)$ to |
| 158 | /// $∏_{i=1}^N [a_i+s_i, b_i+s_i)$. | |
| 0 | 159 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
160 | pub fn shift(&self, shift: &Loc<N, U>) -> Self { |
| 0 | 161 | let mut cube = self.clone(); |
| 162 | for i in 0..N { | |
| 163 | cube.0[i][0] += shift[i]; | |
| 164 | cube.0[i][1] += shift[i]; | |
| 165 | } | |
| 166 | cube | |
| 167 | } | |
| 168 | ||
| 5 | 169 | /// Creates a new cube from an array. |
| 0 | 170 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
171 | pub fn new(data: [[U; 2]; N]) -> Self { |
| 0 | 172 | Cube(data) |
| 173 | } | |
| 174 | } | |
| 175 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
176 | impl<F: Float, const N: usize> Cube<N, F> { |
| 0 | 177 | /// Returns the centre of the cube |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
178 | pub fn center(&self) -> Loc<N, F> { |
| 0 | 179 | map1(self, |&[a, b]| (a + b) / F::TWO).into() |
| 180 | } | |
| 181 | } | |
| 182 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
183 | impl<U: Num> Cube<1, U> { |
| 0 | 184 | /// Get the corners of the cube. |
| 5 | 185 | /// |
| 0 | 186 | /// TODO: generic implementation once const-generics can be involved in |
| 187 | /// calculations. | |
| 188 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
189 | pub fn corners(&self) -> [Loc<1, U>; 2] { |
| 0 | 190 | let [[a, b]] = self.0; |
| 191 | [a.into(), b.into()] | |
| 192 | } | |
| 193 | } | |
| 194 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
195 | impl<U: Num> Cube<2, U> { |
| 0 | 196 | /// Get the corners of the cube in counter-clockwise order. |
| 5 | 197 | /// |
| 0 | 198 | /// TODO: generic implementation once const-generics can be involved in |
| 199 | /// calculations. | |
| 200 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
201 | 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
|
202 | let [[a1, b1], [a2, b2]] = self.0; |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
203 | [ |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
204 | [a1, a2].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
205 | [b1, a2].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
206 | [b1, b2].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
207 | [a1, b2].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
208 | ] |
| 0 | 209 | } |
| 210 | } | |
| 211 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
212 | impl<U: Num> Cube<3, U> { |
| 0 | 213 | /// Get the corners of the cube. |
| 5 | 214 | /// |
| 0 | 215 | /// TODO: generic implementation once const-generics can be involved in |
| 216 | /// calculations. | |
| 217 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
218 | 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
|
219 | 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
|
220 | [ |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
221 | [a1, a2, a3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
222 | [b1, a2, a3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
223 | [b1, b2, a3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
224 | [a1, b2, a3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
225 | [a1, b2, b3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
226 | [b1, b2, b3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
227 | [b1, a2, b3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
228 | [a1, a2, b3].into(), |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
229 | ] |
| 0 | 230 | } |
| 231 | } | |
| 232 | ||
| 233 | // TODO: Implement Add and Sub of Loc to Cube, and Mul and Div by U : Num. | |
| 234 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
235 | impl<U: Num, const N: usize> From<[[U; 2]; N]> for Cube<N, U> { |
| 0 | 236 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
237 | fn from(data: [[U; 2]; N]) -> Self { |
| 0 | 238 | Cube(data) |
| 239 | } | |
| 240 | } | |
| 241 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
242 | impl<U: Num, const N: usize> From<Cube<N, U>> for [[U; 2]; N] { |
| 0 | 243 | #[inline] |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
244 | fn from(Cube(data): Cube<N, U>) -> Self { |
| 0 | 245 | data |
| 246 | } | |
| 247 | } | |
| 248 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
249 | 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
|
250 | where |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
251 | U: Num + PartialOrd, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
252 | { |
| 0 | 253 | /// Checks whether the cube is non-degenerate, i.e., the start coordinate |
| 254 | /// of each axis is strictly less than the end coordinate. | |
| 255 | #[inline] | |
| 256 | pub fn nondegenerate(&self) -> bool { | |
| 257 | self.0.iter().all(|range| range[0] < range[1]) | |
| 258 | } | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
259 | |
| 0 | 260 | /// Checks whether the cube intersects some `other` cube. |
| 261 | /// Matching boundary points are not counted, so `U` is ideally a [`Float`]. | |
| 262 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
263 | 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
|
264 | self.iter_coords() |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
265 | .zip(other.iter_coords()) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
266 | .all(|([a1, b1], [a2, b2])| a1 < b2 && a2 < b1) |
| 0 | 267 | } |
| 268 | ||
| 269 | /// 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
|
270 | 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
|
271 | self.iter_coords() |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
272 | .zip(other.iter_coords()) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
273 | .all(|([a1, b1], [a2, b2])| a1 <= a2 && b1 >= b2) |
| 0 | 274 | } |
| 275 | ||
| 276 | /// Produces the point of minimum $ℓ^p$-norm within the cube `self` for any $p$-norm. | |
| 277 | /// This is the point where each coordinate is closest to zero. | |
| 278 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
279 | pub fn minnorm_point(&self) -> Loc<N, U> { |
| 0 | 280 | let z = U::ZERO; |
| 281 | // As always, we assume that a ≤ b. | |
| 282 | self.map(|a, b| { | |
| 283 | debug_assert!(a <= b); | |
| 284 | match (a < z, z < b) { | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
285 | (false, _) => a, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
286 | (_, false) => b, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
287 | (true, true) => z, |
| 0 | 288 | } |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
289 | }) |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
290 | .into() |
| 0 | 291 | } |
| 292 | ||
| 293 | /// Produces the point of maximum $ℓ^p$-norm within the cube `self` for any $p$-norm. | |
| 294 | /// This is the point where each coordinate is furthest from zero. | |
| 295 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
296 | pub fn maxnorm_point(&self) -> Loc<N, U> { |
| 0 | 297 | let z = U::ZERO; |
| 298 | // As always, we assume that a ≤ b. | |
| 299 | self.map(|a, b| { | |
| 300 | debug_assert!(a <= b); | |
| 301 | match (a < z, z < b) { | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
302 | (false, _) => b, |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
303 | (_, false) => a, |
| 0 | 304 | // A this stage we must have a < 0 (so U must be signed), and want to check |
| 305 | // whether |a| > |b|. We can do this without assuming U to actually implement | |
| 306 | // `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
|
307 | (true, true) => { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
308 | if z > a + b { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
309 | a |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
310 | } else { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
311 | b |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
312 | } |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
313 | } |
| 0 | 314 | } |
|
124
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 | .into() |
| 0 | 317 | } |
| 318 | } | |
| 319 | ||
| 320 | macro_rules! impl_common { | |
| 321 | ($($t:ty)*, $min:ident, $max:ident) => { $( | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
322 | impl<const N : usize> SetOrd for Cube<N, $t> { |
| 0 | 323 | #[inline] |
| 324 | fn common(&self, other : &Self) -> Self { | |
| 325 | map2(self, other, |&[a1, b1], &[a2, b2]| { | |
| 326 | debug_assert!(a1 <= b1 && a2 <= b2); | |
| 327 | [a1.$min(a2), b1.$max(b2)] | |
| 328 | }).into() | |
| 329 | } | |
| 330 | ||
| 331 | #[inline] | |
| 332 | fn intersect(&self, other : &Self) -> Option<Self> { | |
| 333 | let arr = map2(self, other, |&[a1, b1], &[a2, b2]| { | |
| 334 | debug_assert!(a1 <= b1 && a2 <= b2); | |
| 335 | [a1.$max(a2), b1.$min(b2)] | |
| 336 | }); | |
| 337 | arr.iter().all(|&[a, b]| a >= b).then(|| arr.into()) | |
| 338 | } | |
| 339 | } | |
| 340 | )* } | |
| 341 | } | |
| 342 | ||
| 343 | impl_common!(u8 u16 u32 u64 u128 usize | |
| 344 | 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
|
345 | |
| 0 | 346 | // 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
|
347 | #[cfg(feature = "nightly")] |
| 0 | 348 | impl_common!(f32 f64, minimum, maximum); |
| 349 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
350 | impl<U: Num, const N: usize> std::ops::Index<usize> for Cube<N, U> { |
| 0 | 351 | type Output = [U; 2]; |
| 352 | #[inline] | |
| 353 | fn index(&self, index: usize) -> &Self::Output { | |
| 354 | &self.0[index] | |
| 355 | } | |
| 356 | } | |
| 357 | ||
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
55
diff
changeset
|
358 | impl<U: Num, const N: usize> std::ops::IndexMut<usize> for Cube<N, U> { |
| 0 | 359 | #[inline] |
| 360 | fn index_mut(&mut self, index: usize) -> &mut Self::Output { | |
| 361 | &mut self.0[index] | |
| 362 | } | |
| 363 | } |