| |
1 /*! |
| |
2 Proximal penalty abstraction |
| |
3 */ |
| |
4 |
| |
5 use numeric_literals::replace_float_literals; |
| |
6 use alg_tools::types::*; |
| |
7 use serde::{Serialize, Deserialize}; |
| |
8 |
| |
9 use alg_tools::mapping::RealMapping; |
| |
10 use alg_tools::nalgebra_support::ToNalgebraRealField; |
| |
11 use alg_tools::iterate::{ |
| |
12 AlgIteratorIteration, |
| |
13 AlgIterator, |
| |
14 }; |
| |
15 use crate::measures::{ |
| |
16 RNDM, |
| |
17 }; |
| |
18 use crate::types::{ |
| |
19 RefinementSettings, |
| |
20 IterInfo, |
| |
21 }; |
| |
22 use crate::subproblem::{ |
| |
23 InnerSettings, |
| |
24 InnerMethod, |
| |
25 }; |
| |
26 use crate::tolerance::Tolerance; |
| |
27 use crate::measures::merging::SpikeMergingMethod; |
| |
28 use crate::regularisation::RegTerm; |
| |
29 |
| |
30 pub mod wave; |
| |
31 pub mod radon_squared; |
| |
32 pub use radon_squared::RadonSquared; |
| |
33 |
| |
34 /// Settings for the solution of the stepwise optimality condition. |
| |
35 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] |
| |
36 #[serde(default)] |
| |
37 pub struct FBGenericConfig<F : Float> { |
| |
38 /// Tolerance for point insertion. |
| |
39 pub tolerance : Tolerance<F>, |
| |
40 |
| |
41 /// Stop looking for predual maximum (where to isert a new point) below |
| |
42 /// `tolerance` multiplied by this factor. |
| |
43 /// |
| |
44 /// Not used by [`super::radon_fb`]. |
| |
45 pub insertion_cutoff_factor : F, |
| |
46 |
| |
47 /// Settings for branch and bound refinement when looking for predual maxima |
| |
48 pub refinement : RefinementSettings<F>, |
| |
49 |
| |
50 /// Maximum insertions within each outer iteration |
| |
51 /// |
| |
52 /// Not used by [`super::radon_fb`]. |
| |
53 pub max_insertions : usize, |
| |
54 |
| |
55 /// Pair `(n, m)` for maximum insertions `m` on first `n` iterations. |
| |
56 /// |
| |
57 /// Not used by [`super::radon_fb`]. |
| |
58 pub bootstrap_insertions : Option<(usize, usize)>, |
| |
59 |
| |
60 /// Inner method settings |
| |
61 pub inner : InnerSettings<F>, |
| |
62 |
| |
63 /// Spike merging method |
| |
64 pub merging : SpikeMergingMethod<F>, |
| |
65 |
| |
66 /// Tolerance multiplier for merges |
| |
67 pub merge_tolerance_mult : F, |
| |
68 |
| |
69 /// Spike merging method after the last step |
| |
70 pub final_merging : SpikeMergingMethod<F>, |
| |
71 |
| |
72 /// Iterations between merging heuristic tries |
| |
73 pub merge_every : usize, |
| |
74 |
| |
75 // /// Save $μ$ for postprocessing optimisation |
| |
76 // pub postprocessing : bool |
| |
77 } |
| |
78 |
| |
79 #[replace_float_literals(F::cast_from(literal))] |
| |
80 impl<F : Float> Default for FBGenericConfig<F> { |
| |
81 fn default() -> Self { |
| |
82 FBGenericConfig { |
| |
83 tolerance : Default::default(), |
| |
84 insertion_cutoff_factor : 1.0, |
| |
85 refinement : Default::default(), |
| |
86 max_insertions : 100, |
| |
87 //bootstrap_insertions : None, |
| |
88 bootstrap_insertions : Some((10, 1)), |
| |
89 inner : InnerSettings { |
| |
90 method : InnerMethod::Default, |
| |
91 .. Default::default() |
| |
92 }, |
| |
93 merging : SpikeMergingMethod::None, |
| |
94 //merging : Default::default(), |
| |
95 final_merging : Default::default(), |
| |
96 merge_every : 10, |
| |
97 merge_tolerance_mult : 2.0, |
| |
98 // postprocessing : false, |
| |
99 } |
| |
100 } |
| |
101 } |
| |
102 |
| |
103 impl<F : Float> FBGenericConfig<F> { |
| |
104 /// Check if merging should be attempted this iteration |
| |
105 pub fn merge_now<I : AlgIterator>(&self, state : &AlgIteratorIteration<I>) -> bool { |
| |
106 state.iteration() % self.merge_every == 0 |
| |
107 } |
| |
108 } |
| |
109 |
| |
110 |
| |
111 /// Trait for proximal penalties |
| |
112 pub trait ProxPenalty<F, PreadjointCodomain, Reg, const N : usize> |
| |
113 where |
| |
114 F : Float + ToNalgebraRealField, |
| |
115 Reg : RegTerm<F, N>, |
| |
116 { |
| |
117 type ReturnMapping : RealMapping<F, N>; |
| |
118 |
| |
119 /// Insert new spikes into `μ` to approximately satisfy optimality conditions |
| |
120 /// with the forward step term fixed to `τv`. |
| |
121 /// |
| |
122 /// May return `τv + w` for `w` a subdifferential of the regularisation term `reg`, |
| |
123 /// as well as an indication of whether the tolerance bounds `ε` are satisfied. |
| |
124 /// |
| |
125 /// `μ_base + ν_delta` is the base point, where `μ` and `μ_base` are assumed to have the same |
| |
126 /// spike locations, while `ν_delta` may have different locations. |
| |
127 /// |
| |
128 /// `τv` is mutable to allow [`alg_tools::bisection_tree::btfn::BTFN`] refinement. |
| |
129 /// Actual values of `τv` are not supposed to be mutated. |
| |
130 fn insert_and_reweigh<I>( |
| |
131 &self, |
| |
132 μ : &mut RNDM<F, N>, |
| |
133 τv : &mut PreadjointCodomain, |
| |
134 μ_base : &RNDM<F, N>, |
| |
135 ν_delta: Option<&RNDM<F, N>>, |
| |
136 τ : F, |
| |
137 ε : F, |
| |
138 config : &FBGenericConfig<F>, |
| |
139 reg : &Reg, |
| |
140 state : &AlgIteratorIteration<I>, |
| |
141 stats : &mut IterInfo<F, N>, |
| |
142 ) -> (Option<Self::ReturnMapping>, bool) |
| |
143 where |
| |
144 I : AlgIterator; |
| |
145 |
| |
146 |
| |
147 /// Merge spikes, if possible. |
| |
148 fn merge_spikes( |
| |
149 &self, |
| |
150 μ : &mut RNDM<F, N>, |
| |
151 τv : &mut PreadjointCodomain, |
| |
152 μ_base : &RNDM<F, N>, |
| |
153 τ : F, |
| |
154 ε : F, |
| |
155 config : &FBGenericConfig<F>, |
| |
156 reg : &Reg, |
| |
157 ) -> usize; |
| |
158 } |