More Instance parametrisation dev

Sun, 22 Dec 2024 15:30:34 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sun, 22 Dec 2024 15:30:34 -0500
branch
dev
changeset 64
4f6ca107ccb1
parent 63
f7b87d84864d
child 65
9327d544ca0b

More Instance parametrisation

src/direct_product.rs file | annotate | diff | comparison | revisions
src/euclidean.rs file | annotate | diff | comparison | revisions
src/loc.rs file | annotate | diff | comparison | revisions
src/nalgebra_support.rs file | annotate | diff | comparison | revisions
src/norms.rs file | annotate | diff | comparison | revisions
--- a/src/direct_product.rs	Sun Dec 22 14:54:46 2024 -0500
+++ b/src/direct_product.rs	Sun Dec 22 15:30:34 2024 -0500
@@ -267,7 +267,8 @@
         self.0.norm2_squared() + self.1.norm2_squared()
     }
 
-    fn dist2_squared(&self, Pair(ref u, ref v) : &Self) -> F {
+    fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F {
+        let Pair(u, v) = other.decompose();
         self.0.dist2_squared(u) + self.1.dist2_squared(v)
     }
 }
--- a/src/euclidean.rs	Sun Dec 22 14:54:46 2024 -0500
+++ b/src/euclidean.rs	Sun Dec 22 15:30:34 2024 -0500
@@ -48,11 +48,11 @@
     }
 
     /// Calculate the 2-distance squared $\\|x-y\\|_2^2$, where `self` is $x$.
-    fn dist2_squared(&self, y : &Self) -> F;
+    fn dist2_squared<I : Instance<Self>>(&self, y : I) -> F;
 
     /// Calculate the 2-distance $\\|x-y\\|_2$, where `self` is $x$.
     #[inline]
-    fn dist2(&self, y : &Self) -> F {
+    fn dist2<I : Instance<Self>>(&self, y : I) -> F {
         self.dist2_squared(y).sqrt()
     }
 
--- a/src/loc.rs	Sun Dec 22 14:54:46 2024 -0500
+++ b/src/loc.rs	Sun Dec 22 15:30:34 2024 -0500
@@ -448,9 +448,9 @@
         self.iter().fold(F::ZERO, |m, &v| m + v * v)
     }
 
-    fn dist2_squared(&self, other : &Self) -> F {
+    fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F {
         self.iter()
-            .zip(other.iter())
+            .zip(other.ref_instance().iter())
             .fold(F::ZERO, |m, (&v, &w)| { let d = v - w; m + d * d })
     }
 
@@ -465,10 +465,11 @@
     }
 
     #[inline]
-    fn dist2(&self, other : &Self) -> 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 {
-            unsafe { *self.0.get_unchecked(0) - *other.0.get_unchecked(0) }.abs()
+            unsafe { *self.0.get_unchecked(0) - *otherr.0.get_unchecked(0) }.abs()
         } else {
             self.dist2_squared(other).sqrt()
         }
