src/sliding_pdps.rs

changeset 93
8f1e57821d76
parent 89
8d1c959432c8
child 95
d9318317ccac
--- 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,
                 &reg,
-                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>>

mercurial