diff -r 1a38447a89fa -r 9226980e45a7 src/norms.rs --- a/src/norms.rs Sat Dec 14 09:31:27 2024 -0500 +++ b/src/norms.rs Tue Dec 31 08:30:02 2024 -0500 @@ -3,18 +3,31 @@ */ 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)] +/// Helper structure to convert a [`NormExponent`] into a [`Mapping`] +pub struct NormMapping{ + pub(crate) exponent : E, + _phantoms : PhantomData +} + /// 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 + Send + Sync + 'static { + /// Return the norm as a mappin + fn as_mapping(self) -> NormMapping { + NormMapping{ exponent : self, _phantoms : PhantomData } + } +} /// Exponent type for the 1-[`Norm`]. #[derive(Copy,Debug,Clone,Serialize,Eq,PartialEq)] @@ -37,6 +50,15 @@ 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)] +pub struct PairNorm(pub A, pub B, pub J); + +impl NormExponent for PairNorm +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 @@ -154,3 +176,29 @@ } } +impl> Norm for Vec { + fn norm(&self, _l21 : L21) -> F { + self.iter().map(|e| e.norm(L2)).sum() + } +} + +impl> Dist for Vec { + fn dist(&self, other : &Self, _l21 : L21) -> F { + self.iter().zip(other.iter()).map(|(e, g)| e.dist(g, L2)).sum() + } +} + +impl Mapping for NormMapping +where + F : Float, + E : NormExponent, + Domain : Space + Norm, +{ + type Codomain = F; + + #[inline] + fn apply>(&self, x : I) -> F { + x.eval(|r| r.norm(self.exponent)) + } +} +