| 186 }; |
186 }; |
| 187 let mut stats = IterInfo::new(); |
187 let mut stats = IterInfo::new(); |
| 188 |
188 |
| 189 // Run the algorithm |
189 // Run the algorithm |
| 190 for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) { |
190 for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) { |
| 191 let maybe_μ_base = config.merge_now(&state).then(|| μ.clone()); |
191 let maybe_μ_base = config.if_merge_now(&state, |_| μ.clone()); |
| 192 let μ_base_len = μ.len(); |
192 let μ_base_len = μ.len(); |
| 193 |
193 |
| 194 // Calculate smooth part of surrogate model. |
194 // Calculate smooth part of surrogate model. |
| 195 let mut τv = f.differential(&μ) * τ; |
195 let mut τv = f.differential(&μ) * τ; |
| 196 |
196 |
| 199 |
199 |
| 200 stats.inserted += μ.len() - μ_base_len; |
200 stats.inserted += μ.len() - μ_base_len; |
| 201 |
201 |
| 202 // Prune and possibly merge spikes |
202 // Prune and possibly merge spikes |
| 203 if let Some(μ_base) = maybe_μ_base { |
203 if let Some(μ_base) = maybe_μ_base { |
| 204 stats.merged += prox_penalty.merge_spikes( |
204 config.if_merge_now(&state, |ins| { |
| 205 &mut μ, |
205 stats.merged += prox_penalty.merge_spikes( |
| 206 &mut τv, |
206 &mut μ, |
| 207 &μ_base, |
207 &mut τv, |
| 208 τ, |
208 &μ_base, |
| 209 ε, |
209 τ, |
| 210 config, |
210 ε, |
| 211 ®, |
211 ins, |
| 212 Some(|μ̃: &RNDM<N, F>| f.apply(μ̃)), |
212 ®, |
| 213 ); |
213 Some(|μ̃: &RNDM<N, F>| f.apply(μ̃)), |
| |
214 ) |
| |
215 }); |
| 214 } |
216 } |
| 215 |
217 |
| 216 stats.pruned += prune_with_stats(&mut μ); |
218 stats.pruned += prune_with_stats(&mut μ); |
| 217 |
219 |
| 218 // Do extra weight optimisation step heuristic |
220 // Do extra weight optimisation step heuristic |
| 307 prox_penalty.insert_and_reweigh(&mut μ, &mut τv, τ, ε, config, ®, &state, &mut stats)?; |
309 prox_penalty.insert_and_reweigh(&mut μ, &mut τv, τ, ε, config, ®, &state, &mut stats)?; |
| 308 |
310 |
| 309 stats.inserted += μ.len() - μ_base_len; |
311 stats.inserted += μ.len() - μ_base_len; |
| 310 |
312 |
| 311 // (Do not) merge spikes. |
313 // (Do not) merge spikes. |
| 312 if config.merge_now(&state) && !warned_merging { |
314 if !warned_merging { |
| 313 let err = format!("Merging not supported for μFISTA"); |
315 config.if_merge_now(&state, |_| { |
| 314 println!("{}", err.red()); |
316 let err = format!("Merging not supported for μFISTA"); |
| 315 warned_merging = true; |
317 println!("{}", err.red()); |
| |
318 warned_merging = true; |
| |
319 }); |
| 316 } |
320 } |
| 317 |
321 |
| 318 // Do extra weight optimisation step heuristic |
322 // Do extra weight optimisation step heuristic |
| 319 for _ in 0..config.extra_weight_optimisation_steps { |
323 for _ in 0..config.extra_weight_optimisation_steps { |
| 320 τv = f.differential(&μ) * τ; |
324 τv = f.differential(&μ) * τ; |