src/measures/discrete.rs

changeset 52
f0e8704d3f0e
parent 39
6316d68b58af
--- a/src/measures/discrete.rs	Tue Aug 01 10:25:09 2023 +0300
+++ b/src/measures/discrete.rs	Mon Feb 17 13:54:53 2025 -0500
@@ -11,9 +11,11 @@
 
 use alg_tools::norms::Norm;
 use alg_tools::tabledump::TableDump;
-use alg_tools::linops::{Apply, Linear};
+use alg_tools::linops::{Mapping, Linear};
 use alg_tools::iter::{MapF,Mappable};
 use alg_tools::nalgebra_support::ToNalgebraRealField;
+use alg_tools::collection::Collection;
+use alg_tools::instance::{Instance, Decomposition, MyCow, EitherDecomp, Space};
 
 use crate::types::*;
 use super::base::*;
@@ -29,6 +31,8 @@
     pub(super) spikes : Vec<DeltaMeasure<Domain, F>>,
 }
 
+pub type RNDM<F, const N : usize> = DiscreteMeasure<Loc<F, N>, F>;
+
 /// Iterator over the [`DeltaMeasure`] spikes of a [`DiscreteMeasure`].
 pub type SpikeIter<'a, Domain, F> = std::slice::Iter<'a, DeltaMeasure<Domain, F>>;
 
@@ -59,6 +63,20 @@
         self.spikes.len()
     }
 
+    /// Replace with the zero measure.
+    #[inline]
+    pub fn clear(&mut self) {
+        self.spikes.clear()
+    }
+
+    /// Remove `i`:th spike, not maintaining order.
+    ///
+    /// Panics if indiex is out of bounds.
+    #[inline]
+    pub fn swap_remove(&mut self, i : usize) -> DeltaMeasure<Domain, F>{
+        self.spikes.swap_remove(i)
+    }
+
     /// Iterate over (references to) the [`DeltaMeasure`] spikes in this measure
     #[inline]
     pub fn iter_spikes(&self) -> SpikeIter<'_, Domain, F> {
@@ -95,6 +113,13 @@
         self.spikes.iter_mut().zip(iter).for_each(|(δ, α)| δ.set_mass(α));
     }
 
+    /// Update the locations of all the spikes to those produced by an iterator.
+    #[inline]
+    pub fn set_locations<'a, I : Iterator<Item=&'a Domain>>(&mut self, iter : I) 
+    where Domain : 'static + Clone {
+        self.spikes.iter_mut().zip(iter.cloned()).for_each(|(δ, α)| δ.set_location(α));
+    }
+
     // /// Map the masses of all the spikes using a function and an iterator
     // #[inline]
     // pub fn zipmap_masses<
