src/loc.rs

branch
dev
changeset 124
6aa955ad8122
parent 64
4f6ca107ccb1
child 129
d2994e34a5f5
--- a/src/loc.rs	Thu May 01 08:40:33 2025 -0500
+++ b/src/loc.rs	Thu May 01 13:06:58 2025 -0500
@@ -3,44 +3,45 @@
 For working with small vectors in $ℝ^2$ or $ℝ^3$.
 */
 
-use std::ops::{Add,Sub,AddAssign,SubAssign,Mul,Div,MulAssign,DivAssign,Neg,Index,IndexMut};
-use std::slice::{Iter,IterMut};
+use crate::euclidean::*;
+use crate::instance::{BasicDecomposition, Instance};
+use crate::linops::{Linear, Mapping, AXPY};
+use crate::mapping::Space;
+use crate::maputil::{map1, map1_mut, map2, map2_mut, FixedLength, FixedLengthMut};
+use crate::norms::*;
+use crate::types::{Float, Num, SignedNum};
+use serde::ser::{Serialize, SerializeSeq, Serializer};
 use std::fmt::{Display, Formatter};
-use crate::types::{Float,Num,SignedNum};
-use crate::maputil::{FixedLength,FixedLengthMut,map1,map2,map1_mut,map2_mut};
-use crate::euclidean::*;
-use crate::norms::*;
-use crate::linops::{AXPY, Mapping, Linear};
-use crate::instance::{Instance, BasicDecomposition};
-use crate::mapping::Space;
-use serde::ser::{Serialize, Serializer, SerializeSeq};
-
+use std::ops::{
+    Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
+};
+use std::slice::{Iter, IterMut};
 
 /// A container type for (short) `N`-dimensional vectors of element type `F`.
 ///
 /// Supports basic operations of an [`Euclidean`] space, several [`Norm`]s, and
 /// fused [`AXPY`] operations, among others.
-#[derive(Copy,Clone,Debug,PartialEq,Eq)]
-pub struct Loc<F, const N : usize>(
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct Loc<const N: usize, F = f64>(
     /// An array of the elements of the vector
-    pub [F; N]
+    pub [F; N],
 );
 
-impl<F : Display, const N : usize> Display for Loc<F, N>{
+impl<F: Display, const N: usize> Display for Loc<N, F> {
     // Required method
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
-         write!(f, "[")?;
-         let mut comma = "";
-         for e in self.iter() {
+        write!(f, "[")?;
+        let mut comma = "";
+        for e in self.iter() {
             write!(f, "{comma}{e}")?;
             comma = ", ";
-         }
-         write!(f, "]")
+        }
+        write!(f, "]")
     }
 }
 
 // Need to manually implement as [F; N] serialisation is provided only for some N.
-impl<F, const N : usize> Serialize for Loc<F, N>
+impl<F, const N: usize> Serialize for Loc<N, F>
 where
     F: Serialize,
 {
@@ -56,10 +57,10 @@
     }
 }
 
