Tue, 24 Dec 2024 00:24:10 -0500
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