Thu, 06 Feb 2025 23:52:22 -0500
radon rearrangements
0 | 1 | /*! |
2 | Solver for the point source localisation problem using a conditional gradient method. | |
3 | ||
4 | We implement two variants, the “fully corrective” method from | |
5 | ||
6 | * Pieper K., Walter D. _Linear convergence of accelerated conditional gradient algorithms | |
7 | in spaces of measures_, DOI: [10.1051/cocv/2021042](https://doi.org/10.1051/cocv/2021042), | |
8 | arXiv: [1904.09218](https://doi.org/10.48550/arXiv.1904.09218). | |
9 | ||
10 | and what we call the “relaxed” method from | |
11 | ||
12 | * Bredies K., Pikkarainen H. - _Inverse problems in spaces of measures_, | |
13 | DOI: [10.1051/cocv/2011205](https://doi.org/0.1051/cocv/2011205). | |
14 | */ | |
15 | ||
16 | use numeric_literals::replace_float_literals; | |
35 | 17 | use nalgebra::{DMatrix, DVector}; |
0 | 18 | use serde::{Serialize, Deserialize}; |
19 | //use colored::Colorize; | |
20 | ||
21 | use alg_tools::iterate::{ | |
22 | AlgIteratorFactory, | |
23 | AlgIteratorOptions, | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
24 | ValueIteratorFactory, |
0 | 25 | }; |
26 | use alg_tools::euclidean::Euclidean; | |
27 | use alg_tools::norms::Norm; | |
35 | 28 | use alg_tools::linops::Mapping; |
0 | 29 | use alg_tools::sets::Cube; |
30 | use alg_tools::loc::Loc; | |
31 | use alg_tools::bisection_tree::{ | |
32 | BTFN, | |
33 | Bounds, | |
34 | BTNodeLookup, | |
35 | BTNode, | |
36 | BTSearch, | |
37 | P2Minimise, | |
38 | SupportGenerator, | |
39 | LocalAnalysis, | |
40 | }; | |
41 | use alg_tools::mapping::RealMapping; | |
42 | use alg_tools::nalgebra_support::ToNalgebraRealField; | |
35 | 43 | use alg_tools::norms::L2; |
0 | 44 | |
45 | use crate::types::*; | |
46 | use crate::measures::{ | |
35 | 47 | RNDM, |
0 | 48 | DiscreteMeasure, |
49 | DeltaMeasure, | |
50 | Radon, | |
51 | }; | |
52 | use crate::measures::merging::{ | |
53 | SpikeMergingMethod, | |
54 | SpikeMerging, | |
55 | }; | |
56 | use crate::forward_model::ForwardModel; | |
57 | #[allow(unused_imports)] // Used in documentation | |
58 | use crate::subproblem::{ | |
24
d29d1fcf5423
Support arbitrary regularisation terms; implement non-positivity-constrained regularisation.
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
59 | unconstrained::quadratic_unconstrained, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
60 | nonneg::quadratic_nonneg, |
0 | 61 | InnerSettings, |
62 | InnerMethod, | |
63 | }; | |
64 | use crate::tolerance::Tolerance; | |
65 | use crate::plot::{ | |
66 | SeqPlotter, | |
67 | Plotting, | |
68 | PlotLookup | |
69 | }; | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
70 | use crate::regularisation::{ |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
71 | NonnegRadonRegTerm, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
72 | RadonRegTerm, |
32 | 73 | RegTerm |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
74 | }; |
0 | 75 | |
35 | 76 | /// Settings for [`pointsource_fw_reg`]. |
0 | 77 | #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] |
78 | #[serde(default)] | |
79 | pub struct FWConfig<F : Float> { | |
80 | /// Tolerance for branch-and-bound new spike location discovery | |
81 | pub tolerance : Tolerance<F>, | |
82 | /// Inner problem solution configuration. Has to have `method` set to [`InnerMethod::FB`] | |
83 | /// as the conditional gradient subproblems' optimality conditions do not in general have an | |
84 | /// invertible Newton derivative for SSN. | |
85 | pub inner : InnerSettings<F>, | |
86 | /// Variant of the conditional gradient method | |
87 | pub variant : FWVariant, | |
88 | /// Settings for branch and bound refinement when looking for predual maxima | |
89 | pub refinement : RefinementSettings<F>, | |
90 | /// Spike merging heuristic | |
91 | pub merging : SpikeMergingMethod<F>, | |
92 | } | |
93 | ||
94 | /// Conditional gradient method variant; see also [`FWConfig`]. | |
95 | #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] | |
96 | #[allow(dead_code)] | |
97 | pub enum FWVariant { | |
98 | /// Algorithm 2 of Walter-Pieper | |
99 | FullyCorrective, | |
100 | /// Bredies–Pikkarainen. Forces `FWConfig.inner.max_iter = 1`. | |
101 | Relaxed, | |
102 | } | |
103 | ||
104 | impl<F : Float> Default for FWConfig<F> { | |
105 | fn default() -> Self { | |
106 | FWConfig { | |
107 | tolerance : Default::default(), | |
108 | refinement : Default::default(), | |
109 | inner : Default::default(), | |
110 | variant : FWVariant::FullyCorrective, | |
39
6316d68b58af
Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
37
diff
changeset
|
111 | merging : SpikeMergingMethod { enabled : true, ..Default::default() }, |
0 | 112 | } |
113 | } | |
114 | } | |
115 | ||
35 | 116 | pub trait FindimQuadraticModel<Domain, F> : ForwardModel<DiscreteMeasure<Domain, F>, F> |
117 | where | |
118 | F : Float + ToNalgebraRealField, | |
119 | Domain : Clone + PartialEq, | |
120 | { | |
121 | /// Return A_*A and A_* b | |
122 | fn findim_quadratic_model( | |
123 | &self, | |
124 | μ : &DiscreteMeasure<Domain, F>, | |
125 | b : &Self::Observable | |
126 | ) -> (DMatrix<F::MixedType>, DVector<F::MixedType>); | |
127 | } | |
128 | ||
129 | /// Helper struct for pre-initialising the finite-dimensional subproblem solver. | |
0 | 130 | pub struct FindimData<F : Float> { |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
131 | /// ‖A‖^2 |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
132 | opAnorm_squared : F, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
133 | /// Bound $M_0$ from the Bredies–Pikkarainen article. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
134 | m0 : F |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
135 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
136 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
137 | /// Trait for finite dimensional weight optimisation. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
138 | pub trait WeightOptim< |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
139 | F : Float + ToNalgebraRealField, |
35 | 140 | A : ForwardModel<RNDM<F, N>, F>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
141 | I : AlgIteratorFactory<F>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
142 | const N : usize |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
143 | > { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
144 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
145 | /// Return a pre-initialisation struct for [`Self::optimise_weights`]. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
146 | /// |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
147 | /// The parameter `opA` is the forward operator $A$. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
148 | fn prepare_optimise_weights(&self, opA : &A, b : &A::Observable) -> FindimData<F>; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
149 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
150 | /// Solve the finite-dimensional weight optimisation problem for the 2-norm-squared data fidelity |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
151 | /// point source localisation problem. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
152 | /// |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
153 | /// That is, we minimise |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
154 | /// <div>$$ |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
155 | /// μ ↦ \frac{1}{2}\|Aμ-b\|_w^2 + G(μ) |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
156 | /// $$</div> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
157 | /// only with respect to the weights of $μ$. Here $G$ is a regulariser modelled by `Self`. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
158 | /// |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
159 | /// The parameter `μ` is the discrete measure whose weights are to be optimised. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
160 | /// The `opA` parameter is the forward operator $A$, while `b`$ and `α` are as in the |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
161 | /// objective above. The method parameter are set in `inner` (see [`InnerSettings`]), while |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
162 | /// `iterator` is used to iterate the steps of the method, and `plotter` may be used to |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
163 | /// save intermediate iteration states as images. The parameter `findim_data` should be |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
164 | /// prepared using [`Self::prepare_optimise_weights`]: |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
165 | /// |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
166 | /// Returns the number of iterations taken by the method configured in `inner`. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
167 | fn optimise_weights<'a>( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
168 | &self, |
35 | 169 | μ : &mut RNDM<F, N>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
170 | opA : &'a A, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
171 | b : &A::Observable, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
172 | findim_data : &FindimData<F>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
173 | inner : &InnerSettings<F>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
174 | iterator : I |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
175 | ) -> usize; |
0 | 176 | } |
177 | ||
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
178 | /// Trait for regularisation terms supported by [`pointsource_fw_reg`]. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
179 | pub trait RegTermFW< |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
180 | F : Float + ToNalgebraRealField, |
35 | 181 | A : ForwardModel<RNDM<F, N>, F>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
182 | I : AlgIteratorFactory<F>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
183 | const N : usize |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
184 | > : RegTerm<F, N> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
185 | + WeightOptim<F, A, I, N> |
35 | 186 | + Mapping<RNDM<F, N>, Codomain = F> { |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
187 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
188 | /// With $g = A\_\*(Aμ-b)$, returns $(x, g(x))$ for $x$ a new point to be inserted |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
189 | /// into $μ$, as determined by the regulariser. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
190 | /// |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
191 | /// The parameters `refinement_tolerance` and `max_steps` are passed to relevant |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
192 | /// [`BTFN`] minimisation and maximisation routines. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
193 | fn find_insertion( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
194 | &self, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
195 | g : &mut A::PreadjointCodomain, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
196 | refinement_tolerance : F, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
197 | max_steps : usize |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
198 | ) -> (Loc<F, N>, F); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
199 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
200 | /// Insert point `ξ` into `μ` for the relaxed algorithm from Bredies–Pikkarainen. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
201 | fn relaxed_insert<'a>( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
202 | &self, |
35 | 203 | μ : &mut RNDM<F, N>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
204 | g : &A::PreadjointCodomain, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
205 | opA : &'a A, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
206 | ξ : Loc<F, N>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
207 | v_ξ : F, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
208 | findim_data : &FindimData<F> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
209 | ); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
210 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
211 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
212 | #[replace_float_literals(F::cast_from(literal))] |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
213 | impl<F : Float + ToNalgebraRealField, A, I, const N : usize> WeightOptim<F, A, I, N> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
214 | for RadonRegTerm<F> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
215 | where I : AlgIteratorFactory<F>, |
35 | 216 | A : FindimQuadraticModel<Loc<F, N>, F> { |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
217 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
218 | fn prepare_optimise_weights(&self, opA : &A, b : &A::Observable) -> FindimData<F> { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
219 | FindimData{ |
35 | 220 | opAnorm_squared : opA.opnorm_bound(Radon, L2).powi(2), |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
221 | m0 : b.norm2_squared() / (2.0 * self.α()), |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
222 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
223 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
224 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
225 | fn optimise_weights<'a>( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
226 | &self, |
35 | 227 | μ : &mut RNDM<F, N>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
228 | opA : &'a A, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
229 | b : &A::Observable, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
230 | findim_data : &FindimData<F>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
231 | inner : &InnerSettings<F>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
232 | iterator : I |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
233 | ) -> usize { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
234 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
235 | // Form and solve finite-dimensional subproblem. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
236 | let (Ã, g̃) = opA.findim_quadratic_model(&μ, b); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
237 | let mut x = μ.masses_dvector(); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
238 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
239 | // `inner_τ1` is based on an estimate of the operator norm of $A$ from ℳ(Ω) to |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
240 | // ℝ^n. This estimate is a good one for the matrix norm from ℝ^m to ℝ^n when the |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
241 | // former is equipped with the 1-norm. We need the 2-norm. To pass from 1-norm to |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
242 | // 2-norm, we estimate |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
243 | // ‖A‖_{2,2} := sup_{‖x‖_2 ≤ 1} ‖Ax‖_2 ≤ sup_{‖x‖_1 ≤ C} ‖Ax‖_2 |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
244 | // = C sup_{‖x‖_1 ≤ 1} ‖Ax‖_2 = C ‖A‖_{1,2}, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
245 | // where C = √m satisfies ‖x‖_1 ≤ C ‖x‖_2. Since we are intested in ‖A_*A‖, no |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
246 | // square root is needed when we scale: |
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
247 | let normest = findim_data.opAnorm_squared * F::cast_from(μ.len()); |
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
248 | let iters = quadratic_unconstrained(&Ã, &g̃, self.α(), &mut x, |
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
249 | normest, inner, iterator); |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
250 | // Update masses of μ based on solution of finite-dimensional subproblem. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
251 | μ.set_masses_dvector(&x); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
252 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
253 | iters |
0 | 254 | } |
255 | } | |
256 | ||
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
257 | #[replace_float_literals(F::cast_from(literal))] |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
258 | impl<F : Float + ToNalgebraRealField, A, I, S, GA, BTA, const N : usize> RegTermFW<F, A, I, N> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
259 | for RadonRegTerm<F> |
35 | 260 | where |
261 | Cube<F, N> : P2Minimise<Loc<F, N>, F>, | |
262 | I : AlgIteratorFactory<F>, | |
263 | S: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>, | |
264 | GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone, | |
265 | A : FindimQuadraticModel<Loc<F, N>, F, PreadjointCodomain = BTFN<F, GA, BTA, N>>, | |
266 | BTA : BTSearch<F, N, Data=usize, Agg=Bounds<F>>, | |
267 | // FIXME: the following *should not* be needed, they are already implied | |
268 | RNDM<F, N> : Mapping<A::PreadjointCodomain, Codomain = F>, | |
269 | DeltaMeasure<Loc<F, N>, F> : Mapping<A::PreadjointCodomain, Codomain = F>, | |
270 | //A : Mapping<RNDM<F, N>, Codomain = A::Observable>, | |
271 | //A : Mapping<DeltaMeasure<Loc<F, N>, F>, Codomain = A::Observable>, | |
272 | { | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
273 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
274 | fn find_insertion( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
275 | &self, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
276 | g : &mut A::PreadjointCodomain, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
277 | refinement_tolerance : F, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
278 | max_steps : usize |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
279 | ) -> (Loc<F, N>, F) { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
280 | let (ξmax, v_ξmax) = g.maximise(refinement_tolerance, max_steps); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
281 | let (ξmin, v_ξmin) = g.minimise(refinement_tolerance, max_steps); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
282 | if v_ξmin < 0.0 && -v_ξmin > v_ξmax { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
283 | (ξmin, v_ξmin) |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
284 | } else { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
285 | (ξmax, v_ξmax) |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
286 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
287 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
288 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
289 | fn relaxed_insert<'a>( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
290 | &self, |
35 | 291 | μ : &mut RNDM<F, N>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
292 | g : &A::PreadjointCodomain, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
293 | opA : &'a A, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
294 | ξ : Loc<F, N>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
295 | v_ξ : F, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
296 | findim_data : &FindimData<F> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
297 | ) { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
298 | let α = self.0; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
299 | let m0 = findim_data.m0; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
300 | let φ = |t| if t <= m0 { α * t } else { α / (2.0 * m0) * (t*t + m0 * m0) }; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
301 | let v = if v_ξ.abs() <= α { 0.0 } else { m0 / α * v_ξ }; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
302 | let δ = DeltaMeasure { x : ξ, α : v }; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
303 | let dp = μ.apply(g) - δ.apply(g); |
35 | 304 | let d = opA.apply(&*μ) - opA.apply(δ); |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
305 | let r = d.norm2_squared(); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
306 | let s = if r == 0.0 { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
307 | 1.0 |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
308 | } else { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
309 | 1.0.min( (α * μ.norm(Radon) - φ(v.abs()) - dp) / r) |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
310 | }; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
311 | *μ *= 1.0 - s; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
312 | *μ += δ * s; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
313 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
314 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
315 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
316 | #[replace_float_literals(F::cast_from(literal))] |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
317 | impl<F : Float + ToNalgebraRealField, A, I, const N : usize> WeightOptim<F, A, I, N> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
318 | for NonnegRadonRegTerm<F> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
319 | where I : AlgIteratorFactory<F>, |
35 | 320 | A : FindimQuadraticModel<Loc<F, N>, F> { |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
321 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
322 | fn prepare_optimise_weights(&self, opA : &A, b : &A::Observable) -> FindimData<F> { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
323 | FindimData{ |
35 | 324 | opAnorm_squared : opA.opnorm_bound(Radon, L2).powi(2), |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
325 | m0 : b.norm2_squared() / (2.0 * self.α()), |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
326 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
327 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
328 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
329 | fn optimise_weights<'a>( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
330 | &self, |
35 | 331 | μ : &mut RNDM<F, N>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
332 | opA : &'a A, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
333 | b : &A::Observable, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
334 | findim_data : &FindimData<F>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
335 | inner : &InnerSettings<F>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
336 | iterator : I |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
337 | ) -> usize { |
0 | 338 | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
339 | // Form and solve finite-dimensional subproblem. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
340 | let (Ã, g̃) = opA.findim_quadratic_model(&μ, b); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
341 | let mut x = μ.masses_dvector(); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
342 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
343 | // `inner_τ1` is based on an estimate of the operator norm of $A$ from ℳ(Ω) to |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
344 | // ℝ^n. This estimate is a good one for the matrix norm from ℝ^m to ℝ^n when the |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
345 | // former is equipped with the 1-norm. We need the 2-norm. To pass from 1-norm to |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
346 | // 2-norm, we estimate |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
347 | // ‖A‖_{2,2} := sup_{‖x‖_2 ≤ 1} ‖Ax‖_2 ≤ sup_{‖x‖_1 ≤ C} ‖Ax‖_2 |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
348 | // = C sup_{‖x‖_1 ≤ 1} ‖Ax‖_2 = C ‖A‖_{1,2}, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
349 | // where C = √m satisfies ‖x‖_1 ≤ C ‖x‖_2. Since we are intested in ‖A_*A‖, no |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
350 | // square root is needed when we scale: |
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
351 | let normest = findim_data.opAnorm_squared * F::cast_from(μ.len()); |
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
352 | let iters = quadratic_nonneg(&Ã, &g̃, self.α(), &mut x, |
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
353 | normest, inner, iterator); |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
354 | // Update masses of μ based on solution of finite-dimensional subproblem. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
355 | μ.set_masses_dvector(&x); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
356 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
357 | iters |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
358 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
359 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
360 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
361 | #[replace_float_literals(F::cast_from(literal))] |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
362 | impl<F : Float + ToNalgebraRealField, A, I, S, GA, BTA, const N : usize> RegTermFW<F, A, I, N> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
363 | for NonnegRadonRegTerm<F> |
35 | 364 | where |
365 | Cube<F, N> : P2Minimise<Loc<F, N>, F>, | |
366 | I : AlgIteratorFactory<F>, | |
367 | S: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>, | |
368 | GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone, | |
369 | A : FindimQuadraticModel<Loc<F, N>, F, PreadjointCodomain = BTFN<F, GA, BTA, N>>, | |
370 | BTA : BTSearch<F, N, Data=usize, Agg=Bounds<F>>, | |
371 | // FIXME: the following *should not* be needed, they are already implied | |
372 | RNDM<F, N> : Mapping<A::PreadjointCodomain, Codomain = F>, | |
373 | DeltaMeasure<Loc<F, N>, F> : Mapping<A::PreadjointCodomain, Codomain = F>, | |
374 | { | |
0 | 375 | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
376 | fn find_insertion( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
377 | &self, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
378 | g : &mut A::PreadjointCodomain, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
379 | refinement_tolerance : F, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
380 | max_steps : usize |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
381 | ) -> (Loc<F, N>, F) { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
382 | g.maximise(refinement_tolerance, max_steps) |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
383 | } |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
384 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
385 | |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
386 | fn relaxed_insert<'a>( |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
387 | &self, |
35 | 388 | μ : &mut RNDM<F, N>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
389 | g : &A::PreadjointCodomain, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
390 | opA : &'a A, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
391 | ξ : Loc<F, N>, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
392 | v_ξ : F, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
393 | findim_data : &FindimData<F> |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
394 | ) { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
395 | // This is just a verbatim copy of RadonRegTerm::relaxed_insert. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
396 | let α = self.0; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
397 | let m0 = findim_data.m0; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
398 | let φ = |t| if t <= m0 { α * t } else { α / (2.0 * m0) * (t*t + m0 * m0) }; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
399 | let v = if v_ξ.abs() <= α { 0.0 } else { m0 / α * v_ξ }; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
400 | let δ = DeltaMeasure { x : ξ, α : v }; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
401 | let dp = μ.apply(g) - δ.apply(g); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
402 | let d = opA.apply(&*μ) - opA.apply(&δ); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
403 | let r = d.norm2_squared(); |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
404 | let s = if r == 0.0 { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
405 | 1.0 |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
406 | } else { |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
407 | 1.0.min( (α * μ.norm(Radon) - φ(v.abs()) - dp) / r) |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
408 | }; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
409 | *μ *= 1.0 - s; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
410 | *μ += δ * s; |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
411 | } |
0 | 412 | } |
413 | ||
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
414 | |
0 | 415 | /// Solve point source localisation problem using a conditional gradient method |
416 | /// for the 2-norm-squared data fidelity, i.e., the problem | |
417 | /// <div>$$ | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
418 | /// \min_μ \frac{1}{2}\|Aμ-b\|_w^2 + G(μ), |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
419 | /// $$ |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
420 | /// where $G$ is the regularisation term modelled by `reg`. |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
421 | /// </div> |
0 | 422 | /// |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
423 | /// The `opA` parameter is the forward operator $A$, while `b`$ is as in the |
0 | 424 | /// objective above. The method parameter are set in `config` (see [`FWConfig`]), while |
425 | /// `iterator` is used to iterate the steps of the method, and `plotter` may be used to | |
426 | /// save intermediate iteration states as images. | |
427 | #[replace_float_literals(F::cast_from(literal))] | |
37
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
428 | pub fn pointsource_fw_reg<F, I, A, GA, BTA, S, Reg, const N : usize>( |
c5d8bd1a7728
Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
429 | opA : &A, |
0 | 430 | b : &A::Observable, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
431 | reg : Reg, |
0 | 432 | //domain : Cube<F, N>, |
433 | config : &FWConfig<F>, | |
434 | iterator : I, | |
435 | mut plotter : SeqPlotter<F, N>, | |
35 | 436 | ) -> RNDM<F, N> |
0 | 437 | where F : Float + ToNalgebraRealField, |
438 | I : AlgIteratorFactory<IterInfo<F, N>>, | |
439 | for<'b> &'b A::Observable : std::ops::Neg<Output=A::Observable>, | |
440 | GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone, | |
35 | 441 | A : ForwardModel<RNDM<F, N>, F, PreadjointCodomain = BTFN<F, GA, BTA, N>>, |
0 | 442 | BTA : BTSearch<F, N, Data=usize, Agg=Bounds<F>>, |
443 | S: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>, | |
444 | BTNodeLookup: BTNode<F, usize, Bounds<F>, N>, | |
445 | Cube<F, N>: P2Minimise<Loc<F, N>, F>, | |
446 | PlotLookup : Plotting<N>, | |
35 | 447 | RNDM<F, N> : SpikeMerging<F>, |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
448 | Reg : RegTermFW<F, A, ValueIteratorFactory<F, AlgIteratorOptions>, N> { |
0 | 449 | |
450 | // Set up parameters | |
451 | // We multiply tolerance by α for all algoritms. | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
452 | let tolerance = config.tolerance * reg.tolerance_scaling(); |
0 | 453 | let mut ε = tolerance.initial(); |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
454 | let findim_data = reg.prepare_optimise_weights(opA, b); |
0 | 455 | |
456 | // Initialise operators | |
457 | let preadjA = opA.preadjoint(); | |
458 | ||
459 | // Initialise iterates | |
460 | let mut μ = DiscreteMeasure::new(); | |
461 | let mut residual = -b; | |
462 | ||
35 | 463 | // Statistics |
464 | let full_stats = |residual : &A::Observable, | |
465 | ν : &RNDM<F, N>, | |
466 | ε, stats| IterInfo { | |
467 | value : residual.norm2_squared_div2() + reg.apply(ν), | |
468 | n_spikes : ν.len(), | |
469 | ε, | |
470 | .. stats | |
471 | }; | |
472 | let mut stats = IterInfo::new(); | |
0 | 473 | |
474 | // Run the algorithm | |
35 | 475 | for state in iterator.iter_init(|| full_stats(&residual, &μ, ε, stats.clone())) { |
0 | 476 | let inner_tolerance = ε * config.inner.tolerance_mult; |
477 | let refinement_tolerance = ε * config.refinement.tolerance_mult; | |
478 | ||
479 | // Calculate smooth part of surrogate model. | |
35 | 480 | let mut g = preadjA.apply(residual * (-1.0)); |
0 | 481 | |
482 | // Find absolute value maximising point | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
483 | let (ξ, v_ξ) = reg.find_insertion(&mut g, refinement_tolerance, |
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
484 | config.refinement.max_steps); |
0 | 485 | |
486 | let inner_it = match config.variant { | |
487 | FWVariant::FullyCorrective => { | |
488 | // No point in optimising the weight here: the finite-dimensional algorithm is fast. | |
489 | μ += DeltaMeasure { x : ξ, α : 0.0 }; | |
35 | 490 | stats.inserted += 1; |
0 | 491 | config.inner.iterator_options.stop_target(inner_tolerance) |
492 | }, | |
493 | FWVariant::Relaxed => { | |
494 | // Perform a relaxed initialisation of μ | |
25
79943be70720
Implement non-negativity constraints for the conditional gradient methods
Tuomo Valkonen <tuomov@iki.fi>
parents:
24
diff
changeset
|
495 | reg.relaxed_insert(&mut μ, &g, opA, ξ, v_ξ, &findim_data); |
35 | 496 | stats.inserted += 1; |
0 | 497 | // The stop_target is only needed for the type system. |
498 | AlgIteratorOptions{ max_iter : 1, .. config.inner.iterator_options}.stop_target(0.0) | |
499 | } | |
500 | }; | |
501 | ||
35 | 502 | stats.inner_iters += reg.optimise_weights(&mut μ, opA, b, &findim_data, |
503 | &config.inner, inner_it); | |
0 | 504 | |
505 | // Merge spikes and update residual for next step and `if_verbose` below. | |
34
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
506 | let (r, count) = μ.merge_spikes_fitness(config.merging, |
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
507 | |μ̃| opA.apply(μ̃) - b, |
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
508 | A::Observable::norm2_squared); |
efa60bc4f743
Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
32
diff
changeset
|
509 | residual = r; |
35 | 510 | stats.merged += count; |
0 | 511 | |
512 | // Prune points with zero mass | |
513 | let n_before_prune = μ.len(); | |
514 | μ.prune(); | |
515 | debug_assert!(μ.len() <= n_before_prune); | |
35 | 516 | stats.pruned += n_before_prune - μ.len(); |
0 | 517 | |
35 | 518 | stats.this_iters += 1; |
519 | let iter = state.iteration(); | |
0 | 520 | |
35 | 521 | // Give statistics if needed |
0 | 522 | state.if_verbose(|| { |
35 | 523 | plotter.plot_spikes(iter, Some(&g), Option::<&S>::None, &μ); |
524 | full_stats(&residual, &μ, ε, std::mem::replace(&mut stats, IterInfo::new())) | |
525 | }); | |
526 | ||
527 | // Update tolerance | |
528 | ε = tolerance.update(ε, iter); | |
529 | } | |
0 | 530 | |
531 | // Return final iterate | |
532 | μ | |
533 | } |