Mon, 06 Jan 2025 20:29:25 -0500
More Serialize / Deserialize / Debug derives
0 | 1 | /*! |
5 | 2 | Array containers that support vector space operations on floats. |
3 | For working with small vectors in $ℝ^2$ or $ℝ^3$. | |
0 | 4 | */ |
5 | ||
6 | use std::ops::{Add,Sub,AddAssign,SubAssign,Mul,Div,MulAssign,DivAssign,Neg,Index,IndexMut}; | |
7 | use std::slice::{Iter,IterMut}; | |
43 | 8 | use std::fmt::{Display, Formatter}; |
0 | 9 | use crate::types::{Float,Num,SignedNum}; |
10 | use crate::maputil::{FixedLength,FixedLengthMut,map1,map2,map1_mut,map2_mut}; | |
5 | 11 | use crate::euclidean::*; |
0 | 12 | use crate::norms::*; |
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
13 | use crate::linops::{AXPY, Mapping, Linear}; |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
14 | use crate::instance::{Instance, BasicDecomposition}; |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
15 | use crate::mapping::Space; |
86
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
16 | use serde::{Serialize, Deserialize}; |
0 | 17 | |
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
18 | |
5 | 19 | /// A container type for (short) `N`-dimensional vectors of element type `F`. |
20 | /// | |
21 | /// Supports basic operations of an [`Euclidean`] space, several [`Norm`]s, and | |
22 | /// fused [`AXPY`] operations, among others. | |
86
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
23 | #[derive(Copy,Clone,Debug,PartialEq,Eq,Serialize,Deserialize)] |
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
24 | #[serde(bound( |
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
25 | serialize = "[F; N] : Serialize", |
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
26 | deserialize = "[F; N] : for<'a> Deserialize<'a>" |
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
27 | ))] |
5 | 28 | pub struct Loc<F, const N : usize>( |
29 | /// An array of the elements of the vector | |
30 | pub [F; N] | |
31 | ); | |
0 | 32 | |
43 | 33 | impl<F : Display, const N : usize> Display for Loc<F, N>{ |
34 | // Required method | |
35 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | |
36 | write!(f, "[")?; | |
37 | let mut comma = ""; | |
38 | for e in self.iter() { | |
39 | write!(f, "{comma}{e}")?; | |
40 | comma = ", "; | |
41 | } | |
42 | write!(f, "]") | |
43 | } | |
44 | } | |
45 | ||
0 | 46 | impl<F, const N : usize> Loc<F, N> { |
5 | 47 | /// Creates a new `Loc` vector from an array. |
0 | 48 | #[inline] |
49 | pub fn new(arr : [F; N]) -> Self { | |
50 | Loc(arr) | |
51 | } | |
5 | 52 | |
53 | /// Returns an iterator over the elements of the vector | |
0 | 54 | #[inline] |
55 | pub fn iter(&self) -> Iter<'_, F> { | |
56 | self.0.iter() | |
57 | } | |
58 | ||
5 | 59 | /// Returns an iterator over mutable references to the elements of the vector |
0 | 60 | #[inline] |
61 | pub fn iter_mut(&mut self) -> IterMut<'_, F> { | |
62 | self.0.iter_mut() | |
63 | } | |
64 | } | |
65 | ||
66 | impl<F : Copy, const N : usize> Loc<F, N> { | |
5 | 67 | /// Maps `g` over the elements of the vector, returning a new [`Loc`] vector |
0 | 68 | #[inline] |
5 | 69 | pub fn map<H>(&self, g : impl Fn(F) -> H) -> Loc<H, N> { |
0 | 70 | Loc::new(map1(self, |u| g(*u))) |
71 | } | |
72 | ||
5 | 73 | /// Maps `g` over pairs of elements of two vectors, retuning a new one. |
0 | 74 | #[inline] |
5 | 75 | pub fn map2<H>(&self, other : &Self, g : impl Fn(F, F) -> H) -> Loc<H, N> { |
0 | 76 | Loc::new(map2(self, other, |u, v| g(*u, *v))) |
77 | } | |
78 | ||
5 | 79 | /// Maps `g` over mutable references to elements of the vector. |
0 | 80 | #[inline] |
5 | 81 | pub fn map_mut(&mut self, g : impl Fn(&mut F)) { |
0 | 82 | map1_mut(self, g) |
83 | } | |
84 | ||
5 | 85 | /// Maps `g` over pairs of mutable references to elements of `self, and elements |
86 | /// of `other` vector. | |
0 | 87 | #[inline] |
5 | 88 | pub fn map2_mut(&mut self, other : &Self, g : impl Fn(&mut F, F)) { |
0 | 89 | map2_mut(self, other, |u, v| g(u, *v)) |
90 | } | |
91 | ||
5 | 92 | /// Maps `g` over the elements of `self` and returns the product of the results. |
0 | 93 | #[inline] |
5 | 94 | pub fn product_map<A : Num>(&self, g : impl Fn(F) -> A) -> A { |
0 | 95 | match N { |
5 | 96 | 1 => g(unsafe { *self.0.get_unchecked(0) }), |
97 | 2 => g(unsafe { *self.0.get_unchecked(0) }) * | |
98 | g(unsafe { *self.0.get_unchecked(1) }), | |
99 | 3 => g(unsafe { *self.0.get_unchecked(0) }) * | |
100 | g(unsafe { *self.0.get_unchecked(1) }) * | |
101 | g(unsafe { *self.0.get_unchecked(2) }), | |
102 | _ => self.iter().fold(A::ONE, |m, &x| m * g(x)) | |
0 | 103 | } |
104 | } | |
105 | } | |
106 | ||
5 | 107 | /// Construct a [`Loc`]. |
108 | /// | |
109 | /// Use as | |
110 | /// ``` | |
111 | /// # use alg_tools::loc::Loc; | |
112 | /// # use alg_tools::loc; | |
113 | /// let x = loc![1.0, 2.0]; | |
114 | /// ``` | |
0 | 115 | #[macro_export] |
116 | macro_rules! loc { | |
117 | ($($x:expr),+ $(,)?) => { Loc::new([$($x),+]) } | |
118 | } | |
119 | ||
120 | ||
121 | impl<F, const N : usize> From<[F; N]> for Loc<F, N> { | |
122 | #[inline] | |
123 | fn from(other: [F; N]) -> Loc<F, N> { | |
124 | Loc(other) | |
125 | } | |
126 | } | |
127 | ||
128 | /*impl<F : Copy, const N : usize> From<&[F; N]> for Loc<F, N> { | |
129 | #[inline] | |
130 | fn from(other: &[F; N]) -> Loc<F, N> { | |
131 | Loc(*other) | |
132 | } | |
133 | }*/ | |
134 | ||
135 | impl<F> From<F> for Loc<F, 1> { | |
136 | #[inline] | |
137 | fn from(other: F) -> Loc<F, 1> { | |
138 | Loc([other]) | |
139 | } | |
140 | } | |
141 | ||
35
3b82a9d16307
Add Mapping codomain slicing and RealVectorField
Tuomo Valkonen <tuomov@iki.fi>
parents:
28
diff
changeset
|
142 | impl<F> Loc<F, 1> { |
3b82a9d16307
Add Mapping codomain slicing and RealVectorField
Tuomo Valkonen <tuomov@iki.fi>
parents:
28
diff
changeset
|
143 | #[inline] |
3b82a9d16307
Add Mapping codomain slicing and RealVectorField
Tuomo Valkonen <tuomov@iki.fi>
parents:
28
diff
changeset
|
144 | pub fn flatten1d(self) -> F { |
3b82a9d16307
Add Mapping codomain slicing and RealVectorField
Tuomo Valkonen <tuomov@iki.fi>
parents:
28
diff
changeset
|
145 | let Loc([v]) = self; |
3b82a9d16307
Add Mapping codomain slicing and RealVectorField
Tuomo Valkonen <tuomov@iki.fi>
parents:
28
diff
changeset
|
146 | v |
3b82a9d16307
Add Mapping codomain slicing and RealVectorField
Tuomo Valkonen <tuomov@iki.fi>
parents:
28
diff
changeset
|
147 | } |
3b82a9d16307
Add Mapping codomain slicing and RealVectorField
Tuomo Valkonen <tuomov@iki.fi>
parents:
28
diff
changeset
|
148 | } |
3b82a9d16307
Add Mapping codomain slicing and RealVectorField
Tuomo Valkonen <tuomov@iki.fi>
parents:
28
diff
changeset
|
149 | |
0 | 150 | impl<F, const N : usize> From<Loc<F, N>> for [F; N] { |
151 | #[inline] | |
152 | fn from(other : Loc<F, N>) -> [F; N] { | |
153 | other.0 | |
154 | } | |
155 | } | |
156 | ||
157 | /*impl<F : Copy, const N : usize> From<&Loc<F, N>> for [F; N] { | |
158 | #[inline] | |
159 | fn from(other : &Loc<F, N>) -> [F; N] { | |
160 | other.0 | |
161 | } | |
162 | }*/ | |
163 | ||
164 | ||
165 | impl<F, const N : usize> IntoIterator for Loc<F, N> { | |
166 | type Item = <[F; N] as IntoIterator>::Item; | |
167 | type IntoIter = <[F; N] as IntoIterator>::IntoIter; | |
168 | ||
169 | #[inline] | |
170 | fn into_iter(self) -> Self::IntoIter { | |
171 | self.0.into_iter() | |
172 | } | |
173 | } | |
174 | ||
175 | // Indexing | |
176 | ||
177 | impl<F, Ix, const N : usize> Index<Ix> for Loc<F,N> | |
178 | where [F; N] : Index<Ix> { | |
179 | type Output = <[F; N] as Index<Ix>>::Output; | |
180 | ||
181 | #[inline] | |
182 | fn index(&self, ix : Ix) -> &Self::Output { | |
183 | self.0.index(ix) | |
184 | } | |
185 | } | |
186 | ||
187 | impl<F, Ix, const N : usize> IndexMut<Ix> for Loc<F,N> | |
188 | where [F; N] : IndexMut<Ix> { | |
189 | #[inline] | |
190 | fn index_mut(&mut self, ix : Ix) -> &mut Self::Output { | |
191 | self.0.index_mut(ix) | |
192 | } | |
193 | } | |
194 | ||
195 | // Arithmetic | |
196 | ||
197 | macro_rules! make_binop { | |
198 | ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { | |
199 | impl<F : Num, const N : usize> $trait<Loc<F,N>> for Loc<F, N> { | |
200 | type Output = Loc<F, N>; | |
201 | #[inline] | |
202 | fn $fn(mut self, other : Loc<F, N>) -> Self::Output { | |
203 | self.$fn_assign(other); | |
204 | self | |
205 | } | |
206 | } | |
207 | ||
208 | impl<'a, F : Num, const N : usize> $trait<&'a Loc<F,N>> for Loc<F, N> { | |
209 | type Output = Loc<F, N>; | |
210 | #[inline] | |
211 | fn $fn(mut self, other : &'a Loc<F, N>) -> Self::Output { | |
212 | self.$fn_assign(other); | |
213 | self | |
214 | } | |
215 | } | |
216 | ||
217 | impl<'b, F : Num, const N : usize> $trait<Loc<F,N>> for &'b Loc<F, N> { | |
218 | type Output = Loc<F, N>; | |
219 | #[inline] | |
220 | fn $fn(self, other : Loc<F, N>) -> Self::Output { | |
221 | self.map2(&other, |a, b| a.$fn(b)) | |
222 | } | |
223 | } | |
224 | ||
225 | impl<'a, 'b, F : Num, const N : usize> $trait<&'a Loc<F,N>> for &'b Loc<F, N> { | |
226 | type Output = Loc<F, N>; | |
227 | #[inline] | |
228 | fn $fn(self, other : &'a Loc<F, N>) -> Self::Output { | |
229 | self.map2(other, |a, b| a.$fn(b)) | |
230 | } | |
231 | } | |
232 | ||
233 | impl<F : Num, const N : usize> $trait_assign<Loc<F,N>> for Loc<F, N> { | |
234 | #[inline] | |
235 | fn $fn_assign(&mut self, other : Loc<F, N>) { | |
236 | self.map2_mut(&other, |a, b| a.$fn_assign(b)) | |
237 | } | |
238 | } | |
239 | ||
240 | impl<'a, F : Num, const N : usize> $trait_assign<&'a Loc<F,N>> for Loc<F, N> { | |
241 | #[inline] | |
242 | fn $fn_assign(&mut self, other : &'a Loc<F, N>) { | |
243 | self.map2_mut(other, |a, b| a.$fn_assign(b)) | |
244 | } | |
245 | } | |
246 | } | |
247 | } | |
248 | ||
249 | make_binop!(Add, add, AddAssign, add_assign); | |
250 | make_binop!(Sub, sub, SubAssign, sub_assign); | |
251 | ||
28
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
252 | impl<F : Float, const N : usize> std::iter::Sum for Loc<F, N> { |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
253 | fn sum<I: Iterator<Item = Loc<F, N>>>(mut iter: I) -> Self { |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
254 | match iter.next() { |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
255 | None => Self::ORIGIN, |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
256 | Some(mut v) => { |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
257 | for w in iter { |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
258 | v += w |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
259 | } |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
260 | v |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
261 | } |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
262 | } |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
263 | } |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
264 | } |
331345346e7b
Implement std::iter::Sum for Loc<F, N>
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
265 | |
0 | 266 | macro_rules! make_scalarop_rhs { |
267 | ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { | |
268 | impl<F : Num, const N : usize> $trait<F> for Loc<F, N> { | |
269 | type Output = Loc<F, N>; | |
270 | #[inline] | |
271 | fn $fn(self, b : F) -> Self::Output { | |
272 | self.map(|a| a.$fn(b)) | |
273 | } | |
274 | } | |
275 | ||
276 | impl<'a, F : Num, const N : usize> $trait<&'a F> for Loc<F, N> { | |
277 | type Output = Loc<F, N>; | |
278 | #[inline] | |
279 | fn $fn(self, b : &'a F) -> Self::Output { | |
280 | self.map(|a| a.$fn(*b)) | |
281 | } | |
282 | } | |
283 | ||
284 | impl<'b, F : Num, const N : usize> $trait<F> for &'b Loc<F, N> { | |
285 | type Output = Loc<F, N>; | |
286 | #[inline] | |
287 | fn $fn(self, b : F) -> Self::Output { | |
288 | self.map(|a| a.$fn(b)) | |
289 | } | |
290 | } | |
291 | ||
292 | impl<'a, 'b, F : Float, const N : usize> $trait<&'a F> for &'b Loc<F, N> { | |
293 | type Output = Loc<F, N>; | |
294 | #[inline] | |
295 | fn $fn(self, b : &'a F) -> Self::Output { | |
296 | self.map(|a| a.$fn(*b)) | |
297 | } | |
298 | } | |
299 | ||
300 | impl<F : Num, const N : usize> $trait_assign<F> for Loc<F, N> { | |
301 | #[inline] | |
302 | fn $fn_assign(&mut self, b : F) { | |
303 | self.map_mut(|a| a.$fn_assign(b)); | |
304 | } | |
305 | } | |
306 | ||
307 | impl<'a, F : Num, const N : usize> $trait_assign<&'a F> for Loc<F, N> { | |
308 | #[inline] | |
309 | fn $fn_assign(&mut self, b : &'a F) { | |
310 | self.map_mut(|a| a.$fn_assign(*b)); | |
311 | } | |
312 | } | |
313 | } | |
314 | } | |
315 | ||
316 | ||
317 | make_scalarop_rhs!(Mul, mul, MulAssign, mul_assign); | |
318 | make_scalarop_rhs!(Div, div, DivAssign, div_assign); | |
319 | ||
320 | macro_rules! make_unaryop { | |
321 | ($trait:ident, $fn:ident) => { | |
322 | impl<F : SignedNum, const N : usize> $trait for Loc<F, N> { | |
323 | type Output = Loc<F, N>; | |
324 | #[inline] | |
325 | fn $fn(mut self) -> Self::Output { | |
326 | self.map_mut(|a| *a = (*a).$fn()); | |
327 | self | |
328 | } | |
329 | } | |
330 | ||
331 | impl<'a, F : SignedNum, const N : usize> $trait for &'a Loc<F, N> { | |
332 | type Output = Loc<F, N>; | |
333 | #[inline] | |
334 | fn $fn(self) -> Self::Output { | |
335 | self.map(|a| a.$fn()) | |
336 | } | |
337 | } | |
338 | } | |
339 | } | |
340 | ||
341 | make_unaryop!(Neg, neg); | |
342 | ||
343 | macro_rules! make_scalarop_lhs { | |
344 | ($trait:ident, $fn:ident; $($f:ident)+) => { $( | |
345 | impl<const N : usize> $trait<Loc<$f,N>> for $f { | |
346 | type Output = Loc<$f, N>; | |
347 | #[inline] | |
348 | fn $fn(self, v : Loc<$f,N>) -> Self::Output { | |
349 | v.map(|b| self.$fn(b)) | |
350 | } | |
351 | } | |
352 | ||
353 | impl<'a, const N : usize> $trait<&'a Loc<$f,N>> for $f { | |
354 | type Output = Loc<$f, N>; | |
355 | #[inline] | |
356 | fn $fn(self, v : &'a Loc<$f,N>) -> Self::Output { | |
357 | v.map(|b| self.$fn(b)) | |
358 | } | |
359 | } | |
360 | ||
361 | impl<'b, const N : usize> $trait<Loc<$f,N>> for &'b $f { | |
362 | type Output = Loc<$f, N>; | |
363 | #[inline] | |
364 | fn $fn(self, v : Loc<$f,N>) -> Self::Output { | |
365 | v.map(|b| self.$fn(b)) | |
366 | } | |
367 | } | |
368 | ||
369 | impl<'a, 'b, const N : usize> $trait<&'a Loc<$f,N>> for &'b $f { | |
370 | type Output = Loc<$f, N>; | |
371 | #[inline] | |
372 | fn $fn(self, v : &'a Loc<$f, N>) -> Self::Output { | |
373 | v.map(|b| self.$fn(b)) | |
374 | } | |
375 | } | |
376 | )+ } | |
377 | } | |
378 | ||
379 | make_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize); | |
380 | make_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize); | |
381 | ||
382 | // Norms | |
383 | ||
384 | macro_rules! domination { | |
385 | ($norm:ident, $dominates:ident) => { | |
386 | impl<F : Float, const N : usize> Dominated<F, $dominates, Loc<F, N>> for $norm { | |
387 | #[inline] | |
388 | fn norm_factor(&self, _p : $dominates) -> F { | |
389 | F::ONE | |
390 | } | |
391 | #[inline] | |
392 | fn from_norm(&self, p_norm : F, _p : $dominates) -> F { | |
393 | p_norm | |
394 | } | |
395 | } | |
396 | }; | |
397 | ($norm:ident, $dominates:ident, $fn:path) => { | |
398 | impl<F : Float, const N : usize> Dominated<F, $dominates, Loc<F, N>> for $norm { | |
399 | #[inline] | |
400 | fn norm_factor(&self, _p : $dominates) -> F { | |
401 | $fn(F::cast_from(N)) | |
402 | } | |
403 | } | |
404 | }; | |
405 | } | |
406 | ||
407 | domination!(L1, L1); | |
408 | domination!(L2, L2); | |
409 | domination!(Linfinity, Linfinity); | |
410 | ||
411 | domination!(L1, L2, F::sqrt); | |
412 | domination!(L2, Linfinity, F::sqrt); | |
413 | domination!(L1, Linfinity, std::convert::identity); | |
414 | ||
415 | domination!(Linfinity, L1); | |
416 | domination!(Linfinity, L2); | |
417 | domination!(L2, L1); | |
418 | ||
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
419 | impl<F : Float,const N : usize> Euclidean<F> for Loc<F, N> { |
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
420 | type Output = Self; |
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
421 | |
0 | 422 | /// This implementation is not stabilised as it's meant to be used for very small vectors. |
423 | /// Use [`nalgebra`] for larger vectors. | |
424 | #[inline] | |
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
425 | fn dot<I : Instance<Self>>(&self, other : I) -> F { |
0 | 426 | self.0.iter() |
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
427 | .zip(other.ref_instance().0.iter()) |
0 | 428 | .fold(F::ZERO, |m, (&v, &w)| m + v * w) |
429 | } | |
430 | ||
431 | /// This implementation is not stabilised as it's meant to be used for very small vectors. | |
432 | /// Use [`nalgebra`] for larger vectors. | |
433 | #[inline] | |
434 | fn norm2_squared(&self) -> F { | |
435 | self.iter().fold(F::ZERO, |m, &v| m + v * v) | |
436 | } | |
437 | ||
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
438 | fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F { |
0 | 439 | self.iter() |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
440 | .zip(other.ref_instance().iter()) |
0 | 441 | .fold(F::ZERO, |m, (&v, &w)| { let d = v - w; m + d * d }) |
442 | } | |
443 | ||
444 | #[inline] | |
445 | fn norm2(&self) -> F { | |
446 | // Optimisation for N==1 that avoids squaring and square rooting. | |
447 | if N==1 { | |
448 | unsafe { self.0.get_unchecked(0) }.abs() | |
449 | } else { | |
450 | self.norm2_squared().sqrt() | |
451 | } | |
452 | } | |
453 | ||
454 | #[inline] | |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
455 | fn dist2<I : Instance<Self>>(&self, other : I) -> F { |
0 | 456 | // Optimisation for N==1 that avoids squaring and square rooting. |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
457 | let otherr = other.ref_instance(); |
0 | 458 | if N==1 { |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
459 | unsafe { *self.0.get_unchecked(0) - *otherr.0.get_unchecked(0) }.abs() |
0 | 460 | } else { |
461 | self.dist2_squared(other).sqrt() | |
462 | } | |
463 | } | |
464 | } | |
465 | ||
466 | impl<F : Num, const N : usize> Loc<F, N> { | |
52 | 467 | /// Origin point |
0 | 468 | pub const ORIGIN : Self = Loc([F::ZERO; N]); |
469 | } | |
470 | ||
52 | 471 | impl<F : Num + std::ops::Neg<Output=F>, const N : usize> Loc<F, N> { |
472 | /// Reflects along the given coordinate | |
473 | pub fn reflect(mut self, i : usize) -> Self { | |
474 | self[i] = -self[i]; | |
475 | self | |
476 | } | |
477 | ||
478 | /// Reflects along the given coordinate sequences | |
479 | pub fn reflect_many<I : IntoIterator<Item=usize>>(mut self, idxs : I) -> Self { | |
480 | for i in idxs { | |
481 | self[i]=-self[i] | |
482 | } | |
483 | self | |
484 | } | |
485 | } | |
486 | ||
487 | impl<F : std::ops::Neg<Output=F>> Loc<F, 2> { | |
488 | /// Reflect x coordinate | |
489 | pub fn reflect_x(self) -> Self { | |
490 | let Loc([x, y]) = self; | |
491 | [-x, y].into() | |
492 | } | |
493 | ||
494 | /// Reflect y coordinate | |
495 | pub fn reflect_y(self) -> Self { | |
496 | let Loc([x, y]) = self; | |
497 | [x, -y].into() | |
498 | } | |
499 | } | |
500 | ||
501 | impl<F : Float> Loc<F, 2> { | |
502 | /// Rotate by angle φ | |
503 | pub fn rotate(self, φ : F) -> Self { | |
504 | let Loc([x, y]) = self; | |
505 | let sin_φ = φ.sin(); | |
506 | let cos_φ = φ.cos(); | |
507 | [cos_φ * x - sin_φ * y, | |
508 | sin_φ * x + cos_φ * y].into() | |
509 | } | |
510 | } | |
511 | ||
512 | impl<F : std::ops::Neg<Output=F>> Loc<F, 3> { | |
513 | /// Reflect x coordinate | |
514 | pub fn reflect_x(self) -> Self { | |
515 | let Loc([x, y, z]) = self; | |
516 | [-x, y, z].into() | |
517 | } | |
518 | ||
519 | /// Reflect y coordinate | |
520 | pub fn reflect_y(self) -> Self { | |
521 | let Loc([x, y, z]) = self; | |
522 | [x, -y, z].into() | |
523 | } | |
524 | ||
525 | /// Reflect y coordinate | |
526 | pub fn reflect_z(self) -> Self { | |
527 | let Loc([x, y, z]) = self; | |
528 | [x, y, -z].into() | |
529 | } | |
530 | } | |
531 | ||
532 | impl<F : Float> Loc<F, 3> { | |
533 | /// Rotate by angles (yaw, pitch, roll) | |
534 | pub fn rotate(self, Loc([φ, ψ, θ]) : Self) -> Self { | |
535 | let Loc([mut x, mut y, mut z]) = self; | |
536 | let sin_φ = φ.sin(); | |
537 | let cos_φ = φ.cos(); | |
538 | [x, y, z] = [cos_φ * x - sin_φ *y, | |
539 | sin_φ * x + cos_φ * y, | |
540 | z]; | |
541 | let sin_ψ = ψ.sin(); | |
542 | let cos_ψ = ψ.cos(); | |
543 | [x, y, z] = [cos_ψ * x + sin_ψ * z, | |
544 | y, | |
545 | -sin_ψ * x + cos_ψ * z]; | |
546 | let sin_θ = θ.sin(); | |
547 | let cos_θ = θ.cos(); | |
548 | [x, y, z] = [x, | |
549 | cos_θ * y - sin_θ * z, | |
550 | sin_θ * y + cos_θ * z]; | |
551 | [x, y, z].into() | |
552 | } | |
553 | } | |
554 | ||
0 | 555 | impl<F : Float,const N : usize> StaticEuclidean<F> for Loc<F, N> { |
556 | #[inline] | |
557 | fn origin() -> Self { | |
558 | Self::ORIGIN | |
559 | } | |
560 | } | |
561 | ||
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
562 | |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
563 | /// The default norm for `Loc` is [`L2`]. |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
564 | impl<F : Float, const N : usize> Normed<F> for Loc<F, N> { |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
565 | type NormExp = L2; |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
566 | |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
567 | #[inline] |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
568 | fn norm_exponent(&self) -> Self::NormExp { |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
569 | L2 |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
570 | } |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
571 | |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
572 | // #[inline] |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
573 | // fn similar_origin(&self) -> Self { |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
574 | // [F::ZERO; N].into() |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
575 | // } |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
576 | |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
577 | #[inline] |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
578 | fn is_zero(&self) -> bool { |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
579 | self.norm2_squared() == F::ZERO |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
580 | } |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
581 | } |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
582 | |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
583 | impl<F : Float, const N : usize> HasDual<F> for Loc<F, N> { |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
584 | type DualSpace = Self; |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
585 | } |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
586 | |
0 | 587 | impl<F : Float, const N : usize> Norm<F, L2> for Loc<F, N> { |
588 | #[inline] | |
589 | fn norm(&self, _ : L2) -> F { self.norm2() } | |
590 | } | |
591 | ||
592 | impl<F : Float, const N : usize> Dist<F, L2> for Loc<F, N> { | |
593 | #[inline] | |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
594 | fn dist<I : Instance<Self>>(&self, other : I, _ : L2) -> F { self.dist2(other) } |
0 | 595 | } |
596 | ||
60
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
597 | /* Implemented automatically as Euclidean. |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
598 | impl<F : Float, const N : usize> Projection<F, L2> for Loc<F, N> { |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
599 | #[inline] |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
600 | fn proj_ball_mut(&mut self, ρ : F, nrm : L2) { |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
601 | let n = self.norm(nrm); |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
602 | if n > ρ { |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
603 | *self *= ρ/n; |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
604 | } |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
605 | } |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
606 | }*/ |
848ecc05becf
More convexity, normed spaces, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
59
diff
changeset
|
607 | |
0 | 608 | impl<F : Float, const N : usize> Norm<F, L1> for Loc<F, N> { |
609 | /// This implementation is not stabilised as it's meant to be used for very small vectors. | |
610 | /// Use [`nalgebra`] for larger vectors. | |
611 | #[inline] | |
612 | fn norm(&self, _ : L1) -> F { | |
613 | self.iter().fold(F::ZERO, |m, v| m + v.abs()) | |
614 | } | |
615 | } | |
616 | ||
617 | impl<F : Float, const N : usize> Dist<F, L1> for Loc<F, N> { | |
618 | #[inline] | |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
619 | fn dist<I : Instance<Self>>(&self, other : I, _ : L1) -> F { |
0 | 620 | self.iter() |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
621 | .zip(other.ref_instance().iter()) |
0 | 622 | .fold(F::ZERO, |m, (&v, &w)| m + (v-w).abs() ) |
623 | } | |
624 | } | |
625 | ||
626 | impl<F : Float, const N : usize> Projection<F, Linfinity> for Loc<F, N> { | |
627 | #[inline] | |
628 | fn proj_ball_mut(&mut self, ρ : F, _ : Linfinity) { | |
629 | self.iter_mut().for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ)) | |
630 | } | |
631 | } | |
632 | ||
633 | impl<F : Float, const N : usize> Norm<F, Linfinity> for Loc<F, N> { | |
634 | /// This implementation is not stabilised as it's meant to be used for very small vectors. | |
635 | /// Use [`nalgebra`] for larger vectors. | |
636 | #[inline] | |
637 | fn norm(&self, _ : Linfinity) -> F { | |
638 | self.iter().fold(F::ZERO, |m, v| m.max(v.abs())) | |
639 | } | |
640 | } | |
641 | ||
642 | impl<F : Float, const N : usize> Dist<F, Linfinity> for Loc<F, N> { | |
643 | #[inline] | |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
644 | fn dist<I : Instance<Self>>(&self, other : I, _ : Linfinity) -> F { |
0 | 645 | self.iter() |
64
4f6ca107ccb1
More Instance parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents:
63
diff
changeset
|
646 | .zip(other.ref_instance().iter()) |
0 | 647 | .fold(F::ZERO, |m, (&v, &w)| m.max((v-w).abs())) |
648 | } | |
649 | } | |
650 | ||
651 | ||
652 | // Misc. | |
653 | ||
654 | impl<A, const N : usize> FixedLength<N> for Loc<A,N> { | |
655 | type Iter = std::array::IntoIter<A, N>; | |
656 | type Elem = A; | |
657 | #[inline] | |
658 | fn fl_iter(self) -> Self::Iter { | |
659 | self.into_iter() | |
660 | } | |
661 | } | |
662 | ||
663 | impl<A, const N : usize> FixedLengthMut<N> for Loc<A,N> { | |
664 | type IterMut<'a> = std::slice::IterMut<'a, A> where A : 'a; | |
665 | #[inline] | |
666 | fn fl_iter_mut(&mut self) -> Self::IterMut<'_> { | |
667 | self.iter_mut() | |
668 | } | |
669 | } | |
670 | ||
671 | impl<'a, A, const N : usize> FixedLength<N> for &'a Loc<A,N> { | |
672 | type Iter = std::slice::Iter<'a, A>; | |
673 | type Elem = &'a A; | |
674 | #[inline] | |
675 | fn fl_iter(self) -> Self::Iter { | |
676 | self.iter() | |
677 | } | |
678 | } | |
679 | ||
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
680 | |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
681 | impl<F : Num, const N : usize> Space for Loc<F, N> { |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
682 | type Decomp = BasicDecomposition; |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
683 | } |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
684 | |
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
685 | impl<F : Float, const N : usize> Mapping<Loc<F, N>> for Loc<F, N> { |
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
686 | type Codomain = F; |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
687 | |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
688 | fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain { |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
689 | x.eval(|x̃| self.dot(x̃)) |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
690 | } |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
691 | } |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
692 | |
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
693 | impl<F : Float, const N : usize> Linear<Loc<F, N>> for Loc<F, N> { } |
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
694 | |
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
695 | impl<F : Float, const N : usize> AXPY<F, Loc<F, N>> for Loc<F, N> { |
62
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
696 | type Owned = Self; |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
697 | |
0 | 698 | #[inline] |
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
699 | fn axpy<I : Instance<Loc<F, N>>>(&mut self, α : F, x : I, β : F) { |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
700 | x.eval(|x̃| { |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
701 | if β == F::ZERO { |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
702 | map2_mut(self, x̃, |yi, xi| { *yi = α * (*xi) }) |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
703 | } else { |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
704 | map2_mut(self, x̃, |yi, xi| { *yi = β * (*yi) + α * (*xi) }) |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
705 | } |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
706 | }) |
0 | 707 | } |
708 | ||
709 | #[inline] | |
59
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
710 | fn copy_from<I : Instance<Loc<F, N>>>(&mut self, x : I) { |
9226980e45a7
Significantly simplify Mapping / Apply through Instance
Tuomo Valkonen <tuomov@iki.fi>
parents:
52
diff
changeset
|
711 | x.eval(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi )) |
0 | 712 | } |
62
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
713 | |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
714 | #[inline] |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
715 | fn similar_origin(&self) -> Self::Owned { |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
716 | Self::ORIGIN |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
717 | } |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
718 | |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
719 | #[inline] |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
720 | fn set_zero(&mut self) { |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
721 | *self = Self::ORIGIN; |
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
722 | } |
0 | 723 | } |
62
d8305c9b6fdf
Move origin stuff to AXPY form Euclidean
Tuomo Valkonen <tuomov@iki.fi>
parents:
60
diff
changeset
|
724 |