src/fb.rs

Mon, 06 Jan 2025 21:37:03 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 06 Jan 2025 21:37:03 -0500
branch
dev
changeset 38
0f59c0d02e13
parent 37
c5d8bd1a7728
child 39
6316d68b58af
permissions
-rw-r--r--

Attempt to do more Serialize / Deserialize but run into csv problems

0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 /*!
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 Solver for the point source localisation problem using a forward-backward splitting method.
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 This corresponds to the manuscript
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
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
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
9 The main routine is [`pointsource_fb_reg`].
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11 ## Problem
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 <p>
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14 Our objective is to solve
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 \min_{μ ∈ ℳ(Ω)}~ F_0(Aμ-b) + α \|μ\|_{ℳ(Ω)} + δ_{≥ 0}(μ),
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 where $F_0(y)=\frac{1}{2}\|y\|_2^2$ and the forward operator $A \in 𝕃(ℳ(Ω); ℝ^n)$.
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 </p>
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 ## Approach
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 <p>
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 As documented in more detail in the paper, on each step we approximately solve
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 \min_{μ ∈ ℳ(Ω)}~ F(x) + α \|μ\|_{ℳ(Ω)} + δ_{≥ 0}(x) + \frac{1}{2}\|μ-μ^k|_𝒟^2,
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 where $𝒟: 𝕃(ℳ(Ω); C_c(Ω))$ is typically a convolution operator.
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 </p>
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 ## Finite-dimensional subproblems.
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 With $C$ a projection from [`DiscreteMeasure`] to the weights, and $x^k$ such that $x^k=Cμ^k$, we
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 form the discretised linearised inner problem
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 <p>
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 \min_{x ∈ ℝ^n}~ τ\bigl(F(Cx^k) + [C^*∇F(Cx^k)]^⊤(x-x^k) + α {\vec 1}^⊤ x\bigr)
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 + δ_{≥ 0}(x) + \frac{1}{2}\|x-x^k\|_{C^*𝒟C}^2,
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 equivalently
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42 \begin{aligned}
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 \min_x~ & τF(Cx^k) - τ[C^*∇F(Cx^k)]^⊤x^k + \frac{1}{2} (x^k)^⊤ C^*𝒟C x^k
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 \\
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 &
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 - [C^*𝒟C x^k - τC^*∇F(Cx^k)]^⊤ x
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 \\
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 &
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 + \frac{1}{2} x^⊤ C^*𝒟C x
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 + τα {\vec 1}^⊤ x + δ_{≥ 0}(x),
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 \end{aligned}
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 In other words, we obtain the quadratic non-negativity constrained problem
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 \min_{x ∈ ℝ^n}~ \frac{1}{2} x^⊤ Ã x - b̃^⊤ x + c + τα {\vec 1}^⊤ x + δ_{≥ 0}(x).
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 where
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 \begin{aligned}
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 Ã & = C^*𝒟C,
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 \\
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62 g̃ & = C^*𝒟C x^k - τ C^*∇F(Cx^k)
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 = C^* 𝒟 μ^k - τ C^*A^*(Aμ^k - b)
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 \\
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 c & = τ F(Cx^k) - τ[C^*∇F(Cx^k)]^⊤x^k + \frac{1}{2} (x^k)^⊤ C^*𝒟C x^k
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 \\
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 &
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 = \frac{τ}{2} \|Aμ^k-b\|^2 - τ[Aμ^k-b]^⊤Aμ^k + \frac{1}{2} \|μ_k\|_{𝒟}^2
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69 \\
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 &
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 = -\frac{τ}{2} \|Aμ^k-b\|^2 + τ[Aμ^k-b]^⊤ b + \frac{1}{2} \|μ_k\|_{𝒟}^2.
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 \end{aligned}
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 $$
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 </p>
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
76 We solve this with either SSN or FB as determined by
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 [`InnerSettings`] in [`FBGenericConfig::inner`].
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 */
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 use numeric_literals::replace_float_literals;
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 use serde::{Serialize, Deserialize};
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82 use colored::Colorize;
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
84 use alg_tools::iterate::AlgIteratorFactory;
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 use alg_tools::euclidean::Euclidean;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
86 use alg_tools::linops::{Mapping, GEMV};
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 use alg_tools::mapping::RealMapping;
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 use alg_tools::nalgebra_support::ToNalgebraRealField;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
89 use alg_tools::instance::Instance;
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 use crate::types::*;
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 use crate::measures::{
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 DiscreteMeasure,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
94 RNDM,
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95 };
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 use crate::measures::merging::{
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 SpikeMergingMethod,
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 SpikeMerging,
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 };
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
100 use crate::forward_model::{
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
101 ForwardModel,
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
102 AdjointProductBoundedBy,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
103 };
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 use crate::plot::{
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105 SeqPlotter,
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 Plotting,
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 PlotLookup
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108 };
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
109 use crate::regularisation::RegTerm;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
110 use crate::dataterm::{
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
111 calculate_residual,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
112 L2Squared,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
113 DataTerm,
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
114 };
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
115 pub use crate::prox_penalty::{
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
116 FBGenericConfig,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
117 ProxPenalty
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
118 };
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
120 /// Settings for [`pointsource_fb_reg`].
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 #[serde(default)]
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 pub struct FBConfig<F : Float> {
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 /// Step length scaling
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 pub τ0 : F,
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 /// Generic parameters
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
127 pub generic : FBGenericConfig<F>,
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 }
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 #[replace_float_literals(F::cast_from(literal))]
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 impl<F : Float> Default for FBConfig<F> {
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 fn default() -> Self {
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 FBConfig {
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 τ0 : 0.99,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
135 generic : Default::default(),
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 }
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 }
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 }
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
140 pub(crate) fn prune_with_stats<F : Float, const N : usize>(
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
141 μ : &mut RNDM<F, N>,
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
142 ) -> usize {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
143 let n_before_prune = μ.len();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
144 μ.prune();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
145 debug_assert!(μ.len() <= n_before_prune);
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
146 n_before_prune - μ.len()
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
147 }
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
148
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
149 #[replace_float_literals(F::cast_from(literal))]
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
150 pub(crate) fn postprocess<
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
151 F : Float,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
152 V : Euclidean<F> + Clone,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
153 A : GEMV<F, RNDM<F, N>, Codomain = V>,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
154 D : DataTerm<F, V, N>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
155 const N : usize
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
156 > (
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
157 mut μ : RNDM<F, N>,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
158 config : &FBGenericConfig<F>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
159 dataterm : D,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
160 opA : &A,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
161 b : &V,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
162 ) -> RNDM<F, N>
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
163 where
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
164 RNDM<F, N> : SpikeMerging<F>,
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
165 for<'a> &'a RNDM<F, N> : Instance<RNDM<F, N>>,
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
166 {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
167 μ.merge_spikes_fitness(config.merging,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
168 |μ̃| dataterm.calculate_fit_op(μ̃, opA, b),
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
169 |&v| v);
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
170 μ.prune();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
171 μ
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
172 }
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
173
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
174 /// Iteratively solve the pointsource localisation problem using forward-backward splitting.
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175 ///
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
176 /// The settings in `config` have their [respective documentation](FBConfig). `opA` is the
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177 /// forward operator $A$, $b$ the observable, and $\lambda$ the regularisation weight.
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178 /// The operator `op𝒟` is used for forming the proximal term. Typically it is a convolution
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
179 /// operator. Finally, the `iterator` is an outer loop verbosity and iteration count control
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
180 /// as documented in [`alg_tools::iterate`].
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
181 ///
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
182 /// For details on the mathematical formulation, see the [module level](self) documentation.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
183 ///
0
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
184 /// The implementation relies on [`alg_tools::bisection_tree::BTFN`] presentations of
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
185 /// sums of simple functions usign bisection trees, and the related
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
186 /// [`alg_tools::bisection_tree::Aggregator`]s, to efficiently search for component functions
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
187 /// active at a specific points, and to maximise their sums. Through the implementation of the
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
188 /// [`alg_tools::bisection_tree::BT`] bisection trees, it also relies on the copy-on-write features
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
189 /// of [`std::sync::Arc`] to only update relevant parts of the bisection tree when adding functions.
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
190 ///
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
191 /// Returns the final iterate.
eb3c7813b67a Initial version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
192 #[replace_float_literals(F::cast_from(literal))]
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
193 pub fn pointsource_fb_reg<
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
194 F, I, A, Reg, P, const N : usize
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
195 >(
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
196 opA : &A,
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
197 b : &A::Observable,
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
198 reg : Reg,
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
199 prox_penalty : &P,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
200 fbconfig : &FBConfig<F>,
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
201 iterator : I,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
202 mut plotter : SeqPlotter<F, N>,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
203 ) -> RNDM<F, N>
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
204 where
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
205 F : Float + ToNalgebraRealField,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
206 I : AlgIteratorFactory<IterInfo<F, N>>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
207 for<'b> &'b A::Observable : std::ops::Neg<Output=A::Observable>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
208 A : ForwardModel<RNDM<F, N>, F>
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
209 + AdjointProductBoundedBy<RNDM<F, N>, P, FloatType=F>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
210 A::PreadjointCodomain : RealMapping<F, N>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
211 PlotLookup : Plotting<N>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
212 RNDM<F, N> : SpikeMerging<F>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
213 Reg : RegTerm<F, N>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
214 P : ProxPenalty<F, A::PreadjointCodomain, Reg, N>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
215 {
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
216
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
217 // Set up parameters
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
218 let config = &fbconfig.generic;
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
219 let τ = fbconfig.τ0/opA.adjoint_product_bound(prox_penalty).unwrap();
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
220 // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
221 // by τ compared to the conditional gradient approach.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
222 let tolerance = config.tolerance * τ * reg.tolerance_scaling();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
223 let mut ε = tolerance.initial();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
224
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
225 // Initialise iterates
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
226 let mut μ = DiscreteMeasure::new();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
227 let mut residual = -b;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
228
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
229 // Statistics
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
230 let full_stats = |residual : &A::Observable,
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
231 μ : &RNDM<F, N>,
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
232 ε, stats| IterInfo {
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
233 value : residual.norm2_squared_div2() + reg.apply(μ),
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
234 n_spikes : μ.len(),
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
235 ε,
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
236 //postprocessing: config.postprocessing.then(|| μ.clone()),
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
237 .. stats
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
238 };
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
239 let mut stats = IterInfo::new();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
240
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
241 // Run the algorithm
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
242 for state in iterator.iter_init(|| full_stats(&residual, &μ, ε, stats.clone())) {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
243 // Calculate smooth part of surrogate model.
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
244 let mut τv = opA.preadjoint().apply(residual * τ);
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
245
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
246 // Save current base point
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
247 let μ_base = μ.clone();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
248
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
249 // Insert and reweigh
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
250 let (maybe_d, _within_tolerances) = prox_penalty.insert_and_reweigh(
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
251 &mut μ, &mut τv, &μ_base, None,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
252 τ, ε,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
253 config, &reg, &state, &mut stats
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
254 );
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
255
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
256 // Prune and possibly merge spikes
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
257 if config.merge_now(&state) {
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
258 stats.merged += prox_penalty.merge_spikes(&mut μ, &mut τv, &μ_base, τ, ε, config, &reg);
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
259 }
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
260
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
261 stats.pruned += prune_with_stats(&mut μ);
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
262
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
263 // Update residual
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
264 residual = calculate_residual(&μ, opA, b);
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
265
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
266 let iter = state.iteration();
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
267 stats.this_iters += 1;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
268
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
269 // Give statistics if needed
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
270 state.if_verbose(|| {
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
271 plotter.plot_spikes(iter, maybe_d.as_ref(), Some(&τv), &μ);
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
272 full_stats(&residual, &μ, ε, std::mem::replace(&mut stats, IterInfo::new()))
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
273 });
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
274
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
275 // Update main tolerance for next iteration
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
276 ε = tolerance.update(ε, iter);
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
277 }
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
278
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
279 postprocess(μ, config, L2Squared, opA, b)
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
280 }
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
281
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
282 /// Iteratively solve the pointsource localisation problem using inertial forward-backward splitting.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
283 ///
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
284 /// The settings in `config` have their [respective documentation](FBConfig). `opA` is the
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
285 /// forward operator $A$, $b$ the observable, and $\lambda$ the regularisation weight.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
286 /// The operator `op𝒟` is used for forming the proximal term. Typically it is a convolution
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
287 /// operator. Finally, the `iterator` is an outer loop verbosity and iteration count control
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
288 /// as documented in [`alg_tools::iterate`].
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
289 ///
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
290 /// For details on the mathematical formulation, see the [module level](self) documentation.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
291 ///
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
292 /// The implementation relies on [`alg_tools::bisection_tree::BTFN`] presentations of
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
293 /// sums of simple functions usign bisection trees, and the related
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
294 /// [`alg_tools::bisection_tree::Aggregator`]s, to efficiently search for component functions
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
295 /// active at a specific points, and to maximise their sums. Through the implementation of the
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
296 /// [`alg_tools::bisection_tree::BT`] bisection trees, it also relies on the copy-on-write features
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
297 /// of [`std::sync::Arc`] to only update relevant parts of the bisection tree when adding functions.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
298 ///
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
299 /// Returns the final iterate.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
300 #[replace_float_literals(F::cast_from(literal))]
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
301 pub fn pointsource_fista_reg<
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
302 F, I, A, Reg, P, const N : usize
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
303 >(
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
304 opA : &A,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
305 b : &A::Observable,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
306 reg : Reg,
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
307 prox_penalty : &P,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
308 fbconfig : &FBConfig<F>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
309 iterator : I,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
310 mut plotter : SeqPlotter<F, N>,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
311 ) -> RNDM<F, N>
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
312 where
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
313 F : Float + ToNalgebraRealField,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
314 I : AlgIteratorFactory<IterInfo<F, N>>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
315 for<'b> &'b A::Observable : std::ops::Neg<Output=A::Observable>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
316 A : ForwardModel<RNDM<F, N>, F>
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
317 + AdjointProductBoundedBy<RNDM<F, N>, P, FloatType=F>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
318 A::PreadjointCodomain : RealMapping<F, N>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
319 PlotLookup : Plotting<N>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
320 RNDM<F, N> : SpikeMerging<F>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
321 Reg : RegTerm<F, N>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
322 P : ProxPenalty<F, A::PreadjointCodomain, Reg, N>,
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
323 {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
324
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
325 // Set up parameters
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
326 let config = &fbconfig.generic;
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
327 let τ = fbconfig.τ0/opA.adjoint_product_bound(prox_penalty).unwrap();
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
328 let mut λ = 1.0;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
329 // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
330 // by τ compared to the conditional gradient approach.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
331 let tolerance = config.tolerance * τ * reg.tolerance_scaling();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
332 let mut ε = tolerance.initial();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
333
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
334 // Initialise iterates
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
335 let mut μ = DiscreteMeasure::new();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
336 let mut μ_prev = DiscreteMeasure::new();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
337 let mut residual = -b;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
338 let mut warned_merging = false;
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
339
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
340 // Statistics
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
341 let full_stats = |ν : &RNDM<F, N>, ε, stats| IterInfo {
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
342 value : L2Squared.calculate_fit_op(ν, opA, b) + reg.apply(ν),
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
343 n_spikes : ν.len(),
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
344 ε,
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
345 // postprocessing: config.postprocessing.then(|| ν.clone()),
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
346 .. stats
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
347 };
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
348 let mut stats = IterInfo::new();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
349
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
350 // Run the algorithm
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
351 for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
352 // Calculate smooth part of surrogate model.
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
353 let mut τv = opA.preadjoint().apply(residual * τ);
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
354
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
355 // Save current base point
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
356 let μ_base = μ.clone();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
357
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
358 // Insert new spikes and reweigh
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
359 let (maybe_d, _within_tolerances) = prox_penalty.insert_and_reweigh(
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
360 &mut μ, &mut τv, &μ_base, None,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
361 τ, ε,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
362 config, &reg, &state, &mut stats
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
363 );
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
364
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
365 // (Do not) merge spikes.
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
366 if config.merge_now(&state) {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
367 match config.merging {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
368 SpikeMergingMethod::None => { },
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
369 _ => if !warned_merging {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
370 let err = format!("Merging not supported for μFISTA");
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
371 println!("{}", err.red());
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
372 warned_merging = true;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
373 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
374 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
375 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
376
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
377 // Update inertial prameters
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
378 let λ_prev = λ;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
379 λ = 2.0 * λ_prev / ( λ_prev + (4.0 + λ_prev * λ_prev).sqrt() );
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
380 let θ = λ / λ_prev - λ;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
381
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
382 // Perform inertial update on μ.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
383 // This computes μ ← (1 + θ) * μ - θ * μ_prev, pruning spikes where both μ
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
384 // and μ_prev have zero weight. Since both have weights from the finite-dimensional
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
385 // subproblem with a proximal projection step, this is likely to happen when the
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
386 // spike is not needed. A copy of the pruned μ without artithmetic performed is
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
387 // stored in μ_prev.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
388 let n_before_prune = μ.len();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
389 μ.pruning_sub(1.0 + θ, θ, &mut μ_prev);
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
390 debug_assert!(μ.len() <= n_before_prune);
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
391 stats.pruned += n_before_prune - μ.len();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
392
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
393 // Update residual
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
394 residual = calculate_residual(&μ, opA, b);
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
395
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
396 let iter = state.iteration();
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
397 stats.this_iters += 1;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
398
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
399 // Give statistics if needed
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
400 state.if_verbose(|| {
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
401 plotter.plot_spikes(iter, maybe_d.as_ref(), Some(&τv), &μ_prev);
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
402 full_stats(&μ_prev, ε, std::mem::replace(&mut stats, IterInfo::new()))
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
403 });
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
404
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
405 // Update main tolerance for next iteration
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
406 ε = tolerance.update(ε, iter);
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
407 }
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
408
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
409 postprocess(μ_prev, config, L2Squared, opA, b)
24
d29d1fcf5423 Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 13
diff changeset
410 }

mercurial