--- a/src/sliding_fb.rs Fri Aug 14 10:38:27 2026 -0500 +++ b/src/sliding_fb.rs Fri Oct 02 12:03:25 2026 -0500 @@ -1006,7 +1006,7 @@ Dat::DerivativeDomain: DifferentiableMapping<U, Codomain = F> + ClosedMul<F> + MinMaxMapping<U, F>, //for<'a> Dat::Differential<'a>: Lipschitz<&'a P, FloatType = F>, - DiscreteMeasure<U, F>: SpikeMerging<F>, + DiscreteMeasure<U, F>: SpikeMerging<F> + Norm<Radon, F>, Reg: SlidingRegTerm<U, F>, P: TransportProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>, @@ -1038,19 +1038,23 @@ let mut ε = tolerance.initial(); // Statistics - let full_stats = |μ: &DiscreteMeasure<U, F>, ε, stats| IterInfo { - value: f.apply(μ) + reg.apply(μ), - n_spikes: μ.len(), - ε, - // postprocessing: config.insertion.postprocessing.then(|| μ.clone()), - ..stats - }; + let full_stats = + |μ: &DiscreteMeasure<U, F>, v: &mut Dat::DerivativeDomain, ε, stats| IterInfo { + value: f.apply(μ) + reg.apply(μ), + n_spikes: μ.len(), + discrepancy: Some(τ * reg.discrepancy(v, 1.0, ε / τ, μ, &config.insertion)), + μ_norm: μ.norm(Radon), + ε, + // postprocessing: config.insertion.postprocessing.then(|| μ.clone()), + ..stats + }; let mut stats = IterInfo::new(); + // Construct initial smooth part of surrogate model + let mut v = f.differential(&μ); + // Run the algorithm - for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) { - let mut v = f.differential(&μ); - + for state in iterator.iter_init(|| full_stats(&μ, &mut v, ε, stats.clone())) { // Calculate initial transport prox_penalty.initial_transport( &mut γ, @@ -1164,10 +1168,18 @@ let iter = state.iteration(); stats.this_iters += 1; + // Update smooth part of surrogate model + v = f.differential(&μ); + // Give statistics if requested state.if_verbose(|| { - plotter.plot_spikes(iter, None, Some(&τv̆), &μ); - full_stats(&μ, ε, std::mem::replace(&mut stats, IterInfo::new())) + plotter.plot_spikes(iter, None, Some(&v), &μ); + full_stats( + &μ, + &mut v, + ε, + std::mem::replace(&mut stats, IterInfo::new()), + ) }); // Update main tolerance for next iteration @@ -1198,7 +1210,7 @@ Dat::DerivativeDomain: DifferentiableMapping<U, Codomain = F> + ClosedMul<F> + MinMaxMapping<U, F>, //for<'a> Dat::Differential<'a>: Lipschitz<&'a P, FloatType = F>, - DiscreteMeasure<U, F>: SpikeMerging<F>, + DiscreteMeasure<U, F>: SpikeMerging<F> + Norm<Radon, F>, Reg: SlidingRegTerm<U, F>, P: TransportProxPenalty<U, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, DiscreteMeasure<U, F>>,