src/experiments.rs

branch
dev
changeset 39
6316d68b58af
parent 37
c5d8bd1a7728
child 41
b6bdb6cb4d44
equal deleted inserted replaced
37:c5d8bd1a7728 39:6316d68b58af
11 11
12 use alg_tools::bisection_tree::*; 12 use alg_tools::bisection_tree::*;
13 use alg_tools::error::DynResult; 13 use alg_tools::error::DynResult;
14 use alg_tools::norms::Linfinity; 14 use alg_tools::norms::Linfinity;
15 15
16 use crate::ExperimentOverrides; 16 use crate::{ExperimentOverrides, AlgorithmOverrides};
17 use crate::kernels::*; 17 use crate::kernels::*;
18 use crate::kernels::SupportProductFirst as Prod; 18 use crate::kernels::SupportProductFirst as Prod;
19 use crate::pdps::PDPSConfig;
20 use crate::types::*; 19 use crate::types::*;
21 use crate::run::{ 20 use crate::run::{
22 RunnableExperiment, 21 RunnableExperiment,
23 ExperimentV2, 22 ExperimentV2,
24 ExperimentBiased, 23 ExperimentBiased,
25 Named, 24 Named,
26 DefaultAlgorithm, 25 DefaultAlgorithm,
27 AlgorithmConfig,
28 ProxTerm
29 }; 26 };
30 //use crate::fb::FBGenericConfig; 27 //use crate::fb::FBGenericConfig;
31 use crate::rand_distr::{SerializableNormal, SaltAndPepper}; 28 use crate::rand_distr::{SerializableNormal, SaltAndPepper};
32 use crate::regularisation::Regularisation; 29 use crate::regularisation::Regularisation;
33 use alg_tools::euclidean::Euclidean; 30 use alg_tools::euclidean::Euclidean;
62 #[clap(name = "2d_l1")] 59 #[clap(name = "2d_l1")]
63 Experiment2D_L1, 60 Experiment2D_L1,
64 /// Two dimensions, “fast” spread, 1-norm data fidelity 61 /// Two dimensions, “fast” spread, 1-norm data fidelity
65 #[clap(name = "2d_l1_fast")] 62 #[clap(name = "2d_l1_fast")]
66 Experiment2D_L1_Fast, 63 Experiment2D_L1_Fast,
67 /// One dimension, “fast” spread, 2-norm-squared data fidelity with extra TV-regularised bias 64 /// One dimension, “fast” spread, 2-norm-squared data fidelity with extra TV-regularised bias
68 #[clap(name = "1d_tv_fast")] 65 #[clap(name = "1d_tv_fast")]
69 Experiment1D_TV_Fast, 66 Experiment1D_TV_Fast,
67 /// Two dimensions, “fast” spread, 2-norm-squared data fidelity with extra TV-regularised bias
68 #[clap(name = "2d_tv_fast")]
69 Experiment2D_TV_Fast,
70 } 70 }
71 71
72 macro_rules! make_float_constant { 72 macro_rules! make_float_constant {
73 ($name:ident = $value:expr) => { 73 ($name:ident = $value:expr) => {
74 #[derive(Debug, Copy, Eq, PartialEq, Clone, Serialize, Deserialize)] 74 #[derive(Debug, Copy, Eq, PartialEq, Clone, Serialize, Deserialize)]
144 make_float_constant!(CutOff1 = 0.15); 144 make_float_constant!(CutOff1 = 0.15);
145 make_float_constant!(Hat1 = 0.16); 145 make_float_constant!(Hat1 = 0.16);
146 make_float_constant!(HatBias = 0.05); 146 make_float_constant!(HatBias = 0.05);
147 147
148 // We use a different step length for PDPS in 2D experiments 148 // We use a different step length for PDPS in 2D experiments
149 let pdps_2d = || { 149 // let pdps_2d = (DefaultAlgorithm::PDPS,
150 let τ0 = 3.0; 150 // AlgorithmOverrides {
151 PDPSConfig { 151 // tau0 : Some(3.0),
152 τ0, 152 // sigma0 : Some(0.99 / 3.0),
153 σ0 : 0.99 / τ0, 153 // .. Default::default()
154 // }
155 // );
156 // let radon_pdps_2d = (DefaultAlgorithm::RadonPDPS,
157 // AlgorithmOverrides {
158 // tau0 : Some(3.0),
159 // sigma0 : Some(0.99 / 3.0),
160 // .. Default::default()
161 // }
162 // );
163 let sliding_fb_cut_gaussian = (DefaultAlgorithm::SlidingFB,
164 AlgorithmOverrides {
165 theta0 : Some(0.3),
154 .. Default::default() 166 .. Default::default()
155 } 167 }
156 }; 168 );
157 let defaults_2d = HashMap::from([ 169 // let higher_cpos = |alg| (alg,
158 (DefaultAlgorithm::PDPS, AlgorithmConfig::PDPS(pdps_2d(), ProxTerm::Wave)), 170 // AlgorithmOverrides {
159 (DefaultAlgorithm::RadonPDPS, AlgorithmConfig::PDPS(pdps_2d(), ProxTerm::RadonSquared)) 171 // transport_tolerance_pos : Some(1000.0),
160 ]); 172 // .. Default::default()
161 173 // }
174 // );
175 let higher_cpos_merging = |alg| (alg,
176 AlgorithmOverrides {
177 transport_tolerance_pos : Some(1000.0),
178 merge : Some(true),
179 fitness_merging : Some(true),
180 .. Default::default()
181 }
182 );
183 let much_higher_cpos_merging_steptune = |alg| (alg,
184 AlgorithmOverrides {
185 transport_tolerance_pri : Some(1000.0),
186 transport_tolerance_pos : Some(10000.0),
187 sigma0 : Some(0.15),
188 theta0 : Some(0.3),
189 merge : Some(true),
190 fitness_merging : Some(true),
191 .. Default::default()
192 }
193 );
162 // We add a hash of the experiment name to the configured 194 // We add a hash of the experiment name to the configured
163 // noise seed to not use the same noise for different experiments. 195 // noise seed to not use the same noise for different experiments.
164 let mut h = DefaultHasher::new(); 196 let mut h = DefaultHasher::new();
165 name.hash(&mut h); 197 name.hash(&mut h);
166 let noise_seed = cli.noise_seed.unwrap_or(BASE_SEED) + h.finish(); 198 let noise_seed = cli.noise_seed.unwrap_or(BASE_SEED) + h.finish();
167 199
200 let default_merge_radius = 0.01;
201
168 use DefaultExperiment::*; 202 use DefaultExperiment::*;
169 Ok(match self { 203 Ok(match self {
170 Experiment1D => { 204 Experiment1D => {
171 let base_spread = Gaussian { variance : Variance1 }; 205 let base_spread = Gaussian { variance : Variance1 };
172 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity }; 206 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity };
173 Box::new(Named { name, data : ExperimentV2 { 207 Box::new(Named { name, data : ExperimentV2 {
174 domain : [[0.0, 1.0]].into(), 208 domain : [[0.0, 1.0]].into(),
175 sensor_count : [N_SENSORS_1D], 209 sensor_count : [N_SENSORS_1D],
176 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.09)), 210 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.08)),
177 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.2))?, 211 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.2))?,
178 dataterm : DataTerm::L2Squared, 212 dataterm : DataTerm::L2Squared,
179 μ_hat : MU_TRUE_1D_BASIC.into(), 213 μ_hat : MU_TRUE_1D_BASIC.into(),
180 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, 214 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity },
181 spread : Prod(spread_cutoff, base_spread), 215 spread : Prod(spread_cutoff, base_spread),
182 kernel : Prod(AutoConvolution(spread_cutoff), base_spread), 216 kernel : Prod(AutoConvolution(spread_cutoff), base_spread),
183 kernel_plot_width, 217 kernel_plot_width,
184 noise_seed, 218 noise_seed,
185 algorithm_defaults: HashMap::new(), 219 default_merge_radius,
220 algorithm_overrides: HashMap::from([
221 sliding_fb_cut_gaussian,
222 higher_cpos_merging(DefaultAlgorithm::RadonFB),
223 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB),
224 ]),
186 }}) 225 }})
187 }, 226 },
188 Experiment1DFast => { 227 Experiment1DFast => {
189 let base_spread = HatConv { radius : Hat1 }; 228 let base_spread = HatConv { radius : Hat1 };
190 Box::new(Named { name, data : ExperimentV2 { 229 Box::new(Named { name, data : ExperimentV2 {
197 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, 236 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity },
198 spread : base_spread, 237 spread : base_spread,
199 kernel : base_spread, 238 kernel : base_spread,
200 kernel_plot_width, 239 kernel_plot_width,
201 noise_seed, 240 noise_seed,
202 algorithm_defaults: HashMap::new(), 241 default_merge_radius,
242 algorithm_overrides: HashMap::from([
243 higher_cpos_merging(DefaultAlgorithm::RadonFB),
244 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB),
245 ]),
203 }}) 246 }})
204 }, 247 },
205 Experiment2D => { 248 Experiment2D => {
206 let base_spread = Gaussian { variance : Variance1 }; 249 let base_spread = Gaussian { variance : Variance1 };
207 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity }; 250 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity };
215 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity }, 258 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity },
216 spread : Prod(spread_cutoff, base_spread), 259 spread : Prod(spread_cutoff, base_spread),
217 kernel : Prod(AutoConvolution(spread_cutoff), base_spread), 260 kernel : Prod(AutoConvolution(spread_cutoff), base_spread),
218 kernel_plot_width, 261 kernel_plot_width,
219 noise_seed, 262 noise_seed,
220 algorithm_defaults: defaults_2d, 263 default_merge_radius,
264 algorithm_overrides: HashMap::from([
265 sliding_fb_cut_gaussian,
266 higher_cpos_merging(DefaultAlgorithm::RadonFB),
267 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB),
268 // pdps_2d,
269 // radon_pdps_2d
270 ]),
221 }}) 271 }})
222 }, 272 },
223 Experiment2DFast => { 273 Experiment2DFast => {
224 let base_spread = HatConv { radius : Hat1 }; 274 let base_spread = HatConv { radius : Hat1 };
225 Box::new(Named { name, data : ExperimentV2 { 275 Box::new(Named { name, data : ExperimentV2 {
232 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity }, 282 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity },
233 spread : base_spread, 283 spread : base_spread,
234 kernel : base_spread, 284 kernel : base_spread,
235 kernel_plot_width, 285 kernel_plot_width,
236 noise_seed, 286 noise_seed,
237 algorithm_defaults: defaults_2d, 287 default_merge_radius,
288 algorithm_overrides: HashMap::from([
289 // pdps_2d,
290 // radon_pdps_2d
291 higher_cpos_merging(DefaultAlgorithm::RadonFB),
292 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB),
293 ]),
238 }}) 294 }})
239 }, 295 },
240 Experiment1D_L1 => { 296 Experiment1D_L1 => {
241 let base_spread = Gaussian { variance : Variance1 }; 297 let base_spread = Gaussian { variance : Variance1 };
242 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity }; 298 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity };
253 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, 309 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity },
254 spread : Prod(spread_cutoff, base_spread), 310 spread : Prod(spread_cutoff, base_spread),
255 kernel : Prod(AutoConvolution(spread_cutoff), base_spread), 311 kernel : Prod(AutoConvolution(spread_cutoff), base_spread),
256 kernel_plot_width, 312 kernel_plot_width,
257 noise_seed, 313 noise_seed,
258 algorithm_defaults: HashMap::new(), 314 default_merge_radius,
315 algorithm_overrides: HashMap::new(),
259 }}) 316 }})
260 }, 317 },
261 Experiment1D_L1_Fast => { 318 Experiment1D_L1_Fast => {
262 let base_spread = HatConv { radius : Hat1 }; 319 let base_spread = HatConv { radius : Hat1 };
263 Box::new(Named { name, data : ExperimentV2 { 320 Box::new(Named { name, data : ExperimentV2 {
273 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, 330 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity },
274 spread : base_spread, 331 spread : base_spread,
275 kernel : base_spread, 332 kernel : base_spread,
276 kernel_plot_width, 333 kernel_plot_width,
277 noise_seed, 334 noise_seed,
278 algorithm_defaults: HashMap::new(), 335 default_merge_radius,
336 algorithm_overrides: HashMap::new(),
279 }}) 337 }})
280 }, 338 },
281 Experiment2D_L1 => { 339 Experiment2D_L1 => {
282 let base_spread = Gaussian { variance : Variance1 }; 340 let base_spread = Gaussian { variance : Variance1 };
283 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity }; 341 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity };
294 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity }, 352 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity },
295 spread : Prod(spread_cutoff, base_spread), 353 spread : Prod(spread_cutoff, base_spread),
296 kernel : Prod(AutoConvolution(spread_cutoff), base_spread), 354 kernel : Prod(AutoConvolution(spread_cutoff), base_spread),
297 kernel_plot_width, 355 kernel_plot_width,
298 noise_seed, 356 noise_seed,
299 algorithm_defaults: defaults_2d, 357 default_merge_radius,
358 algorithm_overrides: HashMap::from([
359 // pdps_2d,
360 // radon_pdps_2d
361 ]),
300 }}) 362 }})
301 }, 363 },
302 Experiment2D_L1_Fast => { 364 Experiment2D_L1_Fast => {
303 let base_spread = HatConv { radius : Hat1 }; 365 let base_spread = HatConv { radius : Hat1 };
304 Box::new(Named { name, data : ExperimentV2 { 366 Box::new(Named { name, data : ExperimentV2 {
314 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity }, 376 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity },
315 spread : base_spread, 377 spread : base_spread,
316 kernel : base_spread, 378 kernel : base_spread,
317 kernel_plot_width, 379 kernel_plot_width,
318 noise_seed, 380 noise_seed,
319 algorithm_defaults: defaults_2d, 381 default_merge_radius,
382 algorithm_overrides: HashMap::from([
383 // pdps_2d,
384 // radon_pdps_2d
385 ]),
320 }}) 386 }})
321 }, 387 },
322 Experiment1D_TV_Fast => { 388 Experiment1D_TV_Fast => {
323 let base_spread = HatConv { radius : HatBias }; 389 let base_spread = HatConv { radius : HatBias };
324 Box::new(Named { name, data : ExperimentBiased { 390 Box::new(Named { name, data : ExperimentBiased {
337 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, 403 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity },
338 spread : base_spread, 404 spread : base_spread,
339 kernel : base_spread, 405 kernel : base_spread,
340 kernel_plot_width, 406 kernel_plot_width,
341 noise_seed, 407 noise_seed,
342 algorithm_defaults: HashMap::new(), 408 default_merge_radius,
409 algorithm_overrides: HashMap::from([
410 higher_cpos_merging(DefaultAlgorithm::RadonForwardPDPS),
411 higher_cpos_merging(DefaultAlgorithm::RadonSlidingPDPS),
412 ]),
413 },
414 }})
415 },
416 Experiment2D_TV_Fast => {
417 let base_spread = HatConv { radius : Hat1 };
418 Box::new(Named { name, data : ExperimentBiased {
419 λ : 0.005,
420 bias : MappingSum::new([
421 Weighted::new(1.0, BallCharacteristic{ center : [0.3, 0.3].into(), radius : 0.2 }),
422 Weighted::new(0.5, BallCharacteristic{ center : [0.6, 0.6].into(), radius : 0.3 }),
423 ]),
424 base : ExperimentV2 {
425 domain : [[0.0, 1.0]; 2].into(),
426 sensor_count : [N_SENSORS_2D; 2],
427 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.06)),
428 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.15))?, //0.25
429 dataterm : DataTerm::L2Squared,
430 μ_hat : MU_TRUE_2D_BASIC.into(),
431 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity },
432 spread : base_spread,
433 kernel : base_spread,
434 kernel_plot_width,
435 noise_seed,
436 default_merge_radius,
437 algorithm_overrides: HashMap::from([
438 much_higher_cpos_merging_steptune(DefaultAlgorithm::RadonForwardPDPS),
439 much_higher_cpos_merging_steptune(DefaultAlgorithm::RadonSlidingPDPS),
440 ]),
343 }, 441 },
344 }}) 442 }})
345 }, 443 },
346 }) 444 })
347 } 445 }

mercurial