Fri, 16 Jan 2026 19:39:22 -0500
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
| 32 | 1 | /*! |
| 2 | Solver for the point source localisation problem using a sliding | |
| 3 | forward-backward splitting method. | |
| 4 | */ | |
| 5 | ||
| 6 | use numeric_literals::replace_float_literals; | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
7 | use serde::{Deserialize, Serialize}; |
| 32 | 8 | //use colored::Colorize; |
| 9 | //use nalgebra::{DVector, DMatrix}; | |
| 10 | use itertools::izip; | |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
11 | use std::iter::Iterator; |
| 32 | 12 | |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
13 | use crate::fb::*; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
14 | use crate::forward_model::{BoundedCurvature, BoundedCurvatureGuess}; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
15 | use crate::measures::merging::SpikeMerging; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
16 | use crate::measures::{DiscreteMeasure, Radon, RNDM}; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
17 | use crate::plot::Plotter; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
18 | use crate::prox_penalty::{ProxPenalty, StepLengthBound}; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
19 | use crate::regularisation::SlidingRegTerm; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
20 | use crate::types::*; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
21 | use alg_tools::error::DynResult; |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
22 | use alg_tools::euclidean::Euclidean; |
|
62
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
23 | use alg_tools::instance::{ClosedSpace, Instance}; |
| 35 | 24 | use alg_tools::iterate::AlgIteratorFactory; |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
25 | use alg_tools::mapping::{DifferentiableMapping, DifferentiableRealMapping}; |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
26 | use alg_tools::nalgebra_support::ToNalgebraRealField; |
| 35 | 27 | use alg_tools::norms::Norm; |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
28 | use anyhow::ensure; |
| 35 | 29 | |
| 30 | /// Transport settings for [`pointsource_sliding_fb_reg`]. | |
| 31 | #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] | |
| 32 | #[serde(default)] | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
33 | pub struct TransportConfig<F: Float> { |
| 35 | 34 | /// Transport step length $θ$ normalised to $(0, 1)$. |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
35 | pub θ0: F, |
| 35 | 36 | /// Factor in $(0, 1)$ for decreasing transport to adapt to tolerance. |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
37 | pub adaptation: F, |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
38 | /// A posteriori transport tolerance multiplier (C_pos) |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
39 | pub tolerance_mult_con: F, |
| 35 | 40 | } |
| 41 | ||
| 42 | #[replace_float_literals(F::cast_from(literal))] | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
43 | impl<F: Float> TransportConfig<F> { |
| 35 | 44 | /// Check that the parameters are ok. Panics if not. |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
45 | pub fn check(&self) -> DynResult<()> { |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
46 | ensure!(self.θ0 > 0.0); |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
47 | ensure!(0.0 < self.adaptation && self.adaptation < 1.0); |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
48 | ensure!(self.tolerance_mult_con > 0.0); |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
49 | Ok(()) |
| 35 | 50 | } |
| 51 | } | |
| 52 | ||
| 53 | #[replace_float_literals(F::cast_from(literal))] | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
54 | impl<F: Float> Default for TransportConfig<F> { |
| 35 | 55 | fn default() -> Self { |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
56 | TransportConfig { θ0: 0.9, adaptation: 0.9, tolerance_mult_con: 100.0 } |
| 35 | 57 | } |
| 58 | } | |
| 32 | 59 | |
| 60 | /// Settings for [`pointsource_sliding_fb_reg`]. | |
| 61 | #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] | |
| 62 | #[serde(default)] | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
63 | pub struct SlidingFBConfig<F: Float> { |
| 32 | 64 | /// Step length scaling |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
65 | pub τ0: F, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
66 | // Auxiliary variable step length scaling for [`crate::sliding_pdps::pointsource_sliding_fb_pair`] |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
67 | pub σp0: F, |
| 35 | 68 | /// Transport parameters |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
69 | pub transport: TransportConfig<F>, |
| 32 | 70 | /// Generic parameters |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
71 | pub insertion: InsertionConfig<F>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
72 | /// Guess for curvature bound calculations. |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
73 | pub guess: BoundedCurvatureGuess, |
|
62
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
74 | /// Always adaptive step length |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
75 | pub always_adaptive_τ: bool, |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
76 | } |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
77 | |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
78 | impl<'a, F: Float> Into<FBConfig<F>> for &'a SlidingFBConfig<F> { |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
79 | fn into(self) -> FBConfig<F> { |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
80 | let SlidingFBConfig { τ0, σp0, insertion, always_adaptive_τ, .. } = *self; |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
81 | FBConfig { τ0, σp0, insertion, always_adaptive_τ } |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
82 | } |
| 32 | 83 | } |
| 84 | ||
| 85 | #[replace_float_literals(F::cast_from(literal))] | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
86 | impl<F: Float> Default for SlidingFBConfig<F> { |
| 32 | 87 | fn default() -> Self { |
| 88 | SlidingFBConfig { | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
89 | τ0: 0.99, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
90 | σp0: 0.99, |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
91 | transport: Default::default(), |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
92 | insertion: Default::default(), |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
93 | guess: BoundedCurvatureGuess::BetterThanZero, |
|
62
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
94 | always_adaptive_τ: false, |
| 32 | 95 | } |
| 96 | } | |
| 97 | } | |
| 98 | ||
| 35 | 99 | /// Internal type of adaptive transport step length calculation |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
100 | pub(crate) enum TransportStepLength<F: Float, G: Fn(F, F) -> F> { |
| 35 | 101 | /// Fixed, known step length |
| 44 | 102 | #[allow(dead_code)] |
| 35 | 103 | Fixed(F), |
| 104 | /// Adaptive step length, only wrt. maximum transport. | |
| 105 | /// Content of `l` depends on use case, while `g` calculates the step length from `l`. | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
106 | AdaptiveMax { l: F, max_transport: F, g: G }, |
| 35 | 107 | /// Adaptive step length. |
| 108 | /// Content of `l` depends on use case, while `g` calculates the step length from `l`. | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
109 | FullyAdaptive { l: F, max_transport: F, g: G }, |
| 35 | 110 | } |
| 111 | ||
|
41
b6bdb6cb4d44
Remove initial transport adaptation—it is not needed, after all
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
112 | /// Constrution of initial transport `γ1` from initial measure `μ` and `v=F'(μ)` |
|
b6bdb6cb4d44
Remove initial transport adaptation—it is not needed, after all
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
113 | /// with step lengh τ and transport step length `θ_or_adaptive`. |
| 32 | 114 | #[replace_float_literals(F::cast_from(literal))] |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
115 | pub(crate) fn initial_transport<F, G, D, const N: usize>( |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
116 | γ1: &mut RNDM<N, F>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
117 | μ: &mut RNDM<N, F>, |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
118 | τ: F, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
119 | θ_or_adaptive: &mut TransportStepLength<F, G>, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
120 | v: D, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
121 | ) -> (Vec<F>, RNDM<N, F>) |
| 35 | 122 | where |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
123 | F: Float + ToNalgebraRealField, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
124 | G: Fn(F, F) -> F, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
125 | D: DifferentiableRealMapping<N, F>, |
| 35 | 126 | { |
| 127 | use TransportStepLength::*; | |
| 128 | ||
| 129 | // Save current base point and shift μ to new positions. Idea is that | |
| 130 | // μ_base(_masses) = μ^k (vector of masses) | |
| 131 | // μ_base_minus_γ0 = μ^k - π_♯^0γ^{k+1} | |
| 132 | // γ1 = π_♯^1γ^{k+1} | |
| 133 | // μ = μ^{k+1} | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
134 | let μ_base_masses: Vec<F> = μ.iter_masses().collect(); |
| 35 | 135 | let mut μ_base_minus_γ0 = μ.clone(); // Weights will be set in the loop below. |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
136 | // Construct μ^{k+1} and π_♯^1γ^{k+1} initial candidates |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
137 | //let mut sum_norm_dv = 0.0; |
| 35 | 138 | let γ_prev_len = γ1.len(); |
| 139 | assert!(μ.len() >= γ_prev_len); | |
| 140 | γ1.extend(μ[γ_prev_len..].iter().cloned()); | |
| 141 | ||
| 142 | // Calculate initial transport and step length. | |
| 143 | // First calculate initial transported weights | |
| 144 | for (δ, ρ) in izip!(μ.iter_spikes(), γ1.iter_spikes_mut()) { | |
| 145 | // If old transport has opposing sign, the new transport will be none. | |
| 146 | ρ.α = if (ρ.α > 0.0 && δ.α < 0.0) || (ρ.α < 0.0 && δ.α > 0.0) { | |
| 147 | 0.0 | |
| 148 | } else { | |
| 149 | δ.α | |
| 150 | }; | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
151 | } |
| 35 | 152 | |
|
41
b6bdb6cb4d44
Remove initial transport adaptation—it is not needed, after all
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
153 | // Calculate transport rays. |
| 35 | 154 | match *θ_or_adaptive { |
| 155 | Fixed(θ) => { | |
| 156 | let θτ = τ * θ; | |
| 157 | for (δ, ρ) in izip!(μ.iter_spikes(), γ1.iter_spikes_mut()) { | |
| 158 | ρ.x = δ.x - v.differential(&δ.x) * (ρ.α.signum() * θτ); | |
| 159 | } | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
160 | } |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
161 | AdaptiveMax { l: ℓ_F, ref mut max_transport, g: ref calculate_θ } => { |
| 35 | 162 | *max_transport = max_transport.max(γ1.norm(Radon)); |
| 44 | 163 | let θτ = τ * calculate_θ(ℓ_F, *max_transport); |
| 35 | 164 | for (δ, ρ) in izip!(μ.iter_spikes(), γ1.iter_spikes_mut()) { |
| 165 | ρ.x = δ.x - v.differential(&δ.x) * (ρ.α.signum() * θτ); | |
| 166 | } | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
167 | } |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
168 | FullyAdaptive { l: ref mut adaptive_ℓ_F, ref mut max_transport, g: ref calculate_θ } => { |
| 35 | 169 | *max_transport = max_transport.max(γ1.norm(Radon)); |
| 44 | 170 | let mut θ = calculate_θ(*adaptive_ℓ_F, *max_transport); |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
171 | // Do two runs through the spikes to update θ, breaking if first run did not cause |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
172 | // a change. |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
173 | for _i in 0..=1 { |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
174 | let mut changes = false; |
| 35 | 175 | for (δ, ρ) in izip!(μ.iter_spikes(), γ1.iter_spikes_mut()) { |
| 176 | let dv_x = v.differential(&δ.x); | |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
177 | let g = &dv_x * (ρ.α.signum() * θ * τ); |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
178 | ρ.x = δ.x - g; |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
179 | let n = g.norm2(); |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
180 | if n >= F::EPSILON { |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
181 | // Estimate Lipschitz factor of ∇v |
| 44 | 182 | let this_ℓ_F = (dv_x - v.differential(&ρ.x)).norm2() / n; |
| 183 | *adaptive_ℓ_F = adaptive_ℓ_F.max(this_ℓ_F); | |
| 184 | θ = calculate_θ(*adaptive_ℓ_F, *max_transport); | |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
185 | changes = true |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
186 | } |
| 35 | 187 | } |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
188 | if !changes { |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
189 | break; |
| 35 | 190 | } |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
191 | } |
| 32 | 192 | } |
| 35 | 193 | } |
| 194 | ||
| 195 | // Set initial guess for μ=μ^{k+1}. | |
| 196 | for (δ, ρ, &β) in izip!(μ.iter_spikes_mut(), γ1.iter_spikes(), μ_base_masses.iter()) { | |
| 197 | if ρ.α.abs() > F::EPSILON { | |
| 198 | δ.x = ρ.x; | |
| 199 | //δ.α = ρ.α; // already set above | |
| 200 | } else { | |
| 201 | δ.α = β; | |
| 202 | } | |
| 203 | } | |
| 204 | // Calculate μ^k-π_♯^0γ^{k+1} and v̆ = A_*(A[μ_transported + μ_transported_base]-b) | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
205 | μ_base_minus_γ0.set_masses( |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
206 | μ_base_masses |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
207 | .iter() |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
208 | .zip(γ1.iter_masses()) |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
209 | .map(|(&a, b)| a - b), |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
210 | ); |
| 35 | 211 | (μ_base_masses, μ_base_minus_γ0) |
| 212 | } | |
| 213 | ||
| 214 | /// A posteriori transport adaptation. | |
| 215 | #[replace_float_literals(F::cast_from(literal))] | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
216 | pub(crate) fn aposteriori_transport<F, const N: usize>( |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
217 | γ1: &mut RNDM<N, F>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
218 | μ: &mut RNDM<N, F>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
219 | μ_base_minus_γ0: &mut RNDM<N, F>, |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
220 | μ_base_masses: &Vec<F>, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
221 | extra: Option<F>, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
222 | ε: F, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
223 | tconfig: &TransportConfig<F>, |
| 35 | 224 | ) -> bool |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
225 | where |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
226 | F: Float + ToNalgebraRealField, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
227 | { |
| 35 | 228 | // 1. If π_♯^1γ^{k+1} = γ1 has non-zero mass at some point y, but μ = μ^{k+1} does not, |
| 229 | // then the ansatz ∇w̃_x(y) = w^{k+1}(y) may not be satisfied. So set the mass of γ1 | |
| 230 | // at that point to zero, and retry. | |
| 231 | let mut all_ok = true; | |
| 232 | for (α_μ, α_γ1) in izip!(μ.iter_masses(), γ1.iter_masses_mut()) { | |
| 233 | if α_μ == 0.0 && *α_γ1 != 0.0 { | |
| 234 | all_ok = false; | |
| 235 | *α_γ1 = 0.0; | |
| 236 | } | |
| 237 | } | |
| 238 | ||
| 239 | // 2. Through bounding ∫ B_ω(y, z) dλ(x, y, z). | |
| 240 | // through the estimate ≤ C ‖Δ‖‖γ^{k+1}‖ for Δ := μ^{k+1}-μ^k-(π_♯^1-π_♯^0)γ^{k+1}, | |
| 241 | // which holds for some some C if the convolution kernel in 𝒟 has Lipschitz gradient. | |
| 242 | let nγ = γ1.norm(Radon); | |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
243 | let nΔ = μ_base_minus_γ0.norm(Radon) + μ.dist_matching(&γ1) + extra.unwrap_or(0.0); |
| 46 | 244 | let t = ε * tconfig.tolerance_mult_con; |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
245 | if nγ * nΔ > t { |
| 35 | 246 | // Since t/(nγ*nΔ)<1, and the constant tconfig.adaptation < 1, |
| 247 | // this will guarantee that eventually ‖γ‖ decreases sufficiently that we | |
| 248 | // will not enter here. | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
249 | *γ1 *= tconfig.adaptation * t / (nγ * nΔ); |
| 35 | 250 | all_ok = false |
| 251 | } | |
| 252 | ||
| 253 | if !all_ok { | |
| 254 | // Update weights for μ_base_minus_γ0 = μ^k - π_♯^0γ^{k+1} | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
255 | μ_base_minus_γ0.set_masses( |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
256 | μ_base_masses |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
257 | .iter() |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
258 | .zip(γ1.iter_masses()) |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
259 | .map(|(&a, b)| a - b), |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
260 | ); |
| 35 | 261 | } |
| 262 | ||
| 263 | all_ok | |
| 32 | 264 | } |
| 265 | ||
| 266 | /// Iteratively solve the pointsource localisation problem using sliding forward-backward | |
| 267 | /// splitting | |
| 268 | /// | |
| 35 | 269 | /// The parametrisation is as for [`pointsource_fb_reg`]. |
| 32 | 270 | /// Inertia is currently not supported. |
| 271 | #[replace_float_literals(F::cast_from(literal))] | |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
272 | pub fn pointsource_sliding_fb_reg<F, I, Dat, Reg, Plot, P, const N: usize>( |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
273 | f: &Dat, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
274 | reg: &Reg, |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
275 | prox_penalty: &P, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
276 | config: &SlidingFBConfig<F>, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
277 | iterator: I, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
278 | mut plotter: Plot, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
279 | μ0: Option<RNDM<N, F>>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
280 | ) -> DynResult<RNDM<N, F>> |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
281 | where |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
282 | F: Float + ToNalgebraRealField, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
283 | I: AlgIteratorFactory<IterInfo<F>>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
284 | Dat: DifferentiableMapping<RNDM<N, F>, Codomain = F> + BoundedCurvature<F>, |
|
62
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
285 | Dat::DerivativeDomain: |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
286 | ClosedMul<F> + DifferentiableRealMapping<N, F, Codomain = F> + ClosedSpace, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
287 | RNDM<N, F>: SpikeMerging<F>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
288 | Reg: SlidingRegTerm<Loc<N, F>, F>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
289 | P: ProxPenalty<Loc<N, F>, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
290 | Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, RNDM<N, F>>, |
|
62
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
291 | for<'a> &'a Dat::DerivativeDomain: Instance<Dat::DerivativeDomain>, |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
292 | { |
| 35 | 293 | // Check parameters |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
294 | ensure!(config.τ0 > 0.0, "Invalid step length parameter"); |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
295 | config.transport.check()?; |
| 32 | 296 | |
| 297 | // Initialise iterates | |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
298 | let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
299 | let mut γ1 = DiscreteMeasure::new(); |
| 35 | 300 | |
| 301 | // Set up parameters | |
|
41
b6bdb6cb4d44
Remove initial transport adaptation—it is not needed, after all
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
302 | // let opAnorm = opA.opnorm_bound(Radon, L2); |
| 35 | 303 | //let max_transport = config.max_transport.scale |
| 304 | // * reg.radon_norm_bound(b.norm2_squared() / 2.0); | |
| 305 | //let ℓ = opA.transport.lipschitz_factor(L2Squared) * max_transport; | |
| 306 | let ℓ = 0.0; | |
|
62
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
307 | let mut adaptive_τ = AdaptiveStepLength::new(f, prox_penalty, &config.into())?; |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
308 | let τ = adaptive_τ.current(); |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
309 | println!("TODO: τ in calculate_θ should be adaptive"); |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
310 | let (maybe_ℓ_F, maybe_transport_lip) = f.curvature_bound_components(config.guess); |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
311 | let transport_lip = maybe_transport_lip?; |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
312 | let calculate_θ = |ℓ_F, max_transport| { |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
313 | let ℓ_r = transport_lip * max_transport; |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
314 | config.transport.θ0 / (τ * (ℓ + ℓ_F + ℓ_r)) |
| 44 | 315 | }; |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
316 | let mut θ_or_adaptive = match maybe_ℓ_F { |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
317 | //Some(ℓ_F0) => TransportStepLength::Fixed(calculate_θ(ℓ_F0 * b.norm2(), 0.0)), |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
318 | Ok(ℓ_F) => TransportStepLength::AdaptiveMax { |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
319 | l: ℓ_F, // TODO: could estimate computing the real reesidual |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
320 | max_transport: 0.0, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
321 | g: calculate_θ, |
| 44 | 322 | }, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
323 | Err(_) => TransportStepLength::FullyAdaptive { |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
324 | l: 10.0 * F::EPSILON, // Start with something very small to estimate differentials |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
325 | max_transport: 0.0, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
326 | g: calculate_θ, |
| 35 | 327 | }, |
| 328 | }; | |
| 329 | // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled | |
| 330 | // by τ compared to the conditional gradient approach. | |
| 331 | let tolerance = config.insertion.tolerance * τ * reg.tolerance_scaling(); | |
| 332 | let mut ε = tolerance.initial(); | |
| 333 | ||
| 334 | // Statistics | |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
335 | let full_stats = |μ: &RNDM<N, F>, ε, stats| IterInfo { |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
336 | value: f.apply(μ) + reg.apply(μ), |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
337 | n_spikes: μ.len(), |
| 35 | 338 | ε, |
| 339 | // postprocessing: config.insertion.postprocessing.then(|| μ.clone()), | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
340 | ..stats |
| 35 | 341 | }; |
| 32 | 342 | let mut stats = IterInfo::new(); |
| 343 | ||
| 344 | // Run the algorithm | |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
345 | for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) { |
| 35 | 346 | // Calculate initial transport |
|
62
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
347 | let (fμ, v) = f.apply_and_differential(&μ); |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
348 | let τ = adaptive_τ.update(&μ, fμ, &v); |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
349 | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
350 | let (μ_base_masses, mut μ_base_minus_γ0) = |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
351 | initial_transport(&mut γ1, &mut μ, τ, &mut θ_or_adaptive, v); |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
352 | |
| 32 | 353 | // Solve finite-dimensional subproblem several times until the dual variable for the |
| 354 | // regularisation term conforms to the assumptions made for the transport above. | |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
355 | let (maybe_d, _within_tolerances, mut τv̆) = 'adapt_transport: loop { |
| 35 | 356 | // Calculate τv̆ = τA_*(A[μ_transported + μ_transported_base]-b) |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
357 | //let residual_μ̆ = calculate_residual2(&γ1, &μ_base_minus_γ0, opA, b); |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
358 | // TODO: this could be optimised by doing the differential like the |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
359 | // old residual2. |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
360 | let μ̆ = &γ1 + &μ_base_minus_γ0; |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
361 | let mut τv̆ = f.differential(μ̆) * τ; |
| 32 | 362 | |
| 363 | // Construct μ^{k+1} by solving finite-dimensional subproblems and insert new spikes. | |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
364 | let (maybe_d, within_tolerances) = prox_penalty.insert_and_reweigh( |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
365 | &mut μ, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
366 | &mut τv̆, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
367 | &γ1, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
368 | Some(&μ_base_minus_γ0), |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
369 | τ, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
370 | ε, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
371 | &config.insertion, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
372 | ®, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
373 | &state, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
374 | &mut stats, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
375 | )?; |
| 32 | 376 | |
| 35 | 377 | // A posteriori transport adaptation. |
| 378 | if aposteriori_transport( | |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
379 | &mut γ1, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
380 | &mut μ, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
381 | &mut μ_base_minus_γ0, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
382 | &μ_base_masses, |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
383 | None, |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
384 | ε, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
385 | &config.transport, |
| 35 | 386 | ) { |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
387 | break 'adapt_transport (maybe_d, within_tolerances, τv̆); |
| 32 | 388 | } |
| 389 | }; | |
| 390 | ||
|
62
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
391 | // We don't treat merge in adaptive Lipschitz. |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
392 | println!("WARNING: finish_step does not work with sliding"); |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
393 | adaptive_τ.finish_step(&μ); |
|
32328a74c790
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
Tuomo Valkonen <tuomov@iki.fi>
parents:
61
diff
changeset
|
394 | |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
395 | stats.untransported_fraction = Some({ |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
396 | assert_eq!(μ_base_masses.len(), γ1.len()); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
397 | let (a, b) = stats.untransported_fraction.unwrap_or((0.0, 0.0)); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
398 | let source = μ_base_masses.iter().map(|v| v.abs()).sum(); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
399 | (a + μ_base_minus_γ0.norm(Radon), b + source) |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
400 | }); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
401 | stats.transport_error = Some({ |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
402 | assert_eq!(μ_base_masses.len(), γ1.len()); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
403 | let (a, b) = stats.transport_error.unwrap_or((0.0, 0.0)); |
| 35 | 404 | (a + μ.dist_matching(&γ1), b + γ1.norm(Radon)) |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
405 | }); |
| 32 | 406 | |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
407 | // Merge spikes. |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
408 | // This crucially expects the merge routine to be stable with respect to spike locations, |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
409 | // and not to performing any pruning. That is be to done below simultaneously for γ. |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
410 | let ins = &config.insertion; |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
411 | if ins.merge_now(&state) { |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
412 | stats.merged += prox_penalty.merge_spikes( |
|
49
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
413 | &mut μ, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
414 | &mut τv̆, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
415 | &γ1, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
416 | Some(&μ_base_minus_γ0), |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
417 | τ, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
418 | ε, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
419 | ins, |
|
6b0db7251ebe
Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents:
46
diff
changeset
|
420 | ®, |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
421 | Some(|μ̃: &RNDM<N, F>| f.apply(μ̃)), |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
422 | ); |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
423 | } |
| 35 | 424 | |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
425 | // Prune spikes with zero weight. To maintain correct ordering between μ and γ1, also the |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
426 | // latter needs to be pruned when μ is. |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
427 | // TODO: This could do with a two-vector Vec::retain to avoid copies. |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
428 | let μ_new = DiscreteMeasure::from_iter(μ.iter_spikes().filter(|δ| δ.α != F::ZERO).cloned()); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
429 | if μ_new.len() != μ.len() { |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
430 | let mut μ_iter = μ.iter_spikes(); |
|
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
431 | γ1.prune_by(|_| μ_iter.next().unwrap().α != F::ZERO); |
| 35 | 432 | stats.pruned += μ.len() - μ_new.len(); |
|
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
433 | μ = μ_new; |
| 32 | 434 | } |
| 435 | ||
| 35 | 436 | let iter = state.iteration(); |
| 32 | 437 | stats.this_iters += 1; |
| 438 | ||
| 35 | 439 | // Give statistics if requested |
| 32 | 440 | state.if_verbose(|| { |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
441 | plotter.plot_spikes(iter, maybe_d.as_ref(), Some(&τv̆), &μ); |
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
442 | full_stats(&μ, ε, std::mem::replace(&mut stats, IterInfo::new())) |
| 35 | 443 | }); |
| 32 | 444 | |
| 35 | 445 | // Update main tolerance for next iteration |
| 446 | ε = tolerance.update(ε, iter); | |
| 447 | } | |
| 448 | ||
|
61
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
449 | //postprocess(μ, &config.insertion, f) |
|
4f468d35fa29
General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents:
49
diff
changeset
|
450 | postprocess(μ, &config.insertion, |μ̃| f.apply(μ̃)) |
| 32 | 451 | } |