# HG changeset patch # User Tuomo Valkonen # Date 1736217423 18000 # Node ID 0f59c0d02e1351634a861b707f2d0b7f9d3d3132 # Parent c5d8bd1a7728c99ce2acbb5c2dd0768116035ad1 Attempt to do more Serialize / Deserialize but run into csv problems diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/experiments.rs --- 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 : Serialize", + deserialize = "F : for<'a> Deserialize<'a>, + Loc : for<'a> Deserialize<'a>", +))] struct BallCharacteristic { pub center : Loc, pub radius : F, diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/forward_model/sensor_grid.rs --- 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, P : Spread, Convolution : Spread + LocalAnalysis, + [F; N]: Serialize, /*ShiftedSensor : LocalAnalysis, Weighted, F> : LocalAnalysis*/ { type Observable = DVector; @@ -429,6 +431,7 @@ S : Sensor, P : Spread, Convolution : Spread + LocalAnalysis, + [F; N] : Serialize, /*ShiftedSensor : LocalAnalysis, Weighted, F> : LocalAnalysis*/ { diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/kernels/ball_indicator.rs --- 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 { /// The radius of the ball. pub r : C, diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/kernels/base.rs --- 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( /// First kernel pub A, diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/kernels/gaussian.rs --- 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 { /// The variance $σ^2$. pub variance : S, diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/kernels/hat.rs --- 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 { /// The parameter $ε>0$. pub width : C, diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/kernels/hat_convolution.rs --- 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 { /// The parameter $σ$ of the kernel. pub radius : S, diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/kernels/linear.rs --- 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 : Serialize + for<'a> Deserialize<'a>")] pub struct Linear { /// The parameter $ε>0$. pub v : Loc, diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/kernels/mollifier.rs --- 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} /// $$ -#[derive(Copy,Clone,Serialize,Debug,Eq,PartialEq)] +#[derive(Copy,Clone,Serialize,Deserialize,Debug,Eq,PartialEq)] pub struct Mollifier { /// The parameter $ε$ of the mollifier. pub width : C, diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/measures/delta.rs --- 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 { // 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 Serialize for DeltaMeasure, F> -where - F: Serialize, -{ - fn serialize(&self, serializer: S) -> Result - 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 Measure for DeltaMeasure { type Domain = Domain; } diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/measures/discrete.rs --- 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 { pub(super) spikes : Vec>, } @@ -456,25 +456,6 @@ } } -// Need to manually implement serialisation for DeltaMeasure, F> [`csv`] writer fails on -// structs with nested arrays as well as with #[serde(flatten)]. -// Then derive no longer works for DiscreteMeasure -impl Serialize for DiscreteMeasure, F> -where - F: Serialize, -{ - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut s = serializer.serialize_seq(Some(self.spikes.len()))?; - for δ in self.spikes.iter() { - s.serialize_element(δ)?; - } - s.end() - } -} - impl Measure for DiscreteMeasure { type Domain = Domain; } diff -r c5d8bd1a7728 -r 0f59c0d02e13 src/run.rs --- 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 { iter : usize, cpu_time : f64, @@ -372,7 +372,7 @@ } /// Collected experiment statistics -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] struct ExperimentStats { /// 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 { /// 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 : Serialize, + NoiseDistr : Serialize, + [usize; N] : Serialize, + RNDM : Serialize, + Regularisation : Serialize, + F : Serialize, + S : Serialize, + P : Serialize, + K : Serialize", + deserialize = "Cube : for<'a> Deserialize<'a>, + NoiseDistr : for<'a> Deserialize<'a>, + [usize; N] : for<'a> Deserialize<'a>, + RNDM : for<'a> Deserialize<'a>, + Regularisation : 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 where F : Float, - [usize; N] : Serialize, NoiseDistr : Distribution, S : Sensor, P : Spread, @@ -452,7 +471,15 @@ pub algorithm_defaults : HashMap>, } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(bound( + serialize = "ExperimentV2 : Serialize, + B : Serialize, + F : Serialize", + deserialize = "ExperimentV2: for<'a> Deserialize<'a>, + B : for<'a> Deserialize<'a>, + F : for<'a> Deserialize<'a>", +))] pub struct ExperimentBiased where F : Float, [usize; N] : Serialize, @@ -541,6 +568,7 @@ ) -> DynError where PlotLookup : Plotting, + DeltaMeasure, F> : Serialize, { let mut logs = Vec::new(); @@ -647,6 +675,8 @@ BTNodeLookup: BTNode, N>, RNDM : SpikeMerging, NoiseDistr : Distribution + Serialize + std::fmt::Debug, + [F; N] : Serialize, + [[F; 2]; N] : Serialize, // DefaultSG : ForwardModel, F, PreadjointCodomain = PreadjointCodomain, Observable=DVector>, // PreadjointCodomain : Space + Bounded + DifferentiableRealMapping, // DefaultSeminormOp : ProxPenalty, N>, @@ -912,6 +942,8 @@ RNDM : SpikeMerging, NoiseDistr : Distribution + Serialize + std::fmt::Debug, B : Mapping, Codomain = F> + Serialize + std::fmt::Debug, + [F; N] : Serialize, + [[F; 2]; N] : Serialize, // DefaultSG : ForwardModel, F, PreadjointCodomain = PreadjointCodomain, Observable=DVector>, // PreadjointCodomain : Bounded + DifferentiableRealMapping, // DefaultSeminormOp : ProxPenalty, N>, @@ -1169,18 +1201,21 @@ b : &A::Observable, kernel_plot_width : F, ) -> DynError -where F : Float + ToNalgebraRealField, - Sensor : RealMapping + Support + Clone, - Spread : RealMapping + Support + Clone, - Kernel : RealMapping + Support, - Convolution : DifferentiableRealMapping + Support, - 𝒟 : DiscreteMeasureOp, F>, - 𝒟::Codomain : RealMapping, - A : ForwardModel, F>, - for<'a> &'a A::Observable : Instance, - A::PreadjointCodomain : DifferentiableRealMapping + Bounded, - PlotLookup : Plotting, - Cube : SetOrd { +where + F : Float + ToNalgebraRealField, + Sensor : RealMapping + Support + Clone, + Spread : RealMapping + Support + Clone, + Kernel : RealMapping + Support, + Convolution : DifferentiableRealMapping + Support, + 𝒟 : DiscreteMeasureOp, F>, + 𝒟::Codomain : RealMapping, + A : ForwardModel, F>, + for<'a> &'a A::Observable : Instance, + A::PreadjointCodomain : DifferentiableRealMapping + Bounded, + PlotLookup : Plotting, + Cube : SetOrd, + DeltaMeasure, F> : Serialize, +{ if cli.plot < PlotLevel::Data { return Ok(())