diff -r edb95d2b83cc -r d2acaaddd9af src/norms.rs --- a/src/norms.rs Sun Nov 10 09:02:57 2024 -0500 +++ b/src/norms.rs Tue Dec 31 09:12:43 2024 -0500 @@ -5,6 +5,7 @@ use serde::Serialize; use crate::types::*; use crate::euclidean::*; +pub use crate::types::{HasScalarField, HasRealField}; // // Abstract norms @@ -53,7 +54,6 @@ pub struct HuberL21(pub F); impl NormExponent for HuberL21 {} - /// A normed space (type) with exponent or other type `Exponent` for the norm. /// /// Use as @@ -64,27 +64,28 @@ /// /// println!("{}, {} {}", x.norm(L1), x.norm(L2), x.norm(Linfinity)) /// ``` -pub trait Norm { +pub trait Norm : HasScalarField { /// Calculate the norm. - fn norm(&self, _p : Exponent) -> F; + fn norm(&self, _p : Exponent) -> Self::Field; } /// Indicates that the `Self`-[`Norm`] is dominated by the `Exponent`-`Norm` on the space /// `Elem` with the corresponding field `F`. -pub trait Dominated { +pub trait Dominated +where Elem : HasScalarField { /// Indicates the factor $c$ for the inequality $‖x‖ ≤ C ‖x‖_p$. - fn norm_factor(&self, p : Exponent) -> F; + fn norm_factor(&self, p : Exponent) -> Elem::Field; /// 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 : Elem::Field, p : Exponent) -> Elem::Field { p_norm * self.norm_factor(p) } } /// Trait for distances with respect to a norm. -pub trait Dist : Norm { +pub trait Dist : Norm { /// Calculate the distance - fn dist(&self, other : &Self, _p : Exponent) -> F; + fn dist(&self, other : &Self, _p : Exponent) -> Self::Field; } /// Trait for Euclidean projections to the `Exponent`-[`Norm`]-ball. @@ -97,16 +98,15 @@ /// /// println!("{:?}, {:?}", x.proj_ball(1.0, L2), x.proj_ball(0.5, Linfinity)); /// ``` -pub trait Projection : Norm + Euclidean -where F : Float { +pub trait Projection : Norm + Euclidean { /// Projection of `self` to the `q`-norm-ball of radius ρ. - fn proj_ball(mut self, ρ : F, q : Exponent) -> Self { + fn proj_ball(mut self, ρ : Self::Field, 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, ρ : Self::Field, _q : Exponent); } /*impl> Norm for E { @@ -116,12 +116,12 @@ fn dist(&self, other : &Self, _p : L2) -> F { self.dist2(other) } }*/ -impl + Norm> Projection for E { +impl + Euclidean> Projection for E { #[inline] - fn proj_ball(self, ρ : F, _p : L2) -> Self { self.proj_ball2(ρ) } + fn proj_ball(self, ρ : Self::Field, _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, ρ : Self::Field, _p : L2) { self.proj_ball2_mut(ρ) } } impl HuberL1 { @@ -142,13 +142,13 @@ } } -impl> Norm> for E { +impl> Norm> for E { fn norm(&self, huber : HuberL1) -> F { huber.apply(self.norm2_squared()) } } -impl> Dist> for E { +impl> Dist> for E { fn dist(&self, other : &Self, huber : HuberL1) -> F { huber.apply(self.dist2_squared(other)) }