src/loc.rs

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

mercurial