Mon, 06 Jan 2025 11:32:57 -0500
Factor fix
| 0 | 1 | //! This module implementes discrete measures. |
| 2 | ||
| 3 | use std::ops::{ | |
| 4 | Div,Mul,DivAssign,MulAssign,Neg, | |
| 5 | Add,Sub,AddAssign,SubAssign, | |
| 6 | Index,IndexMut, | |
| 7 | }; | |
| 8 | use std::iter::Sum; | |
| 9 | use serde::ser::{Serializer, Serialize, SerializeSeq}; | |
| 10 | use nalgebra::DVector; | |
| 11 | ||
| 12 | use alg_tools::norms::Norm; | |
| 13 | use alg_tools::tabledump::TableDump; | |
| 35 | 14 | use alg_tools::linops::{Mapping, Linear}; |
| 0 | 15 | use alg_tools::iter::{MapF,Mappable}; |
| 16 | use alg_tools::nalgebra_support::ToNalgebraRealField; | |
| 35 | 17 | use alg_tools::collection::Collection; |
| 18 | use alg_tools::instance::{Instance, Decomposition, MyCow, EitherDecomp, Space}; | |
| 0 | 19 | |
| 20 | use crate::types::*; | |
| 21 | use super::base::*; | |
| 22 | use super::delta::*; | |
| 23 | ||
| 24 | /// Representation of a discrete measure. | |
| 25 | /// | |
| 26 | /// This is the measure $μ = ∑_{k=1}^n α_k δ_{x_k}$, consisting of several | |
| 27 | /// [`DeltaMeasure`], i.e., “spikes” $α_k δ_{x_k}$ with weights $\alpha_k$ in `F` at locations | |
| 28 | /// $x_k$ in `Domain`. | |
| 29 | #[derive(Clone,Debug)] | |
| 30 | pub struct DiscreteMeasure<Domain, F : Num> { | |
| 31 | pub(super) spikes : Vec<DeltaMeasure<Domain, F>>, | |
| 32 | } | |
| 33 | ||
| 35 | 34 | pub type RNDM<F, const N : usize> = DiscreteMeasure<Loc<F, N>, F>; |
| 35 | ||
| 0 | 36 | /// Iterator over the [`DeltaMeasure`] spikes of a [`DiscreteMeasure`]. |
| 37 | pub type SpikeIter<'a, Domain, F> = std::slice::Iter<'a, DeltaMeasure<Domain, F>>; | |
| 38 | ||
| 39 | /// Iterator over mutable [`DeltaMeasure`] spikes of a [`DiscreteMeasure`]. | |
| 40 | pub type SpikeIterMut<'a, Domain, F> = std::slice::IterMut<'a, DeltaMeasure<Domain, F>>; | |
| 41 | ||
| 42 | /// Iterator over the locations of the spikes of a [`DiscreteMeasure`]. | |
| 43 | pub type LocationIter<'a, Domain, F> | |
| 44 | = std::iter::Map<SpikeIter<'a, Domain, F>, fn(&'a DeltaMeasure<Domain, F>) -> &'a Domain>; | |
| 45 | ||
| 46 | /// Iterator over the masses of the spikes of a [`DiscreteMeasure`]. | |
| 47 | pub type MassIter<'a, Domain, F> | |
| 48 | = std::iter::Map<SpikeIter<'a, Domain, F>, fn(&'a DeltaMeasure<Domain, F>) -> F>; | |
| 49 | ||
| 50 | /// Iterator over the mutable locations of the spikes of a [`DiscreteMeasure`]. | |
| 51 | pub type MassIterMut<'a, Domain, F> | |
| 52 | = std::iter::Map<SpikeIterMut<'a, Domain, F>, for<'r> fn(&'r mut DeltaMeasure<Domain, F>) -> &'r mut F>; | |
| 53 | ||
| 54 | impl<Domain, F : Num> DiscreteMeasure<Domain, F> { | |
| 55 | /// Create a new zero measure (empty spike set). | |
| 56 | pub fn new() -> Self { | |
| 57 | DiscreteMeasure{ spikes : Vec::new() } | |
| 58 | } | |
| 59 | ||
| 60 | /// Number of [`DeltaMeasure`] spikes in the measure | |
| 61 | #[inline] | |
| 62 | pub fn len(&self) -> usize { | |
| 63 | self.spikes.len() | |
| 64 | } | |
| 65 | ||
| 32 | 66 | /// Replace with the zero measure. |
| 67 | #[inline] | |
| 68 | pub fn clear(&mut self) { | |
| 69 | self.spikes.clear() | |
| 70 | } | |
| 71 | ||
| 72 | /// Remove `i`:th spike, not maintaining order. | |
| 73 | /// | |
| 74 | /// Panics if indiex is out of bounds. | |
| 75 | #[inline] | |
| 76 | pub fn swap_remove(&mut self, i : usize) -> DeltaMeasure<Domain, F>{ | |
| 77 | self.spikes.swap_remove(i) | |
| 78 | } | |
| 79 | ||
| 0 | 80 | /// Iterate over (references to) the [`DeltaMeasure`] spikes in this measure |
| 81 | #[inline] | |
| 82 | pub fn iter_spikes(&self) -> SpikeIter<'_, Domain, F> { | |
| 83 | self.spikes.iter() | |
| 84 | } | |
| 85 | ||
| 86 | /// Iterate over mutable references to the [`DeltaMeasure`] spikes in this measure | |
| 87 | #[inline] | |
| 88 | pub fn iter_spikes_mut(&mut self) -> SpikeIterMut<'_, Domain, F> { | |
| 89 | self.spikes.iter_mut() | |
| 90 | } | |
| 91 | ||
| 92 | /// Iterate over the location of the spikes in this measure | |
| 93 | #[inline] | |
| 94 | pub fn iter_locations(&self) -> LocationIter<'_, Domain, F> { | |
| 95 | self.iter_spikes().map(DeltaMeasure::get_location) | |
| 96 | } | |
| 97 | ||
| 98 | /// Iterate over the masses of the spikes in this measure | |
| 99 | #[inline] | |
| 100 | pub fn iter_masses(&self) -> MassIter<'_, Domain, F> { | |
| 101 | self.iter_spikes().map(DeltaMeasure::get_mass) | |
| 102 | } | |
| 103 | ||
| 104 | /// Iterate over the masses of the spikes in this measure | |
| 105 | #[inline] | |
| 106 | pub fn iter_masses_mut(&mut self) -> MassIterMut<'_, Domain, F> { | |
| 107 | self.iter_spikes_mut().map(DeltaMeasure::get_mass_mut) | |
| 108 | } | |
| 109 | ||
| 110 | /// Update the masses of all the spikes to those produced by an iterator. | |
| 111 | #[inline] | |
| 112 | pub fn set_masses<I : Iterator<Item=F>>(&mut self, iter : I) { | |
| 113 | self.spikes.iter_mut().zip(iter).for_each(|(δ, α)| δ.set_mass(α)); | |
| 114 | } | |
| 115 | ||
| 35 | 116 | /// Update the locations of all the spikes to those produced by an iterator. |
| 117 | #[inline] | |
| 118 | pub fn set_locations<'a, I : Iterator<Item=&'a Domain>>(&mut self, iter : I) | |
| 119 | where Domain : 'static + Clone { | |
| 120 | self.spikes.iter_mut().zip(iter.cloned()).for_each(|(δ, α)| δ.set_location(α)); | |
| 121 | } | |
| 122 | ||
| 0 | 123 | // /// Map the masses of all the spikes using a function and an iterator |
| 124 | // #[inline] | |
| 125 | // pub fn zipmap_masses< | |
| 126 | // I : Iterator<Item=F>, | |
| 127 | // G : Fn(F, I::Item) -> F | |
| 128 | // > (&mut self, iter : I, g : G) { | |
| 129 | // self.spikes.iter_mut().zip(iter).for_each(|(δ, v)| δ.set_mass(g(δ.get_mass(), v))); | |
| 130 | // } | |
| 131 | ||
| 132 | /// Prune all spikes with zero mass. | |
| 133 | #[inline] | |
| 134 | pub fn prune(&mut self) { | |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
135 | self.prune_by(|δ| δ.α != F::ZERO); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
136 | } |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
137 | |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
138 | /// Prune spikes by the predicate `g`. |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
139 | #[inline] |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
140 | pub fn prune_by<G : FnMut(&DeltaMeasure<Domain, F>) -> bool>(&mut self, g : G) { |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
141 | self.spikes.retain(g); |
| 0 | 142 | } |
| 32 | 143 | |
| 144 | /// Add the spikes produced by `iter` to this measure. | |
| 145 | #[inline] | |
| 146 | pub fn extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( | |
| 147 | &mut self, | |
| 148 | iter : I | |
| 149 | ) { | |
| 150 | self.spikes.extend(iter); | |
| 151 | } | |
| 152 | ||
| 153 | /// Add a spike to the measure | |
| 154 | #[inline] | |
| 155 | pub fn push(&mut self, δ : DeltaMeasure<Domain, F>) { | |
| 156 | self.spikes.push(δ); | |
| 157 | } | |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
158 | |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
159 | /// Iterate over triples of masses and locations of two discrete measures, which are assumed |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
160 | /// to have equal locations of same spike indices. |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
161 | pub fn both_matching<'a>(&'a self, other : &'a DiscreteMeasure<Domain, F>) -> |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
162 | impl Iterator<Item=(F, F, &'a Domain)> { |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
163 | let m = self.len().max(other.len()); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
164 | self.iter_spikes().map(Some).chain(std::iter::repeat(None)) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
165 | .zip(other.iter_spikes().map(Some).chain(std::iter::repeat(None))) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
166 | .take(m) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
167 | .map(|(oδ, orδ)| { |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
168 | match (oδ, orδ) { |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
169 | (Some(δ), Some(rδ)) => (δ.α, rδ.α, &δ.x), // Assumed δ.x=rδ.x |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
170 | (Some(δ), None) => (δ.α, F::ZERO, &δ.x), |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
171 | (None, Some(rδ)) => (F::ZERO, rδ.α, &rδ.x), |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
172 | (None, None) => panic!("This cannot happen!"), |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
173 | } |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
174 | }) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
175 | } |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
176 | |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
177 | /// Subtract `other` from `self`, assuming equal locations of same spike indices |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
178 | pub fn sub_matching(&self, other : &DiscreteMeasure<Domain, F>) -> DiscreteMeasure<Domain, F> |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
179 | where Domain : Clone { |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
180 | self.both_matching(other) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
181 | .map(|(α, β, x)| (x.clone(), α - β)) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
182 | .collect() |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
183 | } |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
184 | |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
185 | /// Add `other` to `self`, assuming equal locations of same spike indices |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
186 | pub fn add_matching(&self, other : &DiscreteMeasure<Domain, F>) -> DiscreteMeasure<Domain, F> |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
187 | where Domain : Clone { |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
188 | self.both_matching(other) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
189 | .map(|(α, β, x)| (x.clone(), α + β)) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
190 | .collect() |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
191 | } |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
192 | |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
193 | /// Calculate the Radon-norm distance of `self` to `other`, |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
194 | /// assuming equal locations of same spike indices. |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
195 | pub fn dist_matching(&self, other : &DiscreteMeasure<Domain, F>) -> F where F : Float { |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
196 | self.both_matching(other) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
197 | .map(|(α, β, _)| (α-β).abs()) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
198 | .sum() |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
199 | } |
| 32 | 200 | } |
| 201 | ||
| 202 | impl<Domain, F : Num> IntoIterator for DiscreteMeasure<Domain, F> { | |
| 203 | type Item = DeltaMeasure<Domain, F>; | |
| 35 | 204 | type IntoIter = std::vec::IntoIter<DeltaMeasure<Domain, F>>; |
| 32 | 205 | |
| 206 | #[inline] | |
| 207 | fn into_iter(self) -> Self::IntoIter { | |
| 208 | self.spikes.into_iter() | |
| 209 | } | |
| 0 | 210 | } |
| 211 | ||
| 35 | 212 | impl<'a, Domain, F : Num> IntoIterator for &'a DiscreteMeasure<Domain, F> { |
| 213 | type Item = &'a DeltaMeasure<Domain, F>; | |
| 214 | type IntoIter = SpikeIter<'a, Domain, F>; | |
| 215 | ||
| 216 | #[inline] | |
| 217 | fn into_iter(self) -> Self::IntoIter { | |
| 218 | self.spikes.iter() | |
| 219 | } | |
| 220 | } | |
| 221 | ||
| 222 | impl<Domain, F : Num> Sum<DeltaMeasure<Domain, F>> for DiscreteMeasure<Domain, F> { | |
| 223 | // Required method | |
| 224 | fn sum<I>(iter: I) -> Self | |
| 225 | where | |
| 226 | I : Iterator<Item = DeltaMeasure<Domain, F>> | |
| 227 | { | |
| 228 | Self::from_iter(iter) | |
| 229 | } | |
| 230 | } | |
| 231 | ||
| 232 | impl<'a, Domain : Clone, F : Num> Sum<&'a DeltaMeasure<Domain, F>> | |
| 233 | for DiscreteMeasure<Domain, F> | |
| 234 | { | |
| 235 | // Required method | |
| 236 | fn sum<I>(iter: I) -> Self | |
| 237 | where | |
| 238 | I : Iterator<Item = &'a DeltaMeasure<Domain, F>> | |
| 239 | { | |
| 240 | Self::from_iter(iter.cloned()) | |
| 241 | } | |
| 242 | } | |
| 243 | ||
| 244 | impl<Domain, F : Num> Sum<DiscreteMeasure<Domain, F>> for DiscreteMeasure<Domain, F> { | |
| 245 | // Required method | |
| 246 | fn sum<I>(iter: I) -> Self | |
| 247 | where | |
| 248 | I : Iterator<Item = DiscreteMeasure<Domain, F>> | |
| 249 | { | |
| 250 | Self::from_iter(iter.map(|μ| μ.into_iter()).flatten()) | |
| 251 | } | |
| 252 | } | |
| 253 | ||
| 254 | impl<'a, Domain : Clone, F : Num> Sum<&'a DiscreteMeasure<Domain, F>> | |
| 255 | for DiscreteMeasure<Domain, F> | |
| 256 | { | |
| 257 | // Required method | |
| 258 | fn sum<I>(iter: I) -> Self | |
| 259 | where | |
| 260 | I : Iterator<Item = &'a DiscreteMeasure<Domain, F>> | |
| 261 | { | |
| 262 | Self::from_iter(iter.map(|μ| μ.iter_spikes()).flatten().cloned()) | |
| 263 | } | |
| 264 | } | |
| 265 | ||
| 0 | 266 | impl<Domain : Clone, F : Float> DiscreteMeasure<Domain, F> { |
| 267 | /// Computes `μ1 ← θ * μ1 - ζ * μ2`, pruning entries where both `μ1` (`self`) and `μ2` have | |
| 268 | // zero weight. `μ2` will contain copy of pruned original `μ1` without arithmetic performed. | |
| 269 | /// **This expects `self` and `μ2` to have matching coordinates in each index**. | |
| 270 | // `μ2` can be than `self`, but not longer. | |
| 271 | pub fn pruning_sub(&mut self, θ : F, ζ : F, μ2 : &mut Self) { | |
| 272 | let mut μ2_get = 0; | |
| 273 | let mut μ2_insert = 0; | |
| 32 | 274 | self.spikes.retain_mut(|&mut DeltaMeasure{ α : ref mut α_ref, ref x }| { |
| 0 | 275 | // Get weight of spike in μ2, zero if out of bounds. |
| 276 | let β = μ2.spikes.get(μ2_get).map_or(F::ZERO, DeltaMeasure::get_mass); | |
| 277 | μ2_get += 1; | |
| 278 | ||
| 279 | if *α_ref == F::ZERO && β == F::ZERO { | |
| 280 | // Prune | |
| 281 | true | |
| 282 | } else { | |
| 283 | // Save self weight | |
| 284 | let α = *α_ref; | |
| 285 | // Modify self | |
| 286 | *α_ref = θ * α - ζ * β; | |
| 287 | // Make copy of old self weight in μ2 | |
| 288 | let δ = DeltaMeasure{ α, x : x.clone() }; | |
| 289 | match μ2.spikes.get_mut(μ2_insert) { | |
| 290 | Some(replace) => { | |
| 291 | *replace = δ; | |
| 292 | }, | |
| 293 | None => { | |
| 294 | debug_assert_eq!(μ2.len(), μ2_insert); | |
| 295 | μ2.spikes.push(δ); | |
| 296 | }, | |
| 297 | } | |
| 298 | μ2_insert += 1; | |
| 299 | // Keep | |
| 300 | false | |
| 301 | } | |
| 302 | }); | |
| 303 | // Truncate μ2 to same length as self. | |
| 304 | μ2.spikes.truncate(μ2_insert); | |
| 305 | debug_assert_eq!(μ2.len(), self.len()); | |
| 306 | } | |
| 307 | } | |
| 308 | ||
| 309 | impl<Domain, F : Float> DiscreteMeasure<Domain, F> { | |
| 310 | /// Prune all spikes with mass absolute value less than the given `tolerance`. | |
| 311 | #[inline] | |
| 312 | pub fn prune_approx(&mut self, tolerance : F) { | |
| 313 | self.spikes.retain(|δ| δ.α.abs() > tolerance); | |
| 314 | } | |
| 315 | } | |
| 316 | ||
| 317 | impl<Domain, F : Float + ToNalgebraRealField> DiscreteMeasure<Domain, F> { | |
| 318 | /// Extracts the masses of the spikes as a [`DVector`]. | |
| 319 | pub fn masses_dvector(&self) -> DVector<F::MixedType> { | |
| 320 | DVector::from_iterator(self.len(), | |
| 321 | self.iter_masses() | |
| 322 | .map(|α| α.to_nalgebra_mixed())) | |
| 323 | } | |
| 324 | ||
| 325 | /// Sets the masses of the spikes from the values of a [`DVector`]. | |
| 326 | pub fn set_masses_dvector(&mut self, x : &DVector<F::MixedType>) { | |
| 327 | self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α))); | |
| 328 | } | |
| 329 | } | |
| 330 | ||
| 32 | 331 | // impl<Domain, F :Num> Index<usize> for DiscreteMeasure<Domain, F> { |
| 332 | // type Output = DeltaMeasure<Domain, F>; | |
| 333 | // #[inline] | |
| 334 | // fn index(&self, i : usize) -> &Self::Output { | |
| 335 | // self.spikes.index(i) | |
| 336 | // } | |
| 337 | // } | |
| 338 | ||
| 339 | // impl<Domain, F :Num> IndexMut<usize> for DiscreteMeasure<Domain, F> { | |
| 340 | // #[inline] | |
| 341 | // fn index_mut(&mut self, i : usize) -> &mut Self::Output { | |
| 342 | // self.spikes.index_mut(i) | |
| 343 | // } | |
| 344 | // } | |
| 345 | ||
| 346 | impl< | |
| 347 | Domain, | |
| 348 | F : Num, | |
| 349 | I : std::slice::SliceIndex<[DeltaMeasure<Domain, F>]> | |
| 350 | > Index<I> | |
| 351 | for DiscreteMeasure<Domain, F> { | |
| 352 | type Output = <I as std::slice::SliceIndex<[DeltaMeasure<Domain, F>]>>::Output; | |
| 0 | 353 | #[inline] |
| 32 | 354 | fn index(&self, i : I) -> &Self::Output { |
| 0 | 355 | self.spikes.index(i) |
| 356 | } | |
| 357 | } | |
| 358 | ||
| 32 | 359 | impl< |
| 360 | Domain, | |
| 361 | F : Num, | |
| 362 | I : std::slice::SliceIndex<[DeltaMeasure<Domain, F>]> | |
| 363 | > IndexMut<I> | |
| 364 | for DiscreteMeasure<Domain, F> { | |
| 0 | 365 | #[inline] |
| 32 | 366 | fn index_mut(&mut self, i : I) -> &mut Self::Output { |
| 0 | 367 | self.spikes.index_mut(i) |
| 368 | } | |
| 369 | } | |
| 370 | ||
| 32 | 371 | |
| 0 | 372 | impl<Domain, F : Num, D : Into<DeltaMeasure<Domain, F>>, const K : usize> From<[D; K]> |
| 373 | for DiscreteMeasure<Domain, F> { | |
| 374 | #[inline] | |
| 375 | fn from(list : [D; K]) -> Self { | |
| 376 | list.into_iter().collect() | |
| 377 | } | |
| 378 | } | |
| 379 | ||
| 35 | 380 | impl<Domain, F : Num> From<Vec<DeltaMeasure<Domain, F>>> |
| 381 | for DiscreteMeasure<Domain, F> { | |
| 382 | #[inline] | |
| 383 | fn from(spikes : Vec<DeltaMeasure<Domain, F>>) -> Self { | |
| 384 | DiscreteMeasure{ spikes } | |
| 385 | } | |
| 386 | } | |
| 387 | ||
| 388 | impl<'a, Domain, F : Num, D> From<&'a [D]> | |
| 389 | for DiscreteMeasure<Domain, F> | |
| 390 | where &'a D : Into<DeltaMeasure<Domain, F>> { | |
| 391 | #[inline] | |
| 392 | fn from(list : &'a [D]) -> Self { | |
| 393 | list.into_iter().map(|d| d.into()).collect() | |
| 394 | } | |
| 395 | } | |
| 396 | ||
| 397 | ||
| 398 | impl<Domain, F : Num> From<DeltaMeasure<Domain, F>> | |
| 399 | for DiscreteMeasure<Domain, F> { | |
| 400 | #[inline] | |
| 401 | fn from(δ : DeltaMeasure<Domain, F>) -> Self { | |
| 402 | DiscreteMeasure{ | |
| 403 | spikes : vec!(δ) | |
| 404 | } | |
| 405 | } | |
| 406 | } | |
| 407 | ||
| 408 | impl<'a, Domain : Clone, F : Num> From<&'a DeltaMeasure<Domain, F>> | |
| 409 | for DiscreteMeasure<Domain, F> { | |
| 410 | #[inline] | |
| 411 | fn from(δ : &'a DeltaMeasure<Domain, F>) -> Self { | |
| 412 | DiscreteMeasure{ | |
| 413 | spikes : vec!(δ.clone()) | |
| 414 | } | |
| 415 | } | |
| 416 | } | |
| 417 | ||
| 418 | ||
| 0 | 419 | impl<Domain, F : Num, D : Into<DeltaMeasure<Domain, F>>> FromIterator<D> |
| 420 | for DiscreteMeasure<Domain, F> { | |
| 421 | #[inline] | |
| 422 | fn from_iter<T>(iter : T) -> Self | |
| 423 | where T : IntoIterator<Item=D> { | |
| 424 | DiscreteMeasure{ | |
| 425 | spikes : iter.into_iter().map(|m| m.into()).collect() | |
| 426 | } | |
| 427 | } | |
| 428 | } | |
| 429 | ||
| 430 | impl<'a, F : Num, const N : usize> TableDump<'a> | |
| 431 | for DiscreteMeasure<Loc<F, N>,F> | |
| 432 | where DeltaMeasure<Loc<F, N>, F> : Serialize + 'a { | |
| 433 | type Iter = std::slice::Iter<'a, DeltaMeasure<Loc<F, N>, F>>; | |
| 434 | ||
| 435 | // fn tabledump_headers(&'a self) -> Vec<String> { | |
| 436 | // let mut v : Vec<String> = (0..N).map(|i| format!("x{}", i)).collect(); | |
| 437 | // v.push("weight".into()); | |
| 438 | // v | |
| 439 | // } | |
| 440 | ||
| 441 | fn tabledump_entries(&'a self) -> Self::Iter { | |
| 442 | // Ensure order matching the headers above | |
| 443 | self.spikes.iter() | |
| 444 | } | |
| 445 | } | |
| 446 | ||
| 447 | // Need to manually implement serialisation for DeltaMeasure<Loc<F, N>, F> [`csv`] writer fails on | |
| 448 | // structs with nested arrays as well as with #[serde(flatten)]. | |
| 449 | // Then derive no longer works for DiscreteMeasure | |
| 450 | impl<F : Num, const N : usize> Serialize for DiscreteMeasure<Loc<F, N>, F> | |
| 451 | where | |
| 452 | F: Serialize, | |
| 453 | { | |
| 454 | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
| 455 | where | |
| 456 | S: Serializer, | |
| 457 | { | |
| 458 | let mut s = serializer.serialize_seq(Some(self.spikes.len()))?; | |
| 459 | for δ in self.spikes.iter() { | |
| 460 | s.serialize_element(δ)?; | |
| 461 | } | |
| 462 | s.end() | |
| 463 | } | |
| 464 | } | |
| 465 | ||
| 466 | impl<Domain : PartialEq, F : Float> Measure<F> for DiscreteMeasure<Domain, F> { | |
| 467 | type Domain = Domain; | |
| 468 | } | |
| 469 | ||
| 470 | impl<Domain : PartialEq, F : Float> Norm<F, Radon> for DiscreteMeasure<Domain, F> | |
| 471 | where DeltaMeasure<Domain, F> : Norm<F, Radon> { | |
| 472 | #[inline] | |
| 473 | fn norm(&self, _ : Radon) -> F { | |
| 474 | self.spikes.iter().map(|m| m.norm(Radon)).sum() | |
| 475 | } | |
| 476 | } | |
| 477 | ||
| 35 | 478 | impl<Domain, G, F : Num> Mapping<G> for DiscreteMeasure<Domain, F> |
| 479 | where | |
| 480 | Domain : Space, | |
| 481 | G::Codomain : Sum + Mul<F, Output=G::Codomain>, | |
| 482 | G : Mapping<Domain, Codomain=F> + Clone + Space, | |
| 483 | for<'b> &'b Domain : Instance<Domain>, | |
| 484 | { | |
| 485 | type Codomain = G::Codomain; | |
| 486 | ||
| 0 | 487 | #[inline] |
| 35 | 488 | fn apply<I : Instance<G>>(&self, g : I) -> Self::Codomain { |
| 489 | g.eval(|g| self.spikes.iter().map(|m| g.apply(&m.x) * m.α).sum()) | |
| 0 | 490 | } |
| 491 | } | |
| 492 | ||
| 35 | 493 | impl<Domain, G, F : Num> Linear<G> for DiscreteMeasure<Domain, F> |
| 494 | where | |
| 495 | Domain : Space, | |
| 496 | G::Codomain : Sum + Mul<F, Output=G::Codomain>, | |
| 497 | G : Mapping<Domain, Codomain=F> + Clone + Space, | |
| 498 | for<'b> &'b Domain : Instance<Domain>, | |
| 499 | { } | |
| 0 | 500 | |
| 501 | ||
| 502 | /// Helper trait for constructing arithmetic operations for combinations | |
| 503 | /// of [`DiscreteMeasure`] and [`DeltaMeasure`], and their references. | |
| 504 | trait Lift<F : Num, Domain> { | |
| 505 | type Producer : Iterator<Item=DeltaMeasure<Domain, F>>; | |
| 506 | ||
| 35 | 507 | #[allow(dead_code)] |
| 0 | 508 | /// Lifts `self` into a [`DiscreteMeasure`]. |
| 509 | fn lift(self) -> DiscreteMeasure<Domain, F>; | |
| 510 | ||
| 511 | /// Lifts `self` into a [`DiscreteMeasure`], apply either `f` or `f_mut` whether the type | |
| 512 | /// this method is implemented for is a reference or or not. | |
| 513 | fn lift_with(self, | |
| 514 | f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, | |
| 515 | f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) | |
| 516 | -> DiscreteMeasure<Domain, F>; | |
| 517 | ||
| 518 | /// Extend `self` into a [`DiscreteMeasure`] with the spikes produced by `iter`. | |
| 519 | fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( | |
| 520 | self, | |
| 521 | iter : I | |
| 522 | ) -> DiscreteMeasure<Domain, F>; | |
| 523 | ||
| 524 | /// Returns an iterator for producing copies of the spikes of `self`. | |
| 525 | fn produce(self) -> Self::Producer; | |
| 526 | } | |
| 527 | ||
| 528 | impl<F : Num, Domain> Lift<F, Domain> for DiscreteMeasure<Domain, F> { | |
| 529 | type Producer = std::vec::IntoIter<DeltaMeasure<Domain, F>>; | |
| 530 | ||
| 531 | #[inline] | |
| 532 | fn lift(self) -> DiscreteMeasure<Domain, F> { self } | |
| 533 | ||
| 534 | fn lift_with(mut self, | |
| 535 | _f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, | |
| 536 | f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) | |
| 537 | -> DiscreteMeasure<Domain, F> { | |
| 538 | self.spikes.iter_mut().for_each(f_mut); | |
| 539 | self | |
| 540 | } | |
| 541 | ||
| 542 | #[inline] | |
| 543 | fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( | |
| 544 | mut self, | |
| 545 | iter : I | |
| 546 | ) -> DiscreteMeasure<Domain, F> { | |
| 547 | self.spikes.extend(iter); | |
| 548 | self | |
| 549 | } | |
| 550 | ||
| 551 | #[inline] | |
| 552 | fn produce(self) -> Self::Producer { | |
| 553 | self.spikes.into_iter() | |
| 554 | } | |
| 555 | } | |
| 556 | ||
| 557 | impl<'a, F : Num, Domain : Clone> Lift<F, Domain> for &'a DiscreteMeasure<Domain, F> { | |
| 558 | type Producer = MapF<std::slice::Iter<'a, DeltaMeasure<Domain, F>>, DeltaMeasure<Domain, F>>; | |
| 559 | ||
| 560 | #[inline] | |
| 561 | fn lift(self) -> DiscreteMeasure<Domain, F> { self.clone() } | |
| 562 | ||
| 563 | fn lift_with(self, | |
| 564 | f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, | |
| 565 | _f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) | |
| 566 | -> DiscreteMeasure<Domain, F> { | |
| 567 | DiscreteMeasure{ spikes : self.spikes.iter().map(f).collect() } | |
| 568 | } | |
| 569 | ||
| 570 | #[inline] | |
| 571 | fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( | |
| 572 | self, | |
| 573 | iter : I | |
| 574 | ) -> DiscreteMeasure<Domain, F> { | |
| 575 | let mut res = self.clone(); | |
| 576 | res.spikes.extend(iter); | |
| 577 | res | |
| 578 | } | |
| 579 | ||
| 580 | #[inline] | |
| 581 | fn produce(self) -> Self::Producer { | |
| 582 | // TODO: maybe not optimal to clone here and would benefit from | |
| 583 | // a reference version of lift_extend. | |
| 584 | self.spikes.iter().mapF(Clone::clone) | |
| 585 | } | |
| 586 | } | |
| 587 | ||
| 588 | impl<F : Num, Domain> Lift<F, Domain> for DeltaMeasure<Domain, F> { | |
| 589 | type Producer = std::iter::Once<DeltaMeasure<Domain, F>>; | |
| 590 | ||
| 591 | #[inline] | |
| 592 | fn lift(self) -> DiscreteMeasure<Domain, F> { DiscreteMeasure { spikes : vec![self] } } | |
| 593 | ||
| 594 | #[inline] | |
| 595 | fn lift_with(mut self, | |
| 596 | _f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, | |
| 597 | mut f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) | |
| 598 | -> DiscreteMeasure<Domain, F> { | |
| 599 | f_mut(&mut self); | |
| 600 | DiscreteMeasure{ spikes : vec![self] } | |
| 601 | } | |
| 602 | ||
| 603 | #[inline] | |
| 604 | fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( | |
| 605 | self, | |
| 606 | iter : I | |
| 607 | ) -> DiscreteMeasure<Domain, F> { | |
| 608 | let mut spikes = vec![self]; | |
| 609 | spikes.extend(iter); | |
| 610 | DiscreteMeasure{ spikes : spikes } | |
| 611 | } | |
| 612 | ||
| 613 | #[inline] | |
| 614 | fn produce(self) -> Self::Producer { | |
| 615 | std::iter::once(self) | |
| 616 | } | |
| 617 | } | |
| 618 | ||
| 619 | impl<'a, F : Num, Domain : Clone> Lift<F, Domain> for &'a DeltaMeasure<Domain, F> { | |
| 620 | type Producer = std::iter::Once<DeltaMeasure<Domain, F>>; | |
| 621 | ||
| 622 | #[inline] | |
| 623 | fn lift(self) -> DiscreteMeasure<Domain, F> { DiscreteMeasure { spikes : vec![self.clone()] } } | |
| 624 | ||
| 625 | #[inline] | |
| 626 | fn lift_with(self, | |
| 627 | f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, | |
| 628 | _f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) | |
| 629 | -> DiscreteMeasure<Domain, F> { | |
| 630 | DiscreteMeasure{ spikes : vec![f(self)] } | |
| 631 | } | |
| 632 | ||
| 633 | #[inline] | |
| 634 | fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( | |
| 635 | self, | |
| 636 | iter : I | |
| 637 | ) -> DiscreteMeasure<Domain, F> { | |
| 638 | let mut spikes = vec![self.clone()]; | |
| 639 | spikes.extend(iter); | |
| 640 | DiscreteMeasure{ spikes : spikes } | |
| 641 | } | |
| 642 | ||
| 643 | #[inline] | |
| 644 | fn produce(self) -> Self::Producer { | |
| 645 | std::iter::once(self.clone()) | |
| 646 | } | |
| 647 | } | |
| 648 | ||
| 649 | macro_rules! make_discrete_addsub_assign { | |
| 650 | ($rhs:ty) => { | |
| 651 | // Discrete += (&)Discrete | |
| 652 | impl<'a, F : Num, Domain : Clone> AddAssign<$rhs> | |
| 653 | for DiscreteMeasure<Domain, F> { | |
| 654 | fn add_assign(&mut self, other : $rhs) { | |
| 655 | self.spikes.extend(other.produce()); | |
| 656 | } | |
| 657 | } | |
| 658 | ||
| 659 | impl<'a, F : Num + Neg<Output=F>, Domain : Clone> SubAssign<$rhs> | |
| 660 | for DiscreteMeasure<Domain, F> { | |
| 661 | fn sub_assign(&mut self, other : $rhs) { | |
| 662 | self.spikes.extend(other.produce().map(|δ| -δ)); | |
| 663 | } | |
| 664 | } | |
| 665 | } | |
| 666 | } | |
| 667 | ||
| 668 | make_discrete_addsub_assign!(DiscreteMeasure<Domain, F>); | |
| 669 | make_discrete_addsub_assign!(&'a DiscreteMeasure<Domain, F>); | |
| 670 | make_discrete_addsub_assign!(DeltaMeasure<Domain, F>); | |
| 671 | make_discrete_addsub_assign!(&'a DeltaMeasure<Domain, F>); | |
| 672 | ||
| 673 | macro_rules! make_discrete_addsub { | |
| 674 | ($lhs:ty, $rhs:ty, $alt_order:expr) => { | |
| 675 | impl<'a, 'b, F : Num, Domain : Clone> Add<$rhs> for $lhs { | |
| 676 | type Output = DiscreteMeasure<Domain, F>; | |
| 677 | fn add(self, other : $rhs) -> DiscreteMeasure<Domain, F> { | |
| 678 | if !$alt_order { | |
| 679 | self.lift_extend(other.produce()) | |
| 680 | } else { | |
| 681 | other.lift_extend(self.produce()) | |
| 682 | } | |
| 683 | } | |
| 684 | } | |
| 685 | ||
| 686 | impl<'a, 'b, F : Num + Neg<Output=F>, Domain : Clone> Sub<$rhs> for $lhs { | |
| 687 | type Output = DiscreteMeasure<Domain, F>; | |
| 688 | fn sub(self, other : $rhs) -> DiscreteMeasure<Domain, F> { | |
| 689 | self.lift_extend(other.produce().map(|δ| -δ)) | |
| 690 | } | |
| 691 | } | |
| 692 | }; | |
| 693 | } | |
| 694 | ||
| 695 | make_discrete_addsub!(DiscreteMeasure<Domain, F>, DiscreteMeasure<Domain, F>, false); | |
| 696 | make_discrete_addsub!(DiscreteMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false); | |
| 697 | make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, DiscreteMeasure<Domain, F>, true); | |
| 698 | make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false); | |
| 699 | make_discrete_addsub!(DeltaMeasure<Domain, F>, DiscreteMeasure<Domain, F>, false); | |
| 700 | make_discrete_addsub!(DeltaMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false); | |
| 701 | make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, DiscreteMeasure<Domain, F>, true); | |
| 702 | make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false); | |
| 703 | make_discrete_addsub!(DiscreteMeasure<Domain, F>, DeltaMeasure<Domain, F>, false); | |
| 704 | make_discrete_addsub!(DiscreteMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false); | |
| 705 | make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, DeltaMeasure<Domain, F>, false); | |
| 706 | make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false); | |
| 707 | make_discrete_addsub!(DeltaMeasure<Domain, F>, DeltaMeasure<Domain, F>, false); | |
| 708 | make_discrete_addsub!(DeltaMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false); | |
| 709 | make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, DeltaMeasure<Domain, F>, false); | |
| 710 | make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false); | |
| 711 | ||
| 712 | macro_rules! make_discrete_scalarop_rhs { | |
| 713 | ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { | |
| 714 | make_discrete_scalarop_rhs!(@assign DiscreteMeasure<Domain, F>, F, $trait_assign, $fn_assign); | |
| 715 | make_discrete_scalarop_rhs!(@assign DiscreteMeasure<Domain, F>, &'a F, $trait_assign, $fn_assign); | |
| 716 | make_discrete_scalarop_rhs!(@new DiscreteMeasure<Domain, F>, F, $trait, $fn, $fn_assign); | |
| 717 | make_discrete_scalarop_rhs!(@new DiscreteMeasure<Domain, F>, &'a F, $trait, $fn, $fn_assign); | |
| 718 | make_discrete_scalarop_rhs!(@new &'b DiscreteMeasure<Domain, F>, F, $trait, $fn, $fn_assign); | |
| 719 | make_discrete_scalarop_rhs!(@new &'b DiscreteMeasure<Domain, F>, &'a F, $trait, $fn, $fn_assign); | |
| 720 | }; | |
| 721 | ||
| 722 | (@assign $lhs:ty, $rhs:ty, $trait_assign:ident, $fn_assign:ident) => { | |
| 723 | impl<'a, 'b, F : Num, Domain> $trait_assign<$rhs> for $lhs { | |
| 724 | fn $fn_assign(&mut self, b : $rhs) { | |
| 725 | self.spikes.iter_mut().for_each(|δ| δ.$fn_assign(b)); | |
| 726 | } | |
| 727 | } | |
| 728 | }; | |
| 729 | (@new $lhs:ty, $rhs:ty, $trait:ident, $fn:ident, $fn_assign:ident) => { | |
| 730 | impl<'a, 'b, F : Num, Domain : Clone> $trait<$rhs> for $lhs { | |
| 731 | type Output = DiscreteMeasure<Domain, F>; | |
| 732 | fn $fn(self, b : $rhs) -> Self::Output { | |
| 733 | self.lift_with(|δ| δ.$fn(b), |δ| δ.$fn_assign(b)) | |
| 734 | } | |
| 735 | } | |
| 736 | }; | |
| 737 | } | |
| 738 | ||
| 739 | make_discrete_scalarop_rhs!(Mul, mul, MulAssign, mul_assign); | |
| 740 | make_discrete_scalarop_rhs!(Div, div, DivAssign, div_assign); | |
| 741 | ||
| 742 | macro_rules! make_discrete_unary { | |
| 743 | ($trait:ident, $fn:ident, $type:ty) => { | |
| 744 | impl<'a, F : Num + Neg<Output=F>, Domain : Clone> Neg for $type { | |
| 745 | type Output = DiscreteMeasure<Domain, F>; | |
| 746 | fn $fn(self) -> Self::Output { | |
| 747 | self.lift_with(|δ| δ.$fn(), |δ| δ.α = δ.α.$fn()) | |
| 748 | } | |
| 749 | } | |
| 750 | } | |
| 751 | } | |
| 752 | ||
| 753 | make_discrete_unary!(Neg, neg, DiscreteMeasure<Domain, F>); | |
| 754 | make_discrete_unary!(Neg, neg, &'a DiscreteMeasure<Domain, F>); | |
| 755 | ||
| 756 | // impl<F : Num, Domain> Neg for DiscreteMeasure<Domain, F> { | |
| 757 | // type Output = Self; | |
| 758 | // fn $fn(mut self, b : F) -> Self { | |
| 759 | // self.lift().spikes.iter_mut().for_each(|δ| δ.neg(b)); | |
| 760 | // self | |
| 761 | // } | |
| 762 | // } | |
| 763 | ||
| 764 | macro_rules! make_discrete_scalarop_lhs { | |
| 765 | ($trait:ident, $fn:ident; $($f:ident)+) => { $( | |
| 766 | impl<Domain> $trait<DiscreteMeasure<Domain, $f>> for $f { | |
| 767 | type Output = DiscreteMeasure<Domain, $f>; | |
| 768 | fn $fn(self, mut v : DiscreteMeasure<Domain, $f>) -> Self::Output { | |
| 769 | v.spikes.iter_mut().for_each(|δ| δ.α = self.$fn(δ.α)); | |
| 770 | v | |
| 771 | } | |
| 772 | } | |
| 773 | ||
| 774 | impl<'a, Domain : Copy> $trait<&'a DiscreteMeasure<Domain, $f>> for $f { | |
| 775 | type Output = DiscreteMeasure<Domain, $f>; | |
| 776 | fn $fn(self, v : &'a DiscreteMeasure<Domain, $f>) -> Self::Output { | |
| 777 | DiscreteMeasure{ | |
| 778 | spikes : v.spikes.iter().map(|δ| self.$fn(δ)).collect() | |
| 779 | } | |
| 780 | } | |
| 781 | } | |
| 782 | ||
| 783 | impl<'b, Domain> $trait<DiscreteMeasure<Domain, $f>> for &'b $f { | |
| 784 | type Output = DiscreteMeasure<Domain, $f>; | |
| 785 | fn $fn(self, mut v : DiscreteMeasure<Domain, $f>) -> Self::Output { | |
| 786 | v.spikes.iter_mut().for_each(|δ| δ.α = self.$fn(δ.α)); | |
| 787 | v | |
| 788 | } | |
| 789 | } | |
| 790 | ||
| 791 | impl<'a, 'b, Domain : Copy> $trait<&'a DiscreteMeasure<Domain, $f>> for &'b $f { | |
| 792 | type Output = DiscreteMeasure<Domain, $f>; | |
| 793 | fn $fn(self, v : &'a DiscreteMeasure<Domain, $f>) -> Self::Output { | |
| 794 | DiscreteMeasure{ | |
| 795 | spikes : v.spikes.iter().map(|δ| self.$fn(δ)).collect() | |
| 796 | } | |
| 797 | } | |
| 798 | } | |
| 799 | )+ } | |
| 800 | } | |
| 801 | ||
| 802 | make_discrete_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize); | |
| 803 | make_discrete_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize); | |
| 35 | 804 | |
| 805 | impl<F : Num, Domain> Collection for DiscreteMeasure<Domain, F> { | |
| 806 | type Element = DeltaMeasure<Domain, F>; | |
| 807 | type RefsIter<'a> = std::slice::Iter<'a, Self::Element> where Self : 'a; | |
| 808 | ||
| 809 | #[inline] | |
| 810 | fn iter_refs(&self) -> Self::RefsIter<'_> { | |
| 811 | self.iter_spikes() | |
| 812 | } | |
| 813 | } | |
| 814 | ||
| 815 | impl<Domain : Clone, F : Num> Space for DiscreteMeasure<Domain, F> { | |
| 816 | type Decomp = MeasureDecomp; | |
| 817 | } | |
| 818 | ||
| 819 | pub type SpikeSlice<'b, Domain, F> = &'b [DeltaMeasure<Domain, F>]; | |
| 820 | ||
| 821 | pub type EitherSlice<'b, Domain, F> = EitherDecomp< | |
| 822 | Vec<DeltaMeasure<Domain, F>>, | |
| 823 | SpikeSlice<'b, Domain, F> | |
| 824 | >; | |
| 825 | ||
| 826 | impl<F : Num, Domain : Clone> Decomposition<DiscreteMeasure<Domain, F>> for MeasureDecomp { | |
| 827 | type Decomposition<'b> = EitherSlice<'b, Domain, F> where DiscreteMeasure<Domain, F> : 'b; | |
| 828 | type Reference<'b> = SpikeSlice<'b, Domain, F> where DiscreteMeasure<Domain, F> : 'b; | |
| 829 | ||
| 830 | /// Left the lightweight reference type into a full decomposition type. | |
| 831 | fn lift<'b>(r : Self::Reference<'b>) -> Self::Decomposition<'b> { | |
| 832 | EitherDecomp::Borrowed(r) | |
| 833 | } | |
| 834 | } | |
| 835 | ||
| 836 | impl<F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp> | |
| 837 | for DiscreteMeasure<Domain, F> | |
| 838 | { | |
| 839 | fn decompose<'b>(self) | |
| 840 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b> | |
| 841 | where Self : 'b, DiscreteMeasure<Domain, F> : 'b { | |
| 842 | EitherDecomp::Owned(self.spikes) | |
| 843 | } | |
| 844 | ||
| 845 | fn ref_instance(&self) | |
| 846 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_> | |
| 847 | { | |
| 848 | self.spikes.as_slice() | |
| 849 | } | |
| 850 | ||
| 851 | fn cow<'b>(self) -> MyCow<'b, DiscreteMeasure<Domain, F>> where Self : 'b { | |
| 852 | MyCow::Owned(self) | |
| 853 | } | |
| 854 | ||
| 855 | fn own(self) -> DiscreteMeasure<Domain, F> { | |
| 856 | self | |
| 857 | } | |
| 858 | } | |
| 859 | ||
| 860 | impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp> | |
| 861 | for &'a DiscreteMeasure<Domain, F> | |
| 862 | { | |
| 863 | fn decompose<'b>(self) | |
| 864 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b> | |
| 865 | where Self : 'b, DiscreteMeasure<Domain, F> : 'b { | |
| 866 | EitherDecomp::Borrowed(self.spikes.as_slice()) | |
| 867 | } | |
| 868 | ||
| 869 | fn ref_instance(&self) | |
| 870 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_> | |
| 871 | { | |
| 872 | self.spikes.as_slice() | |
| 873 | } | |
| 874 | ||
| 875 | fn cow<'b>(self) -> MyCow<'b, DiscreteMeasure<Domain, F>> where Self : 'b { | |
| 876 | MyCow::Borrowed(self) | |
| 877 | } | |
| 878 | ||
| 879 | fn own(self) -> DiscreteMeasure<Domain, F> { | |
| 880 | self.clone() | |
| 881 | } | |
| 882 | } | |
| 883 | ||
| 884 | impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp> | |
| 885 | for EitherSlice<'a, Domain, F> | |
| 886 | { | |
| 887 | fn decompose<'b>(self) | |
| 888 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b> | |
| 889 | where Self : 'b, DiscreteMeasure<Domain, F> : 'b { | |
| 890 | self | |
| 891 | } | |
| 892 | ||
| 893 | fn ref_instance(&self) | |
| 894 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_> | |
| 895 | { | |
| 896 | match self { | |
| 897 | EitherDecomp::Owned(v) => v.as_slice(), | |
| 898 | EitherDecomp::Borrowed(s) => s, | |
| 899 | } | |
| 900 | } | |
| 901 | ||
| 902 | fn own(self) -> DiscreteMeasure<Domain, F> { | |
| 903 | match self { | |
| 904 | EitherDecomp::Owned(v) => v.into(), | |
| 905 | EitherDecomp::Borrowed(s) => s.into(), | |
| 906 | } | |
| 907 | } | |
| 908 | } | |
| 909 | ||
| 910 | impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp> | |
| 911 | for &'a EitherSlice<'a, Domain, F> | |
| 912 | { | |
| 913 | fn decompose<'b>(self) | |
| 914 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b> | |
| 915 | where Self : 'b, DiscreteMeasure<Domain, F> : 'b { | |
| 916 | match self { | |
| 917 | EitherDecomp::Owned(v) => EitherDecomp::Borrowed(v.as_slice()), | |
| 918 | EitherDecomp::Borrowed(s) => EitherDecomp::Borrowed(s), | |
| 919 | } | |
| 920 | } | |
| 921 | ||
| 922 | fn ref_instance(&self) | |
| 923 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_> | |
| 924 | { | |
| 925 | match self { | |
| 926 | EitherDecomp::Owned(v) => v.as_slice(), | |
| 927 | EitherDecomp::Borrowed(s) => s, | |
| 928 | } | |
| 929 | } | |
| 930 | ||
| 931 | fn own(self) -> DiscreteMeasure<Domain, F> { | |
| 932 | match self { | |
| 933 | EitherDecomp::Owned(v) => v.as_slice(), | |
| 934 | EitherDecomp::Borrowed(s) => s | |
| 935 | }.into() | |
| 936 | } | |
| 937 | } | |
| 938 | ||
| 939 | impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp> | |
| 940 | for SpikeSlice<'a, Domain, F> | |
| 941 | { | |
| 942 | fn decompose<'b>(self) | |
| 943 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b> | |
| 944 | where Self : 'b, DiscreteMeasure<Domain, F> : 'b { | |
| 945 | EitherDecomp::Borrowed(self) | |
| 946 | } | |
| 947 | ||
| 948 | fn ref_instance(&self) | |
| 949 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_> | |
| 950 | { | |
| 951 | self | |
| 952 | } | |
| 953 | ||
| 954 | fn own(self) -> DiscreteMeasure<Domain, F> { | |
| 955 | self.into() | |
| 956 | } | |
| 957 | } | |
| 958 | ||
| 959 | impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp> | |
| 960 | for &'a SpikeSlice<'a, Domain, F> | |
| 961 | { | |
| 962 | fn decompose<'b>(self) | |
| 963 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b> | |
| 964 | where Self : 'b, DiscreteMeasure<Domain, F> : 'b { | |
| 965 | EitherDecomp::Borrowed(*self) | |
| 966 | } | |
| 967 | ||
| 968 | fn ref_instance(&self) | |
| 969 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_> | |
| 970 | { | |
| 971 | *self | |
| 972 | } | |
| 973 | ||
| 974 | fn own(self) -> DiscreteMeasure<Domain, F> { | |
| 975 | (*self).into() | |
| 976 | } | |
| 977 | } | |
| 978 | ||
| 979 | impl<F : Num, Domain : Clone > Instance<DiscreteMeasure<Domain, F>, MeasureDecomp> | |
| 980 | for DeltaMeasure<Domain, F> | |
| 981 | { | |
| 982 | fn decompose<'b>(self) | |
| 983 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b> | |
| 984 | where Self : 'b, DiscreteMeasure<Domain, F> : 'b { | |
| 985 | EitherDecomp::Owned(vec![self]) | |
| 986 | } | |
| 987 | ||
| 988 | fn ref_instance(&self) | |
| 989 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_> | |
| 990 | { | |
| 991 | std::slice::from_ref(self) | |
| 992 | } | |
| 993 | ||
| 994 | fn own(self) -> DiscreteMeasure<Domain, F> { | |
| 995 | self.into() | |
| 996 | } | |
| 997 | } | |
| 998 | ||
| 999 | impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp> | |
| 1000 | for &'a DeltaMeasure<Domain, F> | |
| 1001 | { | |
| 1002 | fn decompose<'b>(self) | |
| 1003 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b> | |
| 1004 | where Self : 'b, DiscreteMeasure<Domain, F> : 'b { | |
| 1005 | EitherDecomp::Borrowed(std::slice::from_ref(self)) | |
| 1006 | } | |
| 1007 | ||
| 1008 | fn ref_instance(&self) | |
| 1009 | -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_> | |
| 1010 | { | |
| 1011 | std::slice::from_ref(*self) | |
| 1012 | } | |
| 1013 | ||
| 1014 | fn own(self) -> DiscreteMeasure<Domain, F> { | |
| 1015 | self.into() | |
| 1016 | } | |
| 1017 | } |