--- 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 ) } }