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