@@ -107,50 +132,162 @@
     /// Prune all spikes with zero mass.
     #[inline]
     pub fn prune(&mut self) {
-        self.spikes.retain(|δ| δ.α != F::ZERO);
+        self.prune_by(|δ| δ.α != F::ZERO);
+    }
+
+    /// Prune spikes by the predicate `g`.
+    #[inline]
+    pub fn prune_by<G : FnMut(&DeltaMeasure<Domain, F>) -> bool>(&mut self, g : G) {
+        self.spikes.retain(g);
+    }
+
+    /// Add the spikes produced by `iter` to this measure.
+    #[inline]
+    pub fn extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>(
+        &mut self,
+        iter : I
+    ) {
+        self.spikes.extend(iter);
+    }
+
+    /// Add a spike to the measure
+    #[inline]
+    pub fn push(&mut self, δ : DeltaMeasure<Domain, F>) {
+        self.spikes.push(δ);
+    }
+
+    /// Iterate over triples of masses and locations of two discrete measures, which are assumed
+    /// to have equal locations of same spike indices.
+    pub fn both_matching<'a>(&'a self, other : &'a DiscreteMeasure<Domain, F>) ->
+      impl Iterator<Item=(F, F, &'a Domain)> {
+        let m = self.len().max(other.len());
+        self.iter_spikes().map(Some).chain(std::iter::repeat(None))
+            .zip(other.iter_spikes().map(Some).chain(std::iter::repeat(None)))
+            .take(m)
+            .map(|(oδ, orδ)| {
+                match (oδ, orδ) {
+                    (Some(δ), Some(rδ)) => (δ.α, rδ.α, &δ.x), // Assumed δ.x=rδ.x
+                    (Some(δ), None)     => (δ.α, F::ZERO,  &δ.x),
+                    (None, Some(rδ))    => (F::ZERO, rδ.α, &rδ.x),
+                    (None, None)        => panic!("This cannot happen!"),
+                }
+            })
+    }
+
+    /// Subtract `other` from `self`, assuming equal locations of same spike indices
+    pub fn sub_matching(&self, other : &DiscreteMeasure<Domain, F>) -> DiscreteMeasure<Domain, F>
+    where Domain : Clone {
+        self.both_matching(other)
+            .map(|(α, β, x)| (x.clone(), α - β))
+            .collect()
+    }
+
+    /// Add `other` to `self`, assuming equal locations of same spike indices
+    pub fn add_matching(&self, other : &DiscreteMeasure<Domain, F>) -> DiscreteMeasure<Domain, F>
+    where Domain : Clone {
+        self.both_matching(other)
+            .map(|(α, β, x)| (x.clone(), α + β))
+            .collect()
+    }
+
+    /// Calculate the Radon-norm distance of `self` to `other`,
+    /// assuming equal locations of same spike indices.
+    pub fn dist_matching(&self, other : &DiscreteMeasure<Domain, F>) -> F where F : Float {
+        self.both_matching(other)
+            .map(|(α, β, _)| (α-β).abs())
+            .sum()
+    }
+}
+
+impl<Domain, F : Num> IntoIterator for DiscreteMeasure<Domain, F> {
+    type Item =  DeltaMeasure<Domain, F>;
+    type IntoIter = std::vec::IntoIter<DeltaMeasure<Domain, F>>;
+
+    #[inline]
+    fn into_iter(self) -> Self::IntoIter {
+        self.spikes.into_iter()
+    }
+}
+
+impl<'a, Domain, F : Num> IntoIterator for &'a DiscreteMeasure<Domain, F> {
+    type Item =  &'a DeltaMeasure<Domain, F>;
+    type IntoIter =  SpikeIter<'a, Domain, F>;
+
+    #[inline]
+    fn into_iter(self) -> Self::IntoIter {
+        self.spikes.iter()
+    }
+}
+
+impl<Domain, F : Num> Sum<DeltaMeasure<Domain, F>> for DiscreteMeasure<Domain, F>  {
+    // Required method
+    fn sum<I>(iter: I) -> Self
+    where
+        I : Iterator<Item = DeltaMeasure<Domain, F>>
+    {
+        Self::from_iter(iter)
+    }
+}
+
+impl<'a, Domain : Clone, F : Num> Sum<&'a DeltaMeasure<Domain, F>>
+    for DiscreteMeasure<Domain, F>
+{
+    // Required method
+    fn sum<I>(iter: I) -> Self
+    where
+        I : Iterator<Item = &'a DeltaMeasure<Domain, F>>
+    {
+        Self::from_iter(iter.cloned())
+    }
+}
+
+impl<Domain, F : Num> Sum<DiscreteMeasure<Domain, F>> for DiscreteMeasure<Domain, F>  {
+    // Required method
+    fn sum<I>(iter: I) -> Self
+    where
+        I : Iterator<Item = DiscreteMeasure<Domain, F>>
+    {
+        Self::from_iter(iter.map(|μ| μ.into_iter()).flatten())
+    }
+}
+
+impl<'a, Domain : Clone, F : Num> Sum<&'a DiscreteMeasure<Domain, F>>
+    for DiscreteMeasure<Domain, F>
+{
+    // Required method
+    fn sum<I>(iter: I) -> Self
+    where
+        I : Iterator<Item = &'a DiscreteMeasure<Domain, F>>
+    {
+        Self::from_iter(iter.map(|μ| μ.iter_spikes()).flatten().cloned())
     }
 }
 
 impl<Domain : Clone, F : Float> DiscreteMeasure<Domain, F> {
     /// Computes `μ1 ← θ * μ1 - ζ * μ2`, pruning entries where both `μ1` (`self`) and `μ2` have
-    // zero weight. `μ2` will contain copy of pruned original `μ1` without arithmetic performed.
-    /// **This expects `self` and `μ2` to have matching coordinates in each index**.
+    // zero weight. `μ2` will contain a pruned copy of pruned original `μ1` without arithmetic
+    /// performed. **This expects `self` and `μ2` to have matching coordinates in each index**.
     // `μ2` can be than `self`, but not longer.
     pub fn pruning_sub(&mut self, θ : F, ζ : F, μ2 : &mut Self) {
-        let mut μ2_get = 0;
-        let mut μ2_insert = 0;
-        self.spikes.drain_filter(|&mut DeltaMeasure{ α : ref mut α_ref, ref x }| {
-            // Get weight of spike in μ2, zero if out of bounds.
-            let β = μ2.spikes.get(μ2_get).map_or(F::ZERO, DeltaMeasure::get_mass);
-            μ2_get += 1;
-
-            if *α_ref == F::ZERO && β == F::ZERO {
-                // Prune
-                true
+        for δ in &self[μ2.len()..] {
+            μ2.push(DeltaMeasure{ x : δ.x.clone(), α : F::ZERO});
+        }
+        debug_assert_eq!(self.len(), μ2.len());
+        let mut dest = 0;
+        for i in 0..self.len() {
+            let α = self[i].α;
+            let α_new = θ * α - ζ * μ2[i].α;
+            if dest < i {
+                μ2[dest] = DeltaMeasure{ x : self[i].x.clone(), α };
+                self[dest] = DeltaMeasure{ x : self[i].x.clone(), α : α_new };
             } else {
-                // Save self weight
-                let α = *α_ref;
-                // Modify self
-                *α_ref = θ * α - ζ * β;
-                // Make copy of old self weight in μ2
-                let δ = DeltaMeasure{ α, x : x.clone() };
-                match μ2.spikes.get_mut(μ2_insert) {
-                    Some(replace) => {
-                        *replace = δ;
-                    },
-                    None => {
-                        debug_assert_eq!(μ2.len(), μ2_insert);
-                        μ2.spikes.push(δ);
-                    },
-                }
-                μ2_insert += 1;
-                // Keep
-                false
+                μ2[i].α = α;
+                self[i].α = α_new;
             }
-        });
-        // Truncate μ2 to same length as self.
-        μ2.spikes.truncate(μ2_insert);
-        debug_assert_eq!(μ2.len(), self.len());
+            dest += 1;
+        }
+        self.spikes.truncate(dest);
+        μ2.spikes.truncate(dest);
     }
 }
 
@@ -174,23 +311,61 @@
     pub fn set_masses_dvector(&mut self, x : &DVector<F::MixedType>) {
         self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α)));
     }
