Need to construct weighted norms using macros due to compiler (overflow) bugs dev

Tue, 24 Dec 2024 13:40:36 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Tue, 24 Dec 2024 13:40:36 -0500
branch
dev
changeset 71
511bf440e24b
parent 70
672aec2e1acd
child 72
44a4f258a1ff

Need to construct weighted norms using macros due to compiler (overflow) bugs

src/norms.rs file | annotate | diff | comparison | revisions
--- 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<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)]
@@ -179,20 +177,6 @@
     }
 }
 
-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()
@@ -283,29 +267,54 @@
     }
 }
 
-impl<C : Constant, E : HasDualExponent>  HasDualExponent for Weighted<E, C> {
-    type DualExp = Weighted<E::DualExp, C::Type>;
+#[macro_export]
+macro_rules! impl_weighted_norm {
+    ($exponent : ty) => {
+        impl<C, F, D> Norm<F, Weighted<$exponent, C>> for D
+        where
+            F : Float,
+            D : Norm<F, $exponent>,
+            C : Constant<Type = F>,
+        {
+            fn norm(&self, e : Weighted<$exponent, C>) -> F {
+                let v = e.weight.value();
+                assert!(v > F::ZERO);
+                v * self.norm(e.base_fn)
+            }
+        }
+
+        impl<C : Constant> NormExponent for Weighted<$exponent, C> {}
+
+        impl<C : Constant> 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<C, F, T> Projection<F, Weighted<$exponent , C>> for T
+        where
+            T : Projection<F, $exponent >,
+            F : Float,
+            C : Constant<Type = F>,
+        {
+            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<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)
-    }
+//impl_weighted_norm!(L1);
+//impl_weighted_norm!(L2);
+//impl_weighted_norm!(Linfinity);
 
-    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