Tue, 08 Apr 2025 13:31:39 -0500
Bump alg_tools version requirement
| 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 | } |