Remove Send + Sync + 'static requirement on NormExponent. Allow Zed to reindent norms.rs. dev

Mon, 28 Apr 2025 09:08:45 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 28 Apr 2025 09:08:45 -0500
branch
dev
changeset 100
411c6be29fe5
parent 99
9e5b9fc81c52
child 101
997961aa6eee

Remove Send + Sync + 'static requirement on NormExponent. Allow Zed to reindent norms.rs.

src/norms.rs file | annotate | diff | comparison | revisions
--- a/src/norms.rs	Mon Apr 28 08:26:04 2025 -0500
+++ b/src/norms.rs	Mon Apr 28 09:08:45 2025 -0500
@@ -2,79 +2,85 @@
 Norms, projections, etc.
 */
 
+use crate::euclidean::*;
+use crate::mapping::{Instance, Mapping, Space};
+use crate::types::*;
 use serde::Serialize;
 use std::marker::PhantomData;
-use crate::types::*;
-use crate::euclidean::*;
-use crate::mapping::{Mapping, Space, Instance};
 
 //
 // Abstract norms
 //
 
-#[derive(Copy,Clone,Debug)]
+#[derive(Copy, Clone, Debug)]
 /// Helper structure to convert a [`NormExponent`] into a [`Mapping`]
-pub struct NormMapping<F : Float, E : NormExponent>{
-    pub(crate) exponent : E,
-    _phantoms : PhantomData<F>
+pub struct NormMapping<F: Float, E: NormExponent> {
+    pub(crate) exponent: E,
+    _phantoms: PhantomData<F>,
 }
 
 /// An exponent for norms.
 ///
 // Just a collection of desirable attributes for a marker type
-pub trait NormExponent : Copy + Send + Sync + 'static {
+pub trait NormExponent: Copy {
     /// Return the norm as a mappin
-    fn as_mapping<F : Float>(self) -> NormMapping<F, Self> {
-        NormMapping{ exponent : self, _phantoms : PhantomData }
+    fn as_mapping<F: Float>(self) -> NormMapping<F, Self> {
+        NormMapping {
+            exponent: self,
+            _phantoms: PhantomData,
+        }
     }
 }
 
 /// Exponent type for the 1-[`Norm`].
-#[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)]
+#[derive(Copy, Debug, Clone, Serialize, Eq, PartialEq)]
 pub struct L1;
 impl NormExponent for L1 {}
 
 /// Exponent type for the 2-[`Norm`].
-#[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)]
+#[derive(Copy, Debug, Clone, Serialize, Eq, PartialEq)]
 pub struct L2;
 impl NormExponent for L2 {}
 
 /// Exponent type for the ∞-[`Norm`].
-#[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)]
+#[derive(Copy, Debug, Clone, Serialize, Eq, PartialEq)]
 pub struct Linfinity;
 impl NormExponent for Linfinity {}
 
 /// Exponent type for 2,1-[`Norm`].
 /// (1-norm over a domain Ω, 2-norm of a vector at each point of the domain.)
-#[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)]
+#[derive(Copy, Debug, Clone, Serialize, Eq, PartialEq)]
 pub struct L21;
 impl NormExponent for L21 {}
 
 /// 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)]
+#[derive(Copy, Debug, Clone, Serialize, Eq, PartialEq)]
 pub struct PairNorm<A, B, J>(pub A, pub B, pub J);
 
 impl<A, B, J> NormExponent for PairNorm<A, B, J>
-where A : NormExponent, B : NormExponent, J : NormExponent {}
-
+where
+    A: NormExponent,
+    B: NormExponent,
+    J: NormExponent,
+{
+}
 
 /// A Huber/Moreau–Yosida smoothed [`L1`] norm. (Not a norm itself.)
 ///
 /// The parameter γ of this type is the smoothing factor. Zero means no smoothing, and higher
 /// values more smoothing. Behaviour with γ < 0 is undefined.
-#[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)]
-pub struct HuberL1<F : Float>(pub F);
-impl<F : Float> NormExponent for HuberL1<F> {}
+#[derive(Copy, Debug, Clone, Serialize, Eq, PartialEq)]
+pub struct HuberL1<F: Float>(pub F);
+impl<F: Float> NormExponent for HuberL1<F> {}
 
 /// A Huber/Moreau–Yosida smoothed [`L21`] norm. (Not a norm itself.)
 ///
 /// The parameter γ of this type is the smoothing factor. Zero means no smoothing, and higher
 /// values more smoothing. Behaviour with γ < 0 is undefined.
-#[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)]
-pub struct HuberL21<F : Float>(pub F);
-impl<F : Float> NormExponent for HuberL21<F> {}
-
+#[derive(Copy, Debug, Clone, Serialize, Eq, PartialEq)]
+pub struct HuberL21<F: Float>(pub F);
+impl<F: Float> NormExponent for HuberL21<F> {}
 
 /// A normed space (type) with exponent or other type `Exponent` for the norm.
 ///
@@ -86,27 +92,27 @@
 ///
 /// println!("{}, {} {}", x.norm(L1), x.norm(L2), x.norm(Linfinity))
 /// ```
-pub trait Norm<F : Num, Exponent : NormExponent> {
+pub trait Norm<F: Num, Exponent: NormExponent> {
     /// Calculate the norm.
-    fn norm(&self, _p : Exponent) -> F;
+    fn norm(&self, _p: Exponent) -> F;
 }
 
 /// Indicates that the `Self`-[`Norm`] is dominated by the `Exponent`-`Norm` on the space
 /// `Elem` with the corresponding field `F`.
-pub trait Dominated<F : Num, Exponent : NormExponent, Elem> {
+pub trait Dominated<F: Num, Exponent: NormExponent, Elem> {
     /// Indicates the factor $c$ for the inequality $‖x‖ ≤ C ‖x‖_p$.
-    fn norm_factor(&self, p : Exponent) -> F;
+    fn norm_factor(&self, p: Exponent) -> F;
     /// Given a norm-value $‖x‖_p$, calculates $C‖x‖_p$ such that $‖x‖ ≤ C‖x‖_p$
     #[inline]
-    fn from_norm(&self, p_norm : F, p : Exponent) -> F {
+    fn from_norm(&self, p_norm: F, p: Exponent) -> F {
         p_norm * self.norm_factor(p)
     }
 }
 
 /// Trait for distances with respect to a norm.
-pub trait Dist<F : Num, Exponent : NormExponent> : Norm<F, Exponent> + Space {
+pub trait Dist<F: Num, Exponent: NormExponent>: Norm<F, Exponent> + Space {
     /// Calculate the distance
-    fn dist<I : Instance<Self>>(&self, other : I, _p : Exponent) -> F;
+    fn dist<I: Instance<Self>>(&self, other: I, _p: Exponent) -> F;
 }
 
 /// Trait for Euclidean projections to the `Exponent`-[`Norm`]-ball.
@@ -119,16 +125,18 @@
 ///
 /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity));
 /// ```
-pub trait Projection<F : Num, Exponent : NormExponent> : Norm<F, Exponent> + Sized
-where F : Float {
+pub trait Projection<F: Num, Exponent: NormExponent>: Norm<F, Exponent> + Sized
+where
+    F: Float,
+{
     /// Projection of `self` to the `q`-norm-ball of radius ρ.
-    fn proj_ball(mut self, ρ : F, q : Exponent) -> Self {
+    fn proj_ball(mut self, ρ: F, q: Exponent) -> Self {
         self.proj_ball_mut(ρ, q);
         self
     }
 
     /// In-place projection of `self` to the `q`-norm-ball of radius ρ.
-    fn proj_ball_mut(&mut self, ρ : F, q : Exponent);
+    fn proj_ball_mut(&mut self, ρ: F, q: Exponent);
 }
 
 /*impl<F : Float, E : Euclidean<F>> Norm<F, L2> for E {
@@ -138,25 +146,29 @@
     fn dist(&self, other : &Self, _p : L2) -> F { self.dist2(other) }
 }*/
 
-impl<F : Float, E : Euclidean<F> + Norm<F, L2>> Projection<F, L2> for E {
+impl<F: Float, E: Euclidean<F> + Norm<F, L2>> Projection<F, L2> for E {
     #[inline]
-    fn proj_ball(self, ρ : F, _p : L2) -> Self { self.proj_ball2(ρ) }
+    fn proj_ball(self, ρ: F, _p: L2) -> Self {
+        self.proj_ball2(ρ)
+    }
 
     #[inline]
-    fn proj_ball_mut(&mut self, ρ : F, _p : L2) { self.proj_ball2_mut(ρ) }
+    fn proj_ball_mut(&mut self, ρ: F, _p: L2) {
+        self.proj_ball2_mut(ρ)
+    }
 }
 
-impl<F : Float> HuberL1<F> {
-    fn apply(self, xnsq : F) -> F {
+impl<F: Float> HuberL1<F> {
+    fn apply(self, xnsq: F) -> F {
         let HuberL1(γ) = self;
         let xn = xnsq.sqrt();
         if γ == F::ZERO {
             xn
         } else {
             if xn > γ {
-                xn-γ / F::TWO
-            } else if xn<(-γ) {
-                -xn-γ / F::TWO
+                xn - γ / F::TWO
+            } else if xn < (-γ) {
+                -xn - γ / F::TWO
             } else {
                 xnsq / (F::TWO * γ)
             }
@@ -164,14 +176,14 @@
     }
 }
 
-impl<F : Float, E : Euclidean<F>> Norm<F, HuberL1<F>> for E {
-    fn norm(&self, huber : HuberL1<F>) -> F {
+impl<F: Float, E: Euclidean<F>> Norm<F, HuberL1<F>> for E {
+    fn norm(&self, huber: HuberL1<F>) -> F {
         huber.apply(self.norm2_squared())
     }
 }
 
-impl<F : Float, E : Euclidean<F>> Dist<F, HuberL1<F>> for E {
-    fn dist<I : Instance<Self>>(&self, other : I, huber : HuberL1<F>) -> F {
+impl<F: Float, E: Euclidean<F>> Dist<F, HuberL1<F>> for E {
+    fn dist<I: Instance<Self>>(&self, other: I, huber: HuberL1<F>) -> F {
         huber.apply(self.dist2_squared(other))
     }
 }
@@ -190,20 +202,20 @@
 
 impl<E, F, Domain> Mapping<Domain> for NormMapping<F, E>
 where
-    F : Float,
-    E : NormExponent,
-    Domain : Space + Norm<F, E>,
+    F: Float,
+    E: NormExponent,
+    Domain: Space + Norm<F, E>,
 {
     type Codomain = F;
 
     #[inline]
-    fn apply<I : Instance<Domain>>(&self, x : I) -> F {
+    fn apply<I: Instance<Domain>>(&self, x: I) -> F {
         x.eval(|r| r.norm(self.exponent))
     }
 }
 
-pub trait Normed<F : Num = f64> : Space + Norm<F, Self::NormExp> {
-    type NormExp : NormExponent;
+pub trait Normed<F: Num = f64>: Space + Norm<F, Self::NormExp> {
+    type NormExp: NormExponent;
 
     fn norm_exponent(&self) -> Self::NormExp;
 
@@ -217,30 +229,28 @@
     fn is_zero(&self) -> bool;
 }
 
-pub trait HasDual<F : Num = f64> : Normed<F> {
-    type DualSpace : Normed<F>;
+pub trait HasDual<F: Num = f64>: Normed<F> {
+    type DualSpace: Normed<F>;
 }
 
 /// Automatically implemented trait for reflexive spaces
-pub trait Reflexive<F : Num = f64> : HasDual<F>
+pub trait Reflexive<F: Num = f64>: HasDual<F>
 where
-    Self::DualSpace : HasDual<F, DualSpace = Self>
-{ }
+    Self::DualSpace: HasDual<F, DualSpace = Self>,
+{
+}
 
-impl<F : Num, X : HasDual<F>> Reflexive<F> for X
-where
-    X::DualSpace : HasDual<F, DualSpace = X>
-{ }
+impl<F: Num, X: HasDual<F>> Reflexive<F> for X where X::DualSpace: HasDual<F, DualSpace = X> {}
 
-pub trait HasDualExponent : NormExponent {
-    type DualExp : NormExponent;
+pub trait HasDualExponent: NormExponent {
+    type DualExp: NormExponent;
 
     fn dual_exponent(&self) -> Self::DualExp;
 }
 
 impl HasDualExponent for L2 {
     type DualExp = L2;
-    
+
     #[inline]
     fn dual_exponent(&self) -> Self::DualExp {
         L2
@@ -249,17 +259,16 @@
 
 impl HasDualExponent for L1 {
     type DualExp = Linfinity;
-    
+
     #[inline]
     fn dual_exponent(&self) -> Self::DualExp {
         Linfinity
     }
 }
 
-
 impl HasDualExponent for Linfinity {
     type DualExp = L1;
-    
+
     #[inline]
     fn dual_exponent(&self) -> Self::DualExp {
         L1
@@ -271,49 +280,50 @@
     ($exponent : ty) => {
         impl<C, F, D> Norm<F, Weighted<$exponent, C>> for D
         where
-            F : Float,
-            D : Norm<F, $exponent>,
-            C : Constant<Type = F>,
+            F: Float,
+            D: Norm<F, $exponent>,
+            C: Constant<Type = F>,
         {
-            fn norm(&self, e : Weighted<$exponent, C>) -> 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> NormExponent for Weighted<$exponent, C> {}
 
-        impl<C : Constant> HasDualExponent for Weighted<$exponent, C>
-        where $exponent : HasDualExponent {
+        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()
+                    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
+        impl<C, F, T> Projection<F, Weighted<$exponent, C>> for T
         where
-            T : Projection<F, $exponent >,
-            F : Float,
-            C : Constant<Type = F>,
+            T: Projection<F, $exponent>,
+            F: Float,
+            C: Constant<Type = F>,
         {
-            fn proj_ball(self, ρ : F, q : Weighted<$exponent , C>) -> Self {
+            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>) {
+            fn proj_ball_mut(&mut self, ρ: F, q: Weighted<$exponent, C>) {
                 self.proj_ball_mut(ρ / q.weight.value(), q.base_fn)
             }
         }
-    }
+    };
 }
 
 //impl_weighted_norm!(L1);
 //impl_weighted_norm!(L2);
 //impl_weighted_norm!(Linfinity);
-

mercurial