Weighted norms dev

Tue, 24 Dec 2024 00:24:10 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Tue, 24 Dec 2024 00:24:10 -0500
branch
dev
changeset 70
672aec2e1acd
parent 69
e5fab0125a8e
child 71
511bf440e24b

Weighted norms

src/nalgebra_support.rs file | annotate | diff | comparison | revisions
src/norms.rs file | annotate | diff | comparison | revisions
--- a/src/nalgebra_support.rs	Thu Dec 26 12:35:53 2024 -0500
+++ b/src/nalgebra_support.rs	Tue Dec 24 00:24:10 2024 -0500
@@ -13,7 +13,6 @@
     ClosedAddAssign, ClosedMulAssign, SimdComplexField, Vector, OVector, RealField,
     LpNorm, UniformNorm
 };
-use nalgebra::Norm as NalgebraNorm;
 use nalgebra::base::constraint::{
     ShapeConstraint, SameNumberOfRows, SameNumberOfColumns
 };
@@ -256,7 +255,7 @@
 
     #[inline]
     fn norm(&self, _ : L1) -> E {
-        LpNorm(1).norm(self)
+        nalgebra::Norm::norm(&LpNorm(1), self)
     }
 }
 
@@ -268,7 +267,7 @@
       DefaultAllocator : Allocator<M> {
     #[inline]
     fn dist<I : Instance<Self>>(&self, other : I, _ : L1) -> E {
-        LpNorm(1).metric_distance(self, other.ref_instance())
+        nalgebra::Norm::metric_distance(&LpNorm(1), self, other.ref_instance())
     }
 }
 
@@ -281,7 +280,7 @@
 
     #[inline]
     fn norm(&self, _ : L2) -> E {
-        LpNorm(2).norm(self)
+        nalgebra::Norm::norm(&LpNorm(2), self)
     }
 }
 
@@ -293,7 +292,7 @@
       DefaultAllocator : Allocator<M> {
     #[inline]
     fn dist<I : Instance<Self>>(&self, other : I, _ : L2) -> E {
-        LpNorm(2).metric_distance(self, other.ref_instance())
+        nalgebra::Norm::metric_distance(&LpNorm(2), self, other.ref_instance())
     }
 }
 
@@ -306,7 +305,7 @@
 
     #[inline]
     fn norm(&self, _ : Linfinity) -> E {
-        UniformNorm.norm(self)
+        nalgebra::Norm::norm(&UniformNorm, self)
     }
 }
 
@@ -318,7 +317,7 @@
       DefaultAllocator : Allocator<M> {
     #[inline]
     fn dist<I : Instance<Self>>(&self, other : I, _ : Linfinity) -> E {
-        UniformNorm.metric_distance(self, other.ref_instance())
+        nalgebra::Norm::metric_distance(&UniformNorm, self, other.ref_instance())
     }
 }
 
--- a/src/norms.rs	Thu Dec 26 12:35:53 2024 -0500
+++ b/src/norms.rs	Tue Dec 24 00:24:10 2024 -0500
@@ -7,6 +7,7 @@
 use crate::types::*;
 use crate::euclidean::*;
 use crate::mapping::{Mapping, Space, Instance};
+use crate::operator_arithmetic::{Constant, Weighted};
 
 //
 // Abstract norms
@@ -50,6 +51,8 @@
 pub struct L21;
 impl NormExponent for L21 {}
 
+impl<C : Constant, E : NormExponent> NormExponent for Weighted<E, C> {}
+
 /// Norms for pairs (a, b). ‖(a,b)‖ = ‖(‖a‖_A, ‖b‖_B)‖_J
 /// For use with [`crate::direct_product::Pair`]
 #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)]
@@ -176,6 +179,20 @@
     }
 }
 
+impl<C, F, E, D> Norm<F, Weighted<E, C>> for D
+where
+    F : Float,
+    D : Norm<F, E>,
+    C : Constant<Type = F>,
+    E : NormExponent,
+{
+    fn norm(&self, e : Weighted<E, C>) -> F {
+        let v = e.weight.value();
+        assert!(v > F::ZERO);
+        v * self.norm(e.base_fn)
+    }
+}
+
 // 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()
@@ -266,6 +283,29 @@
     }
 }
 
+impl<C : Constant, E : HasDualExponent>  HasDualExponent for Weighted<E, C> {
+    type DualExp = Weighted<E::DualExp, C::Type>;
 
+    fn dual_exponent(&self) -> Self::DualExp {
+        Weighted {
+            weight : C::Type::ONE / self.weight.value(),
+            base_fn : self.base_fn.dual_exponent()
+        }
+    }
+}
 
+impl<C, F, E, T> Projection<F, Weighted<E, C>> for T
+where
+    T : Projection<F, E>,
+    F : Float,
+    C : Constant<Type = F>,
+    E : NormExponent,
+{
+    fn proj_ball(self, ρ : F, q : Weighted<E, C>) -> Self {
+        self.proj_ball(ρ / q.weight.value(), q.base_fn)
+    }
 
+    fn proj_ball_mut(&mut self, ρ : F, q : Weighted<E, C>) {
+        self.proj_ball_mut(ρ / q.weight.value(), q.base_fn)
+    }
+}
\ No newline at end of file

mercurial