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