| 67 /// Two dimensions, “fast” spread, 2-norm-squared data fidelity with extra TV-regularised bias |
60 /// Two dimensions, “fast” spread, 2-norm-squared data fidelity with extra TV-regularised bias |
| 68 #[clap(name = "2d_tv_fast")] |
61 #[clap(name = "2d_tv_fast")] |
| 69 Experiment2D_TV_Fast, |
62 Experiment2D_TV_Fast, |
| 70 } |
63 } |
| 71 |
64 |
| |
65 /// Command line experiment setup overrides |
| |
66 #[skip_serializing_none] |
| |
67 #[derive(Parser, Debug, Serialize, Deserialize, Default, Clone, Hash)] |
| |
68 pub struct DefaultExperimentSetup<F: ClapFloat> { |
| |
69 /// List of experiments to perform |
| |
70 #[arg(value_name = "EXPERIMENT")] |
| |
71 experiments: Vec<DefaultExperiment>, |
| |
72 |
| |
73 #[arg(long)] |
| |
74 /// Regularisation parameter override. |
| |
75 /// |
| |
76 /// Only use if running just a single experiment, as different experiments have different |
| |
77 /// regularisation parameters. |
| |
78 alpha: Option<F>, |
| |
79 |
| |
80 #[arg(long)] |
| |
81 /// Gaussian noise variance override |
| |
82 variance: Option<F>, |
| |
83 |
| |
84 #[arg(long, value_names = &["MAGNITUDE", "PROBABILITY"])] |
| |
85 /// Salt and pepper noise override. |
| |
86 salt_and_pepper: Option<Vec<F>>, |
| |
87 |
| |
88 #[arg(long)] |
| |
89 /// Noise seed |
| |
90 noise_seed: Option<u64>, |
| |
91 } |
| |
92 |
| 72 macro_rules! make_float_constant { |
93 macro_rules! make_float_constant { |
| 73 ($name:ident = $value:expr) => { |
94 ($name:ident = $value:expr) => { |
| 74 #[derive(Debug, Copy, Eq, PartialEq, Clone, Serialize, Deserialize)] |
95 #[derive(Debug, Copy, Eq, PartialEq, Clone, Serialize, Deserialize)] |
| 75 #[serde(into = "float")] |
96 #[serde(into = "float")] |
| 76 struct $name; |
97 struct $name; |
| 77 impl Into<float> for $name { |
98 impl Into<f64> for $name { |
| 78 #[inline] |
99 #[inline] |
| 79 fn into(self) -> float { $value } |
100 fn into(self) -> float { |
| |
101 $value |
| |
102 } |
| 80 } |
103 } |
| 81 impl Constant for $name { |
104 impl Constant for $name { |
| 82 type Type = float; |
105 type Type = float; |
| 83 fn value(&self) -> float { $value } |
106 fn value(&self) -> float { |
| |
107 $value |
| |
108 } |
| 84 } |
109 } |
| 85 } |
110 }; |
| 86 } |
111 } |
| 87 |
112 |
| 88 /// Ground-truth measure spike locations and magnitudes for 1D experiments |
113 /// Ground-truth measure spike locations and magnitudes for 1D experiments |
| 89 static MU_TRUE_1D_BASIC : [(float, float); 4] = [ |
114 static MU_TRUE_1D_BASIC: [(float, float); 4] = |
| 90 (0.10, 10.0), |
115 [(0.10, 10.0), (0.30, 2.0), (0.70, 3.0), (0.80, 5.0)]; |
| 91 (0.30, 2.0), |
|
| 92 (0.70, 3.0), |
|
| 93 (0.80, 5.0) |
|
| 94 ]; |
|
| 95 |
116 |
| 96 /// Ground-truth measure spike locations and magnitudes for 2D experiments |
117 /// Ground-truth measure spike locations and magnitudes for 2D experiments |
| 97 static MU_TRUE_2D_BASIC : [([float; 2], float); 4] = [ |
118 static MU_TRUE_2D_BASIC: [([float; 2], float); 4] = [ |
| 98 ([0.15, 0.15], 10.0), |
119 ([0.15, 0.15], 10.0), |
| 99 ([0.75, 0.45], 2.0), |
120 ([0.75, 0.45], 2.0), |
| 100 ([0.80, 0.50], 4.0), |
121 ([0.80, 0.50], 4.0), |
| 101 ([0.30, 0.70], 5.0) |
122 ([0.30, 0.70], 5.0), |
| 102 ]; |
123 ]; |
| 103 |
124 |
| 104 /// The $\{0,1\}$-valued characteristic function of a ball as a [`Mapping`]. |
125 /// The $\{0,1\}$-valued characteristic function of a ball as a [`Mapping`]. |
| 105 #[derive(Debug,Copy,Clone,Serialize,PartialEq)] |
126 #[derive(Debug, Copy, Clone, Serialize, PartialEq)] |
| 106 struct BallCharacteristic<F : Float, const N : usize> { |
127 struct BallCharacteristic<F: Float, const N: usize> { |
| 107 pub center : Loc<F, N>, |
128 pub center: Loc<N, F>, |
| 108 pub radius : F, |
129 pub radius: F, |
| 109 } |
130 } |
| 110 |
131 |
| 111 impl<F : Float, const N : usize> Mapping<Loc<F, N>> for BallCharacteristic<F, N> { |
132 impl<F: Float, const N: usize> Mapping<Loc<N, F>> for BallCharacteristic<F, N> { |
| 112 type Codomain =F; |
133 type Codomain = F; |
| 113 |
134 |
| 114 fn apply<I : Instance<Loc<F, N>>>(&self, i : I) -> F { |
135 fn apply<I: Instance<Loc<N, F>>>(&self, i: I) -> F { |
| 115 if self.center.dist2(i) <= self.radius { |
136 if self.center.dist2(i) <= self.radius { |
| 116 F::ONE |
137 F::ONE |
| 117 } else { |
138 } else { |
| 118 F::ZERO |
139 F::ZERO |
| 119 } |
140 } |
| 120 } |
141 } |
| 121 } |
142 } |
| 122 |
143 |
| |
144 /// Trait for customising the experiments available from the command line |
| |
145 impl ExperimentSetup for DefaultExperimentSetup<f64> { |
| |
146 type FloatType = f64; |
| |
147 |
| |
148 fn runnables(&self) -> DynResult<Vec<Box<dyn RunnableExperiment<Self::FloatType>>>> { |
| |
149 self.experiments |
| |
150 .iter() |
| |
151 .unique() |
| |
152 .map(|e| e.get_experiment(self)) |
| |
153 .try_collect() |
| |
154 } |
| |
155 } |
| |
156 |
| 123 //#[replace_float_literals(F::cast_from(literal))] |
157 //#[replace_float_literals(F::cast_from(literal))] |
| 124 impl DefaultExperiment { |
158 impl DefaultExperiment { |
| |
159 // fn default_list() -> Vec<Self> { |
| |
160 // use DefaultExperiment::*; |
| |
161 // [ |
| |
162 // Experiment1D, |
| |
163 // Experiment1DFast, |
| |
164 // Experiment2D, |
| |
165 // Experiment2DFast, |
| |
166 // Experiment1D_L1, |
| |
167 // ] |
| |
168 // .into() |
| |
169 // } |
| |
170 |
| 125 /// Convert the experiment shorthand into a runnable experiment configuration. |
171 /// Convert the experiment shorthand into a runnable experiment configuration. |
| 126 pub fn get_experiment(&self, cli : &ExperimentOverrides<float>) -> DynResult<Box<dyn RunnableExperiment<float>>> { |
172 fn get_experiment( |
| 127 let name = "pointsource".to_string() |
173 &self, |
| 128 + self.to_possible_value().unwrap().get_name(); |
174 cli: &DefaultExperimentSetup<f64>, |
| |
175 ) -> DynResult<Box<dyn RunnableExperiment<f64>>> { |
| |
176 let name = "pointsource".to_string() + self.to_possible_value().unwrap().get_name(); |
| 129 |
177 |
| 130 let kernel_plot_width = 0.2; |
178 let kernel_plot_width = 0.2; |
| 131 |
179 |
| 132 const BASE_SEED : u64 = 915373234; |
180 const BASE_SEED: u64 = 915373234; |
| 133 |
181 |
| 134 const N_SENSORS_1D : usize = 100; |
182 const N_SENSORS_1D: usize = 100; |
| 135 make_float_constant!(SensorWidth1D = 0.4/(N_SENSORS_1D as float)); |
183 make_float_constant!(SensorWidth1D = 0.4 / (N_SENSORS_1D as float)); |
| 136 |
184 |
| 137 const N_SENSORS_2D : usize = 16; |
185 const N_SENSORS_2D: usize = 16; |
| 138 make_float_constant!(SensorWidth2D = 0.4/(N_SENSORS_2D as float)); |
186 make_float_constant!(SensorWidth2D = 0.4 / (N_SENSORS_2D as float)); |
| 139 |
187 |
| 140 const N_SENSORS_2D_MORE : usize = 32; |
188 //const N_SENSORS_2D_MORE: usize = 32; |
| 141 make_float_constant!(SensorWidth2DMore = 0.4/(N_SENSORS_2D_MORE as float)); |
189 //make_float_constant!(SensorWidth2DMore = 0.4 / (N_SENSORS_2D_MORE as float)); |
| 142 |
190 |
| 143 make_float_constant!(Variance1 = 0.05.powi(2)); |
191 make_float_constant!(Variance1 = 0.05.powi(2)); |
| 144 make_float_constant!(CutOff1 = 0.15); |
192 make_float_constant!(CutOff1 = 0.15); |
| 145 make_float_constant!(Hat1 = 0.16); |
193 make_float_constant!(Hat1 = 0.16); |
| 146 make_float_constant!(HatBias = 0.05); |
194 make_float_constant!(HatBias = 0.05); |
| 208 let default_merge_radius = 0.01; |
254 let default_merge_radius = 0.01; |
| 209 |
255 |
| 210 use DefaultExperiment::*; |
256 use DefaultExperiment::*; |
| 211 Ok(match self { |
257 Ok(match self { |
| 212 Experiment1D => { |
258 Experiment1D => { |
| 213 let base_spread = Gaussian { variance : Variance1 }; |
259 let base_spread = Gaussian { variance: Variance1 }; |
| 214 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity }; |
260 let spread_cutoff = BallIndicator { r: CutOff1, exponent: Linfinity }; |
| 215 Box::new(Named { name, data : ExperimentV2 { |
261 Box::new(Named { |
| 216 domain : [[0.0, 1.0]].into(), |
262 name, |
| 217 sensor_count : [N_SENSORS_1D], |
263 data: ExperimentV2 { |
| 218 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.08)), |
264 domain: [[0.0, 1.0]].into(), |
| 219 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.2))?, |
265 sensor_count: [N_SENSORS_1D], |
| 220 dataterm : DataTerm::L2Squared, |
266 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.08)), |
| 221 μ_hat : MU_TRUE_1D_BASIC.into(), |
267 noise_distr: SerializableNormal::new(0.0, cli.variance.unwrap_or(0.2))?, |
| 222 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, |
268 dataterm: DataTermType::L222, |
| 223 spread : Prod(spread_cutoff, base_spread), |
269 μ_hat: MU_TRUE_1D_BASIC.into(), |
| 224 kernel : Prod(AutoConvolution(spread_cutoff), base_spread), |
270 sensor: BallIndicator { r: SensorWidth1D, exponent: Linfinity }, |
| 225 kernel_plot_width, |
271 spread: Prod(spread_cutoff, base_spread), |
| 226 noise_seed, |
272 kernel: Prod(AutoConvolution(spread_cutoff), base_spread), |
| 227 default_merge_radius, |
273 kernel_plot_width, |
| 228 algorithm_overrides: HashMap::from([ |
274 noise_seed, |
| 229 sliding_fb_cut_gaussian, |
275 default_merge_radius, |
| 230 higher_cpos_merging(DefaultAlgorithm::RadonFB), |
276 algorithm_overrides: HashMap::from([ |
| 231 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB), |
277 sliding_fb_cut_gaussian, |
| 232 ]), |
278 higher_cpos_merging(DefaultAlgorithm::RadonFB), |
| 233 }}) |
279 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB), |
| 234 }, |
280 ]), |
| |
281 }, |
| |
282 }) |
| |
283 } |
| 235 Experiment1DFast => { |
284 Experiment1DFast => { |
| 236 let base_spread = HatConv { radius : Hat1 }; |
285 let base_spread = HatConv { radius: Hat1 }; |
| 237 Box::new(Named { name, data : ExperimentV2 { |
286 Box::new(Named { |
| 238 domain : [[0.0, 1.0]].into(), |
287 name, |
| 239 sensor_count : [N_SENSORS_1D], |
288 data: ExperimentV2 { |
| 240 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.06)), |
289 domain: [[0.0, 1.0]].into(), |
| 241 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.2))?, |
290 sensor_count: [N_SENSORS_1D], |
| 242 dataterm : DataTerm::L2Squared, |
291 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.06)), |
| 243 μ_hat : MU_TRUE_1D_BASIC.into(), |
292 noise_distr: SerializableNormal::new(0.0, cli.variance.unwrap_or(0.2))?, |
| 244 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, |
293 dataterm: DataTermType::L222, |
| 245 spread : base_spread, |
294 μ_hat: MU_TRUE_1D_BASIC.into(), |
| 246 kernel : base_spread, |
295 sensor: BallIndicator { r: SensorWidth1D, exponent: Linfinity }, |
| 247 kernel_plot_width, |
296 spread: base_spread, |
| 248 noise_seed, |
297 kernel: base_spread, |
| 249 default_merge_radius, |
298 kernel_plot_width, |
| 250 algorithm_overrides: HashMap::from([ |
299 noise_seed, |
| 251 higher_cpos_merging(DefaultAlgorithm::RadonFB), |
300 default_merge_radius, |
| 252 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB), |
301 algorithm_overrides: HashMap::from([ |
| 253 ]), |
302 higher_cpos_merging(DefaultAlgorithm::RadonFB), |
| 254 }}) |
303 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB), |
| 255 }, |
304 ]), |
| |
305 }, |
| |
306 }) |
| |
307 } |
| 256 Experiment2D => { |
308 Experiment2D => { |
| 257 let base_spread = Gaussian { variance : Variance1 }; |
309 let base_spread = Gaussian { variance: Variance1 }; |
| 258 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity }; |
310 let spread_cutoff = BallIndicator { r: CutOff1, exponent: Linfinity }; |
| 259 Box::new(Named { name, data : ExperimentV2 { |
311 Box::new(Named { |
| 260 domain : [[0.0, 1.0]; 2].into(), |
312 name, |
| 261 sensor_count : [N_SENSORS_2D; 2], |
313 data: ExperimentV2 { |
| 262 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.19)), |
314 domain: [[0.0, 1.0]; 2].into(), |
| 263 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.25))?, |
315 sensor_count: [N_SENSORS_2D; 2], |
| 264 dataterm : DataTerm::L2Squared, |
316 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.19)), |
| 265 μ_hat : MU_TRUE_2D_BASIC.into(), |
317 noise_distr: SerializableNormal::new(0.0, cli.variance.unwrap_or(0.25))?, |
| 266 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity }, |
318 dataterm: DataTermType::L222, |
| 267 spread : Prod(spread_cutoff, base_spread), |
319 μ_hat: MU_TRUE_2D_BASIC.into(), |
| 268 kernel : Prod(AutoConvolution(spread_cutoff), base_spread), |
320 sensor: BallIndicator { r: SensorWidth2D, exponent: Linfinity }, |
| 269 kernel_plot_width, |
321 spread: Prod(spread_cutoff, base_spread), |
| 270 noise_seed, |
322 kernel: Prod(AutoConvolution(spread_cutoff), base_spread), |
| 271 default_merge_radius, |
323 kernel_plot_width, |
| 272 algorithm_overrides: HashMap::from([ |
324 noise_seed, |
| 273 sliding_fb_cut_gaussian, |
325 default_merge_radius, |
| 274 higher_cpos_merging(DefaultAlgorithm::RadonFB), |
326 algorithm_overrides: HashMap::from([ |
| 275 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB), |
327 sliding_fb_cut_gaussian, |
| 276 ]), |
328 higher_cpos_merging(DefaultAlgorithm::RadonFB), |
| 277 }}) |
329 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB), |
| 278 }, |
330 ]), |
| |
331 }, |
| |
332 }) |
| |
333 } |
| 279 Experiment2DFast => { |
334 Experiment2DFast => { |
| 280 let base_spread = HatConv { radius : Hat1 }; |
335 let base_spread = HatConv { radius: Hat1 }; |
| 281 Box::new(Named { name, data : ExperimentV2 { |
336 Box::new(Named { |
| 282 domain : [[0.0, 1.0]; 2].into(), |
337 name, |
| 283 sensor_count : [N_SENSORS_2D; 2], |
338 data: ExperimentV2 { |
| 284 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.12)), |
339 domain: [[0.0, 1.0]; 2].into(), |
| 285 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.15))?, //0.25 |
340 sensor_count: [N_SENSORS_2D; 2], |
| 286 dataterm : DataTerm::L2Squared, |
341 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.12)), |
| 287 μ_hat : MU_TRUE_2D_BASIC.into(), |
342 noise_distr: SerializableNormal::new(0.0, cli.variance.unwrap_or(0.15))?, //0.25 |
| 288 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity }, |
343 dataterm: DataTermType::L222, |
| 289 spread : base_spread, |
344 μ_hat: MU_TRUE_2D_BASIC.into(), |
| 290 kernel : base_spread, |
345 sensor: BallIndicator { r: SensorWidth2D, exponent: Linfinity }, |
| 291 kernel_plot_width, |
346 spread: base_spread, |
| 292 noise_seed, |
347 kernel: base_spread, |
| 293 default_merge_radius, |
348 kernel_plot_width, |
| 294 algorithm_overrides: HashMap::from([ |
349 noise_seed, |
| 295 higher_cpos_merging(DefaultAlgorithm::RadonFB), |
350 default_merge_radius, |
| 296 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB), |
351 algorithm_overrides: HashMap::from([ |
| 297 ]), |
352 higher_cpos_merging(DefaultAlgorithm::RadonFB), |
| 298 }}) |
353 higher_cpos_merging(DefaultAlgorithm::RadonSlidingFB), |
| 299 }, |
354 ]), |
| |
355 }, |
| |
356 }) |
| |
357 } |
| 300 Experiment1D_L1 => { |
358 Experiment1D_L1 => { |
| 301 let base_spread = Gaussian { variance : Variance1 }; |
359 let base_spread = Gaussian { variance: Variance1 }; |
| 302 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity }; |
360 let spread_cutoff = BallIndicator { r: CutOff1, exponent: Linfinity }; |
| 303 Box::new(Named { name, data : ExperimentV2 { |
361 Box::new(Named { |
| 304 domain : [[0.0, 1.0]].into(), |
362 name, |
| 305 sensor_count : [N_SENSORS_1D], |
363 data: ExperimentV2 { |
| 306 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.1)), |
364 domain: [[0.0, 1.0]].into(), |
| 307 noise_distr : SaltAndPepper::new( |
365 sensor_count: [N_SENSORS_1D], |
| 308 cli.salt_and_pepper.as_ref().map_or(0.6, |v| v[0]), |
366 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.1)), |
| 309 cli.salt_and_pepper.as_ref().map_or(0.4, |v| v[1]) |
367 noise_distr: SaltAndPepper::new( |
| 310 )?, |
368 cli.salt_and_pepper.as_ref().map_or(0.6, |v| v[0]), |
| 311 dataterm : DataTerm::L1, |
369 cli.salt_and_pepper.as_ref().map_or(0.4, |v| v[1]), |
| 312 μ_hat : MU_TRUE_1D_BASIC.into(), |
370 )?, |
| 313 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, |
371 dataterm: DataTermType::L1, |
| 314 spread : Prod(spread_cutoff, base_spread), |
372 μ_hat: MU_TRUE_1D_BASIC.into(), |
| 315 kernel : Prod(AutoConvolution(spread_cutoff), base_spread), |
373 sensor: BallIndicator { r: SensorWidth1D, exponent: Linfinity }, |
| 316 kernel_plot_width, |
374 spread: Prod(spread_cutoff, base_spread), |
| 317 noise_seed, |
375 kernel: Prod(AutoConvolution(spread_cutoff), base_spread), |
| 318 default_merge_radius, |
376 kernel_plot_width, |
| 319 algorithm_overrides: HashMap::new(), |
377 noise_seed, |
| 320 }}) |
378 default_merge_radius, |
| 321 }, |
379 algorithm_overrides: HashMap::new(), |
| |
380 }, |
| |
381 }) |
| |
382 } |
| 322 Experiment1D_L1_Fast => { |
383 Experiment1D_L1_Fast => { |
| 323 let base_spread = HatConv { radius : Hat1 }; |
384 let base_spread = HatConv { radius: Hat1 }; |
| 324 Box::new(Named { name, data : ExperimentV2 { |
385 Box::new(Named { |
| 325 domain : [[0.0, 1.0]].into(), |
386 name, |
| 326 sensor_count : [N_SENSORS_1D], |
387 data: ExperimentV2 { |
| 327 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.12)), |
388 domain: [[0.0, 1.0]].into(), |
| 328 noise_distr : SaltAndPepper::new( |
389 sensor_count: [N_SENSORS_1D], |
| 329 cli.salt_and_pepper.as_ref().map_or(0.6, |v| v[0]), |
390 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.12)), |
| 330 cli.salt_and_pepper.as_ref().map_or(0.4, |v| v[1]) |
391 noise_distr: SaltAndPepper::new( |
| 331 )?, |
392 cli.salt_and_pepper.as_ref().map_or(0.6, |v| v[0]), |
| 332 dataterm : DataTerm::L1, |
393 cli.salt_and_pepper.as_ref().map_or(0.4, |v| v[1]), |
| 333 μ_hat : MU_TRUE_1D_BASIC.into(), |
394 )?, |
| 334 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, |
395 dataterm: DataTermType::L1, |
| 335 spread : base_spread, |
396 μ_hat: MU_TRUE_1D_BASIC.into(), |
| 336 kernel : base_spread, |
397 sensor: BallIndicator { r: SensorWidth1D, exponent: Linfinity }, |
| 337 kernel_plot_width, |
398 spread: base_spread, |
| 338 noise_seed, |
399 kernel: base_spread, |
| 339 default_merge_radius, |
400 kernel_plot_width, |
| 340 algorithm_overrides: HashMap::new(), |
401 noise_seed, |
| 341 }}) |
402 default_merge_radius, |
| 342 }, |
403 algorithm_overrides: HashMap::new(), |
| |
404 }, |
| |
405 }) |
| |
406 } |
| 343 Experiment2D_L1 => { |
407 Experiment2D_L1 => { |
| 344 let base_spread = Gaussian { variance : Variance1 }; |
408 let base_spread = Gaussian { variance: Variance1 }; |
| 345 let spread_cutoff = BallIndicator { r : CutOff1, exponent : Linfinity }; |
409 let spread_cutoff = BallIndicator { r: CutOff1, exponent: Linfinity }; |
| 346 Box::new(Named { name, data : ExperimentV2 { |
410 Box::new(Named { |
| 347 domain : [[0.0, 1.0]; 2].into(), |
411 name, |
| 348 sensor_count : [N_SENSORS_2D; 2], |
412 data: ExperimentV2 { |
| 349 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.35)), |
413 domain: [[0.0, 1.0]; 2].into(), |
| 350 noise_distr : SaltAndPepper::new( |
414 sensor_count: [N_SENSORS_2D; 2], |
| 351 cli.salt_and_pepper.as_ref().map_or(0.8, |v| v[0]), |
415 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.35)), |
| 352 cli.salt_and_pepper.as_ref().map_or(0.2, |v| v[1]) |
416 noise_distr: SaltAndPepper::new( |
| 353 )?, |
417 cli.salt_and_pepper.as_ref().map_or(0.8, |v| v[0]), |
| 354 dataterm : DataTerm::L1, |
418 cli.salt_and_pepper.as_ref().map_or(0.2, |v| v[1]), |
| 355 μ_hat : MU_TRUE_2D_BASIC.into(), |
419 )?, |
| 356 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity }, |
420 dataterm: DataTermType::L1, |
| 357 spread : Prod(spread_cutoff, base_spread), |
421 μ_hat: MU_TRUE_2D_BASIC.into(), |
| 358 kernel : Prod(AutoConvolution(spread_cutoff), base_spread), |
422 sensor: BallIndicator { r: SensorWidth2D, exponent: Linfinity }, |
| 359 kernel_plot_width, |
423 spread: Prod(spread_cutoff, base_spread), |
| 360 noise_seed, |
424 kernel: Prod(AutoConvolution(spread_cutoff), base_spread), |
| 361 default_merge_radius, |
425 kernel_plot_width, |
| 362 algorithm_overrides: HashMap::from([ |
426 noise_seed, |
| 363 ]), |
427 default_merge_radius, |
| 364 }}) |
428 algorithm_overrides: HashMap::from([]), |
| 365 }, |
429 }, |
| |
430 }) |
| |
431 } |
| 366 Experiment2D_L1_Fast => { |
432 Experiment2D_L1_Fast => { |
| 367 let base_spread = HatConv { radius : Hat1 }; |
433 let base_spread = HatConv { radius: Hat1 }; |
| 368 Box::new(Named { name, data : ExperimentV2 { |
434 Box::new(Named { |
| 369 domain : [[0.0, 1.0]; 2].into(), |
435 name, |
| 370 sensor_count : [N_SENSORS_2D; 2], |
436 data: ExperimentV2 { |
| 371 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.40)), |
437 domain: [[0.0, 1.0]; 2].into(), |
| 372 noise_distr : SaltAndPepper::new( |
438 sensor_count: [N_SENSORS_2D; 2], |
| 373 cli.salt_and_pepper.as_ref().map_or(0.8, |v| v[0]), |
439 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.40)), |
| 374 cli.salt_and_pepper.as_ref().map_or(0.2, |v| v[1]) |
440 noise_distr: SaltAndPepper::new( |
| 375 )?, |
441 cli.salt_and_pepper.as_ref().map_or(0.8, |v| v[0]), |
| 376 dataterm : DataTerm::L1, |
442 cli.salt_and_pepper.as_ref().map_or(0.2, |v| v[1]), |
| 377 μ_hat : MU_TRUE_2D_BASIC.into(), |
443 )?, |
| 378 sensor : BallIndicator { r : SensorWidth2D, exponent : Linfinity }, |
444 dataterm: DataTermType::L1, |
| 379 spread : base_spread, |
445 μ_hat: MU_TRUE_2D_BASIC.into(), |
| 380 kernel : base_spread, |
446 sensor: BallIndicator { r: SensorWidth2D, exponent: Linfinity }, |
| 381 kernel_plot_width, |
447 spread: base_spread, |
| 382 noise_seed, |
448 kernel: base_spread, |
| 383 default_merge_radius, |
449 kernel_plot_width, |
| 384 algorithm_overrides: HashMap::from([ |
450 noise_seed, |
| 385 ]), |
451 default_merge_radius, |
| 386 }}) |
452 algorithm_overrides: HashMap::from([]), |
| 387 }, |
453 }, |
| |
454 }) |
| |
455 } |
| 388 Experiment1D_TV_Fast => { |
456 Experiment1D_TV_Fast => { |
| 389 let base_spread = HatConv { radius : HatBias }; |
457 let base_spread = HatConv { radius: HatBias }; |
| 390 Box::new(Named { name, data : ExperimentBiased { |
458 Box::new(Named { |
| 391 λ : 0.02, |
459 name, |
| 392 bias : MappingSum::new([ |
460 data: ExperimentBiased { |
| 393 Weighted::new(1.0, BallCharacteristic{ center : 0.3.into(), radius : 0.2 }), |
461 λ: 0.02, |
| 394 Weighted::new(0.5, BallCharacteristic{ center : 0.6.into(), radius : 0.3 }), |
462 bias: MappingSum::new([ |
| 395 ]), |
463 Weighted::new(1.0, BallCharacteristic { |
| 396 base : ExperimentV2 { |
464 center: 0.3.into(), |
| 397 domain : [[0.0, 1.0]].into(), |
465 radius: 0.2, |
| 398 sensor_count : [N_SENSORS_1D], |
466 }), |
| 399 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.2)), |
467 Weighted::new(0.5, BallCharacteristic { |
| 400 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.1))?, |
468 center: 0.6.into(), |
| 401 dataterm : DataTerm::L2Squared, |
469 radius: 0.3, |
| 402 μ_hat : MU_TRUE_1D_BASIC.into(), |
470 }), |
| 403 sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity }, |
|
| 404 spread : base_spread, |
|
| 405 kernel : base_spread, |
|
| 406 kernel_plot_width, |
|
| 407 noise_seed, |
|
| 408 default_merge_radius, |
|
| 409 algorithm_overrides: HashMap::from([ |
|
| 410 higher_cpos_merging_steptune(DefaultAlgorithm::RadonForwardPDPS), |
|
| 411 higher_cpos_merging_steptune(DefaultAlgorithm::RadonSlidingPDPS), |
|
| 412 ]), |
471 ]), |
| 413 }, |
472 base: ExperimentV2 { |
| 414 }}) |
473 domain: [[0.0, 1.0]].into(), |
| 415 }, |
474 sensor_count: [N_SENSORS_1D], |
| |
475 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.2)), |
| |
476 noise_distr: SerializableNormal::new(0.0, cli.variance.unwrap_or(0.1))?, |
| |
477 dataterm: DataTermType::L222, |
| |
478 μ_hat: MU_TRUE_1D_BASIC.into(), |
| |
479 sensor: BallIndicator { r: SensorWidth1D, exponent: Linfinity }, |
| |
480 spread: base_spread, |
| |
481 kernel: base_spread, |
| |
482 kernel_plot_width, |
| |
483 noise_seed, |
| |
484 default_merge_radius, |
| |
485 algorithm_overrides: HashMap::from([ |
| |
486 higher_cpos_merging_steptune(DefaultAlgorithm::RadonForwardPDPS), |
| |
487 higher_cpos_merging_steptune(DefaultAlgorithm::RadonSlidingPDPS), |
| |
488 ]), |
| |
489 }, |
| |
490 }, |
| |
491 }) |
| |
492 } |
| 416 Experiment2D_TV_Fast => { |
493 Experiment2D_TV_Fast => { |
| 417 let base_spread = HatConv { radius : Hat1 }; |
494 let base_spread = HatConv { radius: Hat1 }; |
| 418 Box::new(Named { name, data : ExperimentBiased { |
495 Box::new(Named { |
| 419 λ : 0.005, |
496 name, |
| 420 bias : MappingSum::new([ |
497 data: ExperimentBiased { |
| 421 Weighted::new(1.0, BallCharacteristic{ center : [0.3, 0.3].into(), radius : 0.2 }), |
498 λ: 0.005, |
| 422 Weighted::new(0.5, BallCharacteristic{ center : [0.6, 0.6].into(), radius : 0.3 }), |
499 bias: MappingSum::new([ |
| 423 ]), |
500 Weighted::new(1.0, BallCharacteristic { |
| 424 base : ExperimentV2 { |
501 center: [0.3, 0.3].into(), |
| 425 domain : [[0.0, 1.0]; 2].into(), |
502 radius: 0.2, |
| 426 sensor_count : [N_SENSORS_2D; 2], |
503 }), |
| 427 regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.06)), |
504 Weighted::new(0.5, BallCharacteristic { |
| 428 noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.15))?, //0.25 |
505 center: [0.6, 0.6].into(), |
| 429 dataterm : DataTerm::L2Squared, |
506 radius: 0.3, |
| 430 μ_hat : MU_TRUE_2D_BASIC.into(), |
507 }), |
| 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 ]), |
508 ]), |
| 441 }, |
509 base: ExperimentV2 { |
| 442 }}) |
510 domain: [[0.0, 1.0]; 2].into(), |
| 443 }, |
511 sensor_count: [N_SENSORS_2D; 2], |
| |
512 regularisation: Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.06)), |
| |
513 noise_distr: SerializableNormal::new( |
| |
514 0.0, |
| |
515 cli.variance.unwrap_or(0.15), |
| |
516 )?, //0.25 |
| |
517 dataterm: DataTermType::L222, |
| |
518 μ_hat: MU_TRUE_2D_BASIC.into(), |
| |
519 sensor: BallIndicator { r: SensorWidth2D, exponent: Linfinity }, |
| |
520 spread: base_spread, |
| |
521 kernel: base_spread, |
| |
522 kernel_plot_width, |
| |
523 noise_seed, |
| |
524 default_merge_radius, |
| |
525 algorithm_overrides: HashMap::from([ |
| |
526 much_higher_cpos_merging_steptune( |
| |
527 DefaultAlgorithm::RadonForwardPDPS, |
| |
528 ), |
| |
529 much_higher_cpos_merging_steptune( |
| |
530 DefaultAlgorithm::RadonSlidingPDPS, |
| |
531 ), |
| |
532 ]), |
| |
533 }, |
| |
534 }, |
| |
535 }) |
| |
536 } |
| 444 }) |
537 }) |
| 445 } |
538 } |
| 446 } |
539 } |
| 447 |
|