src/measures/discrete.rs

branch
dev
changeset 61
4f468d35fa29
parent 60
9738b51d90d7
child 62
32328a74c790
child 63
7a8a55fd41c0
equal deleted inserted replaced
60:9738b51d90d7 61:4f468d35fa29
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;
14 use alg_tools::linops::{Mapping, Linear};
15 use alg_tools::iter::{MapF,Mappable};
16 use alg_tools::nalgebra_support::ToNalgebraRealField;
17 use alg_tools::collection::Collection;
18 use alg_tools::instance::{Instance, Decomposition, MyCow, EitherDecomp, Space};
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
34 pub type RNDM<F, const N : usize> = DiscreteMeasure<Loc<F, N>, F>;
35
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
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
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
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
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) {
135 self.prune_by(|δ| δ.α != F::ZERO);
136 }
137
138 /// Prune spikes by the predicate `g`.
139 #[inline]
140 pub fn prune_by<G : FnMut(&DeltaMeasure<Domain, F>) -> bool>(&mut self, g : G) {
141 self.spikes.retain(g);
142 }
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 }
158
159 /// Iterate over triples of masses and locations of two discrete measures, which are assumed
160 /// to have equal locations of same spike indices.
161 pub fn both_matching<'a>(&'a self, other : &'a DiscreteMeasure<Domain, F>) ->
162 impl Iterator<Item=(F, F, &'a Domain)> {
163 let m = self.len().max(other.len());
164 self.iter_spikes().map(Some).chain(std::iter::repeat(None))
165 .zip(other.iter_spikes().map(Some).chain(std::iter::repeat(None)))
166 .take(m)
167 .map(|(oδ, orδ)| {
168 match (oδ, orδ) {
169 (Some(δ), Some(rδ)) => (δ.α, rδ.α, &δ.x), // Assumed δ.x=rδ.x
170 (Some(δ), None) => (δ.α, F::ZERO, &δ.x),
171 (None, Some(rδ)) => (F::ZERO, rδ.α, &rδ.x),
172 (None, None) => panic!("This cannot happen!"),
173 }
174 })
175 }
176
177 /// Subtract `other` from `self`, assuming equal locations of same spike indices
178 pub fn sub_matching(&self, other : &DiscreteMeasure<Domain, F>) -> DiscreteMeasure<Domain, F>
179 where Domain : Clone {
180 self.both_matching(other)
181 .map(|(α, β, x)| (x.clone(), α - β))
182 .collect()
183 }
184
185 /// Add `other` to `self`, assuming equal locations of same spike indices
186 pub fn add_matching(&self, other : &DiscreteMeasure<Domain, F>) -> DiscreteMeasure<Domain, F>
187 where Domain : Clone {
188 self.both_matching(other)
189 .map(|(α, β, x)| (x.clone(), α + β))
190 .collect()
191 }
192
193 /// Calculate the Radon-norm distance of `self` to `other`,
194 /// assuming equal locations of same spike indices.
195 pub fn dist_matching(&self, other : &DiscreteMeasure<Domain, F>) -> F where F : Float {
196 self.both_matching(other)
197 .map(|(α, β, _)| (α-β).abs())
198 .sum()
199 }
200 }
201
202 impl<Domain, F : Num> IntoIterator for DiscreteMeasure<Domain, F> {
203 type Item = DeltaMeasure<Domain, F>;
204 type IntoIter = std::vec::IntoIter<DeltaMeasure<Domain, F>>;
205
206 #[inline]
207 fn into_iter(self) -> Self::IntoIter {
208 self.spikes.into_iter()
209 }
210 }
211
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
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 a pruned copy of pruned original `μ1` without arithmetic
269 /// performed. **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 for δ in &self[μ2.len()..] {
273 μ2.push(DeltaMeasure{ x : δ.x.clone(), α : F::ZERO});
274 }
275 debug_assert_eq!(self.len(), μ2.len());
276 let mut dest = 0;
277 for i in 0..self.len() {
278 let α = self[i].α;
279 let α_new = θ * α - ζ * μ2[i].α;
280 if dest < i {
281 μ2[dest] = DeltaMeasure{ x : self[i].x.clone(), α };
282 self[dest] = DeltaMeasure{ x : self[i].x.clone(), α : α_new };
283 } else {
284 μ2[i].α = α;
285 self[i].α = α_new;
286 }
287 dest += 1;
288 }
289 self.spikes.truncate(dest);
290 μ2.spikes.truncate(dest);
291 }
292 }
293
294 impl<Domain, F : Float> DiscreteMeasure<Domain, F> {
295 /// Prune all spikes with mass absolute value less than the given `tolerance`.
296 #[inline]
297 pub fn prune_approx(&mut self, tolerance : F) {
298 self.spikes.retain(|δ| δ.α.abs() > tolerance);
299 }
300 }
301
302 impl<Domain, F : Float + ToNalgebraRealField> DiscreteMeasure<Domain, F> {
303 /// Extracts the masses of the spikes as a [`DVector`].
304 pub fn masses_dvector(&self) -> DVector<F::MixedType> {
305 DVector::from_iterator(self.len(),
306 self.iter_masses()
307 .map(|α| α.to_nalgebra_mixed()))
308 }
309
310 /// Sets the masses of the spikes from the values of a [`DVector`].
311 pub fn set_masses_dvector(&mut self, x : &DVector<F::MixedType>) {
312 self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α)));
313 }
314
315 // /// Extracts the masses of the spikes as a [`Vec`].
316 // pub fn masses_vec(&self) -> Vec<F::MixedType> {
317 // self.iter_masses()
318 // .map(|α| α.to_nalgebra_mixed())
319 // .collect()
320 // }
321
322 // /// Sets the masses of the spikes from the values of a [`Vec`].
323 // pub fn set_masses_vec(&mut self, x : &Vec<F::MixedType>) {
324 // self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α)));
325 // }
326 }
327
328 // impl<Domain, F :Num> Index<usize> for DiscreteMeasure<Domain, F> {
329 // type Output = DeltaMeasure<Domain, F>;
330 // #[inline]
331 // fn index(&self, i : usize) -> &Self::Output {
332 // self.spikes.index(i)
333 // }
334 // }
335
336 // impl<Domain, F :Num> IndexMut<usize> for DiscreteMeasure<Domain, F> {
337 // #[inline]
338 // fn index_mut(&mut self, i : usize) -> &mut Self::Output {
339 // self.spikes.index_mut(i)
340 // }
341 // }
342
343 impl<
344 Domain,
345 F : Num,
346 I : std::slice::SliceIndex<[DeltaMeasure<Domain, F>]>
347 > Index<I>
348 for DiscreteMeasure<Domain, F> {
349 type Output = <I as std::slice::SliceIndex<[DeltaMeasure<Domain, F>]>>::Output;
350 #[inline]
351 fn index(&self, i : I) -> &Self::Output {
352 self.spikes.index(i)
353 }
354 }
355
356 impl<
357 Domain,
358 F : Num,
359 I : std::slice::SliceIndex<[DeltaMeasure<Domain, F>]>
360 > IndexMut<I>
361 for DiscreteMeasure<Domain, F> {
362 #[inline]
363 fn index_mut(&mut self, i : I) -> &mut Self::Output {
364 self.spikes.index_mut(i)
365 }
366 }
367
368
369 impl<Domain, F : Num, D : Into<DeltaMeasure<Domain, F>>, const K : usize> From<[D; K]>
370 for DiscreteMeasure<Domain, F> {
371 #[inline]
372 fn from(list : [D; K]) -> Self {
373 list.into_iter().collect()
374 }
375 }
376
377 impl<Domain, F : Num> From<Vec<DeltaMeasure<Domain, F>>>
378 for DiscreteMeasure<Domain, F> {
379 #[inline]
380 fn from(spikes : Vec<DeltaMeasure<Domain, F>>) -> Self {
381 DiscreteMeasure{ spikes }
382 }
383 }
384
385 impl<'a, Domain, F : Num, D> From<&'a [D]>
386 for DiscreteMeasure<Domain, F>
387 where &'a D : Into<DeltaMeasure<Domain, F>> {
388 #[inline]
389 fn from(list : &'a [D]) -> Self {
390 list.into_iter().map(|d| d.into()).collect()
391 }
392 }
393
394
395 impl<Domain, F : Num> From<DeltaMeasure<Domain, F>>
396 for DiscreteMeasure<Domain, F> {
397 #[inline]
398 fn from(δ : DeltaMeasure<Domain, F>) -> Self {
399 DiscreteMeasure{
400 spikes : vec!(δ)
401 }
402 }
403 }
404
405 impl<'a, Domain : Clone, F : Num> From<&'a DeltaMeasure<Domain, F>>
406 for DiscreteMeasure<Domain, F> {
407 #[inline]
408 fn from(δ : &'a DeltaMeasure<Domain, F>) -> Self {
409 DiscreteMeasure{
410 spikes : vec!(δ.clone())
411 }
412 }
413 }
414
415
416 impl<Domain, F : Num, D : Into<DeltaMeasure<Domain, F>>> FromIterator<D>
417 for DiscreteMeasure<Domain, F> {
418 #[inline]
419 fn from_iter<T>(iter : T) -> Self
420 where T : IntoIterator<Item=D> {
421 DiscreteMeasure{
422 spikes : iter.into_iter().map(|m| m.into()).collect()
423 }
424 }
425 }
426
427 impl<'a, F : Num, const N : usize> TableDump<'a>
428 for DiscreteMeasure<Loc<F, N>,F>
429 where DeltaMeasure<Loc<F, N>, F> : Serialize + 'a {
430 type Iter = std::slice::Iter<'a, DeltaMeasure<Loc<F, N>, F>>;
431
432 // fn tabledump_headers(&'a self) -> Vec<String> {
433 // let mut v : Vec<String> = (0..N).map(|i| format!("x{}", i)).collect();
434 // v.push("weight".into());
435 // v
436 // }
437
438 fn tabledump_entries(&'a self) -> Self::Iter {
439 // Ensure order matching the headers above
440 self.spikes.iter()
441 }
442 }
443
444 // Need to manually implement serialisation for DeltaMeasure<Loc<F, N>, F> [`csv`] writer fails on
445 // structs with nested arrays as well as with #[serde(flatten)].
446 // Then derive no longer works for DiscreteMeasure
447 impl<F : Num, const N : usize> Serialize for DiscreteMeasure<Loc<F, N>, F>
448 where
449 F: Serialize,
450 {
451 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
452 where
453 S: Serializer,
454 {
455 let mut s = serializer.serialize_seq(Some(self.spikes.len()))?;
456 for δ in self.spikes.iter() {
457 s.serialize_element(δ)?;
458 }
459 s.end()
460 }
461 }
462
463 impl<Domain : PartialEq, F : Float> Measure<F> for DiscreteMeasure<Domain, F> {
464 type Domain = Domain;
465 }
466
467 impl<Domain : PartialEq, F : Float> Norm<F, Radon> for DiscreteMeasure<Domain, F>
468 where DeltaMeasure<Domain, F> : Norm<F, Radon> {
469 #[inline]
470 fn norm(&self, _ : Radon) -> F {
471 self.spikes.iter().map(|m| m.norm(Radon)).sum()
472 }
473 }
474
475 impl<Domain, G, F : Num> Mapping<G> for DiscreteMeasure<Domain, F>
476 where
477 Domain : Space,
478 G::Codomain : Sum + Mul<F, Output=G::Codomain>,
479 G : Mapping<Domain, Codomain=F> + Clone + Space,
480 for<'b> &'b Domain : Instance<Domain>,
481 {
482 type Codomain = G::Codomain;
483
484 #[inline]
485 fn apply<I : Instance<G>>(&self, g : I) -> Self::Codomain {
486 g.eval(|g| self.spikes.iter().map(|m| g.apply(&m.x) * m.α).sum())
487 }
488 }
489
490 impl<Domain, G, F : Num> Linear<G> for DiscreteMeasure<Domain, F>
491 where
492 Domain : Space,
493 G::Codomain : Sum + Mul<F, Output=G::Codomain>,
494 G : Mapping<Domain, Codomain=F> + Clone + Space,
495 for<'b> &'b Domain : Instance<Domain>,
496 { }
497
498
499 /// Helper trait for constructing arithmetic operations for combinations
500 /// of [`DiscreteMeasure`] and [`DeltaMeasure`], and their references.
501 trait Lift<F : Num, Domain> {
502 type Producer : Iterator<Item=DeltaMeasure<Domain, F>>;
503
504 #[allow(dead_code)]
505 /// Lifts `self` into a [`DiscreteMeasure`].
506 fn lift(self) -> DiscreteMeasure<Domain, F>;
507
508 /// Lifts `self` into a [`DiscreteMeasure`], apply either `f` or `f_mut` whether the type
509 /// this method is implemented for is a reference or or not.
510 fn lift_with(self,
511 f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>,
512 f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>))
513 -> DiscreteMeasure<Domain, F>;
514
515 /// Extend `self` into a [`DiscreteMeasure`] with the spikes produced by `iter`.
516 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>(
517 self,
518 iter : I
519 ) -> DiscreteMeasure<Domain, F>;
520
521 /// Returns an iterator for producing copies of the spikes of `self`.
522 fn produce(self) -> Self::Producer;
523 }
524
525 impl<F : Num, Domain> Lift<F, Domain> for DiscreteMeasure<Domain, F> {
526 type Producer = std::vec::IntoIter<DeltaMeasure<Domain, F>>;
527
528 #[inline]
529 fn lift(self) -> DiscreteMeasure<Domain, F> { self }
530
531 fn lift_with(mut self,
532 _f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>,
533 f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>))
534 -> DiscreteMeasure<Domain, F> {
535 self.spikes.iter_mut().for_each(f_mut);
536 self
537 }
538
539 #[inline]
540 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>(
541 mut self,
542 iter : I
543 ) -> DiscreteMeasure<Domain, F> {
544 self.spikes.extend(iter);
545 self
546 }
547
548 #[inline]
549 fn produce(self) -> Self::Producer {
550 self.spikes.into_iter()
551 }
552 }
553
554 impl<'a, F : Num, Domain : Clone> Lift<F, Domain> for &'a DiscreteMeasure<Domain, F> {
555 type Producer = MapF<std::slice::Iter<'a, DeltaMeasure<Domain, F>>, DeltaMeasure<Domain, F>>;
556
557 #[inline]
558 fn lift(self) -> DiscreteMeasure<Domain, F> { self.clone() }
559
560 fn lift_with(self,
561 f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>,
562 _f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>))
563 -> DiscreteMeasure<Domain, F> {
564 DiscreteMeasure{ spikes : self.spikes.iter().map(f).collect() }
565 }
566
567 #[inline]
568 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>(
569 self,
570 iter : I
571 ) -> DiscreteMeasure<Domain, F> {
572 let mut res = self.clone();
573 res.spikes.extend(iter);
574 res
575 }
576
577 #[inline]
578 fn produce(self) -> Self::Producer {
579 // TODO: maybe not optimal to clone here and would benefit from
580 // a reference version of lift_extend.
581 self.spikes.iter().mapF(Clone::clone)
582 }
583 }
584
585 impl<F : Num, Domain> Lift<F, Domain> for DeltaMeasure<Domain, F> {
586 type Producer = std::iter::Once<DeltaMeasure<Domain, F>>;
587
588 #[inline]
589 fn lift(self) -> DiscreteMeasure<Domain, F> { DiscreteMeasure { spikes : vec![self] } }
590
591 #[inline]
592 fn lift_with(mut self,
593 _f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>,
594 mut f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>))
595 -> DiscreteMeasure<Domain, F> {
596 f_mut(&mut self);
597 DiscreteMeasure{ spikes : vec![self] }
598 }
599
600 #[inline]
601 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>(
602 self,
603 iter : I
604 ) -> DiscreteMeasure<Domain, F> {
605 let mut spikes = vec![self];
606 spikes.extend(iter);
607 DiscreteMeasure{ spikes : spikes }
608 }
609
610 #[inline]
611 fn produce(self) -> Self::Producer {
612 std::iter::once(self)
613 }
614 }
615
616 impl<'a, F : Num, Domain : Clone> Lift<F, Domain> for &'a DeltaMeasure<Domain, F> {
617 type Producer = std::iter::Once<DeltaMeasure<Domain, F>>;
618
619 #[inline]
620 fn lift(self) -> DiscreteMeasure<Domain, F> { DiscreteMeasure { spikes : vec![self.clone()] } }
621
622 #[inline]
623 fn lift_with(self,
624 f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>,
625 _f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>))
626 -> DiscreteMeasure<Domain, F> {
627 DiscreteMeasure{ spikes : vec![f(self)] }
628 }
629
630 #[inline]
631 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>(
632 self,
633 iter : I
634 ) -> DiscreteMeasure<Domain, F> {
635 let mut spikes = vec![self.clone()];
636 spikes.extend(iter);
637 DiscreteMeasure{ spikes : spikes }
638 }
639
640 #[inline]
641 fn produce(self) -> Self::Producer {
642 std::iter::once(self.clone())
643 }
644 }
645
646 macro_rules! make_discrete_addsub_assign {
647 ($rhs:ty) => {
648 // Discrete += (&)Discrete
649 impl<'a, F : Num, Domain : Clone> AddAssign<$rhs>
650 for DiscreteMeasure<Domain, F> {
651 fn add_assign(&mut self, other : $rhs) {
652 self.spikes.extend(other.produce());
653 }
654 }
655
656 impl<'a, F : Num + Neg<Output=F>, Domain : Clone> SubAssign<$rhs>
657 for DiscreteMeasure<Domain, F> {
658 fn sub_assign(&mut self, other : $rhs) {
659 self.spikes.extend(other.produce().map(|δ| -δ));
660 }
661 }
662 }
663 }
664
665 make_discrete_addsub_assign!(DiscreteMeasure<Domain, F>);
666 make_discrete_addsub_assign!(&'a DiscreteMeasure<Domain, F>);
667 make_discrete_addsub_assign!(DeltaMeasure<Domain, F>);
668 make_discrete_addsub_assign!(&'a DeltaMeasure<Domain, F>);
669
670 macro_rules! make_discrete_addsub {
671 ($lhs:ty, $rhs:ty, $alt_order:expr) => {
672 impl<'a, 'b, F : Num, Domain : Clone> Add<$rhs> for $lhs {
673 type Output = DiscreteMeasure<Domain, F>;
674 fn add(self, other : $rhs) -> DiscreteMeasure<Domain, F> {
675 if !$alt_order {
676 self.lift_extend(other.produce())
677 } else {
678 other.lift_extend(self.produce())
679 }
680 }
681 }
682
683 impl<'a, 'b, F : Num + Neg<Output=F>, Domain : Clone> Sub<$rhs> for $lhs {
684 type Output = DiscreteMeasure<Domain, F>;
685 fn sub(self, other : $rhs) -> DiscreteMeasure<Domain, F> {
686 self.lift_extend(other.produce().map(|δ| -δ))
687 }
688 }
689 };
690 }
691
692 make_discrete_addsub!(DiscreteMeasure<Domain, F>, DiscreteMeasure<Domain, F>, false);
693 make_discrete_addsub!(DiscreteMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false);
694 make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, DiscreteMeasure<Domain, F>, true);
695 make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false);
696 make_discrete_addsub!(DeltaMeasure<Domain, F>, DiscreteMeasure<Domain, F>, false);
697 make_discrete_addsub!(DeltaMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false);
698 make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, DiscreteMeasure<Domain, F>, true);
699 make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false);
700 make_discrete_addsub!(DiscreteMeasure<Domain, F>, DeltaMeasure<Domain, F>, false);
701 make_discrete_addsub!(DiscreteMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false);
702 make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, DeltaMeasure<Domain, F>, false);
703 make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false);
704 make_discrete_addsub!(DeltaMeasure<Domain, F>, DeltaMeasure<Domain, F>, false);
705 make_discrete_addsub!(DeltaMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false);
706 make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, DeltaMeasure<Domain, F>, false);
707 make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false);
708
709 macro_rules! make_discrete_scalarop_rhs {
710 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => {
711 make_discrete_scalarop_rhs!(@assign DiscreteMeasure<Domain, F>, F, $trait_assign, $fn_assign);
712 make_discrete_scalarop_rhs!(@assign DiscreteMeasure<Domain, F>, &'a F, $trait_assign, $fn_assign);
713 make_discrete_scalarop_rhs!(@new DiscreteMeasure<Domain, F>, F, $trait, $fn, $fn_assign);
714 make_discrete_scalarop_rhs!(@new DiscreteMeasure<Domain, F>, &'a F, $trait, $fn, $fn_assign);
715 make_discrete_scalarop_rhs!(@new &'b DiscreteMeasure<Domain, F>, F, $trait, $fn, $fn_assign);
716 make_discrete_scalarop_rhs!(@new &'b DiscreteMeasure<Domain, F>, &'a F, $trait, $fn, $fn_assign);
717 };
718
719 (@assign $lhs:ty, $rhs:ty, $trait_assign:ident, $fn_assign:ident) => {
720 impl<'a, 'b, F : Num, Domain> $trait_assign<$rhs> for $lhs {
721 fn $fn_assign(&mut self, b : $rhs) {
722 self.spikes.iter_mut().for_each(|δ| δ.$fn_assign(b));
723 }
724 }
725 };
726 (@new $lhs:ty, $rhs:ty, $trait:ident, $fn:ident, $fn_assign:ident) => {
727 impl<'a, 'b, F : Num, Domain : Clone> $trait<$rhs> for $lhs {
728 type Output = DiscreteMeasure<Domain, F>;
729 fn $fn(self, b : $rhs) -> Self::Output {
730 self.lift_with(|δ| δ.$fn(b), |δ| δ.$fn_assign(b))
731 }
732 }
733 };
734 }
735
736 make_discrete_scalarop_rhs!(Mul, mul, MulAssign, mul_assign);
737 make_discrete_scalarop_rhs!(Div, div, DivAssign, div_assign);
738
739 macro_rules! make_discrete_unary {
740 ($trait:ident, $fn:ident, $type:ty) => {
741 impl<'a, F : Num + Neg<Output=F>, Domain : Clone> Neg for $type {
742 type Output = DiscreteMeasure<Domain, F>;
743 fn $fn(self) -> Self::Output {
744 self.lift_with(|δ| δ.$fn(), |δ| δ.α = δ.α.$fn())
745 }
746 }
747 }
748 }
749
750 make_discrete_unary!(Neg, neg, DiscreteMeasure<Domain, F>);
751 make_discrete_unary!(Neg, neg, &'a DiscreteMeasure<Domain, F>);
752
753 // impl<F : Num, Domain> Neg for DiscreteMeasure<Domain, F> {
754 // type Output = Self;
755 // fn $fn(mut self, b : F) -> Self {
756 // self.lift().spikes.iter_mut().for_each(|δ| δ.neg(b));
757 // self
758 // }
759 // }
760
761 macro_rules! make_discrete_scalarop_lhs {
762 ($trait:ident, $fn:ident; $($f:ident)+) => { $(
763 impl<Domain> $trait<DiscreteMeasure<Domain, $f>> for $f {
764 type Output = DiscreteMeasure<Domain, $f>;
765 fn $fn(self, mut v : DiscreteMeasure<Domain, $f>) -> Self::Output {
766 v.spikes.iter_mut().for_each(|δ| δ.α = self.$fn(δ.α));
767 v
768 }
769 }
770
771 impl<'a, Domain : Copy> $trait<&'a DiscreteMeasure<Domain, $f>> for $f {
772 type Output = DiscreteMeasure<Domain, $f>;
773 fn $fn(self, v : &'a DiscreteMeasure<Domain, $f>) -> Self::Output {
774 DiscreteMeasure{
775 spikes : v.spikes.iter().map(|δ| self.$fn(δ)).collect()
776 }
777 }
778 }
779
780 impl<'b, Domain> $trait<DiscreteMeasure<Domain, $f>> for &'b $f {
781 type Output = DiscreteMeasure<Domain, $f>;
782 fn $fn(self, mut v : DiscreteMeasure<Domain, $f>) -> Self::Output {
783 v.spikes.iter_mut().for_each(|δ| δ.α = self.$fn(δ.α));
784 v
785 }
786 }
787
788 impl<'a, 'b, Domain : Copy> $trait<&'a DiscreteMeasure<Domain, $f>> for &'b $f {
789 type Output = DiscreteMeasure<Domain, $f>;
790 fn $fn(self, v : &'a DiscreteMeasure<Domain, $f>) -> Self::Output {
791 DiscreteMeasure{
792 spikes : v.spikes.iter().map(|δ| self.$fn(δ)).collect()
793 }
794 }
795 }
796 )+ }
797 }
798
799 make_discrete_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
800 make_discrete_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
801
802 impl<F : Num, Domain> Collection for DiscreteMeasure<Domain, F> {
803 type Element = DeltaMeasure<Domain, F>;
804 type RefsIter<'a> = std::slice::Iter<'a, Self::Element> where Self : 'a;
805
806 #[inline]
807 fn iter_refs(&self) -> Self::RefsIter<'_> {
808 self.iter_spikes()
809 }
810 }
811
812 impl<Domain : Clone, F : Num> Space for DiscreteMeasure<Domain, F> {
813 type Decomp = MeasureDecomp;
814 }
815
816 pub type SpikeSlice<'b, Domain, F> = &'b [DeltaMeasure<Domain, F>];
817
818 pub type EitherSlice<'b, Domain, F> = EitherDecomp<
819 Vec<DeltaMeasure<Domain, F>>,
820 SpikeSlice<'b, Domain, F>
821 >;
822
823 impl<F : Num, Domain : Clone> Decomposition<DiscreteMeasure<Domain, F>> for MeasureDecomp {
824 type Decomposition<'b> = EitherSlice<'b, Domain, F> where DiscreteMeasure<Domain, F> : 'b;
825 type Reference<'b> = SpikeSlice<'b, Domain, F> where DiscreteMeasure<Domain, F> : 'b;
826
827 /// Left the lightweight reference type into a full decomposition type.
828 fn lift<'b>(r : Self::Reference<'b>) -> Self::Decomposition<'b> {
829 EitherDecomp::Borrowed(r)
830 }
831 }
832
833 impl<F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
834 for DiscreteMeasure<Domain, F>
835 {
836 fn decompose<'b>(self)
837 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
838 where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
839 EitherDecomp::Owned(self.spikes)
840 }
841
842 fn ref_instance(&self)
843 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
844 {
845 self.spikes.as_slice()
846 }
847
848 fn cow<'b>(self) -> MyCow<'b, DiscreteMeasure<Domain, F>> where Self : 'b {
849 MyCow::Owned(self)
850 }
851
852 fn own(self) -> DiscreteMeasure<Domain, F> {
853 self
854 }
855 }
856
857 impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
858 for &'a DiscreteMeasure<Domain, F>
859 {
860 fn decompose<'b>(self)
861 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
862 where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
863 EitherDecomp::Borrowed(self.spikes.as_slice())
864 }
865
866 fn ref_instance(&self)
867 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
868 {
869 self.spikes.as_slice()
870 }
871
872 fn cow<'b>(self) -> MyCow<'b, DiscreteMeasure<Domain, F>> where Self : 'b {
873 MyCow::Borrowed(self)
874 }
875
876 fn own(self) -> DiscreteMeasure<Domain, F> {
877 self.clone()
878 }
879 }
880
881 impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
882 for EitherSlice<'a, Domain, F>
883 {
884 fn decompose<'b>(self)
885 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
886 where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
887 self
888 }
889
890 fn ref_instance(&self)
891 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
892 {
893 match self {
894 EitherDecomp::Owned(v) => v.as_slice(),
895 EitherDecomp::Borrowed(s) => s,
896 }
897 }
898
899 fn own(self) -> DiscreteMeasure<Domain, F> {
900 match self {
901 EitherDecomp::Owned(v) => v.into(),
902 EitherDecomp::Borrowed(s) => s.into(),
903 }
904 }
905 }
906
907 impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
908 for &'a EitherSlice<'a, Domain, F>
909 {
910 fn decompose<'b>(self)
911 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
912 where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
913 match self {
914 EitherDecomp::Owned(v) => EitherDecomp::Borrowed(v.as_slice()),
915 EitherDecomp::Borrowed(s) => EitherDecomp::Borrowed(s),
916 }
917 }
918
919 fn ref_instance(&self)
920 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
921 {
922 match self {
923 EitherDecomp::Owned(v) => v.as_slice(),
924 EitherDecomp::Borrowed(s) => s,
925 }
926 }
927
928 fn own(self) -> DiscreteMeasure<Domain, F> {
929 match self {
930 EitherDecomp::Owned(v) => v.as_slice(),
931 EitherDecomp::Borrowed(s) => s
932 }.into()
933 }
934 }
935
936 impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
937 for SpikeSlice<'a, Domain, F>
938 {
939 fn decompose<'b>(self)
940 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
941 where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
942 EitherDecomp::Borrowed(self)
943 }
944
945 fn ref_instance(&self)
946 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
947 {
948 self
949 }
950
951 fn own(self) -> DiscreteMeasure<Domain, F> {
952 self.into()
953 }
954 }
955
956 impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
957 for &'a SpikeSlice<'a, Domain, F>
958 {
959 fn decompose<'b>(self)
960 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
961 where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
962 EitherDecomp::Borrowed(*self)
963 }
964
965 fn ref_instance(&self)
966 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
967 {
968 *self
969 }
970
971 fn own(self) -> DiscreteMeasure<Domain, F> {
972 (*self).into()
973 }
974 }
975
976 impl<F : Num, Domain : Clone > Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
977 for DeltaMeasure<Domain, F>
978 {
979 fn decompose<'b>(self)
980 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
981 where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
982 EitherDecomp::Owned(vec![self])
983 }
984
985 fn ref_instance(&self)
986 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
987 {
988 std::slice::from_ref(self)
989 }
990
991 fn own(self) -> DiscreteMeasure<Domain, F> {
992 self.into()
993 }
994 }
995
996 impl<'a, F : Num, Domain : Clone> Instance<DiscreteMeasure<Domain, F>, MeasureDecomp>
997 for &'a DeltaMeasure<Domain, F>
998 {
999 fn decompose<'b>(self)
1000 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Decomposition<'b>
1001 where Self : 'b, DiscreteMeasure<Domain, F> : 'b {
1002 EitherDecomp::Borrowed(std::slice::from_ref(self))
1003 }
1004
1005 fn ref_instance(&self)
1006 -> <MeasureDecomp as Decomposition<DiscreteMeasure<Domain, F>>>::Reference<'_>
1007 {
1008 std::slice::from_ref(*self)
1009 }
1010
1011 fn own(self) -> DiscreteMeasure<Domain, F> {
1012 self.into()
1013 }
1014 }

mercurial