src/fb.rs

changeset 93
8f1e57821d76
parent 91
47d495348e38
child 98
b9818eb24b47
equal deleted inserted replaced
92:759634edb536 93:8f1e57821d76
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
217 &μ_base, 221 &μ_base,
218 τ, 222 τ,
219 ε, 223 ε,
220 ins, 224 ins,
221 &reg, 225 &reg,
222 Some(|μ̃: &RNDM<N, F>| f.apply(μ̃) + reg.apply(μ̃)), 226 Some(|μ̃: &DiscreteMeasure<U, F>| f.apply(μ̃) + reg.apply(μ̃)),
223 ); 227 );
224 228
225 // Prune. Do not prune new insertions on first round. 229 // Prune. Do not prune new insertions on first round.
226 stats.pruned += prune_with_stats(&mut μ, μ_base_len); 230 stats.pruned += prune_with_stats(&mut μ, μ_base_len);
227 231
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

mercurial