--- a/src/measures/delta.rs Thu Aug 29 00:00:00 2024 -0500 +++ b/src/measures/delta.rs Tue Dec 31 09:25:45 2024 -0500 @@ -7,8 +7,9 @@ use crate::types::*; use std::ops::{Div, Mul, DivAssign, MulAssign, Neg}; use serde::ser::{Serialize, Serializer, SerializeStruct}; -use alg_tools::norms::{Norm, Dist}; -use alg_tools::linops::{Apply, Linear}; +use alg_tools::norms::Norm; +use alg_tools::linops::{Mapping, Linear}; +use alg_tools::instance::{Instance, Space}; /// Representation of a delta measure. /// @@ -50,43 +51,50 @@ } -impl<Domain : PartialEq, F : Float> Measure<F> for DeltaMeasure<Domain, F> { +impl<Domain, F : Float> Measure<F> for DeltaMeasure<Domain, F> { type Domain = Domain; } -impl<Domain : PartialEq, F : Float> Norm<F, Radon> for DeltaMeasure<Domain, F> { +impl<Domain, F : Float> Norm<F, Radon> for DeltaMeasure<Domain, F> { #[inline] fn norm(&self, _ : Radon) -> F { self.α.abs() } } -impl<Domain : PartialEq, F : Float> Dist<F, Radon> for DeltaMeasure<Domain, F> { +// impl<Domain : PartialEq, F : Float> Dist<F, Radon> for DeltaMeasure<Domain, F> { +// #[inline] +// fn dist(&self, other : &Self, _ : Radon) -> F { +// if self.x == other. x { +// (self.α - other.α).abs() +// } else { +// self.α.abs() + other.α.abs() +// } +// } +// } + +impl<Domain, G, F : Num> Mapping<G> for DeltaMeasure<Domain, F> +where + Domain : Space, + G::Codomain : Mul<F, Output=G::Codomain>, + G : Mapping<Domain> + Clone + Space, + for<'b> &'b Domain : Instance<Domain>, +{ + type Codomain = G::Codomain; + #[inline] - fn dist(&self, other : &Self, _ : Radon) -> F { - if self.x == other. x { - (self.α - other.α).abs() - } else { - self.α.abs() + other.α.abs() - } + fn apply<I : Instance<G>>(&self, g : I) -> Self::Codomain { + g.eval(|g̃| g̃.apply(&self.x) * self.α) } } -impl<'b, Domain, G, F : Num, V : Mul<F, Output=V>> Apply<G> for DeltaMeasure<Domain, F> -where G: for<'a> Apply<&'a Domain, Output = V>, - V : Mul<F> { - type Output = V; - - #[inline] - fn apply(&self, g : G) -> Self::Output { - g.apply(&self.x) * self.α - } -} - -impl<Domain, G, F : Num, V : Mul<F, Output=V>> Linear<G> for DeltaMeasure<Domain, F> -where G: for<'a> Apply<&'a Domain, Output = V> { - type Codomain = V; -} +impl<Domain, G, F : Num> Linear<G> for DeltaMeasure<Domain, F> +where + Domain : Space, + G::Codomain : Mul<F, Output=G::Codomain>, + G : Mapping<Domain> + Clone + Space, + for<'b> &'b Domain : Instance<Domain>, +{ } // /// Partial blanket implementation of [`DeltaMeasure`] as a linear functional of [`Mapping`]s. // /// A full blanket implementation is not possible due to annoying Rust limitations: only [`Apply`] @@ -141,12 +149,13 @@ } } -/*impl<F : Num> From<(F, F)> for DeltaMeasure<Loc<F, 1>, F> { +impl<'a, Domain : Clone, F : Num> From<&'a DeltaMeasure<Domain, F>> for DeltaMeasure<Domain, F> { #[inline] - fn from((x, α) : (F, F)) -> Self { - DeltaMeasure{x: Loc([x]), α: α} + fn from(d : &'a DeltaMeasure<Domain, F>) -> Self { + d.clone() } -}*/ +} + impl<Domain, F : Num> DeltaMeasure<Domain, F> { /// Set the mass of the spike. @@ -186,6 +195,26 @@ } } +impl<Domain, F : Num> IntoIterator for DeltaMeasure<Domain, F> { + type Item = Self; + type IntoIter = std::iter::Once<Self>; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + std::iter::once(self) + } +} + +impl<'a, Domain, F : Num> IntoIterator for &'a DeltaMeasure<Domain, F> { + type Item = Self; + type IntoIter = std::iter::Once<Self>; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + std::iter::once(self) + } +} + macro_rules! make_delta_scalarop_rhs { ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => {