src/norms.rs

changeset 6
d80b87b8acd0
parent 5
59dc4c5883f4
--- 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);

mercurial