Fri, 16 Jan 2026 19:39:22 -0500
Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)
| 0 | 1 | /*! |
| 2 | Solver for the point source localisation problem using a forward-backward splitting method. | |
| 3 | ||
| 4 | This corresponds to the manuscript | |
| 5 | ||
|
13
bdc57366d4f5
arXiv links, README beautification
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
6 | * Valkonen T. - _Proximal methods for point source localisation_, |
|
bdc57366d4f5
arXiv links, README beautification
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
7 | [arXiv:2212.02991](https://arxiv.org/abs/2212.02991). |
| 0 | 8 | |
| 35 | 9 | The main routine is [`pointsource_fb_reg`]. |
| 0 | 10 | |
| 11 | ## Problem | |
| 12 | ||
| 13 | <p> | |
| 14 | Our objective is to solve | |
| 15 | $$ | |
| 16 | \min_{μ ∈ ℳ(Ω)}~ F_0(Aμ-b) + α \|μ\|_{ℳ(Ω)} + δ_{≥ 0}(μ), | |
| 17 | $$ | |
| 18 | where $F_0(y)=\frac{1}{2}\|y\|_2^2$ and the forward operator $A \in 𝕃(ℳ(Ω); ℝ^n)$. | |
| 19 | </p> | |
| 20 | ||
| 21 | ## Approach | |
| 22 | ||
| 23 | <p> | |
| 24 | As documented in more detail in the paper, on each step we approximately solve | |
| 25 | $$ | |
| 26 | \min_{μ ∈ ℳ(Ω)}~ F(x) + α \|μ\|_{ℳ(Ω)} + δ_{≥ 0}(x) + \frac{1}{2}\|μ-μ^k|_𝒟^2, | |
| 27 | $$ | |
| 28 | where $𝒟: 𝕃(ℳ(Ω); C_c(Ω))$ is typically a convolution operator. | |
| 29 | </p> | |
| 30 | ||
| 31 | ## Finite-dimensional subproblems. | |
| 32 | ||
| 33 | With $C$ a projection from [`DiscreteMeasure`] to the weights, and $x^k$ such that $x^k=Cμ^k$, we | |
| 34 | form the discretised linearised inner problem | |
| 35 | <p> | |
| 36 | $$ | |
| 37 | \min_{x ∈ ℝ^n}~ τ\bigl(F(Cx^k) + [C^*∇F(Cx^k)]^⊤(x-x^k) + α {\vec 1}^⊤ x\bigr) | |
| 38 | + δ_{≥ 0}(x) + \frac{1}{2}\|x-x^k\|_{C^*𝒟C}^2, | |
| 39 | $$ | |
| 40 | equivalently | |
| 41 | $$ | |
| 42 | \begin{aligned} | |
| 43 | \min_x~ & τF(Cx^k) - τ[C^*∇F(Cx^k)]^⊤x^k + \frac{1}{2} (x^k)^⊤ C^*𝒟C x^k | |
| 44 | \\ | |
| 45 | & | |
| 46 | - [C^*𝒟C x^k - τC^*∇F(Cx^k)]^⊤ x | |
| 47 | \\ | |
| 48 | & | |
| 49 | + \frac{1}{2} x^⊤ C^*𝒟C x | |
| 50 | + τα {\vec 1}^⊤ x + δ_{≥ 0}(x), | |
| 51 | \end{aligned} | |
| 52 | $$ | |
| 53 | In other words, we obtain the quadratic non-negativity constrained problem | |
| 54 | $$ | |
| 55 | \min_{x ∈ ℝ^n}~ \frac{1}{2} x^⊤ Ã x - b̃^⊤ x + c + τα {\vec 1}^⊤ x + δ_{≥ 0}(x). | |
| 56 | $$ | |
| 57 | where | |
| 58 | $$ | |
| 59 | \begin{aligned} | |
| 60 | Ã & = C^*𝒟C, | |
| 61 | \\ | |
| 62 | g̃ & = C^*𝒟C x^k - τ C^*∇F(Cx^k) | |
| 63 | = C^* 𝒟 μ^k - τ C^*A^*(Aμ^k - b) | |
| 64 | \\ | |
| 65 | c & = τ F(Cx^k) - τ[C^*∇F(Cx^k)]^⊤x^k + \frac{1}{2} (x^k)^⊤ C^*𝒟C x^k | |
| 66 | \\ | |
| 67 | & | |
| 68 | = \frac{τ}{2} \|Aμ^k-b\|^2 - τ[Aμ^k-b]^⊤Aμ^k + \frac{1}{2} \|μ_k\|_{𝒟}^2 | |
| 69 | \\ | |
| 70 | & | |
| 71 | = -\frac{τ}{2} \|Aμ^k-b\|^2 + τ[Aμ^k-b]^⊤ b + \frac{1}{2} \|μ_k\|_{𝒟}^2. | |
| 72 | \end{aligned} | |
| 73 | $$ | |
| 74 | </p> | |
| 75 | ||
| 35 | 76 | We solve this with either SSN or FB as determined by |
|
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:
51
diff
changeset
|
77 | [`crate::subproblem::InnerSettings`] in [`InsertionConfig::inner`]. |
| 0 | 78 | */ |
| 79 | ||
|
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:
51
diff
changeset
|
80 | 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:
51
diff
changeset
|
81 | use crate::measures::{DiscreteMeasure, 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:
51
diff
changeset
|
82 | use crate::plot::Plotter; |
|
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
|
83 | use crate::prox_penalty::StepLengthBoundValue; |
|
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:
51
diff
changeset
|
84 | pub use crate::prox_penalty::{InsertionConfig, 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:
51
diff
changeset
|
85 | use crate::regularisation::RegTerm; |
|
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:
51
diff
changeset
|
86 | 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:
51
diff
changeset
|
87 | use alg_tools::error::DynResult; |
|
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
|
88 | use alg_tools::instance::{ClosedSpace, Instance}; |
|
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:
51
diff
changeset
|
89 | use alg_tools::iterate::AlgIteratorFactory; |
|
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
|
90 | use alg_tools::mapping::{DifferentiableMapping, Mapping}; |
|
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:
51
diff
changeset
|
91 | use alg_tools::nalgebra_support::ToNalgebraRealField; |
|
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
|
92 | use anyhow::anyhow; |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
93 | use colored::Colorize; |
| 0 | 94 | use numeric_literals::replace_float_literals; |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
95 | use serde::{Deserialize, Serialize}; |
| 0 | 96 | |
|
24
d29d1fcf5423
Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
97 | /// Settings for [`pointsource_fb_reg`]. |
| 0 | 98 | #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] |
| 99 | #[serde(default)] | |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
100 | pub struct FBConfig<F: Float> { |
| 0 | 101 | /// Step length scaling |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
102 | 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:
51
diff
changeset
|
103 | // Auxiliary variable step length scaling for [`crate::forward_pdps::pointsource_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:
51
diff
changeset
|
104 | pub σp0: F, |
| 0 | 105 | /// 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:
51
diff
changeset
|
106 | pub insertion: InsertionConfig<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
|
107 | /// 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
|
108 | pub always_adaptive_τ: bool, |
| 0 | 109 | } |
| 110 | ||
| 111 | #[replace_float_literals(F::cast_from(literal))] | |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
112 | impl<F: Float> Default for FBConfig<F> { |
| 0 | 113 | fn default() -> Self { |
|
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
|
114 | FBConfig { τ0: 0.99, σp0: 0.99, always_adaptive_τ: false, insertion: Default::default() } |
| 0 | 115 | } |
| 116 | } | |
| 117 | ||
|
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:
51
diff
changeset
|
118 | pub(crate) fn prune_with_stats<F: Float, const N: usize>(μ: &mut RNDM<N, F>) -> usize { |
| 32 | 119 | let n_before_prune = μ.len(); |
| 120 | μ.prune(); | |
| 121 | debug_assert!(μ.len() <= n_before_prune); | |
| 35 | 122 | n_before_prune - μ.len() |
|
24
d29d1fcf5423
Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
123 | } |
|
d29d1fcf5423
Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
124 | |
|
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
|
125 | /// Adaptive step length and Lipschitz parameter estimation state. |
|
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
|
126 | #[derive(Clone, Debug, Serialize)] |
|
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
|
127 | pub enum AdaptiveStepLength<const N: usize, F: Float> { |
|
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
|
128 | 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
|
129 | l: 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
|
130 | μ_old: RNDM<N, 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
|
131 | fμ_old: 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
|
132 | μ_dist: 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
|
133 | τ0: 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
|
134 | l_is_initial: 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
|
135 | }, |
|
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
|
136 | Fixed { |
|
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
|
137 | τ: 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
|
138 | }, |
|
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
|
139 | } |
|
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
|
140 | |
|
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
|
141 | #[replace_float_literals(F::cast_from(literal))] |
|
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
|
142 | impl<const N: usize, F: Float> AdaptiveStepLength<N, 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
|
143 | pub fn new<Dat, Reg, P>(f: &Dat, prox_penalty: &P, fbconfig: &FBConfig<F>) -> DynResult<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
|
144 | where |
|
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
|
145 | F: ToNalgebraRealField, |
|
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
|
146 | Dat: DifferentiableMapping<RNDM<N, F>, Codomain = 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
|
147 | P: ProxPenalty<Loc<N, F>, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
|
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
|
148 | Reg: RegTerm<Loc<N, F>, 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
|
149 | { |
|
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
|
150 | match ( |
|
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
|
151 | prox_penalty.step_length_bound(&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
|
152 | fbconfig.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
|
153 | ) { |
|
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
|
154 | (StepLengthBoundValue::LipschitzFactor(l), false) => { |
|
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
|
155 | Ok(AdaptiveStepLength::Fixed { τ: fbconfig.τ0 / l }) |
|
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
|
156 | } |
|
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
|
157 | (StepLengthBoundValue::LipschitzFactor(l), true) => { |
|
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
|
158 | let μ_old = DiscreteMeasure::new(); |
|
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
|
159 | let fμ_old = f.apply(&μ_old); |
|
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
|
160 | Ok(AdaptiveStepLength::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
|
161 | l: l, |
|
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
|
162 | μ_old, |
|
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
|
163 | fμ_old, |
|
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
|
164 | μ_dist: 0.0, |
|
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
|
165 | τ0: fbconfig.τ0, |
|
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
|
166 | l_is_initial: false, |
|
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
|
167 | }) |
|
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
|
168 | } |
|
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
|
169 | (StepLengthBoundValue::UnreliableLipschitzFactor(l), _) => { |
|
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
|
170 | println!("Lipschitz factor is unreliable; calculating adaptively."); |
|
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
|
171 | let μ_old = DiscreteMeasure::new(); |
|
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
|
172 | let fμ_old = f.apply(&μ_old); |
|
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
|
173 | Ok(AdaptiveStepLength::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
|
174 | l: l, |
|
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
|
175 | μ_old, |
|
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
|
176 | fμ_old, |
|
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
|
177 | μ_dist: 0.0, |
|
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
|
178 | τ0: fbconfig.τ0, |
|
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
|
179 | l_is_initial: true, |
|
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
|
180 | }) |
|
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
|
181 | } |
|
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
|
182 | (StepLengthBoundValue::Failure, _) => Err(anyhow!("No Lipschitz estimate available")), |
|
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
|
183 | } |
|
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
|
184 | } |
|
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
|
185 | |
|
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
|
186 | /// Returns the current value of the step length parameter. |
|
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
|
187 | pub fn current(&self) -> 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
|
188 | match *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
|
189 | AdaptiveStepLength::Adaptive { τ0, l, .. } => τ0 / l, |
|
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
|
190 | AdaptiveStepLength::Fixed { τ } => τ, |
|
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
|
191 | } |
|
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
|
192 | } |
|
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
|
193 | |
|
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
|
194 | /// Update daptive Lipschitz factor and return new step length parameter `τ`. |
|
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
|
195 | /// |
|
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
|
196 | /// Inputs: |
|
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
|
197 | /// * `μ`: current point |
|
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
|
198 | /// * `fμ`: value of the function `f` at `μ`. |
|
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
|
199 | /// * `ν`: derivative of the function `f` at `μ`. |
|
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
|
200 | /// * `τ0`: fractional step length parameter in $[0, 1)$. |
|
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
|
201 | pub fn update<'a, G>(&mut self, μ: &RNDM<N, F>, fμ: F, v: &'a G) -> 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
|
202 | where |
|
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
|
203 | G: ClosedMul<F> + Mapping<Loc<N, F>, Codomain = F> + ClosedSpace, |
|
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
|
204 | &'a G: Instance<G>, |
|
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
|
205 | { |
|
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
|
206 | match 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
|
207 | AdaptiveStepLength::Adaptive { l, μ_old, fμ_old, μ_dist, τ0, l_is_initial } => { |
|
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
|
208 | // Estimate step length parameter |
|
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
|
209 | let b = *fμ_old - fμ - μ_old.apply(v) + μ.apply(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
|
210 | let d = *μ_dist; |
|
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
|
211 | if d.abs() > F::EPSILON && μ.len() > 0 && μ_old.len() > 0 { |
|
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
|
212 | let lc = b / (d * d / 2.0); |
|
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
|
213 | dbg!(b, d, lc); |
|
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
|
214 | if *l_is_initial { |
|
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
|
215 | *l = lc; |
|
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
|
216 | *l_is_initial = false; |
|
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
|
217 | } else { |
|
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
|
218 | *l = l.max(lc); |
|
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
|
219 | } |
|
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
|
220 | } |
|
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
|
221 | |
|
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
|
222 | // Store for next iteration |
|
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
|
223 | *μ_old = μ.clone(); |
|
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
|
224 | *fμ_old = 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
|
225 | |
|
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
|
226 | return *τ0 / *l; |
|
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
|
227 | } |
|
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
|
228 | AdaptiveStepLength::Fixed { τ } => *τ, |
|
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
|
229 | } |
|
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
|
230 | } |
|
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
|
231 | |
|
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
|
232 | /// Finalises a step, storing μ and its distance to the previous μ. |
|
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
|
233 | /// |
|
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
|
234 | /// This is not included in [`Self::update`], as this function is to be called |
|
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
|
235 | /// before pruning and merging, while μ and its previous version in their internal |
|
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
|
236 | /// presentation still having matching indices for the same coordinate. |
|
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
|
237 | pub fn finish_step(&mut self, μ: &RNDM<N, 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
|
238 | if let AdaptiveStepLength::Adaptive { μ_dist, μ_old, .. } = 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
|
239 | *μ_dist = μ.dist_matching(&μ_old); |
|
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
|
240 | } |
|
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
|
241 | } |
|
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
|
242 | } |
|
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
|
243 | |
| 32 | 244 | #[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:
51
diff
changeset
|
245 | pub(crate) fn postprocess<F: Float, Dat: Fn(&RNDM<N, F>) -> F, 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:
51
diff
changeset
|
246 | 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:
51
diff
changeset
|
247 | config: &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:
51
diff
changeset
|
248 | 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:
51
diff
changeset
|
249 | ) -> DynResult<RNDM<N, F>> |
| 35 | 250 | where |
|
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:
51
diff
changeset
|
251 | 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:
51
diff
changeset
|
252 | for<'a> &'a RNDM<N, F>: Instance<RNDM<N, F>>, |
| 35 | 253 | { |
|
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:
51
diff
changeset
|
254 | //μ.merge_spikes_fitness(config.final_merging_method(), |μ̃| f.apply(μ̃), |&v| v); |
|
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:
51
diff
changeset
|
255 | μ.merge_spikes_fitness(config.final_merging_method(), f, |&v| v); |
| 32 | 256 | μ.prune(); |
|
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:
51
diff
changeset
|
257 | Ok(μ) |
| 32 | 258 | } |
|
24
d29d1fcf5423
Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
259 | |
| 32 | 260 | /// Iteratively solve the pointsource localisation problem using forward-backward splitting. |
| 0 | 261 | /// |
| 32 | 262 | /// The settings in `config` have their [respective documentation](FBConfig). `opA` is the |
| 0 | 263 | /// forward operator $A$, $b$ the observable, and $\lambda$ the regularisation weight. |
| 264 | /// The operator `op𝒟` is used for forming the proximal term. Typically it is a convolution | |
| 265 | /// operator. Finally, the `iterator` is an outer loop verbosity and iteration count control | |
| 266 | /// as documented in [`alg_tools::iterate`]. | |
| 267 | /// | |
| 32 | 268 | /// For details on the mathematical formulation, see the [module level](self) documentation. |
| 269 | /// | |
| 0 | 270 | /// Returns the final iterate. |
| 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:
51
diff
changeset
|
272 | pub fn pointsource_fb_reg<F, I, Dat, Reg, P, Plot, 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:
51
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:
51
diff
changeset
|
274 | reg: &Reg, |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
275 | prox_penalty: &P, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
276 | fbconfig: &FBConfig<F>, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
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:
51
diff
changeset
|
278 | mut plotter: Plot, |
|
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
|
279 | μ0: Option<RNDM<N, 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:
51
diff
changeset
|
280 | ) -> DynResult<RNDM<N, F>> |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
281 | where |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
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:
51
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:
51
diff
changeset
|
284 | 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:
51
diff
changeset
|
285 | Dat: DifferentiableMapping<RNDM<N, F>, Codomain = 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
|
286 | Dat::DerivativeDomain: ClosedMul<F> + Mapping<Loc<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:
51
diff
changeset
|
287 | Reg: RegTerm<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:
51
diff
changeset
|
288 | 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:
51
diff
changeset
|
289 | 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
|
290 | for<'a> &'a Dat::DerivativeDomain: Instance<Dat::DerivativeDomain>, |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
291 | { |
| 32 | 292 | // Set up 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:
51
diff
changeset
|
293 | let config = &fbconfig.insertion; |
|
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
|
294 | let mut adaptive_τ = AdaptiveStepLength::new(f, prox_penalty, fbconfig)?; |
|
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
|
295 | |
| 32 | 296 | // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled |
| 297 | // by τ compared to the conditional gradient approach. | |
|
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
|
298 | let tolerance = config.tolerance * adaptive_τ.current() * reg.tolerance_scaling(); |
| 32 | 299 | let mut ε = tolerance.initial(); |
| 300 | ||
| 301 | // 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:
51
diff
changeset
|
302 | let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
| 35 | 303 | |
| 304 | // 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:
51
diff
changeset
|
305 | 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:
51
diff
changeset
|
306 | value: f.apply(μ) + reg.apply(μ), |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
307 | n_spikes: μ.len(), |
| 35 | 308 | ε, |
| 309 | //postprocessing: config.postprocessing.then(|| μ.clone()), | |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
310 | ..stats |
| 35 | 311 | }; |
| 32 | 312 | let mut stats = IterInfo::new(); |
| 313 | ||
| 314 | // 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:
51
diff
changeset
|
315 | for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) { |
| 32 | 316 | // Calculate smooth part of surrogate model. |
|
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:
51
diff
changeset
|
317 | // TODO: optimise τ to be applied to residual. |
|
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
|
318 | 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
|
319 | 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
|
320 | dbg!(τ); |
|
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
|
321 | let mut τv = v * τ; |
| 32 | 322 | |
| 323 | // Save current base point | |
| 324 | let μ_base = μ.clone(); | |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
325 | |
| 32 | 326 | // Insert and reweigh |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
327 | let (maybe_d, _within_tolerances) = prox_penalty.insert_and_reweigh( |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
328 | &mut μ, &mut τv, &μ_base, None, τ, ε, config, ®, &state, &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:
51
diff
changeset
|
329 | )?; |
| 32 | 330 | |
|
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
|
331 | // 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
|
332 | 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
|
333 | |
| 32 | 334 | // Prune and possibly merge spikes |
| 35 | 335 | if config.merge_now(&state) { |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
336 | stats.merged += prox_penalty.merge_spikes( |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
337 | &mut μ, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
338 | &mut τv, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
339 | &μ_base, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
340 | None, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
341 | τ, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
342 | ε, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
343 | config, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
344 | ®, |
|
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:
51
diff
changeset
|
345 | Some(|μ̃: &RNDM<N, F>| f.apply(μ̃)), |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
346 | ); |
| 35 | 347 | } |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
348 | |
| 35 | 349 | stats.pruned += prune_with_stats(&mut μ); |
| 32 | 350 | |
| 35 | 351 | let iter = state.iteration(); |
| 32 | 352 | stats.this_iters += 1; |
| 353 | ||
| 35 | 354 | // Give statistics if needed |
| 32 | 355 | state.if_verbose(|| { |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
356 | 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:
51
diff
changeset
|
357 | full_stats(&μ, ε, std::mem::replace(&mut stats, IterInfo::new())) |
| 35 | 358 | }); |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
359 | |
| 35 | 360 | // Update main tolerance for next iteration |
| 361 | ε = tolerance.update(ε, iter); | |
| 362 | } | |
| 32 | 363 | |
|
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:
51
diff
changeset
|
364 | //postprocess(μ_prev, config, 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:
51
diff
changeset
|
365 | postprocess(μ, config, |μ̃| f.apply(μ̃)) |
| 32 | 366 | } |
|
24
d29d1fcf5423
Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
367 | |
| 32 | 368 | /// Iteratively solve the pointsource localisation problem using inertial forward-backward splitting. |
| 369 | /// | |
| 370 | /// The settings in `config` have their [respective documentation](FBConfig). `opA` is the | |
| 371 | /// forward operator $A$, $b$ the observable, and $\lambda$ the regularisation weight. | |
| 372 | /// The operator `op𝒟` is used for forming the proximal term. Typically it is a convolution | |
| 373 | /// operator. Finally, the `iterator` is an outer loop verbosity and iteration count control | |
| 374 | /// as documented in [`alg_tools::iterate`]. | |
| 375 | /// | |
| 376 | /// For details on the mathematical formulation, see the [module level](self) documentation. | |
| 377 | /// | |
| 378 | /// Returns the final iterate. | |
| 379 | #[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:
51
diff
changeset
|
380 | pub fn pointsource_fista_reg<F, I, Dat, Reg, P, Plot, 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:
51
diff
changeset
|
381 | 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:
51
diff
changeset
|
382 | reg: &Reg, |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
383 | prox_penalty: &P, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
384 | fbconfig: &FBConfig<F>, |
|
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
385 | 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:
51
diff
changeset
|
386 | mut plotter: Plot, |
|
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
|
387 | μ0: Option<RNDM<N, 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:
51
diff
changeset
|
388 | ) -> DynResult<RNDM<N, F>> |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
389 | where |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
390 | 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:
51
diff
changeset
|
391 | 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:
51
diff
changeset
|
392 | 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:
51
diff
changeset
|
393 | Dat: DifferentiableMapping<RNDM<N, F>, Codomain = 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
|
394 | Dat::DerivativeDomain: ClosedMul<F> + Mapping<Loc<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:
51
diff
changeset
|
395 | Reg: RegTerm<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:
51
diff
changeset
|
396 | 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:
51
diff
changeset
|
397 | 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
|
398 | for<'a> &'a Dat::DerivativeDomain: Instance<Dat::DerivativeDomain>, |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
399 | { |
| 32 | 400 | // Set up 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:
51
diff
changeset
|
401 | let config = &fbconfig.insertion; |
|
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
|
402 | let mut adaptive_τ = AdaptiveStepLength::new(f, prox_penalty, fbconfig)?; |
|
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
|
403 | |
| 32 | 404 | let mut λ = 1.0; |
| 405 | // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled | |
| 406 | // by τ compared to the conditional gradient approach. | |
|
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
|
407 | let tolerance = config.tolerance * adaptive_τ.current() * reg.tolerance_scaling(); |
| 32 | 408 | let mut ε = tolerance.initial(); |
| 409 | ||
| 410 | // 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:
51
diff
changeset
|
411 | let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
|
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:
51
diff
changeset
|
412 | let mut μ_prev = μ.clone(); |
| 35 | 413 | let mut warned_merging = false; |
| 414 | ||
| 415 | // 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:
51
diff
changeset
|
416 | 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:
51
diff
changeset
|
417 | value: f.apply(ν) + reg.apply(ν), |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
418 | n_spikes: ν.len(), |
| 35 | 419 | ε, |
| 420 | // postprocessing: config.postprocessing.then(|| ν.clone()), | |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
421 | ..stats |
| 35 | 422 | }; |
| 32 | 423 | let mut stats = IterInfo::new(); |
| 424 | ||
| 425 | // Run the algorithm | |
| 35 | 426 | for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) { |
| 32 | 427 | // Calculate smooth part of surrogate model. |
|
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
|
428 | 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
|
429 | 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
|
430 | let mut τv = v * τ; |
| 32 | 431 | |
| 432 | // Save current base point | |
| 433 | let μ_base = μ.clone(); | |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
434 | |
| 32 | 435 | // Insert new spikes and reweigh |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
436 | let (maybe_d, _within_tolerances) = prox_penalty.insert_and_reweigh( |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
437 | &mut μ, &mut τv, &μ_base, None, τ, ε, config, ®, &state, &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:
51
diff
changeset
|
438 | )?; |
| 32 | 439 | |
|
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
|
440 | // 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
|
441 | 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
|
442 | |
| 32 | 443 | // (Do not) merge spikes. |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
444 | if config.merge_now(&state) && !warned_merging { |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
445 | let err = format!("Merging not supported for μFISTA"); |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
446 | println!("{}", err.red()); |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
447 | warned_merging = true; |
| 32 | 448 | } |
| 449 | ||
| 450 | // Update inertial prameters | |
| 451 | let λ_prev = λ; | |
|
51
0693cc9ba9f0
Update documentation references
Tuomo Valkonen <tuomov@iki.fi>
parents:
39
diff
changeset
|
452 | λ = 2.0 * λ_prev / (λ_prev + (4.0 + λ_prev * λ_prev).sqrt()); |
| 32 | 453 | let θ = λ / λ_prev - λ; |
| 454 | ||
| 455 | // Perform inertial update on μ. | |
| 456 | // This computes μ ← (1 + θ) * μ - θ * μ_prev, pruning spikes where both μ | |
| 457 | // and μ_prev have zero weight. Since both have weights from the finite-dimensional | |
| 458 | // subproblem with a proximal projection step, this is likely to happen when the | |
| 459 | // spike is not needed. A copy of the pruned μ without artithmetic performed is | |
| 460 | // stored in μ_prev. | |
| 461 | let n_before_prune = μ.len(); | |
| 462 | μ.pruning_sub(1.0 + θ, θ, &mut μ_prev); | |
|
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
463 | //let μ_new = (&μ * (1.0 + θ)).sub_matching(&(&μ_prev * θ)); |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
464 | // μ_prev = μ; |
|
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
465 | // μ = μ_new; |
| 32 | 466 | debug_assert!(μ.len() <= n_before_prune); |
| 467 | stats.pruned += n_before_prune - μ.len(); | |
| 468 | ||
| 35 | 469 | let iter = state.iteration(); |
| 32 | 470 | stats.this_iters += 1; |
| 471 | ||
| 35 | 472 | // Give statistics if needed |
| 32 | 473 | state.if_verbose(|| { |
|
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
474 | plotter.plot_spikes(iter, maybe_d.as_ref(), Some(&τv), &μ_prev); |
| 35 | 475 | full_stats(&μ_prev, ε, std::mem::replace(&mut stats, IterInfo::new())) |
| 476 | }); | |
| 477 | ||
| 478 | // Update main tolerance for next iteration | |
| 479 | ε = tolerance.update(ε, iter); | |
| 480 | } | |
| 32 | 481 | |
|
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:
51
diff
changeset
|
482 | //postprocess(μ_prev, config, 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:
51
diff
changeset
|
483 | postprocess(μ_prev, config, |μ̃| f.apply(μ̃)) |
|
24
d29d1fcf5423
Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
484 | } |