+
+    // /// Extracts the masses of the spikes as a [`Vec`].
+    // pub fn masses_vec(&self) -> Vec<F::MixedType> {
+    //     self.iter_masses()
+    //         .map(|α| α.to_nalgebra_mixed())
+    //         .collect()
+    // }
+
+    // /// Sets the masses of the spikes from the values of a [`Vec`].
+    // pub fn set_masses_vec(&mut self, x : &Vec<F::MixedType>) {
+    //     self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α)));
+    // }
 }
 
-impl<Domain, F :Num> Index<usize> for DiscreteMeasure<Domain, F> {
-    type Output = DeltaMeasure<Domain, F>;
+// impl<Domain, F :Num> Index<usize> for DiscreteMeasure<Domain, F> {
+//     type Output = DeltaMeasure<Domain, F>;
+//     #[inline]
+//     fn index(&self, i : usize) -> &Self::Output {
+//         self.spikes.index(i)
+//     }
+// }
+
+// impl<Domain, F :Num> IndexMut<usize> for DiscreteMeasure<Domain, F> {
+//     #[inline]
+//     fn index_mut(&mut self, i : usize) -> &mut Self::Output {
+//         self.spikes.index_mut(i)
+//     }
+// }
+
+impl<
+    Domain,
+    F : Num,
+    I : std::slice::SliceIndex<[DeltaMeasure<Domain, F>]>
+> Index<I>
+for DiscreteMeasure<Domain, F> {
+    type Output = <I as std::slice::SliceIndex<[DeltaMeasure<Domain, F>]>>::Output;
     #[inline]
-    fn index(&self, i : usize) -> &Self::Output {
+    fn index(&self, i : I) -> &Self::Output {
         self.spikes.index(i)
     }
 }
 
-impl<Domain, F :Num> IndexMut<usize> for DiscreteMeasure<Domain, F> {
+impl<
+    Domain,
+    F : Num,
+    I : std::slice::SliceIndex<[DeltaMeasure<Domain, F>]>
+> IndexMut<I>
+for DiscreteMeasure<Domain, F> {
     #[inline]
-    fn index_mut(&mut self, i : usize) -> &mut Self::Output {
+    fn index_mut(&mut self, i : I) -> &mut Self::Output {
         self.spikes.index_mut(i)
     }
 }
 
+
 impl<Domain, F : Num, D : Into<DeltaMeasure<Domain, F>>, const K : usize> From<[D; K]>
 for DiscreteMeasure<Domain, F> {
     #[inline]
@@ -199,6 +374,45 @@
     }
 }
 
+impl<Domain, F : Num> From<Vec<DeltaMeasure<Domain, F>>>
+for DiscreteMeasure<Domain, F> {
+    #[inline]
+    fn from(spikes : Vec<DeltaMeasure<Domain, F>>) -> Self {
+        DiscreteMeasure{ spikes }
+    }
+}
+
+impl<'a, Domain, F : Num, D> From<&'a [D]>
+for DiscreteMeasure<Domain, F>
+where &'a D : Into<DeltaMeasure<Domain, F>> {
+    #[inline]
+    fn from(list : &'a [D]) -> Self {
+        list.into_iter().map(|d| d.into()).collect()
+    }
+}
+
+
+impl<Domain, F : Num> From<DeltaMeasure<Domain, F>>
+for DiscreteMeasure<Domain, F> {
+    #[inline]
+    fn from(δ : DeltaMeasure<Domain, F>) -> Self {
+        DiscreteMeasure{
+            spikes : vec!(δ)
+        }
+    }
+}
+
+impl<'a, Domain : Clone, F : Num> From<&'a DeltaMeasure<Domain, F>>
+for DiscreteMeasure<Domain, F> {
+    #[inline]
+    fn from(δ : &'a DeltaMeasure<Domain, F>) -> Self {
+        DiscreteMeasure{
+            spikes : vec!(δ.clone())
+        }
+    }
+}
+
+
 impl<Domain, F : Num, D : Into<DeltaMeasure<Domain, F>>> FromIterator<D>
 for DiscreteMeasure<Domain, F> {
     #[inline]
@@ -258,19 +472,28 @@
     }
 }
 
-impl<Domain, G, F : Num, Y : Sum + Mul<F, Output=Y>> Apply<G> for DiscreteMeasure<Domain, F>
-where G: for<'a> Apply<&'a Domain, Output = Y> {
-    type Output = Y;
+impl<Domain, G, F : Num> Mapping<G> for DiscreteMeasure<Domain, F>
+where
+    Domain : Space,
+    G::Codomain : Sum + Mul<F, Output=G::Codomain>,
+    G : Mapping<Domain, Codomain=F> + Clone + Space,
+    for<'b> &'b Domain : Instance<Domain>,
+{
+    type Codomain = G::Codomain;
+
     #[inline]
-    fn apply(&self, g : G) -> Y {
-        self.spikes.iter().map(|m| g.apply(&m.x) * m.α).sum()
+    fn apply<I : Instance<G>>(&self, g : I) -> Self::Codomain {
+        g.eval(|g| self.spikes.iter().map(|m| g.apply(&m.x) * m.α).sum())
     }
 }
 
-impl<Domain, G, F : Num, Y : Sum + Mul<F, Output=Y>> Linear<G> for DiscreteMeasure<Domain, F>
-where G : for<'a> Apply<&'a Domain, Output = Y> {
-    type Codomain = Y;
-}
+impl<Domain, G, F : Num> Linear<G> for DiscreteMeasure<Domain, F>
+where
+    Domain : Space,
+    G::Codomain : Sum + Mul<F, Output=G::Codomain>,
+    G : Mapping<Domain, Codomain=F> + Clone + Space,
+    for<'b> &'b Domain : Instance<Domain>,
+{ }
 
 
 /// Helper trait for constructing arithmetic operations for combinations
@@ -278,6 +501,7 @@
 trait Lift<F : Num, Domain> {
     type Producer : Iterator<Item=DeltaMeasure<Domain, F>>;
 
+    #[allow(dead_code)]
     /// Lifts `self` into a [`DiscreteMeasure`].
     fn lift(self) -> DiscreteMeasure<Domain, F>;
 
@@ -574,3 +798,217 @@
 
 make_discrete_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
 make_discrete_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
+
+impl<F : Num, Domain> Collection for DiscreteMeasure<Domain, F> {
+    type Element = DeltaMeasure<Domain, F>;
+    type RefsIter<'a> = std::slice::Iter<'a, Self::Element> where Self : 'a;
+
+    #[inline]
+    fn iter_refs(&self) -> Self::RefsIter<'_> {
+        self.iter_spikes()
+    }
+}
+
+impl<Domain : Clone, F : Num> Space for DiscreteMeasure<Domain, F> {
+    type Decomp = MeasureDecomp;
+}
+
+pub type SpikeSlice<'b, Domain, F> = &'b [DeltaMeasure<Domain, F>];
+
+pub type EitherSlice<'b, Domain, F> = EitherDecomp<
+    Vec<DeltaMeasure<Domain, F>>,
+    SpikeSlice<'b, Domain, F>
+>;
+
+impl<F : Num, Domain : Clone> Decomposition<DiscreteMeasure<Domain, F>> for MeasureDecomp {
+    type Decomposition<'b> = EitherSlice<'b, Domain, F> where DiscreteMeasure<Domain, F> : 'b;
+    type Reference<'b> = SpikeSlice<'b, Domain, F> where DiscreteMeasure<Domain, F> : 'b;
+
+    /// Left the lightweight reference type into a full decomposition type.
+    fn lift<'b>(r : Self::Reference<'b>) -> Self::Decomposition<'b> {
+        EitherDecomp::Borrowed(r)
+    }
+}
+
+impl<F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
+for DiscreteMeasure<Domain, F>
+{
+    fn decompose<'b>(self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
+    where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
+        EitherDecomp::Owned(self.spikes)
+    }
+  
+    fn ref_instance(&self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
+    {
+        self.spikes.as_slice()
+    }
+
+    fn cow<'b>(self) -> MyCow<'b, DiscreteMeasure<Domain, F>> where Self : 'b {
+        MyCow::Owned(self)
+    }
+
+    fn own(self) -> DiscreteMeasure<Domain, F> {
+        self
+    }
+}
+
+impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
+for &'a DiscreteMeasure<Domain, F>
+{
+    fn decompose<'b>(self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
+    where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
+        EitherDecomp::Borrowed(self.spikes.as_slice())
+    }
+  
+    fn ref_instance(&self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
+    {
+        self.spikes.as_slice()
+    }
+
+    fn cow<'b>(self) -> MyCow<'b, DiscreteMeasure<Domain, F>> where Self : 'b {
+        MyCow::Borrowed(self)
+    }
+
+    fn own(self) -> DiscreteMeasure<Domain, F> {
+        self.clone()
+    }
+}
+
+impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
+for EitherSlice<'a, Domain, F>
+{
+    fn decompose<'b>(self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
+    where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
+        self
+    }
+  
+    fn ref_instance(&self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
+    {
+        match self {
+            EitherDecomp::Owned(v) => v.as_slice(),
+            EitherDecomp::Borrowed(s) => s,
+        }
+    }
+
+    fn own(self) -> DiscreteMeasure<Domain, F> {
+        match self {
+            EitherDecomp::Owned(v) => v.into(),
+            EitherDecomp::Borrowed(s) => s.into(),
+        }
+    }
+}
+
+impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
+for &'a EitherSlice<'a, Domain, F>
+{
+    fn decompose<'b>(self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
+    where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
+        match self {
+            EitherDecomp::Owned(v) => EitherDecomp::Borrowed(v.as_slice()),
+            EitherDecomp::Borrowed(s) => EitherDecomp::Borrowed(s),
+        }
+    }
+  
+    fn ref_instance(&self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
+    {
+        match self {
+            EitherDecomp::Owned(v) => v.as_slice(),
+            EitherDecomp::Borrowed(s) => s,
+        }
+    }
+
+    fn own(self) -> DiscreteMeasure<Domain, F> {
+        match self {
+            EitherDecomp::Owned(v) => v.as_slice(),
+            EitherDecomp::Borrowed(s) => s
+        }.into()
+    }
+}
+
+impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
+for SpikeSlice<'a, Domain, F>
+{
+    fn decompose<'b>(self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
+    where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
+        EitherDecomp::Borrowed(self)
+    }
+  
+    fn ref_instance(&self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
+    {
+        self
+    }
+
+    fn own(self) -> DiscreteMeasure<Domain, F> {
+        self.into()
+    }
+}
+
+impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
+for &'a SpikeSlice<'a, Domain, F>
+{
+    fn decompose<'b>(self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
+    where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
+        EitherDecomp::Borrowed(*self)
+    }
+  
+    fn ref_instance(&self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
+    {
+        *self
+    }
+
+    fn own(self) -> DiscreteMeasure<Domain, F> {
+        (*self).into()
+    }
+}
+
+impl<F : Num, Domain : Clone > Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
+for DeltaMeasure<Domain, F>
+{
+    fn decompose<'b>(self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
+    where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
+        EitherDecomp::Owned(vec![self])
+    }
+  
+    fn ref_instance(&self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
+    {
+        std::slice::from_ref(self)
+    }
+
+    fn own(self) -> DiscreteMeasure<Domain, F> {
+        self.into()
+    }
+}
+
+impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
+for &'a DeltaMeasure<Domain, F>
+{
+    fn decompose<'b>(self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
+    where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
+        EitherDecomp::Borrowed(std::slice::from_ref(self))
+    }
+  
+    fn ref_instance(&self)
+        -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
+    {
+        std::slice::from_ref(*self)
+    }
+
+    fn own(self) -> DiscreteMeasure<Domain, F> {
+        self.into()
+    }
+}

mercurial