--- a/src/norms.rs Sat Oct 22 14:40:28 2022 +0300 +++ b/src/norms.rs Tue Oct 25 23:05:40 2022 +0300 @@ -10,22 +10,32 @@ // Abstract norms // +/// An exponent for norms. +/// +// Just a collection of desirabl attributes for a marker type +pub trait NormExponent : Copy + Send + Sync + 'static {} + + /// Exponent type for the 1-[`Norm`]. #[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)] pub struct L2; +impl NormExponent for L2 {} /// Exponent type for the ∞-[`Norm`]. #[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)] pub struct L21; +impl NormExponent for L21 {} /// A Huber/Moreau–Yosida smoothed [`L1`] norm. (Not a norm itself.) /// @@ -33,6 +43,7 @@ /// 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> {} /// A Huber/Moreau–Yosida smoothed [`L21`] norm. (Not a norm itself.) /// @@ -40,6 +51,8 @@ /// 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> {} + /// A normed space (type) with exponent or other type `Exponent` for the norm. /// @@ -51,14 +64,14 @@ /// /// println!("{}, {} {}", x.norm(L1), x.norm(L2), x.norm(Linfinity)) /// ``` -pub trait Norm<F, Exponent> { +pub trait Norm<F : Num, Exponent : NormExponent> { /// Calculate the norm. 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, 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; /// Given a norm-value $‖x‖_p$, calculates $C‖x‖_p$ such that $‖x‖ ≤ C‖x‖_p$ @@ -69,7 +82,7 @@ } /// Trait for distances with respect to a norm. -pub trait Dist<F,Exponent> : Norm<F, Exponent> { +pub trait Dist<F : Num, Exponent : NormExponent> : Norm<F, Exponent> { /// Calculate the distance fn dist(&self, other : &Self, _p : Exponent) -> F; } @@ -84,7 +97,8 @@ /// /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity)); /// ``` -pub trait Projection<F, Exponent> : Norm<F, Exponent> + Euclidean<F> where F : Float { +pub trait Projection<F : Num, Exponent : NormExponent> : Norm<F, Exponent> + Euclidean<F> +where F : Float { /// Projection of `self` to the `q`-norm-ball of radius ρ. fn proj_ball(mut self, ρ : F, q : Exponent) -> Self { self.proj_ball_mut(ρ, q);