src/radon_fb.rs

Thu, 29 Aug 2024 00:00:00 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Thu, 29 Aug 2024 00:00:00 -0500
branch
dev
changeset 34
efa60bc4f743
child 35
b087e3eab191
permissions
-rw-r--r--

Radon FB + sliding improvements

34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 /*!
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 Solver for the point source localisation problem using a simplified forward-backward splitting method.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 Instead of the $𝒟$-norm of `fb.rs`, this uses a standard Radon norm for the proximal map.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5 */
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 use numeric_literals::replace_float_literals;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 use serde::{Serialize, Deserialize};
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 use colored::Colorize;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10 use nalgebra::DVector;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 use alg_tools::iterate::{
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 AlgIteratorFactory,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14 AlgIteratorState,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 use alg_tools::euclidean::Euclidean;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 use alg_tools::linops::Apply;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 use alg_tools::sets::Cube;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 use alg_tools::loc::Loc;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 use alg_tools::bisection_tree::{
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 BTFN,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 Bounds,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 BTNodeLookup,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 BTNode,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 BTSearch,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 P2Minimise,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 SupportGenerator,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 LocalAnalysis,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 use alg_tools::mapping::RealMapping;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 use alg_tools::nalgebra_support::ToNalgebraRealField;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 use crate::types::*;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 use crate::measures::{
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 DiscreteMeasure,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 DeltaMeasure,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 use crate::measures::merging::{
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 SpikeMergingMethod,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 SpikeMerging,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42 use crate::forward_model::ForwardModel;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 use crate::plot::{
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 SeqPlotter,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 Plotting,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 PlotLookup
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 use crate::regularisation::RegTerm;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 use crate::dataterm::{
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 calculate_residual,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 L2Squared,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 DataTerm,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 use crate::fb::{
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 FBGenericConfig,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 postprocess
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 /// Settings for [`pointsource_fb_reg`].
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62 #[serde(default)]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 pub struct RadonFBConfig<F : Float> {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 /// Step length scaling
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 pub τ0 : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 /// Generic parameters
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 pub insertion : FBGenericConfig<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 #[replace_float_literals(F::cast_from(literal))]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 impl<F : Float> Default for RadonFBConfig<F> {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 fn default() -> Self {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 RadonFBConfig {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 τ0 : 0.99,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 insertion : Default::default()
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 #[replace_float_literals(F::cast_from(literal))]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 pub(crate) fn insert_and_reweigh<
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82 'a, F, GA, BTA, S, Reg, State, const N : usize
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 >(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84 μ : &mut DiscreteMeasure<Loc<F, N>, F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 minus_τv : &mut BTFN<F, GA, BTA, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 μ_base : &mut DiscreteMeasure<Loc<F, N>, F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 _ν_delta: Option<&DiscreteMeasure<Loc<F, N>, F>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 τ : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89 ε : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 config : &FBGenericConfig<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 reg : &Reg,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 _state : &State,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 stats : &mut IterInfo<F, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 )
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95 where F : Float + ToNalgebraRealField,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 BTA : BTSearch<F, N, Data=usize, Agg=Bounds<F>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 S: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 BTNodeLookup: BTNode<F, usize, Bounds<F>, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 DiscreteMeasure<Loc<F, N>, F> : SpikeMerging<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 Reg : RegTerm<F, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102 State : AlgIteratorState {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 'i_and_w: for i in 0..=1 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105 // Optimise weights
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 if μ.len() > 0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 // Form finite-dimensional subproblem. The subproblem references to the original μ^k
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108 // from the beginning of the iteration are all contained in the immutable c and g.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
109 let g̃ = DVector::from_iterator(μ.len(),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
110 μ.iter_locations()
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 .map(|ζ| F::to_nalgebra_mixed(minus_τv.apply(ζ))));
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 let mut x = μ.masses_dvector();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 let y = μ_base.masses_dvector();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 // Solve finite-dimensional subproblem.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 stats.inner_iters += reg.solve_findim_l1squared(&y, &g̃, τ, &mut x, ε, config);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 // Update masses of μ based on solution of finite-dimensional subproblem.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119 μ.set_masses_dvector(&x);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 if i>0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 // Simple debugging test to see if more inserts would be needed. Doesn't seem so.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 //let n = μ.dist_matching(μ_base);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 //println!("{:?}", reg.find_tolerance_violation_slack(minus_τv, τ, ε, false, config, n));
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 break 'i_and_w
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129 // Calculate ‖μ - μ_base‖_ℳ
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 let n = μ.dist_matching(μ_base);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 // Find a spike to insert, if needed.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 // This only check the overall tolerances, not tolerances on support of μ-μ_base or μ,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 // which are supposed to have been guaranteed by the finite-dimensional weight optimisation.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 match reg.find_tolerance_violation_slack(minus_τv, τ, ε, false, config, n) {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 None => { break 'i_and_w },
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 Some((ξ, _v_ξ, _in_bounds)) => {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 // Weight is found out by running the finite-dimensional optimisation algorithm
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 // above
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 *μ += DeltaMeasure { x : ξ, α : 0.0 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 *μ_base += DeltaMeasure { x : ξ, α : 0.0 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147 #[replace_float_literals(F::cast_from(literal))]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
148 pub(crate) fn prune_and_maybe_simple_merge<
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 'a, F, GA, BTA, S, Reg, State, const N : usize
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150 >(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151 μ : &mut DiscreteMeasure<Loc<F, N>, F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152 minus_τv : &mut BTFN<F, GA, BTA, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 μ_base : &DiscreteMeasure<Loc<F, N>, F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154 τ : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 ε : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
156 config : &FBGenericConfig<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
157 reg : &Reg,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
158 state : &State,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
159 stats : &mut IterInfo<F, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
160 )
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
161 where F : Float + ToNalgebraRealField,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
163 BTA : BTSearch<F, N, Data=usize, Agg=Bounds<F>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 S: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165 BTNodeLookup: BTNode<F, usize, Bounds<F>, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 DiscreteMeasure<Loc<F, N>, F> : SpikeMerging<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167 Reg : RegTerm<F, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
168 State : AlgIteratorState {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
169
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
170 assert!(μ_base.len() <= μ.len());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
171
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 if state.iteration() % config.merge_every == 0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173 stats.merged += μ.merge_spikes(config.merging, |μ_candidate| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
174 // Important: μ_candidate's new points are afterwards,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175 // and do not conflict with μ_base.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
176 // TODO: could simplify to requiring μ_base instead of μ_radon.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177 // but may complicate with sliding base's exgtra points that need to be
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178 // after μ_candidate's extra points.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
179 // TODO: doesn't seem to work, maybe need to merge μ_base as well?
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
180 // Although that doesn't seem to make sense.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
181 let μ_radon = μ_candidate.sub_matching(μ_base);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
182 reg.verify_merge_candidate_radonsq(minus_τv, μ_candidate, τ, ε, &config, &μ_radon)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
183 //let n = μ_candidate.dist_matching(μ_base);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
184 //reg.find_tolerance_violation_slack(minus_τv, τ, ε, false, config, n).is_none()
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
185 });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
186 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
187
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
188 let n_before_prune = μ.len();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
189 μ.prune();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
190 debug_assert!(μ.len() <= n_before_prune);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
191 stats.pruned += n_before_prune - μ.len();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
192 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
193
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
194
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
195 /// Iteratively solve the pointsource localisation problem using simplified forward-backward splitting.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
196 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
197 /// The settings in `config` have their [respective documentation](FBConfig). `opA` is the
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
198 /// forward operator $A$, $b$ the observable, and $\lambda$ the regularisation weight.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
199 /// Finally, the `iterator` is an outer loop verbosity and iteration count control
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
200 /// as documented in [`alg_tools::iterate`].
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
201 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
202 /// For details on the mathematical formulation, see the [module level](self) documentation.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
203 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
204 /// The implementation relies on [`alg_tools::bisection_tree::BTFN`] presentations of
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
205 /// sums of simple functions usign bisection trees, and the related
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
206 /// [`alg_tools::bisection_tree::Aggregator`]s, to efficiently search for component functions
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
207 /// active at a specific points, and to maximise their sums. Through the implementation of the
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
208 /// [`alg_tools::bisection_tree::BT`] bisection trees, it also relies on the copy-on-write features
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
209 /// of [`std::sync::Arc`] to only update relevant parts of the bisection tree when adding functions.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
210 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
211 /// Returns the final iterate.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
212 #[replace_float_literals(F::cast_from(literal))]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
213 pub fn pointsource_radon_fb_reg<
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
214 'a, F, I, A, GA, BTA, S, Reg, const N : usize
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
215 >(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
216 opA : &'a A,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
217 b : &A::Observable,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
218 reg : Reg,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
219 fbconfig : &RadonFBConfig<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
220 iterator : I,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
221 mut _plotter : SeqPlotter<F, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
222 ) -> DiscreteMeasure<Loc<F, N>, F>
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
223 where F : Float + ToNalgebraRealField,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
224 I : AlgIteratorFactory<IterInfo<F, N>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
225 for<'b> &'b A::Observable : std::ops::Neg<Output=A::Observable>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
226 //+ std::ops::Mul<F, Output=A::Observable>, <-- FIXME: compiler overflow
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
227 A::Observable : std::ops::MulAssign<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
228 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
229 A : ForwardModel<Loc<F, N>, F, PreadjointCodomain = BTFN<F, GA, BTA, N>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
230 BTA : BTSearch<F, N, Data=usize, Agg=Bounds<F>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
231 S: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
232 BTNodeLookup: BTNode<F, usize, Bounds<F>, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
233 Cube<F, N>: P2Minimise<Loc<F, N>, F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
234 PlotLookup : Plotting<N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
235 DiscreteMeasure<Loc<F, N>, F> : SpikeMerging<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
236 Reg : RegTerm<F, N> {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
237
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
238 // Set up parameters
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
239 let config = &fbconfig.insertion;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
240 // We need L such that the descent inequality F(ν) - F(μ) - ⟨F'(μ),ν-μ⟩ ≤ (L/2)‖ν-μ‖²_ℳ ∀ ν,μ
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
241 // holds. Since the left hand side expands as (1/2)‖A(ν-μ)‖₂², this is to say, we need L such
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
242 // that ‖Aμ‖₂² ≤ L ‖μ‖²_ℳ ∀ μ. Thus `opnorm_bound` gives the square root of L.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
243 let τ = fbconfig.τ0/opA.opnorm_bound().powi(2);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
244 // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
245 // by τ compared to the conditional gradient approach.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
246 let tolerance = config.tolerance * τ * reg.tolerance_scaling();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
247 let mut ε = tolerance.initial();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
248
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
249 // Initialise iterates
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
250 let mut μ = DiscreteMeasure::new();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
251 let mut residual = -b;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
252 let mut stats = IterInfo::new();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
253
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
254 // Run the algorithm
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
255 iterator.iterate(|state| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
256 // Calculate smooth part of surrogate model.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
257 // Using `std::mem::replace` here is not ideal, and expects that `empty_observable`
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
258 // has no significant overhead. For some reosn Rust doesn't allow us simply moving
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
259 // the residual and replacing it below before the end of this closure.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
260 residual *= -τ;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
261 let r = std::mem::replace(&mut residual, opA.empty_observable());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
262 let mut minus_τv = opA.preadjoint().apply(r);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
263
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
264 // Save current base point
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
265 let mut μ_base = μ.clone();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
266
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
267 // Insert and reweigh
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
268 insert_and_reweigh(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
269 &mut μ, &mut minus_τv, &mut μ_base, None,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
270 τ, ε,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
271 config, &reg, state, &mut stats
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
272 );
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
273
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
274 // Prune and possibly merge spikes
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
275 prune_and_maybe_simple_merge(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
276 &mut μ, &mut minus_τv, &μ_base,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
277 τ, ε,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
278 config, &reg, state, &mut stats
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
279 );
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
280
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
281 // Update residual
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
282 residual = calculate_residual(&μ, opA, b);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
283
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
284 // Update main tolerance for next iteration
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
285 let ε_prev = ε;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
286 ε = tolerance.update(ε, state.iteration());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
287 stats.this_iters += 1;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
288
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
289 // Give function value if needed
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
290 state.if_verbose(|| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
291 // Plot if so requested
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
292 // plotter.plot_spikes(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
293 // format!("iter {} end;", state.iteration()), &d,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
294 // "start".to_string(), Some(&minus_τv),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
295 // reg.target_bounds(τ, ε_prev), &μ,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
296 // );
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
297 // Calculate mean inner iterations and reset relevant counters.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
298 // Return the statistics
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
299 let res = IterInfo {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
300 value : residual.norm2_squared_div2() + reg.apply(&μ),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
301 n_spikes : μ.len(),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
302 ε : ε_prev,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
303 postprocessing: config.postprocessing.then(|| μ.clone()),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
304 .. stats
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
305 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
306 stats = IterInfo::new();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
307 res
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
308 })
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
309 });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
310
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
311 postprocess(μ, config, L2Squared, opA, b)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
312 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
313
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
314 /// Iteratively solve the pointsource localisation problem using simplified inertial forward-backward splitting.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
315 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
316 /// The settings in `config` have their [respective documentation](FBConfig). `opA` is the
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
317 /// forward operator $A$, $b$ the observable, and $\lambda$ the regularisation weight.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
318 /// Finally, the `iterator` is an outer loop verbosity and iteration count control
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
319 /// as documented in [`alg_tools::iterate`].
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
320 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
321 /// For details on the mathematical formulation, see the [module level](self) documentation.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
322 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
323 /// The implementation relies on [`alg_tools::bisection_tree::BTFN`] presentations of
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
324 /// sums of simple functions usign bisection trees, and the related
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
325 /// [`alg_tools::bisection_tree::Aggregator`]s, to efficiently search for component functions
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
326 /// active at a specific points, and to maximise their sums. Through the implementation of the
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
327 /// [`alg_tools::bisection_tree::BT`] bisection trees, it also relies on the copy-on-write features
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
328 /// of [`std::sync::Arc`] to only update relevant parts of the bisection tree when adding functions.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
329 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
330 /// Returns the final iterate.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
331 #[replace_float_literals(F::cast_from(literal))]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
332 pub fn pointsource_radon_fista_reg<
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
333 'a, F, I, A, GA, BTA, S, Reg, const N : usize
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
334 >(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
335 opA : &'a A,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
336 b : &A::Observable,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
337 reg : Reg,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
338 fbconfig : &RadonFBConfig<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
339 iterator : I,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
340 mut _plotter : SeqPlotter<F, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
341 ) -> DiscreteMeasure<Loc<F, N>, F>
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
342 where F : Float + ToNalgebraRealField,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
343 I : AlgIteratorFactory<IterInfo<F, N>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
344 for<'b> &'b A::Observable : std::ops::Neg<Output=A::Observable>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
345 //+ std::ops::Mul<F, Output=A::Observable>, <-- FIXME: compiler overflow
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
346 A::Observable : std::ops::MulAssign<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
347 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
348 A : ForwardModel<Loc<F, N>, F, PreadjointCodomain = BTFN<F, GA, BTA, N>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
349 BTA : BTSearch<F, N, Data=usize, Agg=Bounds<F>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
350 S: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
351 BTNodeLookup: BTNode<F, usize, Bounds<F>, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
352 Cube<F, N>: P2Minimise<Loc<F, N>, F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
353 PlotLookup : Plotting<N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
354 DiscreteMeasure<Loc<F, N>, F> : SpikeMerging<F>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
355 Reg : RegTerm<F, N> {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
356
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
357 // Set up parameters
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
358 let config = &fbconfig.insertion;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
359 // We need L such that the descent inequality F(ν) - F(μ) - ⟨F'(μ),ν-μ⟩ ≤ (L/2)‖ν-μ‖²_ℳ ∀ ν,μ
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
360 // holds. Since the left hand side expands as (1/2)‖A(ν-μ)‖₂², this is to say, we need L such
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
361 // that ‖Aμ‖₂² ≤ L ‖μ‖²_ℳ ∀ μ. Thus `opnorm_bound` gives the square root of L.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
362 let τ = fbconfig.τ0/opA.opnorm_bound().powi(2);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
363 let mut λ = 1.0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
364 // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
365 // by τ compared to the conditional gradient approach.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
366 let tolerance = config.tolerance * τ * reg.tolerance_scaling();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
367 let mut ε = tolerance.initial();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
368
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
369 // Initialise iterates
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
370 let mut μ = DiscreteMeasure::new();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
371 let mut μ_prev = DiscreteMeasure::new();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
372 let mut residual = -b;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
373 let mut stats = IterInfo::new();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
374 let mut warned_merging = false;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
375
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
376 // Run the algorithm
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
377 iterator.iterate(|state| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
378 // Calculate smooth part of surrogate model.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
379 // Using `std::mem::replace` here is not ideal, and expects that `empty_observable`
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
380 // has no significant overhead. For some reosn Rust doesn't allow us simply moving
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
381 // the residual and replacing it below before the end of this closure.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
382 residual *= -τ;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
383 let r = std::mem::replace(&mut residual, opA.empty_observable());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
384 let mut minus_τv = opA.preadjoint().apply(r);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
385
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
386 // Save current base point
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
387 let mut μ_base = μ.clone();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
388
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
389 // Insert new spikes and reweigh
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
390 insert_and_reweigh(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
391 &mut μ, &mut minus_τv, &mut μ_base, None,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
392 τ, ε,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
393 config, &reg, state, &mut stats
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
394 );
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
395
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
396 // (Do not) merge spikes.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
397 if state.iteration() % config.merge_every == 0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
398 match config.merging {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
399 SpikeMergingMethod::None => { },
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
400 _ => if !warned_merging {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
401 let err = format!("Merging not supported for μFISTA");
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
402 println!("{}", err.red());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
403 warned_merging = true;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
404 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
405 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
406 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
407
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
408 // Update inertial prameters
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
409 let λ_prev = λ;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
410 λ = 2.0 * λ_prev / ( λ_prev + (4.0 + λ_prev * λ_prev).sqrt() );
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
411 let θ = λ / λ_prev - λ;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
412
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
413 // Perform inertial update on μ.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
414 // This computes μ ← (1 + θ) * μ - θ * μ_prev, pruning spikes where both μ
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
415 // and μ_prev have zero weight. Since both have weights from the finite-dimensional
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
416 // subproblem with a proximal projection step, this is likely to happen when the
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
417 // spike is not needed. A copy of the pruned μ without artithmetic performed is
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
418 // stored in μ_prev.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
419 let n_before_prune = μ.len();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
420 μ.pruning_sub(1.0 + θ, θ, &mut μ_prev);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
421 debug_assert!(μ.len() <= n_before_prune);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
422 stats.pruned += n_before_prune - μ.len();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
423
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
424 // Update residual
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
425 residual = calculate_residual(&μ, opA, b);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
426
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
427 // Update main tolerance for next iteration
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
428 let ε_prev = ε;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
429 ε = tolerance.update(ε, state.iteration());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
430 stats.this_iters += 1;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
431
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
432 // Give function value if needed
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
433 state.if_verbose(|| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
434 // Plot if so requested
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
435 // plotter.plot_spikes(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
436 // format!("iter {} end;", state.iteration()), &d,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
437 // "start".to_string(), Some(&minus_τv),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
438 // reg.target_bounds(τ, ε_prev), &μ_prev,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
439 // );
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
440 // Calculate mean inner iterations and reset relevant counters.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
441 // Return the statistics
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
442 let res = IterInfo {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
443 value : L2Squared.calculate_fit_op(&μ_prev, opA, b) + reg.apply(&μ_prev),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
444 n_spikes : μ_prev.len(),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
445 ε : ε_prev,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
446 postprocessing: config.postprocessing.then(|| μ_prev.clone()),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
447 .. stats
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
448 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
449 stats = IterInfo::new();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
450 res
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
451 })
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
452 });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
453
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
454 postprocess(μ_prev, config, L2Squared, opA, b)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
455 }

mercurial