| 77 [`crate::subproblem::InnerSettings`] in [`InsertionConfig::inner`]. |
77 [`crate::subproblem::InnerSettings`] in [`InsertionConfig::inner`]. |
| 78 */ |
78 */ |
| 79 |
79 |
| 80 use crate::domain::{AdmissibleDomain, FullSpace}; |
80 use crate::domain::{AdmissibleDomain, FullSpace}; |
| 81 use crate::measures::merging::SpikeMerging; |
81 use crate::measures::merging::SpikeMerging; |
| 82 use crate::measures::{DiscreteMeasure, RNDM}; |
82 use crate::measures::DiscreteMeasure; |
| 83 use crate::plot::Plotter; |
83 use crate::plot::Plotter; |
| 84 pub use crate::prox_penalty::{InsertionConfig, ProxPenalty, StepLengthBound}; |
84 pub use crate::prox_penalty::{InsertionConfig, ProxPenalty, StepLengthBound}; |
| 85 use crate::regularisation::RegTerm; |
85 use crate::regularisation::RegTerm; |
| 86 use crate::types::*; |
86 use crate::types::*; |
| 87 use alg_tools::error::DynResult; |
87 use alg_tools::error::DynResult; |
| 88 use alg_tools::instance::Instance; |
88 use alg_tools::instance::Instance; |
| 89 use alg_tools::iterate::AlgIteratorFactory; |
89 use alg_tools::iterate::AlgIteratorFactory; |
| |
90 use alg_tools::linops::Space; |
| 90 use alg_tools::mapping::DifferentiableMapping; |
91 use alg_tools::mapping::DifferentiableMapping; |
| 91 use alg_tools::nalgebra_support::ToNalgebraRealField; |
92 use alg_tools::nalgebra_support::ToNalgebraRealField; |
| 92 use colored::Colorize; |
93 use colored::Colorize; |
| 93 use measures::DeltaMeasure; |
94 use measures::DeltaMeasure; |
| 94 use numeric_literals::replace_float_literals; |
95 use numeric_literals::replace_float_literals; |
| 111 fn default() -> Self { |
112 fn default() -> Self { |
| 112 FBConfig { τ0: 0.99, σp0: 0.99, insertion: Default::default() } |
113 FBConfig { τ0: 0.99, σp0: 0.99, insertion: Default::default() } |
| 113 } |
114 } |
| 114 } |
115 } |
| 115 |
116 |
| 116 pub(crate) fn prune_with_stats<F: Float, const N: usize>( |
117 pub(crate) fn prune_with_stats<U: Space, F: Float>( |
| 117 μ: &mut RNDM<N, F>, |
118 μ: &mut DiscreteMeasure<U, F>, |
| 118 until: usize, |
119 until: usize, |
| 119 ) -> usize { |
120 ) -> usize { |
| 120 let n_before_prune = μ.len(); |
121 let n_before_prune = μ.len(); |
| 121 μ.prune_until(until); |
122 μ.prune_until(until); |
| 122 debug_assert!(μ.len() <= n_before_prune); |
123 debug_assert!(μ.len() <= n_before_prune); |
| 123 n_before_prune - μ.len() |
124 n_before_prune - μ.len() |
| 124 } |
125 } |
| 125 |
126 |
| 126 #[replace_float_literals(F::cast_from(literal))] |
127 #[replace_float_literals(F::cast_from(literal))] |
| 127 pub(crate) fn postprocess<F: Float, Dat: Fn(&RNDM<N, F>) -> F, const N: usize>( |
128 pub(crate) fn postprocess<F: Float, U, Dat>( |
| 128 mut μ: RNDM<N, F>, |
129 mut μ: DiscreteMeasure<U, F>, |
| 129 config: &InsertionConfig<F>, |
130 config: &InsertionConfig<F>, |
| 130 f: Dat, |
131 f: Dat, |
| 131 ) -> DynResult<RNDM<N, F>> |
132 ) -> DynResult<DiscreteMeasure<U, F>> |
| 132 where |
133 where |
| 133 RNDM<N, F>: SpikeMerging<F>, |
134 Dat: Fn(&DiscreteMeasure<U, F>) -> F, |
| 134 for<'a> &'a RNDM<N, F>: Instance<RNDM<N, F>>, |
135 U: Space + Clone, |
| |
136 DiscreteMeasure<U, F>: SpikeMerging<F>, |
| |
137 for<'a> &'a DiscreteMeasure<U, F>: Instance<DiscreteMeasure<U, F>>, |
| 135 { |
138 { |
| 136 //μ.merge_spikes_fitness(config.final_merging_method(), |μ̃| f.apply(μ̃), |&v| v); |
139 //μ.merge_spikes_fitness(config.final_merging_method(), |μ̃| f.apply(μ̃), |&v| v); |
| 137 μ.merge_spikes_fitness(config.final_merging_method(), f, |&v| v); |
140 μ.merge_spikes_fitness(config.final_merging_method(), f, |&v| v); |
| 138 μ.prune(); |
141 μ.prune(); |
| 139 Ok(μ) |
142 Ok(μ) |
| 149 /// |
152 /// |
| 150 /// For details on the mathematical formulation, see the [module level](self) documentation. |
153 /// For details on the mathematical formulation, see the [module level](self) documentation. |
| 151 /// |
154 /// |
| 152 /// Returns the final iterate. |
155 /// Returns the final iterate. |
| 153 #[replace_float_literals(F::cast_from(literal))] |
156 #[replace_float_literals(F::cast_from(literal))] |
| 154 pub fn pointsource_fb_dom<F, I, Dat, Reg, P, Plot, const N: usize>( |
157 pub fn pointsource_fb_dom<F, I, Dat, Reg, P, Plot, U>( |
| 155 f: &Dat, |
158 f: &Dat, |
| 156 reg: &Reg, |
159 reg: &Reg, |
| 157 prox_penalty: &P, |
160 prox_penalty: &P, |
| 158 fbconfig: &FBConfig<F>, |
161 fbconfig: &FBConfig<F>, |
| 159 iterator: I, |
162 iterator: I, |
| 160 mut plotter: Plot, |
163 mut plotter: Plot, |
| 161 μ0: Option<RNDM<N, F>>, |
164 μ0: Option<DiscreteMeasure<U, F>>, |
| 162 domain: &mut impl AdmissibleDomain<Loc<N, F>>, |
165 domain: &mut impl AdmissibleDomain<U>, |
| 163 ) -> DynResult<RNDM<N, F>> |
166 ) -> DynResult<DiscreteMeasure<U, F>> |
| 164 where |
167 where |
| |
168 U: Space + Clone, |
| 165 F: Float + ToNalgebraRealField, |
169 F: Float + ToNalgebraRealField, |
| 166 I: AlgIteratorFactory<IterInfo<F>>, |
170 I: AlgIteratorFactory<IterInfo<F>>, |
| 167 RNDM<N, F>: SpikeMerging<F>, |
171 DiscreteMeasure<U, F>: SpikeMerging<F>, |
| 168 Dat: DifferentiableMapping<RNDM<N, F>, Codomain = F>, |
172 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>, |
| 169 Dat::DerivativeDomain: ClosedMul<F>, |
173 Dat::DerivativeDomain: ClosedMul<F>, |
| 170 Reg: RegTerm<Loc<N, F>, F>, |
174 Reg: RegTerm<U, F>, |
| 171 P: ProxPenalty<Loc<N, F>, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
175 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
| 172 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, RNDM<N, F>>, |
176 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>, |
| 173 { |
177 { |
| 174 // Set up parameters |
178 // Set up parameters |
| 175 let config = &fbconfig.insertion; |
179 let config = &fbconfig.insertion; |
| 176 let τ = fbconfig.τ0 / prox_penalty.step_length_bound(&f)?; |
180 let τ = fbconfig.τ0 / prox_penalty.step_length_bound(&f)?; |
| 177 // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled |
181 // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled |
| 181 |
185 |
| 182 // Initialise iterates |
186 // Initialise iterates |
| 183 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
187 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
| 184 |
188 |
| 185 // Statistics |
189 // Statistics |
| 186 let full_stats = |μ: &RNDM<N, F>, ε, stats| IterInfo { |
190 let full_stats = |μ: &DiscreteMeasure<U, F>, ε, stats| IterInfo { |
| 187 value: f.apply(μ) + reg.apply(μ), |
191 value: f.apply(μ) + reg.apply(μ), |
| 188 n_spikes: μ.len(), |
192 n_spikes: μ.len(), |
| 189 ε, |
193 ε, |
| 190 //postprocessing: config.postprocessing.then(|| μ.clone()), |
194 //postprocessing: config.postprocessing.then(|| μ.clone()), |
| 191 ..stats |
195 ..stats |
| 265 //postprocess(μ_prev, config, f) |
269 //postprocess(μ_prev, config, f) |
| 266 postprocess(μ, config, |μ̃| f.apply(μ̃) + reg.apply(μ̃)) |
270 postprocess(μ, config, |μ̃| f.apply(μ̃) + reg.apply(μ̃)) |
| 267 } |
271 } |
| 268 |
272 |
| 269 #[deprecated] |
273 #[deprecated] |
| 270 pub fn pointsource_fb_reg<F, I, Dat, Reg, P, Plot, const N: usize>( |
274 pub fn pointsource_fb_reg<F, U, I, Dat, Reg, P, Plot>( |
| 271 f: &Dat, |
275 f: &Dat, |
| 272 reg: &Reg, |
276 reg: &Reg, |
| 273 prox_penalty: &P, |
277 prox_penalty: &P, |
| 274 fbconfig: &FBConfig<F>, |
278 fbconfig: &FBConfig<F>, |
| 275 iterator: I, |
279 iterator: I, |
| 276 plotter: Plot, |
280 plotter: Plot, |
| 277 μ0: Option<RNDM<N, F>>, |
281 μ0: Option<DiscreteMeasure<U, F>>, |
| 278 ) -> DynResult<RNDM<N, F>> |
282 ) -> DynResult<DiscreteMeasure<U, F>> |
| 279 where |
283 where |
| |
284 U: Space + Clone, |
| 280 F: Float + ToNalgebraRealField, |
285 F: Float + ToNalgebraRealField, |
| 281 I: AlgIteratorFactory<IterInfo<F>>, |
286 I: AlgIteratorFactory<IterInfo<F>>, |
| 282 RNDM<N, F>: SpikeMerging<F>, |
287 DiscreteMeasure<U, F>: SpikeMerging<F>, |
| 283 Dat: DifferentiableMapping<RNDM<N, F>, Codomain = F>, |
288 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>, |
| 284 Dat::DerivativeDomain: ClosedMul<F>, |
289 Dat::DerivativeDomain: ClosedMul<F>, |
| 285 Reg: RegTerm<Loc<N, F>, F>, |
290 Reg: RegTerm<U, F>, |
| 286 P: ProxPenalty<Loc<N, F>, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
291 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
| 287 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, RNDM<N, F>>, |
292 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>, |
| 288 { |
293 { |
| 289 pointsource_fb_dom( |
294 pointsource_fb_dom( |
| 290 f, |
295 f, |
| 291 reg, |
296 reg, |
| 292 prox_penalty, |
297 prox_penalty, |
| 308 /// |
313 /// |
| 309 /// For details on the mathematical formulation, see the [module level](self) documentation. |
314 /// For details on the mathematical formulation, see the [module level](self) documentation. |
| 310 /// |
315 /// |
| 311 /// Returns the final iterate. |
316 /// Returns the final iterate. |
| 312 #[replace_float_literals(F::cast_from(literal))] |
317 #[replace_float_literals(F::cast_from(literal))] |
| 313 pub fn pointsource_fista_reg<F, I, Dat, Reg, P, Plot, const N: usize>( |
318 pub fn pointsource_fista_reg<F, U, I, Dat, Reg, P, Plot>( |
| 314 f: &Dat, |
319 f: &Dat, |
| 315 reg: &Reg, |
320 reg: &Reg, |
| 316 prox_penalty: &P, |
321 prox_penalty: &P, |
| 317 fbconfig: &FBConfig<F>, |
322 fbconfig: &FBConfig<F>, |
| 318 iterator: I, |
323 iterator: I, |
| 319 mut plotter: Plot, |
324 mut plotter: Plot, |
| 320 μ0: Option<RNDM<N, F>>, |
325 μ0: Option<DiscreteMeasure<U, F>>, |
| 321 ) -> DynResult<RNDM<N, F>> |
326 ) -> DynResult<DiscreteMeasure<U, F>> |
| 322 where |
327 where |
| |
328 U: Space + Clone, |
| 323 F: Float + ToNalgebraRealField, |
329 F: Float + ToNalgebraRealField, |
| 324 I: AlgIteratorFactory<IterInfo<F>>, |
330 I: AlgIteratorFactory<IterInfo<F>>, |
| 325 RNDM<N, F>: SpikeMerging<F>, |
331 DiscreteMeasure<U, F>: SpikeMerging<F>, |
| 326 Dat: DifferentiableMapping<RNDM<N, F>, Codomain = F>, |
332 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>, |
| 327 Dat::DerivativeDomain: ClosedMul<F>, |
333 Dat::DerivativeDomain: ClosedMul<F>, |
| 328 Reg: RegTerm<Loc<N, F>, F>, |
334 Reg: RegTerm<U, F>, |
| 329 P: ProxPenalty<Loc<N, F>, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
335 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
| 330 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, RNDM<N, F>>, |
336 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>, |
| 331 { |
337 { |
| 332 // Set up parameters |
338 // Set up parameters |
| 333 let config = &fbconfig.insertion; |
339 let config = &fbconfig.insertion; |
| 334 let τ = fbconfig.τ0 / prox_penalty.step_length_bound(&f)?; |
340 let τ = fbconfig.τ0 / prox_penalty.step_length_bound(&f)?; |
| 335 let mut λ = 1.0; |
341 let mut λ = 1.0; |
| 342 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
348 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
| 343 let mut μ_prev = μ.clone(); |
349 let mut μ_prev = μ.clone(); |
| 344 let mut warned_merging = false; |
350 let mut warned_merging = false; |
| 345 |
351 |
| 346 // Statistics |
352 // Statistics |
| 347 let full_stats = |ν: &RNDM<N, F>, ε, stats| IterInfo { |
353 let full_stats = |ν: &DiscreteMeasure<U, F>, ε, stats| IterInfo { |
| 348 value: f.apply(ν) + reg.apply(ν), |
354 value: f.apply(ν) + reg.apply(ν), |
| 349 n_spikes: ν.len(), |
355 n_spikes: ν.len(), |
| 350 ε, |
356 ε, |
| 351 // postprocessing: config.postprocessing.then(|| ν.clone()), |
357 // postprocessing: config.postprocessing.then(|| ν.clone()), |
| 352 ..stats |
358 ..stats |