| 1 /*! |
1 /*! |
| 2 Array containers that support vector space operations on floats. |
2 Array containers that support vector space operations on floats. |
| 3 For working with small vectors in $ℝ^2$ or $ℝ^3$. |
3 For working with small vectors in $ℝ^2$ or $ℝ^3$. |
| 4 */ |
4 */ |
| 5 |
5 |
| 6 use std::ops::{Add,Sub,AddAssign,SubAssign,Mul,Div,MulAssign,DivAssign,Neg,Index,IndexMut}; |
6 use crate::euclidean::*; |
| 7 use std::slice::{Iter,IterMut}; |
7 use crate::instance::{BasicDecomposition, Instance}; |
| |
8 use crate::linops::{Linear, Mapping, VectorSpace, AXPY}; |
| |
9 use crate::mapping::Space; |
| |
10 use crate::maputil::{map1, map1_mut, map2, map2_mut, FixedLength, FixedLengthMut}; |
| |
11 use crate::norms::*; |
| |
12 use crate::self_ownable; |
| |
13 use crate::types::{Float, Num, SignedNum}; |
| |
14 use serde::ser::{Serialize, SerializeSeq, Serializer}; |
| 8 use std::fmt::{Display, Formatter}; |
15 use std::fmt::{Display, Formatter}; |
| 9 use crate::types::{Float,Num,SignedNum}; |
16 use std::ops::{ |
| 10 use crate::maputil::{FixedLength,FixedLengthMut,map1,map2,map1_mut,map2_mut}; |
17 Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign, |
| 11 use crate::euclidean::*; |
18 }; |
| 12 use crate::norms::*; |
19 use std::slice::{Iter, IterMut}; |
| 13 use crate::linops::{AXPY, Mapping, Linear}; |
|
| 14 use crate::instance::{Instance, BasicDecomposition}; |
|
| 15 use crate::mapping::Space; |
|
| 16 use serde::ser::{Serialize, Serializer, SerializeSeq}; |
|
| 17 |
|
| 18 |
20 |
| 19 /// A container type for (short) `N`-dimensional vectors of element type `F`. |
21 /// A container type for (short) `N`-dimensional vectors of element type `F`. |
| 20 /// |
22 /// |
| 21 /// Supports basic operations of an [`Euclidean`] space, several [`Norm`]s, and |
23 /// Supports basic operations of an [`Euclidean`] space, several [`Norm`]s, and |
| 22 /// fused [`AXPY`] operations, among others. |
24 /// fused [`AXPY`] operations, among others. |
| 23 #[derive(Copy,Clone,Debug,PartialEq,Eq)] |
25 #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
| 24 pub struct Loc<F, const N : usize>( |
26 pub struct Loc<const N: usize, F = f64>( |
| 25 /// An array of the elements of the vector |
27 /// An array of the elements of the vector |
| 26 pub [F; N] |
28 pub [F; N], |
| 27 ); |
29 ); |
| 28 |
30 |
| 29 impl<F : Display, const N : usize> Display for Loc<F, N>{ |
31 self_ownable!(Loc<N, F> where const N: usize, F: Copy); |
| |
32 |
| |
33 impl<F: Display, const N: usize> Display for Loc<N, F> { |
| 30 // Required method |
34 // Required method |
| 31 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
35 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
| 32 write!(f, "[")?; |
36 write!(f, "[")?; |
| 33 let mut comma = ""; |
37 let mut comma = ""; |
| 34 for e in self.iter() { |
38 for e in self.iter() { |
| 35 write!(f, "{comma}{e}")?; |
39 write!(f, "{comma}{e}")?; |
| 36 comma = ", "; |
40 comma = ", "; |
| 37 } |
41 } |
| 38 write!(f, "]") |
42 write!(f, "]") |
| 39 } |
43 } |
| 40 } |
44 } |
| 41 |
45 |
| 42 // Need to manually implement as [F; N] serialisation is provided only for some N. |
46 // Need to manually implement as [F; N] serialisation is provided only for some N. |
| 43 impl<F, const N : usize> Serialize for Loc<F, N> |
47 impl<F, const N: usize> Serialize for Loc<N, F> |
| 44 where |
48 where |
| 45 F: Serialize, |
49 F: Serialize, |
| 46 { |
50 { |
| 47 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
51 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
| 48 where |
52 where |
| 74 pub fn iter_mut(&mut self) -> IterMut<'_, F> { |
78 pub fn iter_mut(&mut self) -> IterMut<'_, F> { |
| 75 self.0.iter_mut() |
79 self.0.iter_mut() |
| 76 } |
80 } |
| 77 } |
81 } |
| 78 |
82 |
| 79 impl<F : Copy, const N : usize> Loc<F, N> { |
83 impl<F: Copy, const N: usize> Loc<N, F> { |
| 80 /// Maps `g` over the elements of the vector, returning a new [`Loc`] vector |
84 /// Maps `g` over the elements of the vector, returning a new [`Loc`] vector |
| 81 #[inline] |
85 #[inline] |
| 82 pub fn map<H>(&self, g : impl Fn(F) -> H) -> Loc<H, N> { |
86 pub fn map<H>(&self, g: impl Fn(F) -> H) -> Loc<N, H> { |
| 83 Loc::new(map1(self, |u| g(*u))) |
87 Loc::new(map1(self, |u| g(*u))) |
| 84 } |
88 } |
| 85 |
89 |
| 86 /// Maps `g` over pairs of elements of two vectors, retuning a new one. |
90 /// Maps `g` over pairs of elements of two vectors, retuning a new one. |
| 87 #[inline] |
91 #[inline] |
| 88 pub fn map2<H>(&self, other : &Self, g : impl Fn(F, F) -> H) -> Loc<H, N> { |
92 pub fn map2<H>(&self, other: &Self, g: impl Fn(F, F) -> H) -> Loc<N, H> { |
| 89 Loc::new(map2(self, other, |u, v| g(*u, *v))) |
93 Loc::new(map2(self, other, |u, v| g(*u, *v))) |
| 90 } |
94 } |
| 91 |
95 |
| 92 /// Maps `g` over mutable references to elements of the vector. |
96 /// Maps `g` over mutable references to elements of the vector. |
| 93 #[inline] |
97 #[inline] |
| 94 pub fn map_mut(&mut self, g : impl Fn(&mut F)) { |
98 pub fn map_mut(&mut self, g: impl Fn(&mut F)) { |
| 95 map1_mut(self, g) |
99 map1_mut(self, g) |
| 96 } |
100 } |
| 97 |
101 |
| 98 /// Maps `g` over pairs of mutable references to elements of `self, and elements |
102 /// Maps `g` over pairs of mutable references to elements of `self, and elements |
| 99 /// of `other` vector. |
103 /// of `other` vector. |
| 100 #[inline] |
104 #[inline] |
| 101 pub fn map2_mut(&mut self, other : &Self, g : impl Fn(&mut F, F)) { |
105 pub fn map2_mut(&mut self, other: &Self, g: impl Fn(&mut F, F)) { |
| 102 map2_mut(self, other, |u, v| g(u, *v)) |
106 map2_mut(self, other, |u, v| g(u, *v)) |
| 103 } |
107 } |
| 104 |
108 |
| 105 /// Maps `g` over the elements of `self` and returns the product of the results. |
109 /// Maps `g` over the elements of `self` and returns the product of the results. |
| 106 #[inline] |
110 #[inline] |
| 107 pub fn product_map<A : Num>(&self, g : impl Fn(F) -> A) -> A { |
111 pub fn product_map<A: Num>(&self, g: impl Fn(F) -> A) -> A { |
| 108 match N { |
112 match N { |
| 109 1 => g(unsafe { *self.0.get_unchecked(0) }), |
113 1 => g(unsafe { *self.0.get_unchecked(0) }), |
| 110 2 => g(unsafe { *self.0.get_unchecked(0) }) * |
114 2 => g(unsafe { *self.0.get_unchecked(0) }) * g(unsafe { *self.0.get_unchecked(1) }), |
| 111 g(unsafe { *self.0.get_unchecked(1) }), |
115 3 => { |
| 112 3 => g(unsafe { *self.0.get_unchecked(0) }) * |
116 g(unsafe { *self.0.get_unchecked(0) }) |
| 113 g(unsafe { *self.0.get_unchecked(1) }) * |
117 * g(unsafe { *self.0.get_unchecked(1) }) |
| 114 g(unsafe { *self.0.get_unchecked(2) }), |
118 * g(unsafe { *self.0.get_unchecked(2) }) |
| 115 _ => self.iter().fold(A::ONE, |m, &x| m * g(x)) |
119 } |
| |
120 _ => self.iter().fold(A::ONE, |m, &x| m * g(x)), |
| 116 } |
121 } |
| 117 } |
122 } |
| 118 } |
123 } |
| 119 |
124 |
| 120 /// Construct a [`Loc`]. |
125 /// Construct a [`Loc`]. |
| 128 #[macro_export] |
133 #[macro_export] |
| 129 macro_rules! loc { |
134 macro_rules! loc { |
| 130 ($($x:expr),+ $(,)?) => { Loc::new([$($x),+]) } |
135 ($($x:expr),+ $(,)?) => { Loc::new([$($x),+]) } |
| 131 } |
136 } |
| 132 |
137 |
| 133 |
138 impl<F, const N: usize> From<[F; N]> for Loc<N, F> { |
| 134 impl<F, const N : usize> From<[F; N]> for Loc<F, N> { |
139 #[inline] |
| 135 #[inline] |
140 fn from(other: [F; N]) -> Loc<N, F> { |
| 136 fn from(other: [F; N]) -> Loc<F, N> { |
|
| 137 Loc(other) |
141 Loc(other) |
| 138 } |
142 } |
| 139 } |
143 } |
| 140 |
144 |
| 141 /*impl<F : Copy, const N : usize> From<&[F; N]> for Loc<F, N> { |
145 /*impl<F : Copy, const N : usize> From<&[F; N]> for Loc<N, F> { |
| 142 #[inline] |
146 #[inline] |
| 143 fn from(other: &[F; N]) -> Loc<F, N> { |
147 fn from(other: &[F; N]) -> Loc<N, F> { |
| 144 Loc(*other) |
148 Loc(*other) |
| 145 } |
149 } |
| 146 }*/ |
150 }*/ |
| 147 |
151 |
| 148 impl<F> From<F> for Loc<F, 1> { |
152 impl<F> From<F> for Loc<1, F> { |
| 149 #[inline] |
153 #[inline] |
| 150 fn from(other: F) -> Loc<F, 1> { |
154 fn from(other: F) -> Loc<1, F> { |
| 151 Loc([other]) |
155 Loc([other]) |
| 152 } |
156 } |
| 153 } |
157 } |
| 154 |
158 |
| 155 impl<F> Loc<F, 1> { |
159 impl<F> Loc<1, F> { |
| 156 #[inline] |
160 #[inline] |
| 157 pub fn flatten1d(self) -> F { |
161 pub fn flatten1d(self) -> F { |
| 158 let Loc([v]) = self; |
162 let Loc([v]) = self; |
| 159 v |
163 v |
| 160 } |
164 } |
| 161 } |
165 } |
| 162 |
166 |
| 163 impl<F, const N : usize> From<Loc<F, N>> for [F; N] { |
167 impl<F, const N: usize> From<Loc<N, F>> for [F; N] { |
| 164 #[inline] |
168 #[inline] |
| 165 fn from(other : Loc<F, N>) -> [F; N] { |
169 fn from(other: Loc<N, F>) -> [F; N] { |
| 166 other.0 |
170 other.0 |
| 167 } |
171 } |
| 168 } |
172 } |
| 169 |
173 |
| 170 /*impl<F : Copy, const N : usize> From<&Loc<F, N>> for [F; N] { |
174 /*impl<F : Copy, const N : usize> From<&Loc<N, F>> for [F; N] { |
| 171 #[inline] |
175 #[inline] |
| 172 fn from(other : &Loc<F, N>) -> [F; N] { |
176 fn from(other : &Loc<N, F>) -> [F; N] { |
| 173 other.0 |
177 other.0 |
| 174 } |
178 } |
| 175 }*/ |
179 }*/ |
| 176 |
180 |
| 177 |
181 impl<F, const N: usize> IntoIterator for Loc<N, F> { |
| 178 impl<F, const N : usize> IntoIterator for Loc<F, N> { |
|
| 179 type Item = <[F; N] as IntoIterator>::Item; |
182 type Item = <[F; N] as IntoIterator>::Item; |
| 180 type IntoIter = <[F; N] as IntoIterator>::IntoIter; |
183 type IntoIter = <[F; N] as IntoIterator>::IntoIter; |
| 181 |
184 |
| 182 #[inline] |
185 #[inline] |
| 183 fn into_iter(self) -> Self::IntoIter { |
186 fn into_iter(self) -> Self::IntoIter { |
| 185 } |
188 } |
| 186 } |
189 } |
| 187 |
190 |
| 188 // Indexing |
191 // Indexing |
| 189 |
192 |
| 190 impl<F, Ix, const N : usize> Index<Ix> for Loc<F,N> |
193 impl<F, Ix, const N: usize> Index<Ix> for Loc<N, F> |
| 191 where [F; N] : Index<Ix> { |
194 where |
| |
195 [F; N]: Index<Ix>, |
| |
196 { |
| 192 type Output = <[F; N] as Index<Ix>>::Output; |
197 type Output = <[F; N] as Index<Ix>>::Output; |
| 193 |
198 |
| 194 #[inline] |
199 #[inline] |
| 195 fn index(&self, ix : Ix) -> &Self::Output { |
200 fn index(&self, ix: Ix) -> &Self::Output { |
| 196 self.0.index(ix) |
201 self.0.index(ix) |
| 197 } |
202 } |
| 198 } |
203 } |
| 199 |
204 |
| 200 impl<F, Ix, const N : usize> IndexMut<Ix> for Loc<F,N> |
205 impl<F, Ix, const N: usize> IndexMut<Ix> for Loc<N, F> |
| 201 where [F; N] : IndexMut<Ix> { |
206 where |
| 202 #[inline] |
207 [F; N]: IndexMut<Ix>, |
| 203 fn index_mut(&mut self, ix : Ix) -> &mut Self::Output { |
208 { |
| |
209 #[inline] |
| |
210 fn index_mut(&mut self, ix: Ix) -> &mut Self::Output { |
| 204 self.0.index_mut(ix) |
211 self.0.index_mut(ix) |
| 205 } |
212 } |
| 206 } |
213 } |
| 207 |
214 |
| 208 // Arithmetic |
215 // Arithmetic |
| 209 |
216 |
| 210 macro_rules! make_binop { |
217 macro_rules! make_binop { |
| 211 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
218 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
| 212 impl<F : Num, const N : usize> $trait<Loc<F,N>> for Loc<F, N> { |
219 impl<F: Num, const N: usize> $trait<Loc<N, F>> for Loc<N, F> { |
| 213 type Output = Loc<F, N>; |
220 type Output = Loc<N, F>; |
| 214 #[inline] |
221 #[inline] |
| 215 fn $fn(mut self, other : Loc<F, N>) -> Self::Output { |
222 fn $fn(mut self, other: Loc<N, F>) -> Self::Output { |
| 216 self.$fn_assign(other); |
223 self.$fn_assign(other); |
| 217 self |
224 self |
| 218 } |
225 } |
| 219 } |
226 } |
| 220 |
227 |
| 221 impl<'a, F : Num, const N : usize> $trait<&'a Loc<F,N>> for Loc<F, N> { |
228 impl<'a, F: Num, const N: usize> $trait<&'a Loc<N, F>> for Loc<N, F> { |
| 222 type Output = Loc<F, N>; |
229 type Output = Loc<N, F>; |
| 223 #[inline] |
230 #[inline] |
| 224 fn $fn(mut self, other : &'a Loc<F, N>) -> Self::Output { |
231 fn $fn(mut self, other: &'a Loc<N, F>) -> Self::Output { |
| 225 self.$fn_assign(other); |
232 self.$fn_assign(other); |
| 226 self |
233 self |
| 227 } |
234 } |
| 228 } |
235 } |
| 229 |
236 |
| 230 impl<'b, F : Num, const N : usize> $trait<Loc<F,N>> for &'b Loc<F, N> { |
237 impl<'b, F: Num, const N: usize> $trait<Loc<N, F>> for &'b Loc<N, F> { |
| 231 type Output = Loc<F, N>; |
238 type Output = Loc<N, F>; |
| 232 #[inline] |
239 #[inline] |
| 233 fn $fn(self, other : Loc<F, N>) -> Self::Output { |
240 fn $fn(self, other: Loc<N, F>) -> Self::Output { |
| 234 self.map2(&other, |a, b| a.$fn(b)) |
241 self.map2(&other, |a, b| a.$fn(b)) |
| 235 } |
242 } |
| 236 } |
243 } |
| 237 |
244 |
| 238 impl<'a, 'b, F : Num, const N : usize> $trait<&'a Loc<F,N>> for &'b Loc<F, N> { |
245 impl<'a, 'b, F: Num, const N: usize> $trait<&'a Loc<N, F>> for &'b Loc<N, F> { |
| 239 type Output = Loc<F, N>; |
246 type Output = Loc<N, F>; |
| 240 #[inline] |
247 #[inline] |
| 241 fn $fn(self, other : &'a Loc<F, N>) -> Self::Output { |
248 fn $fn(self, other: &'a Loc<N, F>) -> Self::Output { |
| 242 self.map2(other, |a, b| a.$fn(b)) |
249 self.map2(other, |a, b| a.$fn(b)) |
| 243 } |
250 } |
| 244 } |
251 } |
| 245 |
252 |
| 246 impl<F : Num, const N : usize> $trait_assign<Loc<F,N>> for Loc<F, N> { |
253 impl<F: Num, const N: usize> $trait_assign<Loc<N, F>> for Loc<N, F> { |
| 247 #[inline] |
254 #[inline] |
| 248 fn $fn_assign(&mut self, other : Loc<F, N>) { |
255 fn $fn_assign(&mut self, other: Loc<N, F>) { |
| 249 self.map2_mut(&other, |a, b| a.$fn_assign(b)) |
256 self.map2_mut(&other, |a, b| a.$fn_assign(b)) |
| 250 } |
257 } |
| 251 } |
258 } |
| 252 |
259 |
| 253 impl<'a, F : Num, const N : usize> $trait_assign<&'a Loc<F,N>> for Loc<F, N> { |
260 impl<'a, F: Num, const N: usize> $trait_assign<&'a Loc<N, F>> for Loc<N, F> { |
| 254 #[inline] |
261 #[inline] |
| 255 fn $fn_assign(&mut self, other : &'a Loc<F, N>) { |
262 fn $fn_assign(&mut self, other: &'a Loc<N, F>) { |
| 256 self.map2_mut(other, |a, b| a.$fn_assign(b)) |
263 self.map2_mut(other, |a, b| a.$fn_assign(b)) |
| 257 } |
264 } |
| 258 } |
265 } |
| 259 } |
266 }; |
| 260 } |
267 } |
| 261 |
268 |
| 262 make_binop!(Add, add, AddAssign, add_assign); |
269 make_binop!(Add, add, AddAssign, add_assign); |
| 263 make_binop!(Sub, sub, SubAssign, sub_assign); |
270 make_binop!(Sub, sub, SubAssign, sub_assign); |
| 264 |
271 |
| 265 impl<F : Float, const N : usize> std::iter::Sum for Loc<F, N> { |
272 impl<F: Float, const N: usize> std::iter::Sum for Loc<N, F> { |
| 266 fn sum<I: Iterator<Item = Loc<F, N>>>(mut iter: I) -> Self { |
273 fn sum<I: Iterator<Item = Loc<N, F>>>(mut iter: I) -> Self { |
| 267 match iter.next() { |
274 match iter.next() { |
| 268 None => Self::ORIGIN, |
275 None => Self::ORIGIN, |
| 269 Some(mut v) => { |
276 Some(mut v) => { |
| 270 for w in iter { |
277 for w in iter { |
| 271 v += w |
278 v += w |
| 276 } |
283 } |
| 277 } |
284 } |
| 278 |
285 |
| 279 macro_rules! make_scalarop_rhs { |
286 macro_rules! make_scalarop_rhs { |
| 280 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
287 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
| 281 impl<F : Num, const N : usize> $trait<F> for Loc<F, N> { |
288 impl<F: Num, const N: usize> $trait<F> for Loc<N, F> { |
| 282 type Output = Loc<F, N>; |
289 type Output = Loc<N, F>; |
| 283 #[inline] |
290 #[inline] |
| 284 fn $fn(self, b : F) -> Self::Output { |
291 fn $fn(self, b: F) -> Self::Output { |
| 285 self.map(|a| a.$fn(b)) |
292 self.map(|a| a.$fn(b)) |
| 286 } |
293 } |
| 287 } |
294 } |
| 288 |
295 |
| 289 impl<'a, F : Num, const N : usize> $trait<&'a F> for Loc<F, N> { |
296 impl<'a, F: Num, const N: usize> $trait<&'a F> for Loc<N, F> { |
| 290 type Output = Loc<F, N>; |
297 type Output = Loc<N, F>; |
| 291 #[inline] |
298 #[inline] |
| 292 fn $fn(self, b : &'a F) -> Self::Output { |
299 fn $fn(self, b: &'a F) -> Self::Output { |
| 293 self.map(|a| a.$fn(*b)) |
300 self.map(|a| a.$fn(*b)) |
| 294 } |
301 } |
| 295 } |
302 } |
| 296 |
303 |
| 297 impl<'b, F : Num, const N : usize> $trait<F> for &'b Loc<F, N> { |
304 impl<'b, F: Num, const N: usize> $trait<F> for &'b Loc<N, F> { |
| 298 type Output = Loc<F, N>; |
305 type Output = Loc<N, F>; |
| 299 #[inline] |
306 #[inline] |
| 300 fn $fn(self, b : F) -> Self::Output { |
307 fn $fn(self, b: F) -> Self::Output { |
| 301 self.map(|a| a.$fn(b)) |
308 self.map(|a| a.$fn(b)) |
| 302 } |
309 } |
| 303 } |
310 } |
| 304 |
311 |
| 305 impl<'a, 'b, F : Float, const N : usize> $trait<&'a F> for &'b Loc<F, N> { |
312 impl<'a, 'b, F: Float, const N: usize> $trait<&'a F> for &'b Loc<N, F> { |
| 306 type Output = Loc<F, N>; |
313 type Output = Loc<N, F>; |
| 307 #[inline] |
314 #[inline] |
| 308 fn $fn(self, b : &'a F) -> Self::Output { |
315 fn $fn(self, b: &'a F) -> Self::Output { |
| 309 self.map(|a| a.$fn(*b)) |
316 self.map(|a| a.$fn(*b)) |
| 310 } |
317 } |
| 311 } |
318 } |
| 312 |
319 |
| 313 impl<F : Num, const N : usize> $trait_assign<F> for Loc<F, N> { |
320 impl<F: Num, const N: usize> $trait_assign<F> for Loc<N, F> { |
| 314 #[inline] |
321 #[inline] |
| 315 fn $fn_assign(&mut self, b : F) { |
322 fn $fn_assign(&mut self, b: F) { |
| 316 self.map_mut(|a| a.$fn_assign(b)); |
323 self.map_mut(|a| a.$fn_assign(b)); |
| 317 } |
324 } |
| 318 } |
325 } |
| 319 |
326 |
| 320 impl<'a, F : Num, const N : usize> $trait_assign<&'a F> for Loc<F, N> { |
327 impl<'a, F: Num, const N: usize> $trait_assign<&'a F> for Loc<N, F> { |
| 321 #[inline] |
328 #[inline] |
| 322 fn $fn_assign(&mut self, b : &'a F) { |
329 fn $fn_assign(&mut self, b: &'a F) { |
| 323 self.map_mut(|a| a.$fn_assign(*b)); |
330 self.map_mut(|a| a.$fn_assign(*b)); |
| 324 } |
331 } |
| 325 } |
332 } |
| 326 } |
333 }; |
| 327 } |
334 } |
| 328 |
|
| 329 |
335 |
| 330 make_scalarop_rhs!(Mul, mul, MulAssign, mul_assign); |
336 make_scalarop_rhs!(Mul, mul, MulAssign, mul_assign); |
| 331 make_scalarop_rhs!(Div, div, DivAssign, div_assign); |
337 make_scalarop_rhs!(Div, div, DivAssign, div_assign); |
| 332 |
338 |
| 333 macro_rules! make_unaryop { |
339 macro_rules! make_unaryop { |
| 334 ($trait:ident, $fn:ident) => { |
340 ($trait:ident, $fn:ident) => { |
| 335 impl<F : SignedNum, const N : usize> $trait for Loc<F, N> { |
341 impl<F: SignedNum, const N: usize> $trait for Loc<N, F> { |
| 336 type Output = Loc<F, N>; |
342 type Output = Loc<N, F>; |
| 337 #[inline] |
343 #[inline] |
| 338 fn $fn(mut self) -> Self::Output { |
344 fn $fn(mut self) -> Self::Output { |
| 339 self.map_mut(|a| *a = (*a).$fn()); |
345 self.map_mut(|a| *a = (*a).$fn()); |
| 340 self |
346 self |
| 341 } |
347 } |
| 342 } |
348 } |
| 343 |
349 |
| 344 impl<'a, F : SignedNum, const N : usize> $trait for &'a Loc<F, N> { |
350 impl<'a, F: SignedNum, const N: usize> $trait for &'a Loc<N, F> { |
| 345 type Output = Loc<F, N>; |
351 type Output = Loc<N, F>; |
| 346 #[inline] |
352 #[inline] |
| 347 fn $fn(self) -> Self::Output { |
353 fn $fn(self) -> Self::Output { |
| 348 self.map(|a| a.$fn()) |
354 self.map(|a| a.$fn()) |
| 349 } |
355 } |
| 350 } |
356 } |
| 351 } |
357 }; |
| 352 } |
358 } |
| 353 |
359 |
| 354 make_unaryop!(Neg, neg); |
360 make_unaryop!(Neg, neg); |
| 355 |
361 |
| 356 macro_rules! make_scalarop_lhs { |
362 macro_rules! make_scalarop_lhs { |
| 357 ($trait:ident, $fn:ident; $($f:ident)+) => { $( |
363 ($trait:ident, $fn:ident; $($f:ident)+) => { $( |
| 358 impl<const N : usize> $trait<Loc<$f,N>> for $f { |
364 impl<const N : usize> $trait<Loc<N, $f>> for $f { |
| 359 type Output = Loc<$f, N>; |
365 type Output = Loc<N, $f>; |
| 360 #[inline] |
366 #[inline] |
| 361 fn $fn(self, v : Loc<$f,N>) -> Self::Output { |
367 fn $fn(self, v : Loc<N, $f>) -> Self::Output { |
| 362 v.map(|b| self.$fn(b)) |
368 v.map(|b| self.$fn(b)) |
| 363 } |
369 } |
| 364 } |
370 } |
| 365 |
371 |
| 366 impl<'a, const N : usize> $trait<&'a Loc<$f,N>> for $f { |
372 impl<'a, const N : usize> $trait<&'a Loc<N, $f>> for $f { |
| 367 type Output = Loc<$f, N>; |
373 type Output = Loc<N, $f>; |
| 368 #[inline] |
374 #[inline] |
| 369 fn $fn(self, v : &'a Loc<$f,N>) -> Self::Output { |
375 fn $fn(self, v : &'a Loc<N, $f>) -> Self::Output { |
| 370 v.map(|b| self.$fn(b)) |
376 v.map(|b| self.$fn(b)) |
| 371 } |
377 } |
| 372 } |
378 } |
| 373 |
379 |
| 374 impl<'b, const N : usize> $trait<Loc<$f,N>> for &'b $f { |
380 impl<'b, const N : usize> $trait<Loc<N, $f>> for &'b $f { |
| 375 type Output = Loc<$f, N>; |
381 type Output = Loc<N, $f>; |
| 376 #[inline] |
382 #[inline] |
| 377 fn $fn(self, v : Loc<$f,N>) -> Self::Output { |
383 fn $fn(self, v : Loc<N, $f>) -> Self::Output { |
| 378 v.map(|b| self.$fn(b)) |
384 v.map(|b| self.$fn(b)) |
| 379 } |
385 } |
| 380 } |
386 } |
| 381 |
387 |
| 382 impl<'a, 'b, const N : usize> $trait<&'a Loc<$f,N>> for &'b $f { |
388 impl<'a, 'b, const N : usize> $trait<&'a Loc<N, $f>> for &'b $f { |
| 383 type Output = Loc<$f, N>; |
389 type Output = Loc<N, $f>; |
| 384 #[inline] |
390 #[inline] |
| 385 fn $fn(self, v : &'a Loc<$f, N>) -> Self::Output { |
391 fn $fn(self, v : &'a Loc<N, $f>) -> Self::Output { |
| 386 v.map(|b| self.$fn(b)) |
392 v.map(|b| self.$fn(b)) |
| 387 } |
393 } |
| 388 } |
394 } |
| 389 )+ } |
395 )+ } |
| 390 } |
396 } |
| 427 |
433 |
| 428 domination!(Linfinity, L1); |
434 domination!(Linfinity, L1); |
| 429 domination!(Linfinity, L2); |
435 domination!(Linfinity, L2); |
| 430 domination!(L2, L1); |
436 domination!(L2, L1); |
| 431 |
437 |
| 432 impl<F : Float,const N : usize> Euclidean<F> for Loc<F, N> { |
438 impl<F: Float, const N: usize> Euclidean<F> for Loc<N, F> { |
| 433 type Output = Self; |
439 type PrincipalE = Self; |
| 434 |
440 |
| 435 /// This implementation is not stabilised as it's meant to be used for very small vectors. |
441 /// This implementation is not stabilised as it's meant to be used for very small vectors. |
| 436 /// Use [`nalgebra`] for larger vectors. |
442 /// Use [`nalgebra`] for larger vectors. |
| 437 #[inline] |
443 #[inline] |
| 438 fn dot<I : Instance<Self>>(&self, other : I) -> F { |
444 fn dot<I: Instance<Self>>(&self, other: I) -> F { |
| 439 self.0.iter() |
445 other.eval_ref(|r| { |
| 440 .zip(other.ref_instance().0.iter()) |
446 self.0 |
| 441 .fold(F::ZERO, |m, (&v, &w)| m + v * w) |
447 .iter() |
| |
448 .zip(r.0.iter()) |
| |
449 .fold(F::ZERO, |m, (&v, &w)| m + v * w) |
| |
450 }) |
| 442 } |
451 } |
| 443 |
452 |
| 444 /// This implementation is not stabilised as it's meant to be used for very small vectors. |
453 /// This implementation is not stabilised as it's meant to be used for very small vectors. |
| 445 /// Use [`nalgebra`] for larger vectors. |
454 /// Use [`nalgebra`] for larger vectors. |
| 446 #[inline] |
455 #[inline] |
| 447 fn norm2_squared(&self) -> F { |
456 fn norm2_squared(&self) -> F { |
| 448 self.iter().fold(F::ZERO, |m, &v| m + v * v) |
457 self.iter().fold(F::ZERO, |m, &v| m + v * v) |
| 449 } |
458 } |
| 450 |
459 |
| 451 fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F { |
460 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { |
| 452 self.iter() |
461 other.eval_ref(|r| { |
| 453 .zip(other.ref_instance().iter()) |
462 self.iter().zip(r.iter()).fold(F::ZERO, |m, (&v, &w)| { |
| 454 .fold(F::ZERO, |m, (&v, &w)| { let d = v - w; m + d * d }) |
463 let d = v - w; |
| |
464 m + d * d |
| |
465 }) |
| |
466 }) |
| 455 } |
467 } |
| 456 |
468 |
| 457 #[inline] |
469 #[inline] |
| 458 fn norm2(&self) -> F { |
470 fn norm2(&self) -> F { |
| 459 // Optimisation for N==1 that avoids squaring and square rooting. |
471 // Optimisation for N==1 that avoids squaring and square rooting. |
| 460 if N==1 { |
472 if N == 1 { |
| 461 unsafe { self.0.get_unchecked(0) }.abs() |
473 unsafe { self.0.get_unchecked(0) }.abs() |
| 462 } else { |
474 } else { |
| 463 self.norm2_squared().sqrt() |
475 self.norm2_squared().sqrt() |
| 464 } |
476 } |
| 465 } |
477 } |
| 466 |
478 |
| 467 #[inline] |
479 #[inline] |
| 468 fn dist2<I : Instance<Self>>(&self, other : I) -> F { |
480 fn dist2<I: Instance<Self>>(&self, other: I) -> F { |
| 469 // Optimisation for N==1 that avoids squaring and square rooting. |
481 // Optimisation for N==1 that avoids squaring and square rooting. |
| 470 let otherr = other.ref_instance(); |
482 if N == 1 { |
| 471 if N==1 { |
483 other.eval_ref(|r| unsafe { *self.0.get_unchecked(0) - *r.0.get_unchecked(0) }.abs()) |
| 472 unsafe { *self.0.get_unchecked(0) - *otherr.0.get_unchecked(0) }.abs() |
|
| 473 } else { |
484 } else { |
| 474 self.dist2_squared(other).sqrt() |
485 self.dist2_squared(other).sqrt() |
| 475 } |
486 } |
| 476 } |
487 } |
| 477 } |
488 } |
| 478 |
489 |
| 479 impl<F : Num, const N : usize> Loc<F, N> { |
490 impl<F: Num, const N: usize> Loc<N, F> { |
| 480 /// Origin point |
491 /// Origin point |
| 481 pub const ORIGIN : Self = Loc([F::ZERO; N]); |
492 pub const ORIGIN: Self = Loc([F::ZERO; N]); |
| 482 } |
493 } |
| 483 |
494 |
| 484 impl<F : Num + std::ops::Neg<Output=F>, const N : usize> Loc<F, N> { |
495 impl<F: Num + std::ops::Neg<Output = F>, const N: usize> Loc<N, F> { |
| 485 /// Reflects along the given coordinate |
496 /// Reflects along the given coordinate |
| 486 pub fn reflect(mut self, i : usize) -> Self { |
497 pub fn reflect(mut self, i: usize) -> Self { |
| 487 self[i] = -self[i]; |
498 self[i] = -self[i]; |
| 488 self |
499 self |
| 489 } |
500 } |
| 490 |
501 |
| 491 /// Reflects along the given coordinate sequences |
502 /// Reflects along the given coordinate sequences |
| 492 pub fn reflect_many<I : IntoIterator<Item=usize>>(mut self, idxs : I) -> Self { |
503 pub fn reflect_many<I: IntoIterator<Item = usize>>(mut self, idxs: I) -> Self { |
| 493 for i in idxs { |
504 for i in idxs { |
| 494 self[i]=-self[i] |
505 self[i] = -self[i] |
| 495 } |
506 } |
| 496 self |
507 self |
| 497 } |
508 } |
| 498 } |
509 } |
| 499 |
510 |
| 500 impl<F : std::ops::Neg<Output=F>> Loc<F, 2> { |
511 impl<F: std::ops::Neg<Output = F>> Loc<2, F> { |
| 501 /// Reflect x coordinate |
512 /// Reflect x coordinate |
| 502 pub fn reflect_x(self) -> Self { |
513 pub fn reflect_x(self) -> Self { |
| 503 let Loc([x, y]) = self; |
514 let Loc([x, y]) = self; |
| 504 [-x, y].into() |
515 [-x, y].into() |
| 505 } |
516 } |
| 540 let Loc([x, y, z]) = self; |
550 let Loc([x, y, z]) = self; |
| 541 [x, y, -z].into() |
551 [x, y, -z].into() |
| 542 } |
552 } |
| 543 } |
553 } |
| 544 |
554 |
| 545 impl<F : Float> Loc<F, 3> { |
555 impl<F: Float> Loc<3, F> { |
| 546 /// Rotate by angles (yaw, pitch, roll) |
556 /// Rotate by angles (yaw, pitch, roll) |
| 547 pub fn rotate(self, Loc([φ, ψ, θ]) : Self) -> Self { |
557 pub fn rotate(self, Loc([φ, ψ, θ]): Self) -> Self { |
| 548 let Loc([mut x, mut y, mut z]) = self; |
558 let Loc([mut x, mut y, mut z]) = self; |
| 549 let sin_φ = φ.sin(); |
559 let sin_φ = φ.sin(); |
| 550 let cos_φ = φ.cos(); |
560 let cos_φ = φ.cos(); |
| 551 [x, y, z] = [cos_φ * x - sin_φ *y, |
561 [x, y, z] = [cos_φ * x - sin_φ * y, sin_φ * x + cos_φ * y, z]; |
| 552 sin_φ * x + cos_φ * y, |
|
| 553 z]; |
|
| 554 let sin_ψ = ψ.sin(); |
562 let sin_ψ = ψ.sin(); |
| 555 let cos_ψ = ψ.cos(); |
563 let cos_ψ = ψ.cos(); |
| 556 [x, y, z] = [cos_ψ * x + sin_ψ * z, |
564 [x, y, z] = [cos_ψ * x + sin_ψ * z, y, -sin_ψ * x + cos_ψ * z]; |
| 557 y, |
|
| 558 -sin_ψ * x + cos_ψ * z]; |
|
| 559 let sin_θ = θ.sin(); |
565 let sin_θ = θ.sin(); |
| 560 let cos_θ = θ.cos(); |
566 let cos_θ = θ.cos(); |
| 561 [x, y, z] = [x, |
567 [x, y, z] = [x, cos_θ * y - sin_θ * z, sin_θ * y + cos_θ * z]; |
| 562 cos_θ * y - sin_θ * z, |
|
| 563 sin_θ * y + cos_θ * z]; |
|
| 564 [x, y, z].into() |
568 [x, y, z].into() |
| 565 } |
569 } |
| 566 } |
570 } |
| 567 |
571 |
| 568 impl<F : Float,const N : usize> StaticEuclidean<F> for Loc<F, N> { |
572 impl<F: Float, const N: usize> StaticEuclidean<F> for Loc<N, F> { |
| 569 #[inline] |
573 #[inline] |
| 570 fn origin() -> Self { |
574 fn origin() -> Self { |
| 571 Self::ORIGIN |
575 Self::ORIGIN |
| 572 } |
576 } |
| 573 } |
577 } |
| 574 |
578 |
| 575 |
|
| 576 /// The default norm for `Loc` is [`L2`]. |
579 /// The default norm for `Loc` is [`L2`]. |
| 577 impl<F : Float, const N : usize> Normed<F> for Loc<F, N> { |
580 impl<F: Float, const N: usize> Normed<F> for Loc<N, F> { |
| 578 type NormExp = L2; |
581 type NormExp = L2; |
| 579 |
582 |
| 580 #[inline] |
583 #[inline] |
| 581 fn norm_exponent(&self) -> Self::NormExp { |
584 fn norm_exponent(&self) -> Self::NormExp { |
| 582 L2 |
585 L2 |
| 591 fn is_zero(&self) -> bool { |
594 fn is_zero(&self) -> bool { |
| 592 self.norm2_squared() == F::ZERO |
595 self.norm2_squared() == F::ZERO |
| 593 } |
596 } |
| 594 } |
597 } |
| 595 |
598 |
| 596 impl<F : Float, const N : usize> HasDual<F> for Loc<F, N> { |
599 impl<F: Float, const N: usize> HasDual<F> for Loc<N, F> { |
| 597 type DualSpace = Self; |
600 type DualSpace = Self; |
| 598 } |
601 |
| 599 |
602 fn dual_origin(&self) -> Self::DualSpace { |
| 600 impl<F : Float, const N : usize> Norm<F, L2> for Loc<F, N> { |
603 self.similar_origin() |
| 601 #[inline] |
604 } |
| 602 fn norm(&self, _ : L2) -> F { self.norm2() } |
605 } |
| 603 } |
606 |
| 604 |
607 impl<F: Float, const N: usize> Norm<L2, F> for Loc<N, F> { |
| 605 impl<F : Float, const N : usize> Dist<F, L2> for Loc<F, N> { |
608 #[inline] |
| 606 #[inline] |
609 fn norm(&self, _: L2) -> F { |
| 607 fn dist<I : Instance<Self>>(&self, other : I, _ : L2) -> F { self.dist2(other) } |
610 self.norm2() |
| |
611 } |
| |
612 } |
| |
613 |
| |
614 impl<F: Float, const N: usize> Dist<L2, F> for Loc<N, F> { |
| |
615 #[inline] |
| |
616 fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> F { |
| |
617 self.dist2(other) |
| |
618 } |
| 608 } |
619 } |
| 609 |
620 |
| 610 /* Implemented automatically as Euclidean. |
621 /* Implemented automatically as Euclidean. |
| 611 impl<F : Float, const N : usize> Projection<F, L2> for Loc<F, N> { |
622 impl<F : Float, const N : usize> Projection<F, L2> for Loc<N, F> { |
| 612 #[inline] |
623 #[inline] |
| 613 fn proj_ball_mut(&mut self, ρ : F, nrm : L2) { |
624 fn proj_ball_mut(&mut self, ρ : F, nrm : L2) { |
| 614 let n = self.norm(nrm); |
625 let n = self.norm(nrm); |
| 615 if n > ρ { |
626 if n > ρ { |
| 616 *self *= ρ/n; |
627 *self *= ρ/n; |
| 617 } |
628 } |
| 618 } |
629 } |
| 619 }*/ |
630 }*/ |
| 620 |
631 |
| 621 impl<F : Float, const N : usize> Norm<F, L1> for Loc<F, N> { |
632 impl<F: Float, const N: usize> Norm<L1, F> for Loc<N, F> { |
| 622 /// This implementation is not stabilised as it's meant to be used for very small vectors. |
633 /// This implementation is not stabilised as it's meant to be used for very small vectors. |
| 623 /// Use [`nalgebra`] for larger vectors. |
634 /// Use [`nalgebra`] for larger vectors. |
| 624 #[inline] |
635 #[inline] |
| 625 fn norm(&self, _ : L1) -> F { |
636 fn norm(&self, _: L1) -> F { |
| 626 self.iter().fold(F::ZERO, |m, v| m + v.abs()) |
637 self.iter().fold(F::ZERO, |m, v| m + v.abs()) |
| 627 } |
638 } |
| 628 } |
639 } |
| 629 |
640 |
| 630 impl<F : Float, const N : usize> Dist<F, L1> for Loc<F, N> { |
641 impl<F: Float, const N: usize> Dist<L1, F> for Loc<N, F> { |
| 631 #[inline] |
642 #[inline] |
| 632 fn dist<I : Instance<Self>>(&self, other : I, _ : L1) -> F { |
643 fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> F { |
| 633 self.iter() |
644 other.eval_ref(|r| { |
| 634 .zip(other.ref_instance().iter()) |
645 self.iter() |
| 635 .fold(F::ZERO, |m, (&v, &w)| m + (v-w).abs() ) |
646 .zip(r.iter()) |
| 636 } |
647 .fold(F::ZERO, |m, (&v, &w)| m + (v - w).abs()) |
| 637 } |
648 }) |
| 638 |
649 } |
| 639 impl<F : Float, const N : usize> Projection<F, Linfinity> for Loc<F, N> { |
650 } |
| 640 #[inline] |
651 |
| 641 fn proj_ball_mut(&mut self, ρ : F, _ : Linfinity) { |
652 impl<F: Float, const N: usize> Projection<F, Linfinity> for Loc<N, F> { |
| 642 self.iter_mut().for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) |
653 #[inline] |
| 643 } |
654 fn proj_ball(mut self, ρ: F, exp: Linfinity) -> Self { |
| 644 } |
655 self.proj_ball_mut(ρ, exp); |
| 645 |
656 self |
| 646 impl<F : Float, const N : usize> Norm<F, Linfinity> for Loc<F, N> { |
657 } |
| |
658 } |
| |
659 |
| |
660 impl<F: Float, const N: usize> ProjectionMut<F, Linfinity> for Loc<N, F> { |
| |
661 #[inline] |
| |
662 fn proj_ball_mut(&mut self, ρ: F, _: Linfinity) { |
| |
663 self.iter_mut() |
| |
664 .for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) |
| |
665 } |
| |
666 } |
| |
667 |
| |
668 impl<F: Float, const N: usize> Norm<Linfinity, F> for Loc<N, F> { |
| 647 /// This implementation is not stabilised as it's meant to be used for very small vectors. |
669 /// This implementation is not stabilised as it's meant to be used for very small vectors. |
| 648 /// Use [`nalgebra`] for larger vectors. |
670 /// Use [`nalgebra`] for larger vectors. |
| 649 #[inline] |
671 #[inline] |
| 650 fn norm(&self, _ : Linfinity) -> F { |
672 fn norm(&self, _: Linfinity) -> F { |
| 651 self.iter().fold(F::ZERO, |m, v| m.max(v.abs())) |
673 self.iter().fold(F::ZERO, |m, v| m.max(v.abs())) |
| 652 } |
674 } |
| 653 } |
675 } |
| 654 |
676 |
| 655 impl<F : Float, const N : usize> Dist<F, Linfinity> for Loc<F, N> { |
677 impl<F: Float, const N: usize> Dist<Linfinity, F> for Loc<N, F> { |
| 656 #[inline] |
678 #[inline] |
| 657 fn dist<I : Instance<Self>>(&self, other : I, _ : Linfinity) -> F { |
679 fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> F { |
| 658 self.iter() |
680 other.eval_ref(|r| { |
| 659 .zip(other.ref_instance().iter()) |
681 self.iter() |
| 660 .fold(F::ZERO, |m, (&v, &w)| m.max((v-w).abs())) |
682 .zip(r.iter()) |
| 661 } |
683 .fold(F::ZERO, |m, (&v, &w)| m.max((v - w).abs())) |
| 662 } |
684 }) |
| 663 |
685 } |
| |
686 } |
| 664 |
687 |
| 665 // Misc. |
688 // Misc. |
| 666 |
689 |
| 667 impl<A, const N : usize> FixedLength<N> for Loc<A,N> { |
690 impl<A, const N: usize> FixedLength<N> for Loc<N, A> { |
| 668 type Iter = std::array::IntoIter<A, N>; |
691 type Iter = std::array::IntoIter<A, N>; |
| 669 type Elem = A; |
692 type Elem = A; |
| 670 #[inline] |
693 #[inline] |
| 671 fn fl_iter(self) -> Self::Iter { |
694 fn fl_iter(self) -> Self::Iter { |
| 672 self.into_iter() |
695 self.into_iter() |
| 673 } |
696 } |
| 674 } |
697 } |
| 675 |
698 |
| 676 impl<A, const N : usize> FixedLengthMut<N> for Loc<A,N> { |
699 impl<A, const N: usize> FixedLengthMut<N> for Loc<N, A> { |
| 677 type IterMut<'a> = std::slice::IterMut<'a, A> where A : 'a; |
700 type IterMut<'a> |
| |
701 = std::slice::IterMut<'a, A> |
| |
702 where |
| |
703 A: 'a; |
| 678 #[inline] |
704 #[inline] |
| 679 fn fl_iter_mut(&mut self) -> Self::IterMut<'_> { |
705 fn fl_iter_mut(&mut self) -> Self::IterMut<'_> { |
| 680 self.iter_mut() |
706 self.iter_mut() |
| 681 } |
707 } |
| 682 } |
708 } |
| 683 |
709 |
| 684 impl<'a, A, const N : usize> FixedLength<N> for &'a Loc<A,N> { |
710 impl<'a, A, const N: usize> FixedLength<N> for &'a Loc<N, A> { |
| 685 type Iter = std::slice::Iter<'a, A>; |
711 type Iter = std::slice::Iter<'a, A>; |
| 686 type Elem = &'a A; |
712 type Elem = &'a A; |
| 687 #[inline] |
713 #[inline] |
| 688 fn fl_iter(self) -> Self::Iter { |
714 fn fl_iter(self) -> Self::Iter { |
| 689 self.iter() |
715 self.iter() |
| 690 } |
716 } |
| 691 } |
717 } |
| 692 |
718 |
| 693 |
719 impl<F: Num, const N: usize> Space for Loc<N, F> { |
| 694 impl<F : Num, const N : usize> Space for Loc<F, N> { |
720 type Principal = Self; |
| 695 type Decomp = BasicDecomposition; |
721 type Decomp = BasicDecomposition; |
| 696 } |
722 } |
| 697 |
723 |
| 698 impl<F : Float, const N : usize> Mapping<Loc<F, N>> for Loc<F, N> { |
724 impl<F: Float, const N: usize> Mapping<Loc<N, F>> for Loc<N, F> { |
| 699 type Codomain = F; |
725 type Codomain = F; |
| 700 |
726 |
| 701 fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain { |
727 fn apply<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Codomain { |
| 702 x.eval(|x̃| self.dot(x̃)) |
728 x.eval_decompose(|x̃| self.dot(x̃)) |
| 703 } |
729 } |
| 704 } |
730 } |
| 705 |
731 |
| 706 impl<F : Float, const N : usize> Linear<Loc<F, N>> for Loc<F, N> { } |
732 impl<F: Float, const N: usize> Linear<Loc<N, F>> for Loc<N, F> {} |
| 707 |
733 |
| 708 impl<F : Float, const N : usize> AXPY<F, Loc<F, N>> for Loc<F, N> { |
734 impl<F: Float, const N: usize> VectorSpace for Loc<N, F> { |
| 709 type Owned = Self; |
735 type Field = F; |
| 710 |
736 type PrincipalV = Self; |
| 711 #[inline] |
737 |
| 712 fn axpy<I : Instance<Loc<F, N>>>(&mut self, α : F, x : I, β : F) { |
738 // #[inline] |
| 713 x.eval(|x̃| { |
739 // fn make_origin_generator(&self) -> StaticEuclideanOriginGenerator { |
| |
740 // StaticEuclideanOriginGenerator |
| |
741 // } |
| |
742 |
| |
743 #[inline] |
| |
744 fn similar_origin(&self) -> Self::PrincipalV { |
| |
745 Self::ORIGIN |
| |
746 } |
| |
747 |
| |
748 #[inline] |
| |
749 fn similar_origin_inst<I: Instance<Self>>(_: I) -> Self::PrincipalV { |
| |
750 Self::ORIGIN |
| |
751 } |
| |
752 |
| |
753 // #[inline] |
| |
754 // fn into_owned(self) -> Self::Owned { |
| |
755 // self |
| |
756 // } |
| |
757 } |
| |
758 |
| |
759 impl<F: Float, const N: usize> AXPY<Loc<N, F>> for Loc<N, F> { |
| |
760 #[inline] |
| |
761 fn axpy<I: Instance<Loc<N, F>>>(&mut self, α: F, x: I, β: F) { |
| |
762 x.eval_ref(|x̃| { |
| 714 if β == F::ZERO { |
763 if β == F::ZERO { |
| 715 map2_mut(self, x̃, |yi, xi| { *yi = α * (*xi) }) |
764 map2_mut(self, x̃, |yi, xi| *yi = α * (*xi)) |
| 716 } else { |
765 } else { |
| 717 map2_mut(self, x̃, |yi, xi| { *yi = β * (*yi) + α * (*xi) }) |
766 map2_mut(self, x̃, |yi, xi| *yi = β * (*yi) + α * (*xi)) |
| 718 } |
767 } |
| 719 }) |
768 }) |
| 720 } |
769 } |
| 721 |
770 |
| 722 #[inline] |
771 #[inline] |
| 723 fn copy_from<I : Instance<Loc<F, N>>>(&mut self, x : I) { |
772 fn copy_from<I: Instance<Loc<N, F>>>(&mut self, x: I) { |
| 724 x.eval(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi )) |
773 x.eval_ref(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi)) |
| 725 } |
|
| 726 |
|
| 727 #[inline] |
|
| 728 fn similar_origin(&self) -> Self::Owned { |
|
| 729 Self::ORIGIN |
|
| 730 } |
774 } |
| 731 |
775 |
| 732 #[inline] |
776 #[inline] |
| 733 fn set_zero(&mut self) { |
777 fn set_zero(&mut self) { |
| 734 *self = Self::ORIGIN; |
778 *self = Self::ORIGIN; |
| 735 } |
779 } |
| 736 } |
780 } |
| 737 |
|