--- a/src/sliding_pdps.rs Tue Aug 04 20:11:10 2026 -0500 +++ b/src/sliding_pdps.rs Thu Aug 06 11:14:15 2026 -0500 @@ -7,7 +7,7 @@ use crate::fb::*; use crate::forward_model::{BoundedCurvature, BoundedCurvatureGuess}; use crate::measures::merging::SpikeMerging; -use crate::measures::{DiscreteMeasure, RNDM}; +use crate::measures::DiscreteMeasure; use crate::plot::Plotter; use crate::prox_penalty::StepLengthBoundPair; use crate::regularisation::SlidingRegTerm; @@ -18,13 +18,14 @@ use alg_tools::direct_product::Pair; use alg_tools::error::DynResult; use alg_tools::euclidean::ClosedEuclidean; +use alg_tools::instance::{Instance, Space}; use alg_tools::iterate::AlgIteratorFactory; use alg_tools::linops::{ BoundedLinear, IdOp, SimplyAdjointable, StaticEuclideanOriginGenerator, ZeroOp, AXPY, GEMV, }; -use alg_tools::mapping::{DifferentiableMapping, DifferentiableRealMapping, Instance}; +use alg_tools::mapping::DifferentiableMapping; use alg_tools::nalgebra_support::ToNalgebraRealField; -use alg_tools::norms::L2; +use alg_tools::norms::{Dist, L2}; use anyhow::ensure; use measures::DeltaMeasure; use numeric_literals::replace_float_literals; @@ -64,7 +65,7 @@ } } -type MeasureZ<F, Z, const N: usize> = Pair<RNDM<N, F>, Z>; +type MeasureZ<F, Z, U> = Pair<DiscreteMeasure<U, F>, Z>; /// Iteratively solve the pointsource localisation with an additional variable /// using sliding primal-dual proximal splitting @@ -85,7 +86,7 @@ Plot, /*KOpM, */ KOpZ, H, - const N: usize, + U, >( f: &Dat, reg: &Reg, @@ -93,32 +94,34 @@ config: &SlidingPDPSConfig<F>, iterator: I, mut plotter: Plot, - (μ0, mut z, mut y): (Option<RNDM<N, F>>, Z, Y), + (μ0, mut z, mut y): (Option<DiscreteMeasure<U, F>>, Z, Y), //opKμ : KOpM, opKz: &KOpZ, fnR: &R, fnH: &H, - domain: &mut impl AdmissibleDomain<Loc<N, F>>, -) -> DynResult<MeasureZ<F, Z, N>> + domain: &mut impl AdmissibleDomain<U>, +) -> DynResult<MeasureZ<F, Z, U>> where F: Float + ToNalgebraRealField, + U: Space + Clone + Dist<L2, F>, + for<'a> &'a U: Instance<U>, I: AlgIteratorFactory<IterInfo<F>>, - Dat: DifferentiableMapping<MeasureZ<F, Z, N>, Codomain = F, DerivativeDomain = Pair<S, Z>> + Dat: DifferentiableMapping<MeasureZ<F, Z, U>, Codomain = F, DerivativeDomain = Pair<S, Z>> + BoundedCurvature<F>, - S: DifferentiableRealMapping<N, F> + ClosedMul<F> + MinMaxMapping<Loc<N, F>, F>, + S: DifferentiableMapping<U, Codomain = F> + ClosedMul<F> + MinMaxMapping<U, F>, for<'a> Pair<&'a P, &'a IdOp<Z>>: StepLengthBoundPair<F, Dat>, //Pair<S, Z>: ClosedMul<F>, - RNDM<N, F>: SpikeMerging<F>, - Reg: SlidingRegTerm<Loc<N, F>, F>, - P: TransportProxPenalty<Loc<N, F>, S, Reg, F>, - // KOpM : Linear<RNDM<N, F>, Codomain=Y> - // + GEMV<F, RNDM<N, F>> + DiscreteMeasure<U, F>: SpikeMerging<F>, + Reg: SlidingRegTerm<U, F>, + P: TransportProxPenalty<U, S, Reg, F>, + // KOpM : Linear<DiscreteMeasure<U, F>, Codomain=Y> + // + GEMV<F, DiscreteMeasure<U, F>> // + Preadjointable< - // RNDM<N, F>, Y, + // DiscreteMeasure<U, F>, Y, // PreadjointCodomain = S, // > // + TransportLipschitz<L2Squared, FloatType=F> - // + AdjointProductBoundedBy<RNDM<N, F>, 𝒟, FloatType=F>, + // + AdjointProductBoundedBy<DiscreteMeasure<U, F>, 𝒟, FloatType=F>, // for<'b> KOpM::Preadjoint<'b> : GEMV<F, Y>, // Since Z is Hilbert, we may just as well use adjoints for K_z. KOpZ: BoundedLinear<Z, L2, L2, F, Codomain = Y> @@ -132,7 +135,7 @@ R: Prox<Z, Codomain = F>, H: Conjugable<Y, F, Codomain = F>, for<'b> H::Conjugate<'b>: Prox<Y>, - Plot: Plotter<P::ReturnMapping, S, RNDM<N, F>>, + Plot: Plotter<P::ReturnMapping, S, DiscreteMeasure<U, F>>, { // Check parameters /*ensure!( @@ -206,7 +209,7 @@ let starH = fnH.conjugate(); // Statistics - let full_stats = |μ: &RNDM<N, F>, z: &Z, ε, stats| IterInfo { + let full_stats = |μ: &DiscreteMeasure<U, F>, z: &Z, ε, stats| IterInfo { value: f.apply(Pair(μ, z)) + fnR.apply(z) + reg.apply(μ) @@ -317,7 +320,7 @@ ε, ins, ®, - Some(|μ̃: &RNDM<N, F>| f.apply(Pair(μ̃, &z)) + reg.apply(μ̃)), + Some(|μ̃: &DiscreteMeasure<U, F>| f.apply(Pair(μ̃, &z)) + reg.apply(μ̃)), ); γ.prune_compat(&mut μ, &mut stats); @@ -375,7 +378,7 @@ ε = tolerance.update(ε, iter); } - let fit = |μ̃: &RNDM<N, F>| { + let fit = |μ̃: &DiscreteMeasure<U, F>| { f.apply(Pair(μ̃, &z)) /*+ fnR.apply(z) + reg.apply(μ)*/ + fnH.apply(/* opKμ.apply(&μ̃) + */ opKz.apply(&z)) + reg.apply(μ̃) @@ -392,32 +395,34 @@ /// The implementation uses [`pointsource_sliding_pdps_pair`] with appropriate dummy /// variables, operators, and functions. #[replace_float_literals(F::cast_from(literal))] -pub fn pointsource_sliding_fb_pair_dom<F, I, S, Dat, Reg, P, Z, R, Plot, const N: usize>( +pub fn pointsource_sliding_fb_pair_dom<F, I, S, Dat, Reg, P, Z, R, Plot, U>( f: &Dat, reg: &Reg, prox_penalty: &P, config: &SlidingFBConfig<F>, iterator: I, plotter: Plot, - (μ0, z): (Option<RNDM<N, F>>, Z), + (μ0, z): (Option<DiscreteMeasure<U, F>>, Z), //opKμ : KOpM, fnR: &R, - domain: &mut impl AdmissibleDomain<Loc<N, F>>, -) -> DynResult<MeasureZ<F, Z, N>> + domain: &mut impl AdmissibleDomain<U>, +) -> DynResult<MeasureZ<F, Z, U>> where F: Float + ToNalgebraRealField, + U: Space + Clone + Dist<L2, F>, + for<'a> &'a U: Instance<U>, I: AlgIteratorFactory<IterInfo<F>>, - Dat: DifferentiableMapping<MeasureZ<F, Z, N>, Codomain = F, DerivativeDomain = Pair<S, Z>> + Dat: DifferentiableMapping<MeasureZ<F, Z, U>, Codomain = F, DerivativeDomain = Pair<S, Z>> + BoundedCurvature<F>, - S: DifferentiableRealMapping<N, F> + ClosedMul<F> + MinMaxMapping<Loc<N, F>, F>, - RNDM<N, F>: SpikeMerging<F>, - Reg: SlidingRegTerm<Loc<N, F>, F>, - P: TransportProxPenalty<Loc<N, F>, S, Reg, F>, + S: DifferentiableMapping<U, Codomain = F> + ClosedMul<F> + MinMaxMapping<U, F>, + DiscreteMeasure<U, F>: SpikeMerging<F>, + Reg: SlidingRegTerm<U, F>, + P: TransportProxPenalty<U, S, Reg, F>, for<'a> Pair<&'a P, &'a IdOp<Z>>: StepLengthBoundPair<F, Dat>, Z: ClosedEuclidean<F> + AXPY + Clone, for<'b> &'b Z: Instance<Z>, R: Prox<Z, Codomain = F>, - Plot: Plotter<P::ReturnMapping, S, RNDM<N, F>>, + Plot: Plotter<P::ReturnMapping, S, DiscreteMeasure<U, F>>, // We should not need to explicitly require this: for<'b> &'b Loc<0, F>: Instance<Loc<0, F>>, // Loc<0, F>: StaticEuclidean<Field = F, PrincipalE = Loc<0, F>> @@ -463,7 +468,7 @@ Plot, /*KOpM, */ KOpZ, H, - const N: usize, + U, >( f: &Dat, reg: &Reg, @@ -471,31 +476,33 @@ config: &SlidingPDPSConfig<F>, iterator: I, plotter: Plot, - init: (Option<RNDM<N, F>>, Z, Y), + init: (Option<DiscreteMeasure<U, F>>, Z, Y), //opKμ : KOpM, opKz: &KOpZ, fnR: &R, fnH: &H, -) -> DynResult<MeasureZ<F, Z, N>> +) -> DynResult<MeasureZ<F, Z, U>> where F: Float + ToNalgebraRealField, + U: Space + Clone + Dist<L2, F>, + for<'a> &'a U: Instance<U>, I: AlgIteratorFactory<IterInfo<F>>, - Dat: DifferentiableMapping<MeasureZ<F, Z, N>, Codomain = F, DerivativeDomain = Pair<S, Z>> + Dat: DifferentiableMapping<MeasureZ<F, Z, U>, Codomain = F, DerivativeDomain = Pair<S, Z>> + BoundedCurvature<F>, - S: DifferentiableRealMapping<N, F> + ClosedMul<F> + MinMaxMapping<Loc<N, F>, F>, + S: DifferentiableMapping<U, Codomain = F> + ClosedMul<F> + MinMaxMapping<U, F>, for<'a> Pair<&'a P, &'a IdOp<Z>>: StepLengthBoundPair<F, Dat>, //Pair<S, Z>: ClosedMul<F>, - RNDM<N, F>: SpikeMerging<F>, - Reg: SlidingRegTerm<Loc<N, F>, F>, - P: TransportProxPenalty<Loc<N, F>, S, Reg, F>, - // KOpM : Linear<RNDM<N, F>, Codomain=Y> - // + GEMV<F, RNDM<N, F>> + DiscreteMeasure<U, F>: SpikeMerging<F>, + Reg: SlidingRegTerm<U, F>, + P: TransportProxPenalty<U, S, Reg, F>, + // KOpM : Linear<DiscreteMeasure<U, F>, Codomain=Y> + // + GEMV<F, DiscreteMeasure<U, F>> // + Preadjointable< - // RNDM<N, F>, Y, + // DiscreteMeasure<U, F>, Y, // PreadjointCodomain = S, // > // + TransportLipschitz<L2Squared, FloatType=F> - // + AdjointProductBoundedBy<RNDM<N, F>, 𝒟, FloatType=F>, + // + AdjointProductBoundedBy<DiscreteMeasure<U, F>, 𝒟, FloatType=F>, // for<'b> KOpM::Preadjoint<'b> : GEMV<F, Y>, // Since Z is Hilbert, we may just as well use adjoints for K_z. KOpZ: BoundedLinear<Z, L2, L2, F, Codomain = Y> @@ -509,7 +516,7 @@ R: Prox<Z, Codomain = F>, H: Conjugable<Y, F, Codomain = F>, for<'b> H::Conjugate<'b>: Prox<Y>, - Plot: Plotter<P::ReturnMapping, S, RNDM<N, F>>, + Plot: Plotter<P::ReturnMapping, S, DiscreteMeasure<U, F>>, { pointsource_sliding_pdps_pair_dom( f, @@ -529,31 +536,33 @@ #[deprecated] /// Version of [`pointsource_sliding_fb_pair_dom`] without domain specification #[replace_float_literals(F::cast_from(literal))] -pub fn pointsource_sliding_fb_pair<F, I, S, Dat, Reg, P, Z, R, Plot, const N: usize>( +pub fn pointsource_sliding_fb_pair<F, I, S, Dat, Reg, P, Z, R, Plot, U>( f: &Dat, reg: &Reg, prox_penalty: &P, config: &SlidingFBConfig<F>, iterator: I, plotter: Plot, - (μ0, z): (Option<RNDM<N, F>>, Z), + (μ0, z): (Option<DiscreteMeasure<U, F>>, Z), //opKμ : KOpM, fnR: &R, -) -> DynResult<MeasureZ<F, Z, N>> +) -> DynResult<MeasureZ<F, Z, U>> where F: Float + ToNalgebraRealField, + U: Space + Clone + Dist<L2, F>, + for<'a> &'a U: Instance<U>, I: AlgIteratorFactory<IterInfo<F>>, - Dat: DifferentiableMapping<MeasureZ<F, Z, N>, Codomain = F, DerivativeDomain = Pair<S, Z>> + Dat: DifferentiableMapping<MeasureZ<F, Z, U>, Codomain = F, DerivativeDomain = Pair<S, Z>> + BoundedCurvature<F>, - S: DifferentiableRealMapping<N, F> + ClosedMul<F> + MinMaxMapping<Loc<N, F>, F>, - RNDM<N, F>: SpikeMerging<F>, - Reg: SlidingRegTerm<Loc<N, F>, F>, - P: TransportProxPenalty<Loc<N, F>, S, Reg, F>, + S: DifferentiableMapping<U, Codomain = F> + ClosedMul<F> + MinMaxMapping<U, F>, + DiscreteMeasure<U, F>: SpikeMerging<F>, + Reg: SlidingRegTerm<U, F>, + P: TransportProxPenalty<U, S, Reg, F>, for<'a> Pair<&'a P, &'a IdOp<Z>>: StepLengthBoundPair<F, Dat>, Z: ClosedEuclidean<F> + AXPY + Clone, for<'b> &'b Z: Instance<Z>, R: Prox<Z, Codomain = F>, - Plot: Plotter<P::ReturnMapping, S, RNDM<N, F>>, + Plot: Plotter<P::ReturnMapping, S, DiscreteMeasure<U, F>>, // We should not need to explicitly require this: for<'b> &'b Loc<0, F>: Instance<Loc<0, F>>, // Loc<0, F>: StaticEuclidean<Field = F, PrincipalE = Loc<0, F>>