src/experiments.rs

branch
dev
changeset 35
b087e3eab191
parent 34
efa60bc4f743
child 37
c5d8bd1a7728
--- a/src/experiments.rs	Thu Aug 29 00:00:00 2024 -0500
+++ b/src/experiments.rs	Tue Dec 31 09:25:45 2024 -0500
@@ -21,6 +21,7 @@
 use crate::run::{
     RunnableExperiment,
     ExperimentV2,
+    ExperimentBiased,
     Named,
     DefaultAlgorithm,
     AlgorithmConfig
@@ -28,6 +29,10 @@
 //use crate::fb::FBGenericConfig;
 use crate::rand_distr::{SerializableNormal, SaltAndPepper};
 use crate::regularisation::Regularisation;
+use alg_tools::euclidean::Euclidean;
+use alg_tools::instance::Instance;
+use alg_tools::mapping::Mapping;
+use alg_tools::operator_arithmetic::{MappingSum, Weighted};
 
 /// Experiments shorthands, to be used with the command line parser
 
@@ -58,6 +63,9 @@
     /// Two dimensions, “fast” spread, 1-norm data fidelity
     #[clap(name = "2d_l1_fast")]
     Experiment2D_L1_Fast,
+     /// One dimension, “fast” spread, 2-norm-squared data fidelity with extra TV-regularised bias
+    #[clap(name = "1d_tv_fast")]
+    Experiment1D_TV_Fast,
 }
 
 macro_rules! make_float_constant {
@@ -92,6 +100,25 @@
     ([0.30, 0.70], 5.0)
 ];
 
+/// The $\{0,1\}$-valued characteristic function of a ball as a [`Mapping`].
+#[derive(Debug,Copy,Clone,Serialize,PartialEq)]
+struct BallCharacteristic<F : Float, const N : usize> {
+    pub center : Loc<F, N>,
+    pub radius : F,
+}
+
+impl<F : Float, const N : usize> Mapping<Loc<F, N>> for BallCharacteristic<F, N> {
+    type Codomain =F;
+
+    fn apply<I : Instance<Loc<F, N>>>(&self, i : I) -> F {
+        if self.center.dist2(i) <= self.radius {
+            F::ONE
+        } else {
+            F::ZERO
+        }
+    }
+}
+
 //#[replace_float_literals(F::cast_from(literal))]
 impl DefaultExperiment {
     /// Convert the experiment shorthand into a runnable experiment configuration.
@@ -115,6 +142,7 @@
         make_float_constant!(Variance1 = 0.05.powi(2));
         make_float_constant!(CutOff1 = 0.15);
         make_float_constant!(Hat1 = 0.16);
+        make_float_constant!(HatBias = 0.05);
 
         // We use a different step length for PDPS in 2D experiments
         let pdps_2d = || {
@@ -294,6 +322,30 @@
                     ]),
                 }})
             },
+            Experiment1D_TV_Fast => {
+                let base_spread = HatConv { radius : HatBias };
+                Box::new(Named { name, data : ExperimentBiased {
+                    λ : 0.02,
+                    bias : MappingSum::new([
+                        Weighted::new(1.0, BallCharacteristic{ center : 0.3.into(), radius : 0.2 }),
+                        Weighted::new(0.5, BallCharacteristic{ center : 0.6.into(), radius : 0.3 }),
+                    ]),
+                    base : ExperimentV2 {
+                        domain : [[0.0, 1.0]].into(),
+                        sensor_count : [N_SENSORS_1D],
+                        regularisation : Regularisation::NonnegRadon(cli.alpha.unwrap_or(0.2)),
+                        noise_distr : SerializableNormal::new(0.0, cli.variance.unwrap_or(0.1))?,
+                        dataterm : DataTerm::L2Squared,
+                        μ_hat : MU_TRUE_1D_BASIC.into(),
+                        sensor : BallIndicator { r : SensorWidth1D, exponent : Linfinity },
+                        spread : base_spread,
+                        kernel : base_spread,
+                        kernel_plot_width,
+                        noise_seed,
+                        algorithm_defaults: HashMap::new(),
+                    },
+                }})
+            },
         })
     }
 }

mercurial