119 // } |
119 // } |
120 |
120 |
121 /// Prune all spikes with zero mass. |
121 /// Prune all spikes with zero mass. |
122 #[inline] |
122 #[inline] |
123 pub fn prune(&mut self) { |
123 pub fn prune(&mut self) { |
124 self.spikes.retain(|δ| δ.α != F::ZERO); |
124 self.prune_by(|δ| δ.α != F::ZERO); |
|
125 } |
|
126 |
|
127 /// Prune spikes by the predicate `g`. |
|
128 #[inline] |
|
129 pub fn prune_by<G : FnMut(&DeltaMeasure<Domain, F>) -> bool>(&mut self, g : G) { |
|
130 self.spikes.retain(g); |
125 } |
131 } |
126 |
132 |
127 /// Add the spikes produced by `iter` to this measure. |
133 /// Add the spikes produced by `iter` to this measure. |
128 #[inline] |
134 #[inline] |
129 pub fn extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( |
135 pub fn extend<I : Iterator<Item=DeltaMeasure<Domain, F>>>( |
135 |
141 |
136 /// Add a spike to the measure |
142 /// Add a spike to the measure |
137 #[inline] |
143 #[inline] |
138 pub fn push(&mut self, δ : DeltaMeasure<Domain, F>) { |
144 pub fn push(&mut self, δ : DeltaMeasure<Domain, F>) { |
139 self.spikes.push(δ); |
145 self.spikes.push(δ); |
|
146 } |
|
147 |
|
148 /// Iterate over triples of masses and locations of two discrete measures, which are assumed |
|
149 /// to have equal locations of same spike indices. |
|
150 pub fn both_matching<'a>(&'a self, other : &'a DiscreteMeasure<Domain, F>) -> |
|
151 impl Iterator<Item=(F, F, &'a Domain)> { |
|
152 let m = self.len().max(other.len()); |
|
153 self.iter_spikes().map(Some).chain(std::iter::repeat(None)) |
|
154 .zip(other.iter_spikes().map(Some).chain(std::iter::repeat(None))) |
|
155 .take(m) |
|
156 .map(|(oδ, orδ)| { |
|
157 match (oδ, orδ) { |
|
158 (Some(δ), Some(rδ)) => (δ.α, rδ.α, &δ.x), // Assumed δ.x=rδ.x |
|
159 (Some(δ), None) => (δ.α, F::ZERO, &δ.x), |
|
160 (None, Some(rδ)) => (F::ZERO, rδ.α, &rδ.x), |
|
161 (None, None) => panic!("This cannot happen!"), |
|
162 } |
|
163 }) |
|
164 } |
|
165 |
|
166 /// Subtract `other` from `self`, assuming equal locations of same spike indices |
|
167 pub fn sub_matching(&self, other : &DiscreteMeasure<Domain, F>) -> DiscreteMeasure<Domain, F> |
|
168 where Domain : Clone { |
|
169 self.both_matching(other) |
|
170 .map(|(α, β, x)| (x.clone(), α - β)) |
|
171 .collect() |
|
172 } |
|
173 |
|
174 /// Add `other` to `self`, assuming equal locations of same spike indices |
|
175 pub fn add_matching(&self, other : &DiscreteMeasure<Domain, F>) -> DiscreteMeasure<Domain, F> |
|
176 where Domain : Clone { |
|
177 self.both_matching(other) |
|
178 .map(|(α, β, x)| (x.clone(), α + β)) |
|
179 .collect() |
|
180 } |
|
181 |
|
182 /// Calculate the Radon-norm distance of `self` to `other`, |
|
183 /// assuming equal locations of same spike indices. |
|
184 pub fn dist_matching(&self, other : &DiscreteMeasure<Domain, F>) -> F where F : Float { |
|
185 self.both_matching(other) |
|
186 .map(|(α, β, _)| (α-β).abs()) |
|
187 .sum() |
140 } |
188 } |
141 } |
189 } |
142 |
190 |
143 impl<Domain, F : Num> IntoIterator for DiscreteMeasure<Domain, F> { |
191 impl<Domain, F : Num> IntoIterator for DiscreteMeasure<Domain, F> { |
144 type Item = DeltaMeasure<Domain, F>; |
192 type Item = DeltaMeasure<Domain, F>; |