-impl<F, const N : usize> Loc<F, N> {
+impl<F, const N: usize> Loc<N, F> {
     /// Creates a new `Loc` vector from an array.
     #[inline]
-    pub fn new(arr : [F; N]) -> Self {
+    pub fn new(arr: [F; N]) -> Self {
         Loc(arr)
     }
 
@@ -76,43 +77,44 @@
     }
 }
 
-impl<F : Copy, const N : usize> Loc<F, N> {
+impl<F: Copy, const N: usize> Loc<N, F> {
     /// Maps `g` over the elements of the vector, returning a new [`Loc`] vector
     #[inline]
-    pub fn map<H>(&self, g : impl Fn(F) -> H) -> Loc<H, N> {
+    pub fn map<H>(&self, g: impl Fn(F) -> H) -> Loc<N, H> {
         Loc::new(map1(self, |u| g(*u)))
     }
 
     /// Maps `g` over pairs of elements of two vectors, retuning a new one.
     #[inline]
-    pub fn map2<H>(&self, other : &Self, g : impl Fn(F, F) -> H) -> Loc<H, N> {
+    pub fn map2<H>(&self, other: &Self, g: impl Fn(F, F) -> H) -> Loc<N, H> {
         Loc::new(map2(self, other, |u, v| g(*u, *v)))
     }
 
     /// Maps `g` over mutable references to elements of the vector.
     #[inline]
-    pub fn map_mut(&mut self, g : impl Fn(&mut F)) {
+    pub fn map_mut(&mut self, g: impl Fn(&mut F)) {
         map1_mut(self, g)
     }
 
     /// Maps `g` over pairs of mutable references to elements of `self, and elements
     /// of `other` vector.
     #[inline]
-    pub fn map2_mut(&mut self, other : &Self, g : impl Fn(&mut F, F)) {
+    pub fn map2_mut(&mut self, other: &Self, g: impl Fn(&mut F, F)) {
         map2_mut(self, other, |u, v| g(u, *v))
     }
 
     /// Maps `g` over the elements of `self` and returns the product of the results.
     #[inline]
-    pub fn product_map<A : Num>(&self, g : impl Fn(F) -> A) -> A {
+    pub fn product_map<A: Num>(&self, g: impl Fn(F) -> A) -> A {
         match N {
             1 => g(unsafe { *self.0.get_unchecked(0) }),
-            2 => g(unsafe { *self.0.get_unchecked(0) }) *
-                 g(unsafe { *self.0.get_unchecked(1) }),
-            3 => g(unsafe { *self.0.get_unchecked(0) }) *
-                 g(unsafe { *self.0.get_unchecked(1) }) *
-                 g(unsafe { *self.0.get_unchecked(2) }),
-            _ => self.iter().fold(A::ONE, |m, &x| m * g(x))
+            2 => g(unsafe { *self.0.get_unchecked(0) }) * g(unsafe { *self.0.get_unchecked(1) }),
+            3 => {
+                g(unsafe { *self.0.get_unchecked(0) })
+                    * g(unsafe { *self.0.get_unchecked(1) })
+                    * g(unsafe { *self.0.get_unchecked(2) })
+            }
+            _ => self.iter().fold(A::ONE, |m, &x| m * g(x)),
         }
     }
 }
@@ -130,29 +132,28 @@
     ($($x:expr),+ $(,)?) => { Loc::new([$($x),+]) }
 }
 
-
-impl<F, const N : usize> From<[F; N]> for Loc<F, N> {
+impl<F, const N: usize> From<[F; N]> for Loc<N, F> {
     #[inline]
-    fn from(other: [F; N]) -> Loc<F, N> {
+    fn from(other: [F; N]) -> Loc<N, F> {
         Loc(other)
     }
 }
 
-/*impl<F : Copy, const N : usize> From<&[F; N]> for Loc<F, N> {
+/*impl<F : Copy, const N : usize> From<&[F; N]> for Loc<N, F> {
     #[inline]
-    fn from(other: &[F; N]) -> Loc<F, N> {
+    fn from(other: &[F; N]) -> Loc<N, F> {
         Loc(*other)
     }
 }*/
 
-impl<F> From<F> for Loc<F, 1> {
+impl<F> From<F> for Loc<1, F> {
     #[inline]
-    fn from(other: F) -> Loc<F, 1> {
+    fn from(other: F) -> Loc<1, F> {
         Loc([other])
     }
 }
 
-impl<F> Loc<F, 1> {
+impl<F> Loc<1, F> {
     #[inline]
     pub fn flatten1d(self) -> F {
         let Loc([v]) = self;
@@ -160,22 +161,21 @@
     }
 }
 
-impl<F, const N : usize> From<Loc<F, N>> for [F; N] {
+impl<F, const N: usize> From<Loc<N, F>> for [F; N] {
     #[inline]
-    fn from(other : Loc<F, N>) -> [F; N] {
+    fn from(other: Loc<N, F>) -> [F; N] {
         other.0
     }
 }
 
-/*impl<F : Copy, const N : usize> From<&Loc<F, N>> for [F; N] {
+/*impl<F : Copy, const N : usize> From<&Loc<N, F>> for [F; N] {
     #[inline]
-    fn from(other : &Loc<F, N>) -> [F; N] {
+    fn from(other : &Loc<N, F>) -> [F; N] {
         other.0
     }
 }*/
 
-
-impl<F, const N : usize> IntoIterator for Loc<F, N> {
+impl<F, const N: usize> IntoIterator for Loc<N, F> {
     type Item = <[F; N] as IntoIterator>::Item;
     type IntoIter = <[F; N] as IntoIterator>::IntoIter;
 
@@ -187,20 +187,24 @@
 
 // Indexing
 
-impl<F, Ix, const N : usize> Index<Ix> for Loc<F,N>
-where [F; N] : Index<Ix> {
+impl<F, Ix, const N: usize> Index<Ix> for Loc<N, F>
+where
+    [F; N]: Index<Ix>,
+{
     type Output = <[F; N] as Index<Ix>>::Output;
 
     #[inline]
-    fn index(&self, ix : Ix) -> &Self::Output {
+    fn index(&self, ix: Ix) -> &Self::Output {
         self.0.index(ix)
     }
 }
 
-impl<F, Ix, const N : usize> IndexMut<Ix> for Loc<F,N>
-where [F; N] : IndexMut<Ix> {
+impl<F, Ix, const N: usize> IndexMut<Ix> for Loc<N, F>
+where
+    [F; N]: IndexMut<Ix>,
+{
     #[inline]
-    fn index_mut(&mut self, ix : Ix) -> &mut Self::Output {
+    fn index_mut(&mut self, ix: Ix) -> &mut Self::Output {
         self.0.index_mut(ix)
     }
 }
@@ -209,61 +213,61 @@
 
 macro_rules! make_binop {
     ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => {
-        impl<F : Num, const N : usize> $trait<Loc<F,N>> for Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<F: Num, const N: usize> $trait<Loc<N, F>> for Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
-            fn $fn(mut self, other : Loc<F, N>) -> Self::Output {
+            fn $fn(mut self, other: Loc<N, F>) -> Self::Output {
                 self.$fn_assign(other);
                 self
             }
         }
 
-        impl<'a, F : Num, const N : usize> $trait<&'a Loc<F,N>> for Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<'a, F: Num, const N: usize> $trait<&'a Loc<N, F>> for Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
-            fn $fn(mut self, other : &'a Loc<F, N>) -> Self::Output {
+            fn $fn(mut self, other: &'a Loc<N, F>) -> Self::Output {
                 self.$fn_assign(other);
                 self
             }
         }
 
-        impl<'b, F : Num, const N : usize> $trait<Loc<F,N>> for &'b Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<'b, F: Num, const N: usize> $trait<Loc<N, F>> for &'b Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
-            fn $fn(self, other : Loc<F, N>) -> Self::Output {
+            fn $fn(self, other: Loc<N, F>) -> Self::Output {
                 self.map2(&other, |a, b| a.$fn(b))
             }
         }
 
-        impl<'a, 'b, F : Num, const N : usize> $trait<&'a Loc<F,N>> for &'b Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<'a, 'b, F: Num, const N: usize> $trait<&'a Loc<N, F>> for &'b Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
-            fn $fn(self, other : &'a Loc<F, N>) -> Self::Output {
+            fn $fn(self, other: &'a Loc<N, F>) -> Self::Output {
                 self.map2(other, |a, b| a.$fn(b))
             }
         }
 
-       impl<F : Num, const N : usize> $trait_assign<Loc<F,N>> for Loc<F, N> {
+        impl<F: Num, const N: usize> $trait_assign<Loc<N, F>> for Loc<N, F> {
             #[inline]
-            fn $fn_assign(&mut self, other : Loc<F, N>) {
+            fn $fn_assign(&mut self, other: Loc<N, F>) {
                 self.map2_mut(&other, |a, b| a.$fn_assign(b))
             }
         }
 
-        impl<'a, F : Num, const N : usize> $trait_assign<&'a Loc<F,N>> for Loc<F, N> {
+        impl<'a, F: Num, const N: usize> $trait_assign<&'a Loc<N, F>> for Loc<N, F> {
             #[inline]
-            fn $fn_assign(&mut self, other : &'a Loc<F, N>) {
+            fn $fn_assign(&mut self, other: &'a Loc<N, F>) {
                 self.map2_mut(other, |a, b| a.$fn_assign(b))
             }
         }
-    }
+    };
 }
 
 make_binop!(Add, add, AddAssign, add_assign);
 make_binop!(Sub, sub, SubAssign, sub_assign);
 
-impl<F : Float, const N : usize> std::iter::Sum for Loc<F, N> {
-    fn sum<I: Iterator<Item = Loc<F, N>>>(mut iter: I) -> Self {
+impl<F: Float, const N: usize> std::iter::Sum for Loc<N, F> {
+    fn sum<I: Iterator<Item = Loc<N, F>>>(mut iter: I) -> Self {
         match iter.next() {
             None => Self::ORIGIN,
             Some(mut v) => {
@@ -278,62 +282,61 @@
 
 macro_rules! make_scalarop_rhs {
     ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => {
-        impl<F : Num, const N : usize> $trait<F> for Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<F: Num, const N: usize> $trait<F> for Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
-            fn $fn(self, b : F) -> Self::Output {
+            fn $fn(self, b: F) -> Self::Output {
                 self.map(|a| a.$fn(b))
             }
         }
 
-        impl<'a, F : Num, const N : usize> $trait<&'a F> for Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<'a, F: Num, const N: usize> $trait<&'a F> for Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
-            fn $fn(self, b : &'a F) -> Self::Output {
+            fn $fn(self, b: &'a F) -> Self::Output {
                 self.map(|a| a.$fn(*b))
             }
         }
 
-        impl<'b, F : Num, const N : usize> $trait<F> for &'b Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<'b, F: Num, const N: usize> $trait<F> for &'b Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
-            fn $fn(self, b : F) -> Self::Output {
+            fn $fn(self, b: F) -> Self::Output {
                 self.map(|a| a.$fn(b))
             }
         }
 
-        impl<'a, 'b, F : Float, const N : usize> $trait<&'a F> for &'b Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<'a, 'b, F: Float, const N: usize> $trait<&'a F> for &'b Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
-            fn $fn(self, b : &'a F) -> Self::Output {
+            fn $fn(self, b: &'a F) -> Self::Output {
                 self.map(|a| a.$fn(*b))
             }
         }
 
-        impl<F : Num, const N : usize> $trait_assign<F> for Loc<F, N> {
+        impl<F: Num, const N: usize> $trait_assign<F> for Loc<N, F> {
             #[inline]
-            fn $fn_assign(&mut self, b : F) {
+            fn $fn_assign(&mut self, b: F) {
                 self.map_mut(|a| a.$fn_assign(b));
             }
         }
 
-        impl<'a, F : Num, const N : usize> $trait_assign<&'a F> for Loc<F, N> {
+        impl<'a, F: Num, const N: usize> $trait_assign<&'a F> for Loc<N, F> {
             #[inline]
-            fn $fn_assign(&mut self, b : &'a F) {
+            fn $fn_assign(&mut self, b: &'a F) {
                 self.map_mut(|a| a.$fn_assign(*b));
             }
         }
-    }
+    };
 }
 
-
 make_scalarop_rhs!(Mul, mul, MulAssign, mul_assign);
 make_scalarop_rhs!(Div, div, DivAssign, div_assign);
 
 macro_rules! make_unaryop {
     ($trait:ident, $fn:ident) => {
-        impl<F : SignedNum, const N : usize> $trait for Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<F: SignedNum, const N: usize> $trait for Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
             fn $fn(mut self) -> Self::Output {
                 self.map_mut(|a| *a = (*a).$fn());
@@ -341,48 +344,48 @@
             }
         }
 
-        impl<'a, F : SignedNum, const N : usize> $trait for &'a Loc<F, N> {
-            type Output = Loc<F, N>;
+        impl<'a, F: SignedNum, const N: usize> $trait for &'a Loc<N, F> {
+            type Output = Loc<N, F>;
             #[inline]
             fn $fn(self) -> Self::Output {
                 self.map(|a| a.$fn())
             }
         }
-    }
+    };
 }
 
 make_unaryop!(Neg, neg);
 
 macro_rules! make_scalarop_lhs {
     ($trait:ident, $fn:ident; $($f:ident)+) => { $(
-        impl<const N : usize> $trait<Loc<$f,N>> for $f {
-            type Output = Loc<$f, N>;
+        impl<const N : usize> $trait<Loc<N, $f>> for $f {
+            type Output = Loc<N, $f>;
             #[inline]
-            fn $fn(self, v : Loc<$f,N>) -> Self::Output {
+            fn $fn(self, v : Loc<N, $f>) -> Self::Output {
                 v.map(|b| self.$fn(b))
             }
         }
 
-        impl<'a, const N : usize> $trait<&'a Loc<$f,N>> for $f {
-            type Output = Loc<$f, N>;
+        impl<'a, const N : usize> $trait<&'a Loc<N, $f>> for $f {
+            type Output = Loc<N, $f>;
             #[inline]
-            fn $fn(self, v : &'a Loc<$f,N>) -> Self::Output {
+            fn $fn(self, v : &'a Loc<N, $f>) -> Self::Output {
                 v.map(|b| self.$fn(b))
             }
         }
 
-        impl<'b, const N : usize> $trait<Loc<$f,N>> for &'b $f {
-            type Output = Loc<$f, N>;
+        impl<'b, const N : usize> $trait<Loc<N, $f>> for &'b $f {
+            type Output = Loc<N, $f>;
             #[inline]
-            fn $fn(self, v : Loc<$f,N>) -> Self::Output {
+            fn $fn(self, v : Loc<N, $f>) -> Self::Output {
                 v.map(|b| self.$fn(b))
             }
         }
 
-        impl<'a, 'b, const N : usize> $trait<&'a Loc<$f,N>> for &'b $f {
-            type Output = Loc<$f, N>;
+        impl<'a, 'b, const N : usize> $trait<&'a Loc<N, $f>> for &'b $f {
+            type Output = Loc<N, $f>;
             #[inline]
-            fn $fn(self, v : &'a Loc<$f, N>) -> Self::Output {
+            fn $fn(self, v : &'a Loc<N, $f>) -> Self::Output {
                 v.map(|b| self.$fn(b))
             }
         }
@@ -396,21 +399,21 @@
 
 macro_rules! domination {
     ($norm:ident, $dominates:ident) => {
-        impl<F : Float, const N : usize> Dominated<F, $dominates, Loc<F, N>> for $norm {
+        impl<F: Float, const N: usize> Dominated<F, $dominates, Loc<N, F>> for $norm {
             #[inline]
-            fn norm_factor(&self, _p : $dominates) -> F {
+            fn norm_factor(&self, _p: $dominates) -> F {
                 F::ONE
             }
             #[inline]
-            fn from_norm(&self, p_norm : F, _p : $dominates) -> F {
+            fn from_norm(&self, p_norm: F, _p: $dominates) -> F {
                 p_norm
             }
         }
     };
     ($norm:ident, $dominates:ident, $fn:path) => {
-        impl<F : Float, const N : usize> Dominated<F, $dominates, Loc<F, N>> for $norm {
+        impl<F: Float, const N: usize> Dominated<F, $dominates, Loc<N, F>> for $norm {
             #[inline]
-            fn norm_factor(&self, _p : $dominates) -> F {
+            fn norm_factor(&self, _p: $dominates) -> F {
                 $fn(F::cast_from(N))
             }
         }
@@ -429,16 +432,17 @@
 domination!(Linfinity, L2);
 domination!(L2, L1);
 
-impl<F : Float,const N : usize> Euclidean<F> for Loc<F, N> {
+impl<F: Float, const N: usize> Euclidean<F> for Loc<N, F> {
     type Output = Self;
 
     /// This implementation is not stabilised as it's meant to be used for very small vectors.
     /// Use [`nalgebra`] for larger vectors.
     #[inline]
-    fn dot<I : Instance<Self>>(&self, other : I) -> F {
-        self.0.iter()
-              .zip(other.ref_instance().0.iter())
-              .fold(F::ZERO, |m, (&v, &w)| m + v * w)
+    fn dot<I: Instance<Self>>(&self, other: I) -> F {
+        self.0
+            .iter()
+            .zip(other.ref_instance().0.iter())
+            .fold(F::ZERO, |m, (&v, &w)| m + v * w)
     }
 
     /// This implementation is not stabilised as it's meant to be used for very small vectors.
@@ -448,16 +452,19 @@
         self.iter().fold(F::ZERO, |m, &v| m + v * v)
     }
 
-    fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F {
+    fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F {
         self.iter()
             .zip(other.ref_instance().iter())
-            .fold(F::ZERO, |m, (&v, &w)| { let d = v - w; m + d * d })
+            .fold(F::ZERO, |m, (&v, &w)| {
+                let d = v - w;
+                m + d * d
+            })
     }
 
     #[inline]
     fn norm2(&self) -> F {
         // Optimisation for N==1 that avoids squaring and square rooting.
-        if N==1 {
+        if N == 1 {
             unsafe { self.0.get_unchecked(0) }.abs()
         } else {
             self.norm2_squared().sqrt()
@@ -465,10 +472,10 @@
     }
 
     #[inline]
-    fn dist2<I : Instance<Self>>(&self, other : I) -> F {
+    fn dist2<I: Instance<Self>>(&self, other: I) -> F {
         // Optimisation for N==1 that avoids squaring and square rooting.
         let otherr = other.ref_instance();
-        if N==1 {
+        if N == 1 {
             unsafe { *self.0.get_unchecked(0) - *otherr.0.get_unchecked(0) }.abs()
         } else {
             self.dist2_squared(other).sqrt()
@@ -476,28 +483,28 @@
     }
 }
 
-impl<F : Num, const N : usize> Loc<F, N> {
+impl<F: Num, const N: usize> Loc<N, F> {
     /// Origin point
-    pub const ORIGIN : Self = Loc([F::ZERO; N]);
+    pub const ORIGIN: Self = Loc([F::ZERO; N]);
 }
 
-impl<F : Num + std::ops::Neg<Output=F>, const N : usize> Loc<F, N> {
+impl<F: Num + std::ops::Neg<Output = F>, const N: usize> Loc<N, F> {
     /// Reflects along the given coordinate
-    pub fn reflect(mut self, i : usize) -> Self {
+    pub fn reflect(mut self, i: usize) -> Self {
         self[i] = -self[i];
         self
     }
 
     /// Reflects along the given coordinate sequences
-    pub fn reflect_many<I : IntoIterator<Item=usize>>(mut self, idxs : I) -> Self {
+    pub fn reflect_many<I: IntoIterator<Item = usize>>(mut self, idxs: I) -> Self {
         for i in idxs {
-            self[i]=-self[i]
+            self[i] = -self[i]
         }
         self
     }
 }
 
-impl<F : std::ops::Neg<Output=F>> Loc<F, 2> {
+impl<F: std::ops::Neg<Output = F>> Loc<2, F> {
     /// Reflect x coordinate
     pub fn reflect_x(self) -> Self {
         let Loc([x, y]) = self;
@@ -511,18 +518,17 @@
     }
 }
 
-impl<F : Float> Loc<F, 2> {
+impl<F: Float> Loc<2, F> {
     /// Rotate by angle φ
-    pub fn rotate(self, φ : F) -> Self {
+    pub fn rotate(self, φ: F) -> Self {
         let Loc([x, y]) = self;
         let sin_φ = φ.sin();
         let cos_φ = φ.cos();
-        [cos_φ * x - sin_φ * y,
-         sin_φ * x + cos_φ * y].into()
+        [cos_φ * x - sin_φ * y, sin_φ * x + cos_φ * y].into()
     }
 }
 
-impl<F : std::ops::Neg<Output=F>> Loc<F, 3> {
+impl<F: std::ops::Neg<Output = F>> Loc<3, F> {
     /// Reflect x coordinate
     pub fn reflect_x(self) -> Self {
         let Loc([x, y, z]) = self;
@@ -542,39 +548,32 @@
     }
 }
 
-impl<F : Float> Loc<F, 3> {
+impl<F: Float> Loc<3, F> {
     /// Rotate by angles (yaw, pitch, roll)
-    pub fn rotate(self, Loc([φ, ψ, θ]) : Self) -> Self {
+    pub fn rotate(self, Loc([φ, ψ, θ]): Self) -> Self {
         let Loc([mut x, mut y, mut z]) = self;
         let sin_φ = φ.sin();
         let cos_φ = φ.cos();
-        [x, y, z] = [cos_φ * x - sin_φ *y,
-                     sin_φ * x + cos_φ * y,
-                     z];
+        [x, y, z] = [cos_φ * x - sin_φ * y, sin_φ * x + cos_φ * y, z];
         let sin_ψ = ψ.sin();
         let cos_ψ = ψ.cos();
-        [x, y, z] = [cos_ψ * x + sin_ψ * z,
-                     y,
-                     -sin_ψ * x + cos_ψ * z];
+        [x, y, z] = [cos_ψ * x + sin_ψ * z, y, -sin_ψ * x + cos_ψ * z];
         let sin_θ = θ.sin();
         let cos_θ = θ.cos();
-        [x, y, z] = [x,
-                     cos_θ * y - sin_θ * z,
-                     sin_θ * y + cos_θ * z];
+        [x, y, z] = [x, cos_θ * y - sin_θ * z, sin_θ * y + cos_θ * z];
         [x, y, z].into()
     }
 }
 
-impl<F : Float,const N : usize> StaticEuclidean<F> for Loc<F, N> {
+impl<F: Float, const N: usize> StaticEuclidean<F> for Loc<N, F> {
     #[inline]
     fn origin() -> Self {
         Self::ORIGIN
     }
 }
 
-
 /// The default norm for `Loc` is [`L2`].
-impl<F : Float, const N : usize> Normed<F> for Loc<F, N> {
+impl<F: Float, const N: usize> Normed<F> for Loc<N, F> {
     type NormExp = L2;
 
     #[inline]
@@ -593,22 +592,26 @@
     }
 }
 
-impl<F : Float, const N : usize> HasDual<F> for Loc<F, N> {
+impl<F: Float, const N: usize> HasDual<F> for Loc<N, F> {
     type DualSpace = Self;
 }
 
-impl<F : Float, const N : usize> Norm<F, L2> for Loc<F, N> {
+impl<F: Float, const N: usize> Norm<L2, F> for Loc<N, F> {
     #[inline]
-    fn norm(&self, _ : L2) -> F { self.norm2() }
+    fn norm(&self, _: L2) -> F {
+        self.norm2()
+    }
 }
 
-impl<F : Float, const N : usize> Dist<F, L2> for Loc<F, N> {
+impl<F: Float, const N: usize> Dist<F, L2> for Loc<N, F> {
     #[inline]
-    fn dist<I : Instance<Self>>(&self, other : I, _ : L2) -> F { self.dist2(other) }
+    fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> F {
+        self.dist2(other)
+    }
 }
 
 /* Implemented automatically as Euclidean.
-impl<F : Float, const N : usize> Projection<F, L2> for Loc<F, N> {
+impl<F : Float, const N : usize> Projection<F, L2> for Loc<N, F> {
     #[inline]
     fn proj_ball_mut(&mut self, ρ : F, nrm : L2) {
         let n = self.norm(nrm);
@@ -618,53 +621,53 @@
     }
 }*/
 
-impl<F : Float, const N : usize> Norm<F, L1> for Loc<F, N> {
+impl<F: Float, const N: usize> Norm<L1, F> for Loc<N, F> {
     /// This implementation is not stabilised as it's meant to be used for very small vectors.
     /// Use [`nalgebra`] for larger vectors.
     #[inline]
-    fn norm(&self, _ : L1) -> F {
+    fn norm(&self, _: L1) -> F {
         self.iter().fold(F::ZERO, |m, v| m + v.abs())
     }
 }
 
-impl<F : Float, const N : usize> Dist<F, L1> for Loc<F, N> {
+impl<F: Float, const N: usize> Dist<F, L1> for Loc<N, F> {
     #[inline]
-    fn dist<I : Instance<Self>>(&self, other : I, _ : L1) -> F {
+    fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> F {
         self.iter()
             .zip(other.ref_instance().iter())
-            .fold(F::ZERO, |m, (&v, &w)| m + (v-w).abs() )
+            .fold(F::ZERO, |m, (&v, &w)| m + (v - w).abs())
     }
 }
 
-impl<F : Float, const N : usize> Projection<F, Linfinity> for Loc<F, N> {
+impl<F: Float, const N: usize> Projection<F, Linfinity> for Loc<N, F> {
     #[inline]
-    fn proj_ball_mut(&mut self, ρ : F, _ : Linfinity) {
-        self.iter_mut().for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ))
+    fn proj_ball_mut(&mut self, ρ: F, _: Linfinity) {
+        self.iter_mut()
+            .for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ))
     }
 }
 
-impl<F : Float, const N : usize> Norm<F, Linfinity> for Loc<F, N> {
+impl<F: Float, const N: usize> Norm<Linfinity, F> for Loc<N, F> {
     /// This implementation is not stabilised as it's meant to be used for very small vectors.
     /// Use [`nalgebra`] for larger vectors.
     #[inline]
-    fn norm(&self, _ : Linfinity) -> F {
+    fn norm(&self, _: Linfinity) -> F {
         self.iter().fold(F::ZERO, |m, v| m.max(v.abs()))
     }
 }
 
-impl<F : Float, const N : usize> Dist<F, Linfinity> for Loc<F, N> {
+impl<F: Float, const N: usize> Dist<F, Linfinity> for Loc<N, F> {
     #[inline]
-    fn dist<I : Instance<Self>>(&self, other : I, _ : Linfinity) -> F {
+    fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> F {
         self.iter()
             .zip(other.ref_instance().iter())
-            .fold(F::ZERO, |m, (&v, &w)| m.max((v-w).abs()))
+            .fold(F::ZERO, |m, (&v, &w)| m.max((v - w).abs()))
     }
 }
 
-
 // Misc.
 
-impl<A, const N : usize> FixedLength<N> for Loc<A,N> {
+impl<A, const N: usize> FixedLength<N> for Loc<N, A> {
     type Iter = std::array::IntoIter<A, N>;
     type Elem = A;
     #[inline]
@@ -673,15 +676,18 @@
     }
 }
 
-impl<A, const N : usize> FixedLengthMut<N> for Loc<A,N> {
-    type IterMut<'a> = std::slice::IterMut<'a, A> where A : 'a;
+impl<A, const N: usize> FixedLengthMut<N> for Loc<N, A> {
+    type IterMut<'a>
+        = std::slice::IterMut<'a, A>
+    where
+        A: 'a;
     #[inline]
     fn fl_iter_mut(&mut self) -> Self::IterMut<'_> {
         self.iter_mut()
     }
 }
 
-impl<'a, A, const N : usize> FixedLength<N> for &'a Loc<A,N> {
+impl<'a, A, const N: usize> FixedLength<N> for &'a Loc<N, A> {
     type Iter = std::slice::Iter<'a, A>;
     type Elem = &'a A;
     #[inline]
@@ -690,38 +696,37 @@
     }
 }
 
-
-impl<F : Num, const N : usize> Space for Loc<F, N> {
+impl<F: Num, const N: usize> Space for Loc<N, F> {
     type Decomp = BasicDecomposition;
 }
 
-impl<F : Float, const N : usize> Mapping<Loc<F, N>> for Loc<F, N> {
+impl<F: Float, const N: usize> Mapping<Loc<N, F>> for Loc<N, F> {
     type Codomain = F;
 
-    fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain {
+    fn apply<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Codomain {
         x.eval(|x̃| self.dot(x̃))
     }
 }
 
-impl<F : Float, const N : usize> Linear<Loc<F, N>> for Loc<F, N> { }
+impl<F: Float, const N: usize> Linear<Loc<N, F>> for Loc<N, F> {}
 
-impl<F : Float, const N : usize> AXPY<F, Loc<F, N>> for Loc<F, N> {
+impl<F: Float, const N: usize> AXPY<F, Loc<N, F>> for Loc<N, F> {
     type Owned = Self;
 
     #[inline]
-    fn axpy<I : Instance<Loc<F, N>>>(&mut self, α : F, x : I, β : F) {
+    fn axpy<I: Instance<Loc<N, F>>>(&mut self, α: F, x: I, β: F) {
         x.eval(|x̃| {
             if β == F::ZERO {
-                map2_mut(self, x̃, |yi, xi| { *yi = α * (*xi) })
+                map2_mut(self, x̃, |yi, xi| *yi = α * (*xi))
             } else {
-                map2_mut(self, x̃, |yi, xi| { *yi = β * (*yi) + α * (*xi) })
+                map2_mut(self, x̃, |yi, xi| *yi = β * (*yi) + α * (*xi))
             }
         })
     }
 
     #[inline]
-    fn copy_from<I : Instance<Loc<F, N>>>(&mut self, x : I) {
-        x.eval(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi ))
+    fn copy_from<I: Instance<Loc<N, F>>>(&mut self, x: I) {
+        x.eval(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi))
     }
 
     #[inline]
@@ -734,4 +739,3 @@
         *self = Self::ORIGIN;
     }
 }
-

mercurial