src/prox_penalty/wave.rs

branch
dev
changeset 39
6316d68b58af
parent 37
c5d8bd1a7728
equal deleted inserted replaced
37:c5d8bd1a7728 39:6316d68b58af
34 }; 34 };
35 use crate::seminorms::DiscreteMeasureOp; 35 use crate::seminorms::DiscreteMeasureOp;
36 use crate::types::{ 36 use crate::types::{
37 IterInfo, 37 IterInfo,
38 }; 38 };
39 use crate::measures::merging::SpikeMergingMethod;
40 use crate::regularisation::RegTerm; 39 use crate::regularisation::RegTerm;
41 use super::{ProxPenalty, FBGenericConfig}; 40 use super::{ProxPenalty, FBGenericConfig};
42 41
43 #[replace_float_literals(F::cast_from(literal))] 42 #[replace_float_literals(F::cast_from(literal))]
44 impl<F, GA, BTA, S, Reg, 𝒟, G𝒟, K, const N : usize> 43 impl<F, GA, BTA, S, Reg, 𝒟, G𝒟, K, const N : usize>
72 ) -> (Option<BTFN<F, BothGenerators<GA, G𝒟>, BTA, N>>, bool) 71 ) -> (Option<BTFN<F, BothGenerators<GA, G𝒟>, BTA, N>>, bool)
73 where 72 where
74 I : AlgIterator 73 I : AlgIterator
75 { 74 {
76 75
77 // TODO: is this inefficient to do in every iteration?
78 let op𝒟norm = self.opnorm_bound(Radon, Linfinity); 76 let op𝒟norm = self.opnorm_bound(Radon, Linfinity);
79 77
80 // Maximum insertion count and measure difference calculation depend on insertion style. 78 // Maximum insertion count and measure difference calculation depend on insertion style.
81 let (max_insertions, warn_insertions) = match (state.iteration(), config.bootstrap_insertions) { 79 let (max_insertions, warn_insertions) = match (state.iteration(), config.bootstrap_insertions) {
82 (i, Some((l, k))) if i <= l => (k, false), 80 (i, Some((l, k))) if i <= l => (k, false),
96 // from the beginning of the iteration are all contained in the immutable c and g. 94 // from the beginning of the iteration are all contained in the immutable c and g.
97 // TODO: observe negation of -τv after switch from minus_τv: finite-dimensional 95 // TODO: observe negation of -τv after switch from minus_τv: finite-dimensional
98 // problems have not yet been updated to sign change. 96 // problems have not yet been updated to sign change.
99 let à = self.findim_matrix(μ.iter_locations()); 97 let à = self.findim_matrix(μ.iter_locations());
100 let g̃ = DVector::from_iterator(μ.len(), 98 let g̃ = DVector::from_iterator(μ.len(),
101 μ.iter_locations() 99 μ.iter_locations()
102 .map(|ζ| ω0.apply(ζ) - τv.apply(ζ)) 100 .map(|ζ| ω0.apply(ζ) - τv.apply(ζ))
103 .map(F::to_nalgebra_mixed)); 101 .map(F::to_nalgebra_mixed));
104 let mut x = μ.masses_dvector(); 102 let mut x = μ.masses_dvector();
105 103
106 // The gradient of the forward component of the inner objective is C^*𝒟Cx - g̃. 104 // The gradient of the forward component of the inner objective is C^*𝒟Cx - g̃.
125 }; 123 };
126 124
127 // If no merging heuristic is used, let's be more conservative about spike insertion, 125 // If no merging heuristic is used, let's be more conservative about spike insertion,
128 // and skip it after first round. If merging is done, being more greedy about spike 126 // and skip it after first round. If merging is done, being more greedy about spike
129 // insertion also seems to improve performance. 127 // insertion also seems to improve performance.
130 let skip_by_rough_check = if let SpikeMergingMethod::None = config.merging { 128 let skip_by_rough_check = if config.merging.enabled {
131 false 129 false
132 } else { 130 } else {
133 count > 0 131 count > 0
134 }; 132 };
135 133
166 fn merge_spikes( 164 fn merge_spikes(
167 &self, 165 &self,
168 μ : &mut RNDM<F, N>, 166 μ : &mut RNDM<F, N>,
169 τv : &mut BTFN<F, GA, BTA, N>, 167 τv : &mut BTFN<F, GA, BTA, N>,
170 μ_base : &RNDM<F, N>, 168 μ_base : &RNDM<F, N>,
169 ν_delta: Option<&RNDM<F, N>>,
171 τ : F, 170 τ : F,
172 ε : F, 171 ε : F,
173 config : &FBGenericConfig<F>, 172 config : &FBGenericConfig<F>,
174 reg : &Reg, 173 reg : &Reg,
174 fitness : Option<impl Fn(&RNDM<F, N>) -> F>,
175 ) -> usize 175 ) -> usize
176 { 176 {
177 if config.fitness_merging {
178 if let Some(f) = fitness {
179 return μ.merge_spikes_fitness(config.merging, f, |&v| v)
180 .1
181 }
182 }
177 μ.merge_spikes(config.merging, |μ_candidate| { 183 μ.merge_spikes(config.merging, |μ_candidate| {
178 let mut d = &*τv + self.preapply(μ_candidate.sub_matching(μ_base)); 184 let mut d = &*τv + self.preapply(match ν_delta {
185 None => μ_candidate.sub_matching(μ_base),
186 Some(ν) => μ_candidate.sub_matching(μ_base) - ν,
187 });
179 reg.verify_merge_candidate(&mut d, μ_candidate, τ, ε, config) 188 reg.verify_merge_candidate(&mut d, μ_candidate, τ, ε, config)
180 }) 189 })
181 } 190 }
182 } 191 }

mercurial