10 use alg_tools::nalgebra_support::ToNalgebraRealField; |
10 use alg_tools::nalgebra_support::ToNalgebraRealField; |
11 use alg_tools::iterate::{ |
11 use alg_tools::iterate::{ |
12 AlgIteratorIteration, |
12 AlgIteratorIteration, |
13 AlgIterator, |
13 AlgIterator, |
14 }; |
14 }; |
15 use crate::measures::{ |
15 use crate::measures::RNDM; |
16 RNDM, |
|
17 }; |
|
18 use crate::types::{ |
16 use crate::types::{ |
19 RefinementSettings, |
17 RefinementSettings, |
20 IterInfo, |
18 IterInfo, |
21 }; |
19 }; |
22 use crate::subproblem::{ |
20 use crate::subproblem::InnerSettings; |
23 InnerSettings, |
|
24 InnerMethod, |
|
25 }; |
|
26 use crate::tolerance::Tolerance; |
21 use crate::tolerance::Tolerance; |
27 use crate::measures::merging::SpikeMergingMethod; |
22 use crate::measures::merging::SpikeMergingMethod; |
28 use crate::regularisation::RegTerm; |
23 use crate::regularisation::RegTerm; |
29 |
24 |
30 pub mod wave; |
25 pub mod wave; |
64 pub merging : SpikeMergingMethod<F>, |
59 pub merging : SpikeMergingMethod<F>, |
65 |
60 |
66 /// Tolerance multiplier for merges |
61 /// Tolerance multiplier for merges |
67 pub merge_tolerance_mult : F, |
62 pub merge_tolerance_mult : F, |
68 |
63 |
69 /// Spike merging method after the last step |
64 /// Merge spikes after last step (even if merging not generally enabled) |
70 pub final_merging : SpikeMergingMethod<F>, |
65 pub final_merging : bool, |
|
66 |
|
67 /// Use fitness as merging criterion. Implies worse convergence guarantees. |
|
68 pub fitness_merging : bool, |
71 |
69 |
72 /// Iterations between merging heuristic tries |
70 /// Iterations between merging heuristic tries |
73 pub merge_every : usize, |
71 pub merge_every : usize, |
74 |
72 |
75 // /// Save $μ$ for postprocessing optimisation |
73 // /// Save $μ$ for postprocessing optimisation |
84 insertion_cutoff_factor : 1.0, |
82 insertion_cutoff_factor : 1.0, |
85 refinement : Default::default(), |
83 refinement : Default::default(), |
86 max_insertions : 100, |
84 max_insertions : 100, |
87 //bootstrap_insertions : None, |
85 //bootstrap_insertions : None, |
88 bootstrap_insertions : Some((10, 1)), |
86 bootstrap_insertions : Some((10, 1)), |
89 inner : InnerSettings { |
87 inner : Default::default(), |
90 method : InnerMethod::Default, |
88 merging : Default::default(), |
91 .. Default::default() |
89 final_merging : true, |
92 }, |
90 fitness_merging : false, |
93 merging : SpikeMergingMethod::None, |
|
94 //merging : Default::default(), |
|
95 final_merging : Default::default(), |
|
96 merge_every : 10, |
91 merge_every : 10, |
97 merge_tolerance_mult : 2.0, |
92 merge_tolerance_mult : 2.0, |
98 // postprocessing : false, |
93 // postprocessing : false, |
99 } |
94 } |
100 } |
95 } |
101 } |
96 } |
102 |
97 |
103 impl<F : Float> FBGenericConfig<F> { |
98 impl<F : Float> FBGenericConfig<F> { |
104 /// Check if merging should be attempted this iteration |
99 /// Check if merging should be attempted this iteration |
105 pub fn merge_now<I : AlgIterator>(&self, state : &AlgIteratorIteration<I>) -> bool { |
100 pub fn merge_now<I : AlgIterator>(&self, state : &AlgIteratorIteration<I>) -> bool { |
106 state.iteration() % self.merge_every == 0 |
101 self.merging.enabled && state.iteration() % self.merge_every == 0 |
|
102 } |
|
103 |
|
104 /// Returns the final merging method |
|
105 pub fn final_merging_method(&self) -> SpikeMergingMethod<F> { |
|
106 SpikeMergingMethod{ enabled : self.final_merging, ..self.merging} |
107 } |
107 } |
108 } |
108 } |
109 |
109 |
110 |
110 |
111 /// Trait for proximal penalties |
111 /// Trait for proximal penalties |
143 where |
143 where |
144 I : AlgIterator; |
144 I : AlgIterator; |
145 |
145 |
146 |
146 |
147 /// Merge spikes, if possible. |
147 /// Merge spikes, if possible. |
|
148 /// |
|
149 /// Either optimality condition merging or objective value (fitness) merging |
|
150 /// may be used, the latter only if `fitness` is provided and `config.fitness_merging` |
|
151 /// is set. |
148 fn merge_spikes( |
152 fn merge_spikes( |
149 &self, |
153 &self, |
150 μ : &mut RNDM<F, N>, |
154 μ : &mut RNDM<F, N>, |
151 τv : &mut PreadjointCodomain, |
155 τv : &mut PreadjointCodomain, |
152 μ_base : &RNDM<F, N>, |
156 μ_base : &RNDM<F, N>, |
|
157 ν_delta: Option<&RNDM<F, N>>, |
153 τ : F, |
158 τ : F, |
154 ε : F, |
159 ε : F, |
155 config : &FBGenericConfig<F>, |
160 config : &FBGenericConfig<F>, |
156 reg : &Reg, |
161 reg : &Reg, |
|
162 fitness : Option<impl Fn(&RNDM<F, N>) -> F>, |
157 ) -> usize; |
163 ) -> usize; |
|
164 |
|
165 /// Merge spikes, if possible. |
|
166 /// |
|
167 /// Unlike [`merge_spikes`], this variant only supports optimality condition based merging |
|
168 #[inline] |
|
169 fn merge_spikes_no_fitness( |
|
170 &self, |
|
171 μ : &mut RNDM<F, N>, |
|
172 τv : &mut PreadjointCodomain, |
|
173 μ_base : &RNDM<F, N>, |
|
174 ν_delta: Option<&RNDM<F, N>>, |
|
175 τ : F, |
|
176 ε : F, |
|
177 config : &FBGenericConfig<F>, |
|
178 reg : &Reg, |
|
179 ) -> usize { |
|
180 /// This is a hack to create a `None` of same type as a `Some` |
|
181 // for the `impl Fn` parameter of `merge_spikes`. |
|
182 #[inline] |
|
183 fn into_none<T>(_ : Option<T>) -> Option<T>{ |
|
184 None |
|
185 } |
|
186 self.merge_spikes(μ, τv, μ_base, ν_delta, τ, ε, config, reg, |
|
187 into_none(Some(|_ : &RNDM<F, N>| F::ZERO))) |
|
188 } |
158 } |
189 } |