# HG changeset patch # User Tuomo Valkonen # Date 1735065636 18000 # Node ID 511bf440e24b5afeb149db4f4ff4937b6f4c2d82 # Parent 672aec2e1acd29b7ab8c0027627233009ead8cba Need to construct weighted norms using macros due to compiler (overflow) bugs diff -r 672aec2e1acd -r 511bf440e24b src/norms.rs --- a/src/norms.rs Tue Dec 24 00:24:10 2024 -0500 +++ b/src/norms.rs Tue Dec 24 13:40:36 2024 -0500 @@ -51,8 +51,6 @@ pub struct L21; impl NormExponent for L21 {} -impl NormExponent for Weighted {} - /// 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)] @@ -179,20 +177,6 @@ } } -impl Norm> for D -where - F : Float, - D : Norm, - C : Constant, - E : NormExponent, -{ - fn norm(&self, e : Weighted) -> F { - let v = e.weight.value(); - assert!(v > F::ZERO); - v * self.norm(e.base_fn) - } -} - // impl> Norm for Vec { // fn norm(&self, _l21 : L21) -> F { // self.iter().map(|e| e.norm(L2)).sum() @@ -283,29 +267,54 @@ } } -impl HasDualExponent for Weighted { - type DualExp = Weighted; +#[macro_export] +macro_rules! impl_weighted_norm { + ($exponent : ty) => { + impl Norm> for D + where + F : Float, + D : Norm, + C : Constant, + { + fn norm(&self, e : Weighted<$exponent, C>) -> F { + let v = e.weight.value(); + assert!(v > F::ZERO); + v * self.norm(e.base_fn) + } + } + + impl NormExponent for Weighted<$exponent, C> {} + + impl HasDualExponent for Weighted<$exponent, C> + where $exponent : HasDualExponent { + type DualExp = Weighted<<$exponent as HasDualExponent>::DualExp, C::Type>; - fn dual_exponent(&self) -> Self::DualExp { - Weighted { - weight : C::Type::ONE / self.weight.value(), - base_fn : self.base_fn.dual_exponent() + fn dual_exponent(&self) -> Self::DualExp { + Weighted { + weight : C::Type::ONE / self.weight.value(), + base_fn : self.base_fn.dual_exponent() + } + } + } + + impl Projection> for T + where + T : Projection, + F : Float, + C : Constant, + { + fn proj_ball(self, ρ : F, q : Weighted<$exponent , C>) -> Self { + self.proj_ball(ρ / q.weight.value(), q.base_fn) + } + + fn proj_ball_mut(&mut self, ρ : F, q : Weighted<$exponent , C>) { + self.proj_ball_mut(ρ / q.weight.value(), q.base_fn) + } } } } -impl Projection> for T -where - T : Projection, - F : Float, - C : Constant, - E : NormExponent, -{ - fn proj_ball(self, ρ : F, q : Weighted) -> Self { - self.proj_ball(ρ / q.weight.value(), q.base_fn) - } +//impl_weighted_norm!(L1); +//impl_weighted_norm!(L2); +//impl_weighted_norm!(Linfinity); - fn proj_ball_mut(&mut self, ρ : F, q : Weighted) { - self.proj_ball_mut(ρ / q.weight.value(), q.base_fn) - } -} \ No newline at end of file