|
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::{Apply, Linear}; |
|
15 use alg_tools::iter::{MapF,Mappable}; |
|
16 use alg_tools::nalgebra_support::ToNalgebraRealField; |
|
17 |
|
18 use crate::types::*; |
|
19 use super::base::*; |
|
20 use super::delta::*; |
|
21 |
|
22 /// Representation of a discrete measure. |
|
23 /// |
|
24 /// This is the measure $μ = ∑_{k=1}^n α_k δ_{x_k}$, consisting of several |
|
25 /// [`DeltaMeasure`], i.e., “spikes” $α_k δ_{x_k}$ with weights $\alpha_k$ in `F` at locations |
|
26 /// $x_k$ in `Domain`. |
|
27 #[derive(Clone,Debug)] |
|
28 pub struct DiscreteMeasure<Domain, F : Num> { |
|
29 pub(super) spikes : Vec<DeltaMeasure<Domain, F>>, |
|
30 } |
|
31 |
|
32 /// Iterator over the [`DeltaMeasure`] spikes of a [`DiscreteMeasure`]. |
|
33 pub type SpikeIter<'a, Domain, F> = std::slice::Iter<'a, DeltaMeasure<Domain, F>>; |
|
34 |
|
35 /// Iterator over mutable [`DeltaMeasure`] spikes of a [`DiscreteMeasure`]. |
|
36 pub type SpikeIterMut<'a, Domain, F> = std::slice::IterMut<'a, DeltaMeasure<Domain, F>>; |
|
37 |
|
38 /// Iterator over the locations of the spikes of a [`DiscreteMeasure`]. |
|
39 pub type LocationIter<'a, Domain, F> |
|
40 = std::iter::Map<SpikeIter<'a, Domain, F>, fn(&'a DeltaMeasure<Domain, F>) -> &'a Domain>; |
|
41 |
|
42 /// Iterator over the masses of the spikes of a [`DiscreteMeasure`]. |
|
43 pub type MassIter<'a, Domain, F> |
|
44 = std::iter::Map<SpikeIter<'a, Domain, F>, fn(&'a DeltaMeasure<Domain, F>) -> F>; |
|
45 |
|
46 /// Iterator over the mutable locations of the spikes of a [`DiscreteMeasure`]. |
|
47 pub type MassIterMut<'a, Domain, F> |
|
48 = std::iter::Map<SpikeIterMut<'a, Domain, F>, for<'r> fn(&'r mut DeltaMeasure<Domain, F>) -> &'r mut F>; |
|
49 |
|
50 impl<Domain, F : Num> DiscreteMeasure<Domain, F> { |
|
51 /// Create a new zero measure (empty spike set). |
|
52 pub fn new() -> Self { |
|
53 DiscreteMeasure{ spikes : Vec::new() } |
|
54 } |
|
55 |
|
56 /// Number of [`DeltaMeasure`] spikes in the measure |
|
57 #[inline] |
|
58 pub fn len(&self) -> usize { |
|
59 self.spikes.len() |
|
60 } |
|
61 |
|
62 /// Iterate over (references to) the [`DeltaMeasure`] spikes in this measure |
|
63 #[inline] |
|
64 pub fn iter_spikes(&self) -> SpikeIter<'_, Domain, F> { |
|
65 self.spikes.iter() |
|
66 } |
|
67 |
|
68 /// Iterate over mutable references to the [`DeltaMeasure`] spikes in this measure |
|
69 #[inline] |
|
70 pub fn iter_spikes_mut(&mut self) -> SpikeIterMut<'_, Domain, F> { |
|
71 self.spikes.iter_mut() |
|
72 } |
|
73 |
|
74 /// Iterate over the location of the spikes in this measure |
|
75 #[inline] |
|
76 pub fn iter_locations(&self) -> LocationIter<'_, Domain, F> { |
|
77 self.iter_spikes().map(DeltaMeasure::get_location) |
|
78 } |
|
79 |
|
80 /// Iterate over the masses of the spikes in this measure |
|
81 #[inline] |
|
82 pub fn iter_masses(&self) -> MassIter<'_, Domain, F> { |
|
83 self.iter_spikes().map(DeltaMeasure::get_mass) |
|
84 } |
|
85 |
|
86 /// Iterate over the masses of the spikes in this measure |
|
87 #[inline] |
|
88 pub fn iter_masses_mut(&mut self) -> MassIterMut<'_, Domain, F> { |
|
89 self.iter_spikes_mut().map(DeltaMeasure::get_mass_mut) |
|
90 } |
|
91 |
|
92 /// Update the masses of all the spikes to those produced by an iterator. |
|
93 #[inline] |
|
94 pub fn set_masses<I : Iterator<Item=F>>(&mut self, iter : I) { |
|
95 self.spikes.iter_mut().zip(iter).for_each(|(δ, α)| δ.set_mass(α)); |
|
96 } |
|
97 |
|
98 // /// Map the masses of all the spikes using a function and an iterator |
|
99 // #[inline] |
|
100 // pub fn zipmap_masses< |
|
101 // I : Iterator<Item=F>, |
|
102 // G : Fn(F, I::Item) -> F |
|
103 // > (&mut self, iter : I, g : G) { |
|
104 // self.spikes.iter_mut().zip(iter).for_each(|(δ, v)| δ.set_mass(g(δ.get_mass(), v))); |
|
105 // } |
|
106 |
|
107 /// Prune all spikes with zero mass. |
|
108 #[inline] |
|
109 pub fn prune(&mut self) { |
|
110 self.spikes.retain(|δ| δ.α != F::ZERO); |
|
111 } |
|
112 } |
|
113 |
|
114 impl<Domain : Clone, F : Float> DiscreteMeasure<Domain, F> { |
|
115 /// Computes `μ1 ← θ * μ1 - ζ * μ2`, pruning entries where both `μ1` (`self`) and `μ2` have |
|
116 // zero weight. `μ2` will contain copy of pruned original `μ1` without arithmetic performed. |
|
117 /// **This expects `self` and `μ2` to have matching coordinates in each index**. |
|
118 // `μ2` can be than `self`, but not longer. |
|
119 pub fn pruning_sub(&mut self, θ : F, ζ : F, μ2 : &mut Self) { |
|
120 let mut μ2_get = 0; |
|
121 let mut μ2_insert = 0; |
|
122 self.spikes.drain_filter(|&mut DeltaMeasure{ α : ref mut α_ref, ref x }| { |
|
123 // Get weight of spike in μ2, zero if out of bounds. |
|
124 let β = μ2.spikes.get(μ2_get).map_or(F::ZERO, DeltaMeasure::get_mass); |
|
125 μ2_get += 1; |
|
126 |
|
127 if *α_ref == F::ZERO && β == F::ZERO { |
|
128 // Prune |
|
129 true |
|
130 } else { |
|
131 // Save self weight |
|
132 let α = *α_ref; |
|
133 // Modify self |
|
134 *α_ref = θ * α - ζ * β; |
|
135 // Make copy of old self weight in μ2 |
|
136 let δ = DeltaMeasure{ α, x : x.clone() }; |
|
137 match μ2.spikes.get_mut(μ2_insert) { |
|
138 Some(replace) => { |
|
139 *replace = δ; |
|
140 }, |
|
141 None => { |
|
142 debug_assert_eq!(μ2.len(), μ2_insert); |
|
143 μ2.spikes.push(δ); |
|
144 }, |
|
145 } |
|
146 μ2_insert += 1; |
|
147 // Keep |
|
148 false |
|
149 } |
|
150 }); |
|
151 // Truncate μ2 to same length as self. |
|
152 μ2.spikes.truncate(μ2_insert); |
|
153 debug_assert_eq!(μ2.len(), self.len()); |
|
154 } |
|
155 } |
|
156 |
|
157 impl<Domain, F : Float> DiscreteMeasure<Domain, F> { |
|
158 /// Prune all spikes with mass absolute value less than the given `tolerance`. |
|
159 #[inline] |
|
160 pub fn prune_approx(&mut self, tolerance : F) { |
|
161 self.spikes.retain(|δ| δ.α.abs() > tolerance); |
|
162 } |
|
163 } |
|
164 |
|
165 impl<Domain, F : Float + ToNalgebraRealField> DiscreteMeasure<Domain, F> { |
|
166 /// Extracts the masses of the spikes as a [`DVector`]. |
|
167 pub fn masses_dvector(&self) -> DVector<F::MixedType> { |
|
168 DVector::from_iterator(self.len(), |
|
169 self.iter_masses() |
|
170 .map(|α| α.to_nalgebra_mixed())) |
|
171 } |
|
172 |
|
173 /// Sets the masses of the spikes from the values of a [`DVector`]. |
|
174 pub fn set_masses_dvector(&mut self, x : &DVector<F::MixedType>) { |
|
175 self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α))); |
|
176 } |
|
177 } |
|
178 |
|
179 impl<Domain, F :Num> Index<usize> for DiscreteMeasure<Domain, F> { |
|
180 type Output = DeltaMeasure<Domain, F>; |
|
181 #[inline] |
|
182 fn index(&self, i : usize) -> &Self::Output { |
|
183 self.spikes.index(i) |
|
184 } |
|
185 } |
|
186 |
|
187 impl<Domain, F :Num> IndexMut<usize> for DiscreteMeasure<Domain, F> { |
|
188 #[inline] |
|
189 fn index_mut(&mut self, i : usize) -> &mut Self::Output { |
|
190 self.spikes.index_mut(i) |
|
191 } |
|
192 } |
|
193 |
|
194 impl<Domain, F : Num, D : Into<DeltaMeasure<Domain, F>>, const K : usize> From<[D; K]> |
|
195 for DiscreteMeasure<Domain, F> { |
|
196 #[inline] |
|
197 fn from(list : [D; K]) -> Self { |
|
198 list.into_iter().collect() |
|
199 } |
|
200 } |
|
201 |
|
202 impl<Domain, F : Num, D : Into<DeltaMeasure<Domain, F>>> FromIterator<D> |
|
203 for DiscreteMeasure<Domain, F> { |
|
204 #[inline] |
|
205 fn from_iter<T>(iter : T) -> Self |
|
206 where T : IntoIterator<Item=D> { |
|
207 DiscreteMeasure{ |
|
208 spikes : iter.into_iter().map(|m| m.into()).collect() |
|
209 } |
|
210 } |
|
211 } |
|
212 |
|
213 impl<'a, F : Num, const N : usize> TableDump<'a> |
|
214 for DiscreteMeasure<Loc<F, N>,F> |
|
215 where DeltaMeasure<Loc<F, N>, F> : Serialize + 'a { |
|
216 type Iter = std::slice::Iter<'a, DeltaMeasure<Loc<F, N>, F>>; |
|
217 |
|
218 // fn tabledump_headers(&'a self) -> Vec<String> { |
|
219 // let mut v : Vec<String> = (0..N).map(|i| format!("x{}", i)).collect(); |
|
220 // v.push("weight".into()); |
|
221 // v |
|
222 // } |
|
223 |
|
224 fn tabledump_entries(&'a self) -> Self::Iter { |
|
225 // Ensure order matching the headers above |
|
226 self.spikes.iter() |
|
227 } |
|
228 } |
|
229 |
|
230 // Need to manually implement serialisation for DeltaMeasure<Loc<F, N>, F> [`csv`] writer fails on |
|
231 // structs with nested arrays as well as with #[serde(flatten)]. |
|
232 // Then derive no longer works for DiscreteMeasure |
|
233 impl<F : Num, const N : usize> Serialize for DiscreteMeasure<Loc<F, N>, F> |
|
234 where |
|
235 F: Serialize, |
|
236 { |
|
237 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
|
238 where |
|
239 S: Serializer, |
|
240 { |
|
241 let mut s = serializer.serialize_seq(Some(self.spikes.len()))?; |
|
242 for δ in self.spikes.iter() { |
|
243 s.serialize_element(δ)?; |
|
244 } |
|
245 s.end() |
|
246 } |
|
247 } |
|
248 |
|
249 impl<Domain : PartialEq, F : Float> Measure<F> for DiscreteMeasure<Domain, F> { |
|
250 type Domain = Domain; |
|
251 } |
|
252 |
|
253 impl<Domain : PartialEq, F : Float> Norm<F, Radon> for DiscreteMeasure<Domain, F> |
|
254 where DeltaMeasure<Domain, F> : Norm<F, Radon> { |
|
255 #[inline] |
|
256 fn norm(&self, _ : Radon) -> F { |
|
257 self.spikes.iter().map(|m| m.norm(Radon)).sum() |
|
258 } |
|
259 } |
|
260 |
|
261 impl<Domain, G, F : Num, Y : Sum + Mul<F, Output=Y>> Apply<G> for DiscreteMeasure<Domain, F> |
|
262 where G: for<'a> Apply<&'a Domain, Output = Y> { |
|
263 type Output = Y; |
|
264 #[inline] |
|
265 fn apply(&self, g : G) -> Y { |
|
266 self.spikes.iter().map(|m| g.apply(&m.x) * m.α).sum() |
|
267 } |
|
268 } |
|
269 |
|
270 impl<Domain, G, F : Num, Y : Sum + Mul<F, Output=Y>> Linear<G> for DiscreteMeasure<Domain, F> |
|
271 where G : for<'a> Apply<&'a Domain, Output = Y> { |
|
272 type Codomain = Y; |
|
273 } |
|
274 |
|
275 |
|
276 /// Helper trait for constructing arithmetic operations for combinations |
|
277 /// of [`DiscreteMeasure`] and [`DeltaMeasure`], and their references. |
|
278 trait Lift<F : Num, Domain> { |
|
279 type Producer : Iterator<Item=DeltaMeasure<Domain, F>>; |
|
280 |
|
281 /// Lifts `self` into a [`DiscreteMeasure`]. |
|
282 fn lift(self) -> DiscreteMeasure<Domain, F>; |
|
283 |
|
284 /// Lifts `self` into a [`DiscreteMeasure`], apply either `f` or `f_mut` whether the type |
|
285 /// this method is implemented for is a reference or or not. |
|
286 fn lift_with(self, |
|
287 f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, |
|
288 f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) |
|
289 -> DiscreteMeasure<Domain, F>; |
|
290 |
|
291 /// Extend `self` into a [`DiscreteMeasure`] with the spikes produced by `iter`. |
|
292 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( |
|
293 self, |
|
294 iter : I |
|
295 ) -> DiscreteMeasure<Domain, F>; |
|
296 |
|
297 /// Returns an iterator for producing copies of the spikes of `self`. |
|
298 fn produce(self) -> Self::Producer; |
|
299 } |
|
300 |
|
301 impl<F : Num, Domain> Lift<F, Domain> for DiscreteMeasure<Domain, F> { |
|
302 type Producer = std::vec::IntoIter<DeltaMeasure<Domain, F>>; |
|
303 |
|
304 #[inline] |
|
305 fn lift(self) -> DiscreteMeasure<Domain, F> { self } |
|
306 |
|
307 fn lift_with(mut self, |
|
308 _f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, |
|
309 f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) |
|
310 -> DiscreteMeasure<Domain, F> { |
|
311 self.spikes.iter_mut().for_each(f_mut); |
|
312 self |
|
313 } |
|
314 |
|
315 #[inline] |
|
316 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( |
|
317 mut self, |
|
318 iter : I |
|
319 ) -> DiscreteMeasure<Domain, F> { |
|
320 self.spikes.extend(iter); |
|
321 self |
|
322 } |
|
323 |
|
324 #[inline] |
|
325 fn produce(self) -> Self::Producer { |
|
326 self.spikes.into_iter() |
|
327 } |
|
328 } |
|
329 |
|
330 impl<'a, F : Num, Domain : Clone> Lift<F, Domain> for &'a DiscreteMeasure<Domain, F> { |
|
331 type Producer = MapF<std::slice::Iter<'a, DeltaMeasure<Domain, F>>, DeltaMeasure<Domain, F>>; |
|
332 |
|
333 #[inline] |
|
334 fn lift(self) -> DiscreteMeasure<Domain, F> { self.clone() } |
|
335 |
|
336 fn lift_with(self, |
|
337 f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, |
|
338 _f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) |
|
339 -> DiscreteMeasure<Domain, F> { |
|
340 DiscreteMeasure{ spikes : self.spikes.iter().map(f).collect() } |
|
341 } |
|
342 |
|
343 #[inline] |
|
344 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( |
|
345 self, |
|
346 iter : I |
|
347 ) -> DiscreteMeasure<Domain, F> { |
|
348 let mut res = self.clone(); |
|
349 res.spikes.extend(iter); |
|
350 res |
|
351 } |
|
352 |
|
353 #[inline] |
|
354 fn produce(self) -> Self::Producer { |
|
355 // TODO: maybe not optimal to clone here and would benefit from |
|
356 // a reference version of lift_extend. |
|
357 self.spikes.iter().mapF(Clone::clone) |
|
358 } |
|
359 } |
|
360 |
|
361 impl<F : Num, Domain> Lift<F, Domain> for DeltaMeasure<Domain, F> { |
|
362 type Producer = std::iter::Once<DeltaMeasure<Domain, F>>; |
|
363 |
|
364 #[inline] |
|
365 fn lift(self) -> DiscreteMeasure<Domain, F> { DiscreteMeasure { spikes : vec![self] } } |
|
366 |
|
367 #[inline] |
|
368 fn lift_with(mut self, |
|
369 _f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, |
|
370 mut f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) |
|
371 -> DiscreteMeasure<Domain, F> { |
|
372 f_mut(&mut self); |
|
373 DiscreteMeasure{ spikes : vec![self] } |
|
374 } |
|
375 |
|
376 #[inline] |
|
377 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( |
|
378 self, |
|
379 iter : I |
|
380 ) -> DiscreteMeasure<Domain, F> { |
|
381 let mut spikes = vec![self]; |
|
382 spikes.extend(iter); |
|
383 DiscreteMeasure{ spikes : spikes } |
|
384 } |
|
385 |
|
386 #[inline] |
|
387 fn produce(self) -> Self::Producer { |
|
388 std::iter::once(self) |
|
389 } |
|
390 } |
|
391 |
|
392 impl<'a, F : Num, Domain : Clone> Lift<F, Domain> for &'a DeltaMeasure<Domain, F> { |
|
393 type Producer = std::iter::Once<DeltaMeasure<Domain, F>>; |
|
394 |
|
395 #[inline] |
|
396 fn lift(self) -> DiscreteMeasure<Domain, F> { DiscreteMeasure { spikes : vec![self.clone()] } } |
|
397 |
|
398 #[inline] |
|
399 fn lift_with(self, |
|
400 f : impl Fn(&DeltaMeasure<Domain, F>) -> DeltaMeasure<Domain, F>, |
|
401 _f_mut : impl FnMut(&mut DeltaMeasure<Domain, F>)) |
|
402 -> DiscreteMeasure<Domain, F> { |
|
403 DiscreteMeasure{ spikes : vec![f(self)] } |
|
404 } |
|
405 |
|
406 #[inline] |
|
407 fn lift_extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( |
|
408 self, |
|
409 iter : I |
|
410 ) -> DiscreteMeasure<Domain, F> { |
|
411 let mut spikes = vec![self.clone()]; |
|
412 spikes.extend(iter); |
|
413 DiscreteMeasure{ spikes : spikes } |
|
414 } |
|
415 |
|
416 #[inline] |
|
417 fn produce(self) -> Self::Producer { |
|
418 std::iter::once(self.clone()) |
|
419 } |
|
420 } |
|
421 |
|
422 macro_rules! make_discrete_addsub_assign { |
|
423 ($rhs:ty) => { |
|
424 // Discrete += (&)Discrete |
|
425 impl<'a, F : Num, Domain : Clone> AddAssign<$rhs> |
|
426 for DiscreteMeasure<Domain, F> { |
|
427 fn add_assign(&mut self, other : $rhs) { |
|
428 self.spikes.extend(other.produce()); |
|
429 } |
|
430 } |
|
431 |
|
432 impl<'a, F : Num + Neg<Output=F>, Domain : Clone> SubAssign<$rhs> |
|
433 for DiscreteMeasure<Domain, F> { |
|
434 fn sub_assign(&mut self, other : $rhs) { |
|
435 self.spikes.extend(other.produce().map(|δ| -δ)); |
|
436 } |
|
437 } |
|
438 } |
|
439 } |
|
440 |
|
441 make_discrete_addsub_assign!(DiscreteMeasure<Domain, F>); |
|
442 make_discrete_addsub_assign!(&'a DiscreteMeasure<Domain, F>); |
|
443 make_discrete_addsub_assign!(DeltaMeasure<Domain, F>); |
|
444 make_discrete_addsub_assign!(&'a DeltaMeasure<Domain, F>); |
|
445 |
|
446 macro_rules! make_discrete_addsub { |
|
447 ($lhs:ty, $rhs:ty, $alt_order:expr) => { |
|
448 impl<'a, 'b, F : Num, Domain : Clone> Add<$rhs> for $lhs { |
|
449 type Output = DiscreteMeasure<Domain, F>; |
|
450 fn add(self, other : $rhs) -> DiscreteMeasure<Domain, F> { |
|
451 if !$alt_order { |
|
452 self.lift_extend(other.produce()) |
|
453 } else { |
|
454 other.lift_extend(self.produce()) |
|
455 } |
|
456 } |
|
457 } |
|
458 |
|
459 impl<'a, 'b, F : Num + Neg<Output=F>, Domain : Clone> Sub<$rhs> for $lhs { |
|
460 type Output = DiscreteMeasure<Domain, F>; |
|
461 fn sub(self, other : $rhs) -> DiscreteMeasure<Domain, F> { |
|
462 self.lift_extend(other.produce().map(|δ| -δ)) |
|
463 } |
|
464 } |
|
465 }; |
|
466 } |
|
467 |
|
468 make_discrete_addsub!(DiscreteMeasure<Domain, F>, DiscreteMeasure<Domain, F>, false); |
|
469 make_discrete_addsub!(DiscreteMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false); |
|
470 make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, DiscreteMeasure<Domain, F>, true); |
|
471 make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false); |
|
472 make_discrete_addsub!(DeltaMeasure<Domain, F>, DiscreteMeasure<Domain, F>, false); |
|
473 make_discrete_addsub!(DeltaMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false); |
|
474 make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, DiscreteMeasure<Domain, F>, true); |
|
475 make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, &'b DiscreteMeasure<Domain, F>, false); |
|
476 make_discrete_addsub!(DiscreteMeasure<Domain, F>, DeltaMeasure<Domain, F>, false); |
|
477 make_discrete_addsub!(DiscreteMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false); |
|
478 make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, DeltaMeasure<Domain, F>, false); |
|
479 make_discrete_addsub!(&'a DiscreteMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false); |
|
480 make_discrete_addsub!(DeltaMeasure<Domain, F>, DeltaMeasure<Domain, F>, false); |
|
481 make_discrete_addsub!(DeltaMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false); |
|
482 make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, DeltaMeasure<Domain, F>, false); |
|
483 make_discrete_addsub!(&'a DeltaMeasure<Domain, F>, &'b DeltaMeasure<Domain, F>, false); |
|
484 |
|
485 macro_rules! make_discrete_scalarop_rhs { |
|
486 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
|
487 make_discrete_scalarop_rhs!(@assign DiscreteMeasure<Domain, F>, F, $trait_assign, $fn_assign); |
|
488 make_discrete_scalarop_rhs!(@assign DiscreteMeasure<Domain, F>, &'a F, $trait_assign, $fn_assign); |
|
489 make_discrete_scalarop_rhs!(@new DiscreteMeasure<Domain, F>, F, $trait, $fn, $fn_assign); |
|
490 make_discrete_scalarop_rhs!(@new DiscreteMeasure<Domain, F>, &'a F, $trait, $fn, $fn_assign); |
|
491 make_discrete_scalarop_rhs!(@new &'b DiscreteMeasure<Domain, F>, F, $trait, $fn, $fn_assign); |
|
492 make_discrete_scalarop_rhs!(@new &'b DiscreteMeasure<Domain, F>, &'a F, $trait, $fn, $fn_assign); |
|
493 }; |
|
494 |
|
495 (@assign $lhs:ty, $rhs:ty, $trait_assign:ident, $fn_assign:ident) => { |
|
496 impl<'a, 'b, F : Num, Domain> $trait_assign<$rhs> for $lhs { |
|
497 fn $fn_assign(&mut self, b : $rhs) { |
|
498 self.spikes.iter_mut().for_each(|δ| δ.$fn_assign(b)); |
|
499 } |
|
500 } |
|
501 }; |
|
502 (@new $lhs:ty, $rhs:ty, $trait:ident, $fn:ident, $fn_assign:ident) => { |
|
503 impl<'a, 'b, F : Num, Domain : Clone> $trait<$rhs> for $lhs { |
|
504 type Output = DiscreteMeasure<Domain, F>; |
|
505 fn $fn(self, b : $rhs) -> Self::Output { |
|
506 self.lift_with(|δ| δ.$fn(b), |δ| δ.$fn_assign(b)) |
|
507 } |
|
508 } |
|
509 }; |
|
510 } |
|
511 |
|
512 make_discrete_scalarop_rhs!(Mul, mul, MulAssign, mul_assign); |
|
513 make_discrete_scalarop_rhs!(Div, div, DivAssign, div_assign); |
|
514 |
|
515 macro_rules! make_discrete_unary { |
|
516 ($trait:ident, $fn:ident, $type:ty) => { |
|
517 impl<'a, F : Num + Neg<Output=F>, Domain : Clone> Neg for $type { |
|
518 type Output = DiscreteMeasure<Domain, F>; |
|
519 fn $fn(self) -> Self::Output { |
|
520 self.lift_with(|δ| δ.$fn(), |δ| δ.α = δ.α.$fn()) |
|
521 } |
|
522 } |
|
523 } |
|
524 } |
|
525 |
|
526 make_discrete_unary!(Neg, neg, DiscreteMeasure<Domain, F>); |
|
527 make_discrete_unary!(Neg, neg, &'a DiscreteMeasure<Domain, F>); |
|
528 |
|
529 // impl<F : Num, Domain> Neg for DiscreteMeasure<Domain, F> { |
|
530 // type Output = Self; |
|
531 // fn $fn(mut self, b : F) -> Self { |
|
532 // self.lift().spikes.iter_mut().for_each(|δ| δ.neg(b)); |
|
533 // self |
|
534 // } |
|
535 // } |
|
536 |
|
537 macro_rules! make_discrete_scalarop_lhs { |
|
538 ($trait:ident, $fn:ident; $($f:ident)+) => { $( |
|
539 impl<Domain> $trait<DiscreteMeasure<Domain, $f>> for $f { |
|
540 type Output = DiscreteMeasure<Domain, $f>; |
|
541 fn $fn(self, mut v : DiscreteMeasure<Domain, $f>) -> Self::Output { |
|
542 v.spikes.iter_mut().for_each(|δ| δ.α = self.$fn(δ.α)); |
|
543 v |
|
544 } |
|
545 } |
|
546 |
|
547 impl<'a, Domain : Copy> $trait<&'a DiscreteMeasure<Domain, $f>> for $f { |
|
548 type Output = DiscreteMeasure<Domain, $f>; |
|
549 fn $fn(self, v : &'a DiscreteMeasure<Domain, $f>) -> Self::Output { |
|
550 DiscreteMeasure{ |
|
551 spikes : v.spikes.iter().map(|δ| self.$fn(δ)).collect() |
|
552 } |
|
553 } |
|
554 } |
|
555 |
|
556 impl<'b, Domain> $trait<DiscreteMeasure<Domain, $f>> for &'b $f { |
|
557 type Output = DiscreteMeasure<Domain, $f>; |
|
558 fn $fn(self, mut v : DiscreteMeasure<Domain, $f>) -> Self::Output { |
|
559 v.spikes.iter_mut().for_each(|δ| δ.α = self.$fn(δ.α)); |
|
560 v |
|
561 } |
|
562 } |
|
563 |
|
564 impl<'a, 'b, Domain : Copy> $trait<&'a DiscreteMeasure<Domain, $f>> for &'b $f { |
|
565 type Output = DiscreteMeasure<Domain, $f>; |
|
566 fn $fn(self, v : &'a DiscreteMeasure<Domain, $f>) -> Self::Output { |
|
567 DiscreteMeasure{ |
|
568 spikes : v.spikes.iter().map(|δ| self.$fn(δ)).collect() |
|
569 } |
|
570 } |
|
571 } |
|
572 )+ } |
|
573 } |
|
574 |
|
575 make_discrete_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize); |
|
576 make_discrete_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize); |