Mon, 06 Jan 2025 21:37:03 -0500
Attempt to do more Serialize / Deserialize but run into csv problems
--- a/src/experiments.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/experiments.rs Mon Jan 06 21:37:03 2025 -0500 @@ -102,7 +102,13 @@ ]; /// The $\{0,1\}$-valued characteristic function of a ball as a [`Mapping`]. -#[derive(Debug,Copy,Clone,Serialize,PartialEq)] +#[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq)] +#[serde(bound( + serialize = "F : Serialize, + Loc<F, N> : Serialize", + deserialize = "F : for<'a> Deserialize<'a>, + Loc<F, N> : for<'a> Deserialize<'a>", +))] struct BallCharacteristic<F : Float, const N : usize> { pub center : Loc<F, N>, pub radius : F,
--- a/src/forward_model/sensor_grid.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/forward_model/sensor_grid.rs Mon Jan 06 21:37:03 2025 -0500 @@ -9,6 +9,7 @@ }; use std::iter::Zip; use std::ops::RangeFrom; +use serde::Serialize; pub use alg_tools::linops::*; use alg_tools::norms::{ @@ -407,6 +408,7 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N>, + [F; N]: Serialize, /*ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, Weighted<ShiftedSensor<F, S, P, N>, F> : LocalAnalysis<F, BT::Agg, N>*/ { type Observable = DVector<F>; @@ -429,6 +431,7 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N>, + [F; N] : Serialize, /*ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, Weighted<ShiftedSensor<F, S, P, N>, F> : LocalAnalysis<F, BT::Agg, N>*/ {
--- a/src/kernels/ball_indicator.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/kernels/ball_indicator.rs Mon Jan 06 21:37:03 2025 -0500 @@ -2,7 +2,7 @@ //! Implementation of the indicator function of a ball with respect to various norms. use float_extras::f64::tgamma as gamma; use numeric_literals::replace_float_literals; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use alg_tools::types::*; use alg_tools::norms::*; use alg_tools::loc::Loc; @@ -28,7 +28,7 @@ /// Representation of the indicator of the ball $𝔹_q = \\{ x ∈ ℝ^N \mid \\|x\\|\_q ≤ r \\}$, /// where $q$ is the `Exponent`, and $r$ is the radius [`Constant`] `C`. -#[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] +#[derive(Copy,Clone,Serialize,Deserialize,Debug,Eq,PartialEq)] pub struct BallIndicator<C : Constant, Exponent : NormExponent, const N : usize> { /// The radius of the ball. pub r : C,
--- a/src/kernels/base.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/kernels/base.rs Mon Jan 06 21:37:03 2025 -0500 @@ -1,6 +1,6 @@ //! Things for constructing new kernels from component kernels and traits for analysing them -use serde::Serialize; +use serde::{Serialize, Deserialize}; use numeric_literals::replace_float_literals; use alg_tools::types::*; @@ -296,7 +296,7 @@ /// The kernels typically implement [`Support`]s and [`Mapping`]. // /// Trait implementations have to be on a case-by-case basis. -#[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] +#[derive(Copy,Clone,Serialize,Deserialize,Debug,Eq,PartialEq)] pub struct Convolution<A, B>( /// First kernel pub A,
--- a/src/kernels/gaussian.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/kernels/gaussian.rs Mon Jan 06 21:37:03 2025 -0500 @@ -2,7 +2,7 @@ use float_extras::f64::erf; use numeric_literals::replace_float_literals; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use alg_tools::types::*; use alg_tools::euclidean::Euclidean; use alg_tools::norms::*; @@ -34,7 +34,7 @@ /// /// This is the function $f(x) = C e^{-\\|x\\|\_2^2/(2σ^2)}$ for $x ∈ ℝ^N$ /// with $C=1/(2πσ^2)^{N/2}$. -#[derive(Copy,Clone,Debug,Serialize,Eq)] +#[derive(Copy,Clone,Debug,Serialize,Deserialize,Eq)] pub struct Gaussian<S : Constant, const N : usize> { /// The variance $σ^2$. pub variance : S,
--- a/src/kernels/hat.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/kernels/hat.rs Mon Jan 06 21:37:03 2025 -0500 @@ -1,7 +1,7 @@ //! Implementation of the hat function use numeric_literals::replace_float_literals; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use alg_tools::types::*; use alg_tools::norms::*; use alg_tools::loc::Loc; @@ -19,7 +19,7 @@ use crate::types::Lipschitz; /// Representation of the hat function $f(x)=1-\\|x\\|\_1/ε$ of `width` $ε$ on $ℝ^N$. -#[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] +#[derive(Copy,Clone,Serialize,Deserialize,Debug,Eq,PartialEq)] pub struct Hat<C : Constant, const N : usize> { /// The parameter $ε>0$. pub width : C,
--- a/src/kernels/hat_convolution.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/kernels/hat_convolution.rs Mon Jan 06 21:37:03 2025 -0500 @@ -1,7 +1,7 @@ //! Implementation of the convolution of two hat functions, //! and its convolution with a [`CubeIndicator`]. use numeric_literals::replace_float_literals; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use alg_tools::types::*; use alg_tools::norms::*; use alg_tools::loc::Loc; @@ -69,7 +69,7 @@ // $$ // [∇f(x\_1, …, x\_n)]_j = \frac{4}{σ} (h\*h)'(x\_j/σ) \prod\_{j ≠ i} \frac{4}{σ} (h\*h)(x\_i/σ) // $$ -#[derive(Copy,Clone,Debug,Serialize,Eq)] +#[derive(Copy,Clone,Debug,Serialize,Deserialize,Eq)] pub struct HatConv<S : Constant, const N : usize> { /// The parameter $σ$ of the kernel. pub radius : S,
--- a/src/kernels/linear.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/kernels/linear.rs Mon Jan 06 21:37:03 2025 -0500 @@ -1,7 +1,7 @@ //! Implementation of the linear function use numeric_literals::replace_float_literals; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use alg_tools::types::*; use alg_tools::norms::*; use alg_tools::loc::Loc; @@ -18,7 +18,8 @@ use alg_tools::euclidean::Euclidean; /// Representation of the hat function $f(x)=1-\\|x\\|\_1/ε$ of `width` $ε$ on $ℝ^N$. -#[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] +#[derive(Copy,Clone,Serialize,Deserialize,Debug,Eq,PartialEq)] +#[serde(bound = "Loc<F, N> : Serialize + for<'a> Deserialize<'a>")] pub struct Linear<F : Float, const N : usize> { /// The parameter $ε>0$. pub v : Loc<F, N>,
--- a/src/kernels/mollifier.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/kernels/mollifier.rs Mon Jan 06 21:37:03 2025 -0500 @@ -4,7 +4,7 @@ use rgsl::hypergeometric::hyperg_U; use float_extras::f64::tgamma as gamma; use numeric_literals::replace_float_literals; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use alg_tools::types::*; use alg_tools::euclidean::Euclidean; use alg_tools::norms::*; @@ -29,7 +29,7 @@ /// 0, & \text{otherwise}. /// \end{cases} /// $$</div> -#[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] +#[derive(Copy,Clone,Serialize,Deserialize,Debug,Eq,PartialEq)] pub struct Mollifier<C : Constant, const N : usize> { /// The parameter $ε$ of the mollifier. pub width : C,
--- a/src/measures/delta.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/measures/delta.rs Mon Jan 06 21:37:03 2025 -0500 @@ -6,7 +6,7 @@ use super::base::*; use crate::types::*; use std::ops::{Div, Mul, DivAssign, MulAssign, Neg}; -use serde::ser::{Serialize, Serializer, SerializeStruct}; +use serde::{Serialize, Deserialize}; use alg_tools::norms::Norm; use alg_tools::linops::{Mapping, Linear}; use alg_tools::instance::{Instance, Space}; @@ -15,7 +15,7 @@ /// /// This is a single spike $\alpha \delta\_x$ for some location $x$ in `Domain` and /// a mass $\alpha$ in `F`. -#[derive(Clone,Copy,Debug)] +#[derive(Clone,Copy,Debug,Serialize,Deserialize)] pub struct DeltaMeasure<Domain, F : Num> { // This causes [`csv`] to crash. //#[serde(flatten)] @@ -25,32 +25,6 @@ pub α : F } -const COORDINATE_NAMES : &'static [&'static str] = &[ - "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7" -]; - -// Need to manually implement serialisation as [`csv`] writer fails on -// structs with nested arrays as well as with #[serde(flatten)]. -impl<F : Num, const N : usize> Serialize for DeltaMeasure<Loc<F, N>, F> -where - F: Serialize, -{ - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - assert!(N <= COORDINATE_NAMES.len()); - - let mut s = serializer.serialize_struct("DeltaMeasure", N+1)?; - for (i, e) in (0..).zip(self.x.iter()) { - s.serialize_field(COORDINATE_NAMES[i], e)?; - } - s.serialize_field("weight", &self.α)?; - s.end() - } -} - - impl<Domain, F : Float> Measure<F> for DeltaMeasure<Domain, F> { type Domain = Domain; }
--- a/src/measures/discrete.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/measures/discrete.rs Mon Jan 06 21:37:03 2025 -0500 @@ -6,7 +6,7 @@ Index,IndexMut, }; use std::iter::Sum; -use serde::ser::{Serializer, Serialize, SerializeSeq}; +use serde::{Serialize, Deserialize}; use nalgebra::DVector; use alg_tools::norms::Norm; @@ -26,7 +26,7 @@ /// This is the measure $μ = ∑_{k=1}^n α_k δ_{x_k}$, consisting of several /// [`DeltaMeasure`], i.e., “spikes” $α_k δ_{x_k}$ with weights $\alpha_k$ in `F` at locations /// $x_k$ in `Domain`. -#[derive(Clone,Debug)] +#[derive(Clone,Debug,Serialize,Deserialize)] pub struct DiscreteMeasure<Domain, F : Num> { pub(super) spikes : Vec<DeltaMeasure<Domain, F>>, } @@ -456,25 +456,6 @@ } } -// Need to manually implement serialisation for DeltaMeasure<Loc<F, N>, F> [`csv`] writer fails on -// structs with nested arrays as well as with #[serde(flatten)]. -// Then derive no longer works for DiscreteMeasure -impl<F : Num, const N : usize> Serialize for DiscreteMeasure<Loc<F, N>, F> -where - F: Serialize, -{ - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - let mut s = serializer.serialize_seq(Some(self.spikes.len()))?; - for δ in self.spikes.iter() { - s.serialize_element(δ)?; - } - s.end() - } -} - impl<Domain : PartialEq, F : Float> Measure<F> for DiscreteMeasure<Domain, F> { type Domain = Domain; }
--- a/src/run.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/run.rs Mon Jan 06 21:37:03 2025 -0500 @@ -327,7 +327,7 @@ // } /// Plotting level configuration -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, ValueEnum, Debug)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, ValueEnum, Debug)] pub enum PlotLevel { /// Plot nothing #[clap(name = "none")] @@ -357,7 +357,7 @@ >; /// This is a dirty workaround to rust-csv not supporting struct flattening etc. -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] struct CSVLog<F> { iter : usize, cpu_time : f64, @@ -372,7 +372,7 @@ } /// Collected experiment statistics -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] struct ExperimentStats<F : Float> { /// Signal-to-noise ratio in decibels ssnr : F, @@ -398,7 +398,7 @@ } } /// Collected algorithm statistics -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] struct AlgorithmStats<F : Float> { /// Overall CPU time spent cpu_time : F, @@ -416,10 +416,29 @@ /// Struct for experiment configurations -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(bound( + serialize = "Cube<F, N> : Serialize, + NoiseDistr : Serialize, + [usize; N] : Serialize, + RNDM<F, N> : Serialize, + Regularisation<F> : Serialize, + F : Serialize, + S : Serialize, + P : Serialize, + K : Serialize", + deserialize = "Cube<F, N> : for<'a> Deserialize<'a>, + NoiseDistr : for<'a> Deserialize<'a>, + [usize; N] : for<'a> Deserialize<'a>, + RNDM<F, N> : for<'a> Deserialize<'a>, + Regularisation<F> : for<'a> Deserialize<'a>, + F : for<'a> Deserialize<'a>, + S : for<'a> Deserialize<'a>, + P : for<'a> Deserialize<'a>, + K : for<'a> Deserialize<'a>,", +))] pub struct ExperimentV2<F, NoiseDistr, S, K, P, const N : usize> where F : Float, - [usize; N] : Serialize, NoiseDistr : Distribution<F>, S : Sensor<F, N>, P : Spread<F, N>, @@ -452,7 +471,15 @@ pub algorithm_defaults : HashMap<DefaultAlgorithm, AlgorithmConfig<F>>, } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(bound( + serialize = "ExperimentV2<F, NoiseDistr, S, K, P, N> : Serialize, + B : Serialize, + F : Serialize", + deserialize = "ExperimentV2<F, NoiseDistr, S, K, P, N >: for<'a> Deserialize<'a>, + B : for<'a> Deserialize<'a>, + F : for<'a> Deserialize<'a>", +))] pub struct ExperimentBiased<F, NoiseDistr, S, K, P, B, const N : usize> where F : Float, [usize; N] : Serialize, @@ -541,6 +568,7 @@ ) -> DynError where PlotLookup : Plotting<N>, + DeltaMeasure<Loc<F, N>, F> : Serialize, { let mut logs = Vec::new(); @@ -647,6 +675,8 @@ BTNodeLookup: BTNode<F, usize, Bounds<F>, N>, RNDM<F, N> : SpikeMerging<F>, NoiseDistr : Distribution<F> + Serialize + std::fmt::Debug, + [F; N] : Serialize, + [[F; 2]; N] : Serialize, // DefaultSG<F, S, P, N> : ForwardModel<RNDM<F, N>, F, PreadjointCodomain = PreadjointCodomain, Observable=DVector<F::MixedType>>, // PreadjointCodomain : Space + Bounded<F> + DifferentiableRealMapping<F, N>, // DefaultSeminormOp<F, K, N> : ProxPenalty<F, PreadjointCodomain, RadonRegTerm<F>, N>, @@ -912,6 +942,8 @@ RNDM<F, N> : SpikeMerging<F>, NoiseDistr : Distribution<F> + Serialize + std::fmt::Debug, B : Mapping<Loc<F, N>, Codomain = F> + Serialize + std::fmt::Debug, + [F; N] : Serialize, + [[F; 2]; N] : Serialize, // DefaultSG<F, S, P, N> : ForwardModel<RNDM<F, N>, F, PreadjointCodomain = PreadjointCodomain, Observable=DVector<F::MixedType>>, // PreadjointCodomain : Bounded<F> + DifferentiableRealMapping<F, N>, // DefaultSeminormOp<F, K, N> : ProxPenalty<F, PreadjointCodomain, RadonRegTerm<F>, N>, @@ -1169,18 +1201,21 @@ b : &A::Observable, kernel_plot_width : F, ) -> DynError -where F : Float + ToNalgebraRealField, - Sensor : RealMapping<F, N> + Support<F, N> + Clone, - Spread : RealMapping<F, N> + Support<F, N> + Clone, - Kernel : RealMapping<F, N> + Support<F, N>, - Convolution<Sensor, Spread> : DifferentiableRealMapping<F, N> + Support<F, N>, - 𝒟 : DiscreteMeasureOp<Loc<F, N>, F>, - 𝒟::Codomain : RealMapping<F, N>, - A : ForwardModel<RNDM<F, N>, F>, - for<'a> &'a A::Observable : Instance<A::Observable>, - A::PreadjointCodomain : DifferentiableRealMapping<F, N> + Bounded<F>, - PlotLookup : Plotting<N>, - Cube<F, N> : SetOrd { +where + F : Float + ToNalgebraRealField, + Sensor : RealMapping<F, N> + Support<F, N> + Clone, + Spread : RealMapping<F, N> + Support<F, N> + Clone, + Kernel : RealMapping<F, N> + Support<F, N>, + Convolution<Sensor, Spread> : DifferentiableRealMapping<F, N> + Support<F, N>, + 𝒟 : DiscreteMeasureOp<Loc<F, N>, F>, + 𝒟::Codomain : RealMapping<F, N>, + A : ForwardModel<RNDM<F, N>, F>, + for<'a> &'a A::Observable : Instance<A::Observable>, + A::PreadjointCodomain : DifferentiableRealMapping<F, N> + Bounded<F>, + PlotLookup : Plotting<N>, + Cube<F, N> : SetOrd, + DeltaMeasure<Loc<F, N>, F> : Serialize, +{ if cli.plot < PlotLevel::Data { return Ok(())