src/loc.rs

branch
dev
changeset 81
d2acaaddd9af
parent 43
239aa32f0e7d
--- a/src/loc.rs	Sun Nov 10 09:02:57 2024 -0500
+++ b/src/loc.rs	Tue Dec 31 09:12:43 2024 -0500
@@ -6,6 +6,7 @@
 use std::ops::{Add,Sub,AddAssign,SubAssign,Mul,Div,MulAssign,DivAssign,Neg,Index,IndexMut};
 use std::slice::{Iter,IterMut};
 use std::fmt::{Display, Formatter};
+use std::borrow::Borrow;
 use crate::types::{Float,Num,SignedNum};
 use crate::maputil::{FixedLength,FixedLengthMut,map1,map2,map1_mut,map2_mut};
 use crate::euclidean::*;
@@ -23,6 +24,10 @@
     pub [F; N]
 );
 
+impl<F : Num, const N : usize> HasScalarField for Loc<F, N> {
+    type Field = F;
+}
+
 impl<F : Display, const N : usize> Display for Loc<F, N>{
     // Required method
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
@@ -393,7 +398,7 @@
 
 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<$dominates, Loc<F, N>> for $norm {
             #[inline]
             fn norm_factor(&self, _p : $dominates) -> F {
                 F::ONE
@@ -405,7 +410,7 @@
         }
     };
     ($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<$dominates, Loc<F, N>> for $norm {
             #[inline]
             fn norm_factor(&self, _p : $dominates) -> F {
                 $fn(F::cast_from(N))
@@ -426,18 +431,18 @@
 domination!(Linfinity, L2);
 domination!(L2, L1);
 
-impl<F : Num,const N : usize> Dot<Loc<F, N>,F> for Loc<F, N> {
+impl<F : Num, T : Borrow<Loc<F, N>>, const N : usize> Dot<T> for Loc<F, N> {
     /// This implementation is not stabilised as it's meant to be used for very small vectors.
     /// Use [`nalgebra`] for larger vectors.
     #[inline]
-    fn dot(&self, other : &Loc<F, N>) -> F {
+    fn dot(&self, other : T) -> F {
         self.0.iter()
-              .zip(other.0.iter())
+              .zip(other.borrow().0.iter())
               .fold(F::ZERO, |m, (&v, &w)| m + v * w)
     }
 }
 
-impl<F : Float,const N : usize> Euclidean<F> for Loc<F, N> {
+impl<F : Float,const N : usize> Euclidean for Loc<F, N> {
     type Output = Self;
 
     #[inline]
@@ -483,24 +488,24 @@
     pub const ORIGIN : Self = Loc([F::ZERO; N]);
 }
 
-impl<F : Float,const N : usize> StaticEuclidean<F> for Loc<F, N> {
+impl<F : Float,const N : usize> StaticEuclidean for Loc<F, N> {
     #[inline]
     fn origin() -> Self {
         Self::ORIGIN
     }
 }
 
-impl<F : Float, const N : usize> Norm<F, L2> for Loc<F, N> {
+impl<F : Float, const N : usize> Norm<L2> for Loc<F, N> {
     #[inline]
     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<L2> for Loc<F, N> {
     #[inline]
     fn dist(&self, other : &Self, _ : L2) -> F { self.dist2(other) }
 }
 
-impl<F : Float, const N : usize> Norm<F, L1> for Loc<F, N> {
+impl<F : Float, const N : usize> Norm<L1> for Loc<F, N> {
     /// This implementation is not stabilised as it's meant to be used for very small vectors.
     /// Use [`nalgebra`] for larger vectors.
     #[inline]
@@ -509,7 +514,7 @@
     }
 }
 
-impl<F : Float, const N : usize> Dist<F, L1> for Loc<F, N> {
+impl<F : Float, const N : usize> Dist<L1> for Loc<F, N> {
     #[inline]
     fn dist(&self, other : &Self, _ : L1) -> F {
         self.iter()
@@ -518,14 +523,14 @@
     }
 }
 
-impl<F : Float, const N : usize> Projection<F, Linfinity> for Loc<F, N> {
+impl<F : Float, const N : usize> Projection<Linfinity> for Loc<F, N> {
     #[inline]
     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> for Loc<F, N> {
     /// This implementation is not stabilised as it's meant to be used for very small vectors.
     /// Use [`nalgebra`] for larger vectors.
     #[inline]
@@ -534,7 +539,7 @@
     }
 }
 
-impl<F : Float, const N : usize> Dist<F, Linfinity> for Loc<F, N> {
+impl<F : Float, const N : usize> Dist<Linfinity> for Loc<F, N> {
     #[inline]
     fn dist(&self, other : &Self, _ : Linfinity) -> F {
         self.iter()
@@ -572,19 +577,18 @@
     }
 }
 
-impl<F : Num, const N : usize> AXPY<F, Loc<F, N>> for Loc<F, N> {
-
+impl<'a, T : Borrow<Loc<F, N>>, F : Num, const N : usize> AXPY<F, T> for Loc<F, N> {
     #[inline]
-    fn axpy(&mut self, α : F, x : &Loc<F, N>, β : F) {
+    fn axpy(&mut self, α : F, x : T, β : F) {
         if β == F::ZERO {
-            map2_mut(self, x, |yi, xi| { *yi = α * (*xi) })
+            map2_mut(self, x.borrow(), |yi, xi| { *yi = α * (*xi) })
         } else {
-            map2_mut(self, x, |yi, xi| { *yi = β * (*yi) + α * (*xi) })
+            map2_mut(self, x.borrow(), |yi, xi| { *yi = β * (*yi) + α * (*xi) })
         }
     }
 
     #[inline]
-    fn copy_from(&mut self, x : &Loc<F, N>) {
-        map2_mut(self, x, |yi, xi| *yi = *xi )
+    fn copy_from(&mut self, x : T) {
+        map2_mut(self, x.borrow(), |yi, xi| *yi = *xi )
     }
 }

mercurial