263 } |
263 } |
264 } |
264 } |
265 |
265 |
266 impl<Domain : Clone, F : Float> DiscreteMeasure<Domain, F> { |
266 impl<Domain : Clone, F : Float> DiscreteMeasure<Domain, F> { |
267 /// Computes `μ1 ← θ * μ1 - ζ * μ2`, pruning entries where both `μ1` (`self`) and `μ2` have |
267 /// Computes `μ1 ← θ * μ1 - ζ * μ2`, pruning entries where both `μ1` (`self`) and `μ2` have |
268 // zero weight. `μ2` will contain copy of pruned original `μ1` without arithmetic performed. |
268 // zero weight. `μ2` will contain a pruned copy of pruned original `μ1` without arithmetic |
269 /// **This expects `self` and `μ2` to have matching coordinates in each index**. |
269 /// performed. **This expects `self` and `μ2` to have matching coordinates in each index**. |
270 // `μ2` can be than `self`, but not longer. |
270 // `μ2` can be than `self`, but not longer. |
271 pub fn pruning_sub(&mut self, θ : F, ζ : F, μ2 : &mut Self) { |
271 pub fn pruning_sub(&mut self, θ : F, ζ : F, μ2 : &mut Self) { |
272 let mut μ2_get = 0; |
272 for δ in &self[μ2.len()..] { |
273 let mut μ2_insert = 0; |
273 μ2.push(DeltaMeasure{ x : δ.x.clone(), α : F::ZERO}); |
274 self.spikes.retain_mut(|&mut DeltaMeasure{ α : ref mut α_ref, ref x }| { |
274 } |
275 // Get weight of spike in μ2, zero if out of bounds. |
275 debug_assert_eq!(self.len(), μ2.len()); |
276 let β = μ2.spikes.get(μ2_get).map_or(F::ZERO, DeltaMeasure::get_mass); |
276 let mut dest = 0; |
277 μ2_get += 1; |
277 for i in 0..self.len() { |
278 |
278 let α = self[i].α; |
279 if *α_ref == F::ZERO && β == F::ZERO { |
279 let α_new = θ * α - ζ * μ2[i].α; |
280 // Prune |
280 if dest < i { |
281 true |
281 μ2[dest] = DeltaMeasure{ x : self[i].x.clone(), α }; |
|
282 self[dest] = DeltaMeasure{ x : self[i].x.clone(), α : α_new }; |
282 } else { |
283 } else { |
283 // Save self weight |
284 μ2[i].α = α; |
284 let α = *α_ref; |
285 self[i].α = α_new; |
285 // Modify self |
286 } |
286 *α_ref = θ * α - ζ * β; |
287 dest += 1; |
287 // Make copy of old self weight in μ2 |
288 } |
288 let δ = DeltaMeasure{ α, x : x.clone() }; |
289 self.spikes.truncate(dest); |
289 match μ2.spikes.get_mut(μ2_insert) { |
290 μ2.spikes.truncate(dest); |
290 Some(replace) => { |
|
291 *replace = δ; |
|
292 }, |
|
293 None => { |
|
294 debug_assert_eq!(μ2.len(), μ2_insert); |
|
295 μ2.spikes.push(δ); |
|
296 }, |
|
297 } |
|
298 μ2_insert += 1; |
|
299 // Keep |
|
300 false |
|
301 } |
|
302 }); |
|
303 // Truncate μ2 to same length as self. |
|
304 μ2.spikes.truncate(μ2_insert); |
|
305 debug_assert_eq!(μ2.len(), self.len()); |
|
306 } |
291 } |
307 } |
292 } |
308 |
293 |
309 impl<Domain, F : Float> DiscreteMeasure<Domain, F> { |
294 impl<Domain, F : Float> DiscreteMeasure<Domain, F> { |
310 /// Prune all spikes with mass absolute value less than the given `tolerance`. |
295 /// Prune all spikes with mass absolute value less than the given `tolerance`. |
325 /// Sets the masses of the spikes from the values of a [`DVector`]. |
310 /// Sets the masses of the spikes from the values of a [`DVector`]. |
326 pub fn set_masses_dvector(&mut self, x : &DVector<F::MixedType>) { |
311 pub fn set_masses_dvector(&mut self, x : &DVector<F::MixedType>) { |
327 self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α))); |
312 self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α))); |
328 } |
313 } |
329 |
314 |
330 /// Extracts the masses of the spikes as a [`Vec`]. |
315 // /// Extracts the masses of the spikes as a [`Vec`]. |
331 pub fn masses_vec(&self) -> Vec<F::MixedType> { |
316 // pub fn masses_vec(&self) -> Vec<F::MixedType> { |
332 self.iter_masses() |
317 // self.iter_masses() |
333 .map(|α| α.to_nalgebra_mixed()) |
318 // .map(|α| α.to_nalgebra_mixed()) |
334 .collect() |
319 // .collect() |
335 } |
320 // } |
336 |
321 |
337 /// Sets the masses of the spikes from the values of a [`Vec`]. |
322 // /// Sets the masses of the spikes from the values of a [`Vec`]. |
338 pub fn set_masses_vec(&mut self, x : &Vec<F::MixedType>) { |
323 // pub fn set_masses_vec(&mut self, x : &Vec<F::MixedType>) { |
339 self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α))); |
324 // self.set_masses(x.iter().map(|&α| F::from_nalgebra_mixed(α))); |
340 } |
325 // } |
341 } |
326 } |
342 |
327 |
343 // impl<Domain, F :Num> Index<usize> for DiscreteMeasure<Domain, F> { |
328 // impl<Domain, F :Num> Index<usize> for DiscreteMeasure<Domain, F> { |
344 // type Output = DeltaMeasure<Domain, F>; |
329 // type Output = DeltaMeasure<Domain, F>; |
345 // #[inline] |
330 // #[inline] |