src/fb.rs

changeset 98
b9818eb24b47
parent 93
8f1e57821d76
equal deleted inserted replaced
97:f91f382ba4ae 98:b9818eb24b47
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; 82 use crate::measures::{DiscreteMeasure, Radon};
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::bounds::MinMaxMapping;
87 use alg_tools::error::DynResult; 88 use alg_tools::error::DynResult;
88 use alg_tools::instance::Instance; 89 use alg_tools::instance::Instance;
89 use alg_tools::iterate::AlgIteratorFactory; 90 use alg_tools::iterate::AlgIteratorFactory;
90 use alg_tools::linops::Space; 91 use alg_tools::linops::Space;
91 use alg_tools::mapping::DifferentiableMapping; 92 use alg_tools::mapping::DifferentiableMapping;
92 use alg_tools::nalgebra_support::ToNalgebraRealField; 93 use alg_tools::nalgebra_support::ToNalgebraRealField;
94 use alg_tools::norms::Norm;
93 use colored::Colorize; 95 use colored::Colorize;
94 use measures::DeltaMeasure; 96 use measures::DeltaMeasure;
95 use numeric_literals::replace_float_literals; 97 use numeric_literals::replace_float_literals;
96 use serde::{Deserialize, Serialize}; 98 use serde::{Deserialize, Serialize};
97 99
166 ) -> DynResult<DiscreteMeasure<U, F>> 168 ) -> DynResult<DiscreteMeasure<U, F>>
167 where 169 where
168 U: Space + Clone, 170 U: Space + Clone,
169 F: Float + ToNalgebraRealField, 171 F: Float + ToNalgebraRealField,
170 I: AlgIteratorFactory<IterInfo<F>>, 172 I: AlgIteratorFactory<IterInfo<F>>,
171 DiscreteMeasure<U, F>: SpikeMerging<F>, 173 DiscreteMeasure<U, F>: SpikeMerging<F> + Norm<Radon, F>,
172 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>, 174 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>,
173 Dat::DerivativeDomain: ClosedMul<F>, 175 Dat::DerivativeDomain: ClosedMul<F> + MinMaxMapping<U, F>,
174 Reg: RegTerm<U, F>, 176 Reg: RegTerm<U, F>,
175 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, 177 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>,
176 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>, 178 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>,
177 { 179 {
178 // Set up parameters 180 // Set up parameters
185 187
186 // Initialise iterates 188 // Initialise iterates
187 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); 189 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new());
188 190
189 // Statistics 191 // Statistics
190 let full_stats = |μ: &DiscreteMeasure<U, F>, ε, stats| IterInfo { 192 let full_stats =
191 value: f.apply(μ) + reg.apply(μ), 193 |μ: &DiscreteMeasure<U, F>, τv: &mut Dat::DerivativeDomain, ε, stats| IterInfo {
192 n_spikes: μ.len(), 194 value: f.apply(μ) + reg.apply(μ),
193 ε, 195 n_spikes: μ.len(),
194 //postprocessing: config.postprocessing.then(|| μ.clone()), 196 μ_norm: μ.norm(Radon),
195 ..stats 197 ε,
196 }; 198 discrepancy: Some(reg.discrepancy(τv, τ, ε, μ, config)),
199 //postprocessing: config.postprocessing.then(|| μ.clone()),
200 ..stats
201 };
197 let mut stats = IterInfo::new(); 202 let mut stats = IterInfo::new();
198 203
204 // Calculate smooth part of surrogate model.
205 let mut τv = f.differential(&μ) * τ;
206
199 // Run the algorithm 207 // Run the algorithm
200 for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) { 208 for state in iterator.iter_init(|| full_stats(&μ, &mut τv, ε, stats.clone())) {
201 let maybe_μ_base = config.if_merge_now_check(&state, || μ.clone()); 209 let maybe_μ_base = config.if_merge_now_check(&state, || μ.clone());
202 let μ_base_len = μ.len(); 210 let μ_base_len = μ.len();
203
204 // Calculate smooth part of surrogate model.
205 let mut τv = f.differential(&μ) * τ;
206 211
207 // Do spike insertiona nd finite-dimensional weight optimisation 212 // Do spike insertiona nd finite-dimensional weight optimisation
208 prox_penalty.insert_and_reweigh(&mut μ, &mut τv, τ, ε, config, &reg, &state, &mut stats)?; 213 prox_penalty.insert_and_reweigh(&mut μ, &mut τv, τ, ε, config, &reg, &state, &mut stats)?;
209 214
210 stats.inserted += μ.len() - μ_base_len; 215 stats.inserted += μ.len() - μ_base_len;
254 } 259 }
255 260
256 let iter = state.iteration(); 261 let iter = state.iteration();
257 stats.this_iters += 1; 262 stats.this_iters += 1;
258 263
264 // Calculate smooth part of surrogate model.
265 τv = f.differential(&μ) * τ;
266
259 // Give statistics if needed 267 // Give statistics if needed
260 state.if_verbose(|| { 268 state.if_verbose(|| {
261 plotter.plot_spikes(iter, None, Some(&τv), &μ); 269 plotter.plot_spikes(iter, None, Some(&τv), &μ);
262 full_stats(&μ, ε, std::mem::replace(&mut stats, IterInfo::new())) 270 full_stats(
271 &μ,
272 &mut τv,
273 ε,
274 std::mem::replace(&mut stats, IterInfo::new()),
275 )
263 }); 276 });
264 277
265 // Update main tolerance for next iteration 278 // Update main tolerance for next iteration
266 ε = tolerance.update(ε, iter); 279 ε = tolerance.update(ε, iter);
267 } 280 }
282 ) -> DynResult<DiscreteMeasure<U, F>> 295 ) -> DynResult<DiscreteMeasure<U, F>>
283 where 296 where
284 U: Space + Clone, 297 U: Space + Clone,
285 F: Float + ToNalgebraRealField, 298 F: Float + ToNalgebraRealField,
286 I: AlgIteratorFactory<IterInfo<F>>, 299 I: AlgIteratorFactory<IterInfo<F>>,
287 DiscreteMeasure<U, F>: SpikeMerging<F>, 300 DiscreteMeasure<U, F>: SpikeMerging<F> + Norm<Radon, F>,
288 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>, 301 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>,
289 Dat::DerivativeDomain: ClosedMul<F>, 302 Dat::DerivativeDomain: ClosedMul<F> + MinMaxMapping<U, F>,
290 Reg: RegTerm<U, F>, 303 Reg: RegTerm<U, F>,
291 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, 304 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>,
292 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>, 305 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>,
293 { 306 {
294 pointsource_fb_dom( 307 pointsource_fb_dom(
328 U: Space + Clone, 341 U: Space + Clone,
329 F: Float + ToNalgebraRealField, 342 F: Float + ToNalgebraRealField,
330 I: AlgIteratorFactory<IterInfo<F>>, 343 I: AlgIteratorFactory<IterInfo<F>>,
331 DiscreteMeasure<U, F>: SpikeMerging<F>, 344 DiscreteMeasure<U, F>: SpikeMerging<F>,
332 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>, 345 Dat: DifferentiableMapping<DiscreteMeasure<U, F>, Codomain = F>,
333 Dat::DerivativeDomain: ClosedMul<F>, 346 Dat::DerivativeDomain: ClosedMul<F> + MinMaxMapping<U, F>,
334 Reg: RegTerm<U, F>, 347 Reg: RegTerm<U, F>,
335 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, 348 P: ProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>,
336 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>, 349 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>,
337 { 350 {
338 // Set up parameters 351 // Set up parameters
348 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); 361 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new());
349 let mut μ_prev = μ.clone(); 362 let mut μ_prev = μ.clone();
350 let mut warned_merging = false; 363 let mut warned_merging = false;
351 364
352 // Statistics 365 // Statistics
353 let full_stats = |ν: &DiscreteMeasure<U, F>, ε, stats| IterInfo { 366 let full_stats = |ν: &DiscreteMeasure<U, F>,
367 maybe_τv: Option<&mut Dat::DerivativeDomain>,
368 ε,
369 stats| IterInfo {
354 value: f.apply(ν) + reg.apply(ν), 370 value: f.apply(ν) + reg.apply(ν),
355 n_spikes: ν.len(), 371 n_spikes: ν.len(),
356 ε, 372 ε,
373 discrepancy: maybe_τv.map(|τv| reg.discrepancy(τv, τ, ε, ν, config)),
357 // postprocessing: config.postprocessing.then(|| ν.clone()), 374 // postprocessing: config.postprocessing.then(|| ν.clone()),
358 ..stats 375 ..stats
359 }; 376 };
360 let mut stats = IterInfo::new(); 377 let mut stats = IterInfo::new();
361 378
362 // Run the algorithm 379 // Run the algorithm
363 for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) { 380 for state in iterator.iter_init(|| full_stats(&μ, None, ε, stats.clone())) {
364 let μ_base_len = μ.len(); 381 let μ_base_len = μ.len();
365 // Calculate smooth part of surrogate model. 382 // Calculate smooth part of surrogate model.
366 let mut τv = f.differential(&μ) * τ; 383 let mut τv = f.differential(&μ) * τ;
367 384
368 // Do spike insertiona nd finite-dimensional weight optimisation 385 // Do spike insertiona nd finite-dimensional weight optimisation
408 stats.this_iters += 1; 425 stats.this_iters += 1;
409 426
410 // Give statistics if needed 427 // Give statistics if needed
411 state.if_verbose(|| { 428 state.if_verbose(|| {
412 plotter.plot_spikes(iter, None, Some(&τv), &μ_prev); 429 plotter.plot_spikes(iter, None, Some(&τv), &μ_prev);
413 full_stats(&μ_prev, ε, std::mem::replace(&mut stats, IterInfo::new())) 430 full_stats(
431 &μ_prev,
432 Some(&mut τv),
433 ε,
434 std::mem::replace(&mut stats, IterInfo::new()),
435 )
414 }); 436 });
415 437
416 // Update main tolerance for next iteration 438 // Update main tolerance for next iteration
417 ε = tolerance.update(ε, iter); 439 ε = tolerance.update(ε, iter);
418 } 440 }

mercurial