src/measures/delta.rs

branch
dev
changeset 61
4f468d35fa29
parent 60
9738b51d90d7
child 62
32328a74c790
child 63
7a8a55fd41c0
--- a/src/measures/delta.rs	Sun Apr 27 15:03:51 2025 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,320 +0,0 @@
-/*!
-This module implementes delta measures, i.e., single spikes $\alpha \delta_x$ for some
-location $x$ and mass $\alpha$.
-*/
-
-use super::base::*;
-use crate::types::*;
-use std::ops::{Div, Mul, DivAssign, MulAssign, Neg};
-use serde::ser::{Serialize, Serializer, SerializeStruct};
-use alg_tools::norms::Norm;
-use alg_tools::linops::{Mapping, Linear};
-use alg_tools::instance::{Instance, Space};
-
-/// Representation of a delta measure.
-///
-/// This is a single spike $\alpha \delta\_x$ for some location $x$ in `Domain` and
-/// a mass $\alpha$ in `F`.
-#[derive(Clone,Copy,Debug)]
-pub struct DeltaMeasure<Domain, F : Num> {
-    // This causes [`csv`] to crash.
-    //#[serde(flatten)]
-    /// Location of the spike
-    pub x : Domain,
-    /// Mass of the spike
-    pub α : F
-}
-
-const COORDINATE_NAMES : &'static [&'static str] = &[
-    "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7"
-];
-
-// Need to manually implement serialisation as [`csv`] writer fails on
-// structs with nested arrays as well as with #[serde(flatten)].
-impl<F : Num, const N : usize> Serialize for DeltaMeasure<Loc<F, N>, F>
-where
-    F: Serialize,
-{
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        assert!(N <= COORDINATE_NAMES.len());
-
-        let mut s = serializer.serialize_struct("DeltaMeasure", N+1)?;
-        for (i, e) in (0..).zip(self.x.iter()) {
-            s.serialize_field(COORDINATE_NAMES[i], e)?;
-        }
-        s.serialize_field("weight", &self.α)?;
-        s.end()
-    }
-}
-
-
-impl<Domain, F : Float> Measure<F> for DeltaMeasure<Domain, F> {
-    type Domain = Domain;
-}
-
-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> {
-//     #[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 apply<I : Instance<G>>(&self, g : I) -> Self::Codomain {
-        g.eval(|g̃| g̃.apply(&self.x) * self.α)
-    }
-}
-
-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`]
-// /// on a reference is implemented, but a consuming [`Apply`] has to be implemented on a case-by-case
-// /// basis, not because an implementation could not be written, but because the Rust trait system
-// /// chokes up.
-// impl<Domain, G, F : Num, V> Linear<G> for DeltaMeasure<Domain, F>
-// where G: for<'a> Apply<&'a Domain, Output = V>,
-//       V : Mul<F>,
-//       Self: Apply<G, Output =  <V as Mul<F>>::Output> {
-//     type Codomain = <V as Mul<F>>::Output;
-// }
-
-// impl<'b, Domain, G, F : Num, V> Apply<&'b G> for DeltaMeasure<Domain, F>
-// where G: for<'a> Apply<&'a Domain, Output = V>,
-//       V : Mul<F> {
-//     type Output = <V as Mul<F>>::Output;
-
-//     #[inline]
-//     fn apply(&self, g : &'b G) -> Self::Output {
-//         g.apply(&self.x) * self.α
-//     }
-// }
-
-// /// Implementation of the necessary apply for BTFNs
-// mod btfn_apply {
-//     use super::*;
-//     use alg_tools::bisection_tree::{BTFN, BTImpl, SupportGenerator, LocalAnalysis};
-
-//     impl<F : Float, BT, G, V, const N : usize> Apply<BTFN<F, G, BT, N>>
-//     for DeltaMeasure<Loc<F, N>, F>
-//     where BT : BTImpl<F, N>,
-//         G : SupportGenerator<F, N, Id=BT::Data>,
-//         G::SupportType : LocalAnalysis<F, BT::Agg, N> + for<'a> Apply<&'a Loc<F, N>, Output = V>,
-//         V : std::iter::Sum + Mul<F> {
-        
-//         type Output = <V as Mul<F>>::Output;
-
-//         #[inline]
-//         fn apply(&self, g : BTFN<F, G, BT, N>) -> Self::Output {
-//             g.apply(&self.x) * self.α
-//         }
-//     }
-// }
-
-
-impl<D, Domain, F : Num> From<(D, F)> for DeltaMeasure<Domain, F>
-where D : Into<Domain> {
-    #[inline]
-    fn from((x, α) : (D, F)) -> Self {
-        DeltaMeasure{x: x.into(), α: α}
-    }
-}
-
-impl<'a, Domain : Clone, F : Num> From<&'a DeltaMeasure<Domain, F>> for DeltaMeasure<Domain, F> {
-    #[inline]
-    fn from(d : &'a DeltaMeasure<Domain, F>) -> Self {
-        d.clone()
-    }
-}
-
-
-impl<Domain, F : Num> DeltaMeasure<Domain, F> {
-    /// Set the mass of the spike.
-    #[inline]
-    pub fn set_mass(&mut self, α : F) {
-        self.α = α
-    }
-
-    /// Set the location of the spike.
-    #[inline]
-    pub fn set_location(&mut self, x : Domain) {
-        self.x = x
-    }
-
-    /// Get the mass of the spike.
-    #[inline]
-    pub fn get_mass(&self) -> F {
-        self.α
-    }
-
-    /// Get a mutable reference to the mass of the spike.
-    #[inline]
-    pub fn get_mass_mut(&mut self) -> &mut F {
-        &mut self.α
-    }
-
-    /// Get a reference to the location of the spike.
-    #[inline]
-    pub fn get_location(&self) -> &Domain {
-        &self.x
-    }
-
-    /// Get a mutable reference to the location of the spike.
-    #[inline]
-    pub fn get_location_mut(&mut self) -> &mut Domain {
-        &mut self.x
-    }
-}
-
-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) => {
-        impl<F : Num, Domain> $trait<F> for DeltaMeasure<Domain, F> {
-            type Output = Self;
-            fn $fn(mut self, b : F) -> Self {
-                self.α.$fn_assign(b);
-                self
-            }
-        }
-
-        impl<'a, F : Num, Domain> $trait<&'a F> for DeltaMeasure<Domain, F> {
-            type Output = Self;
-            fn $fn(mut self, b : &'a F) -> Self {
-                self.α.$fn_assign(*b);
-                self
-            }
-        }
-
-        impl<'b, F : Num, Domain : Clone> $trait<F> for &'b DeltaMeasure<Domain, F> {
-            type Output = DeltaMeasure<Domain, F>;
-            fn $fn(self, b : F) -> Self::Output {
-                DeltaMeasure { α : self.α.$fn(b), x : self.x.clone() }
-            }
-        }
-
-        impl<'a, 'b, F : Num, Domain : Clone> $trait<&'a F> for &'b DeltaMeasure<Domain, F> {
-            type Output = DeltaMeasure<Domain, F>;
-            fn $fn(self, b : &'a F) -> Self::Output {
-                DeltaMeasure { α : self.α.$fn(*b), x : self.x.clone() }
-            }
-        }
-
-        impl<F : Num, Domain> $trait_assign<F> for DeltaMeasure<Domain, F> {
-            fn $fn_assign(&mut self, b : F) {
-                self.α.$fn_assign(b)
-            }
-        }
-
-        impl<'a, F : Num, Domain> $trait_assign<&'a F> for DeltaMeasure<Domain, F> {
-            fn $fn_assign(&mut self, b : &'a F) {
-                self.α.$fn_assign(*b)
-            }
-        }
-    }
-}
-
-make_delta_scalarop_rhs!(Mul, mul, MulAssign, mul_assign);
-make_delta_scalarop_rhs!(Div, div, DivAssign, div_assign);
-
-macro_rules! make_delta_scalarop_lhs {
-    ($trait:ident, $fn:ident; $($f:ident)+) => { $(
-        impl<Domain> $trait<DeltaMeasure<Domain, $f>> for $f {
-            type Output = DeltaMeasure<Domain, $f>;
-            fn $fn(self, mut δ : DeltaMeasure<Domain, $f>) -> Self::Output {
-                δ.α = self.$fn(δ.α);
-                δ
-            }
-        }
-
-        impl<'a, Domain : Clone> $trait<&'a DeltaMeasure<Domain, $f>> for $f {
-            type Output = DeltaMeasure<Domain, $f>;
-            fn $fn(self, δ : &'a DeltaMeasure<Domain, $f>) -> Self::Output {
-                DeltaMeasure{ x : δ.x.clone(), α : self.$fn(δ.α) }
-            }
-        }
-
-        impl<'b, Domain> $trait<DeltaMeasure<Domain, $f>> for &'b $f {
-            type Output = DeltaMeasure<Domain, $f>;
-            fn $fn(self, mut δ : DeltaMeasure<Domain, $f>) -> Self::Output {
-                δ.α = self.$fn(δ.α);
-                δ
-            }
-        }
-
-        impl<'a, 'b, Domain : Clone> $trait<&'a DeltaMeasure<Domain, $f>> for &'b $f {
-            type Output = DeltaMeasure<Domain, $f>;
-            fn $fn(self, δ : &'a DeltaMeasure<Domain, $f>) -> Self::Output {
-                DeltaMeasure{ x : δ.x.clone(), α : self.$fn(δ.α) }
-            }
-        }
-    )+ }
-}
-
-make_delta_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
-make_delta_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
-
-macro_rules! make_delta_unary {
-    ($trait:ident, $fn:ident, $type:ty) => {
-        impl<'a, F : Num + Neg<Output=F>, Domain : Clone> Neg for $type {
-            type Output = DeltaMeasure<Domain, F>;
-            fn $fn(self) -> Self::Output {
-                let mut tmp = self.clone();
-                tmp.α = tmp.α.$fn();
-                tmp
-            }
-        }
-    }
-}
-
-make_delta_unary!(Neg, neg, DeltaMeasure<Domain, F>);
-make_delta_unary!(Neg, neg, &'a DeltaMeasure<Domain, F>);
-

mercurial