@@ -603,7 +604,7 @@
 
 impl<F : Float, const N : usize> Dist<F, L2> for Loc<F, N> {
     #[inline]
-    fn dist(&self, other : &Self, _ : L2) -> F { self.dist2(other) }
+    fn dist<I : Instance<Self>>(&self, other : I, _ : L2) -> F { self.dist2(other) }
 }
 
 /* Implemented automatically as Euclidean.
@@ -628,9 +629,9 @@
 
 impl<F : Float, const N : usize> Dist<F, L1> for Loc<F, N> {
     #[inline]
-    fn dist(&self, other : &Self, _ : L1) -> F {
+    fn dist<I : Instance<Self>>(&self, other : I, _ : L1) -> F {
         self.iter()
-            .zip(other.iter())
+            .zip(other.ref_instance().iter())
             .fold(F::ZERO, |m, (&v, &w)| m + (v-w).abs() )
     }
 }
@@ -653,9 +654,9 @@
 
 impl<F : Float, const N : usize> Dist<F, Linfinity> for Loc<F, N> {
     #[inline]
-    fn dist(&self, other : &Self, _ : Linfinity) -> F {
+    fn dist<I : Instance<Self>>(&self, other : I, _ : Linfinity) -> F {
         self.iter()
-            .zip(other.iter())
+            .zip(other.ref_instance().iter())
             .fold(F::ZERO, |m, (&v, &w)| m.max((v-w).abs()))
     }
 }
--- a/src/nalgebra_support.rs	Sun Dec 22 14:54:46 2024 -0500
+++ b/src/nalgebra_support.rs	Sun Dec 22 15:30:34 2024 -0500
@@ -198,8 +198,8 @@
     }
 
     #[inline]
-    fn dist2_squared(&self, other : &Self) -> E {
-        metric_distance_squared(self, other)
+    fn dist2_squared<I : Instance<Self>>(&self, other : I) -> E {
+        metric_distance_squared(self, other.ref_instance())
     }
 }
 
@@ -263,12 +263,12 @@
 impl<E,M,S> Dist<E, L1>
 for Vector<E,M,S>
 where M : Dim,
-      S : Storage<E,M>,
+      S : Storage<E,M> + Clone,
       E : Float + Scalar + Zero + One + RealField,
       DefaultAllocator : Allocator<M> {
     #[inline]
-    fn dist(&self, other : &Self, _ : L1) -> E {
-        LpNorm(1).metric_distance(self, other)
+    fn dist<I : Instance<Self>>(&self, other : I, _ : L1) -> E {
+        LpNorm(1).metric_distance(self, other.ref_instance())
     }
 }
 
@@ -288,12 +288,12 @@
 impl<E,M,S> Dist<E, L2>
 for Vector<E,M,S>
 where M : Dim,
-      S : Storage<E,M>,
+      S : Storage<E,M> + Clone,
       E : Float + Scalar + Zero + One + RealField,
       DefaultAllocator : Allocator<M> {
     #[inline]
-    fn dist(&self, other : &Self, _ : L2) -> E {
-        LpNorm(2).metric_distance(self, other)
+    fn dist<I : Instance<Self>>(&self, other : I, _ : L2) -> E {
+        LpNorm(2).metric_distance(self, other.ref_instance())
     }
 }
 
@@ -313,12 +313,12 @@
 impl<E,M,S> Dist<E, Linfinity>
 for Vector<E,M,S>
 where M : Dim,
-      S : Storage<E,M>,
+      S : Storage<E,M> + Clone,
       E : Float + Scalar + Zero + One + RealField,
       DefaultAllocator : Allocator<M> {
     #[inline]
-    fn dist(&self, other : &Self, _ : Linfinity) -> E {
-        UniformNorm.metric_distance(self, other)
+    fn dist<I : Instance<Self>>(&self, other : I, _ : Linfinity) -> E {
+        UniformNorm.metric_distance(self, other.ref_instance())
     }
 }
 
--- a/src/norms.rs	Sun Dec 22 14:54:46 2024 -0500
+++ b/src/norms.rs	Sun Dec 22 15:30:34 2024 -0500
@@ -104,9 +104,9 @@
 }
 
 /// Trait for distances with respect to a norm.
-pub trait Dist<F : Num, Exponent : NormExponent> : Norm<F, Exponent> {
+pub trait Dist<F : Num, Exponent : NormExponent> : Norm<F, Exponent> + Space {
     /// Calculate the distance
-    fn dist(&self, other : &Self, _p : Exponent) -> F;
+    fn dist<I : Instance<Self>>(&self, other : I, _p : Exponent) -> F;
 }
 
 /// Trait for Euclidean projections to the `Exponent`-[`Norm`]-ball.
@@ -171,22 +171,22 @@
 }
 
 impl<F : Float, E : Euclidean<F>> Dist<F, HuberL1<F>> for E {
-    fn dist(&self, other : &Self, huber : HuberL1<F>) -> F {
+    fn dist<I : Instance<Self>>(&self, other : I, huber : HuberL1<F>) -> F {
         huber.apply(self.dist2_squared(other))
     }
 }
 
-impl<F : Float, E : Norm<F, L2>> Norm<F, L21> for Vec<E> {
-    fn norm(&self, _l21 : L21) -> F {
-        self.iter().map(|e| e.norm(L2)).sum()
-    }
-}
+// impl<F : Float, E : Norm<F, L2>> Norm<F, L21> for Vec<E> {
+//     fn norm(&self, _l21 : L21) -> F {
+//         self.iter().map(|e| e.norm(L2)).sum()
+//     }
+// }
 
-impl<F : Float, E : Dist<F, L2>> Dist<F, L21> for Vec<E> {
-    fn dist(&self, other : &Self, _l21 : L21) -> F {
-        self.iter().zip(other.iter()).map(|(e, g)| e.dist(g, L2)).sum()
-    }
-}
+// impl<F : Float, E : Dist<F, L2>> Dist<F, L21> for Vec<E> {
+//     fn dist<I : Instance<Self>>(&self, other : I, _l21 : L21) -> F {
+//         self.iter().zip(other.iter()).map(|(e, g)| e.dist(g, L2)).sum()
+//     }
+// }
 
 impl<E, F, Domain> Mapping<Domain> for NormMapping<F, E>
 where

mercurial