| 40 |
40 |
| 41 use crate::fb::{postprocess, prune_with_stats}; |
41 use crate::fb::{postprocess, prune_with_stats}; |
| 42 use crate::forward_model::ForwardModel; |
42 use crate::forward_model::ForwardModel; |
| 43 use crate::measures::merging::SpikeMerging; |
43 use crate::measures::merging::SpikeMerging; |
| 44 use crate::measures::merging::SpikeMergingMethod; |
44 use crate::measures::merging::SpikeMergingMethod; |
| 45 use crate::measures::{DiscreteMeasure, RNDM}; |
45 use crate::measures::DiscreteMeasure; |
| 46 use crate::plot::Plotter; |
46 use crate::plot::Plotter; |
| 47 pub use crate::prox_penalty::{InsertionConfig, ProxPenalty, StepLengthBoundPD}; |
47 pub use crate::prox_penalty::{InsertionConfig, ProxPenalty, StepLengthBoundPD}; |
| 48 use crate::regularisation::RegTerm; |
48 use crate::regularisation::RegTerm; |
| 49 use crate::types::*; |
49 use crate::types::*; |
| 50 use alg_tools::convex::{Conjugable, ConvexMapping, Prox}; |
50 use alg_tools::convex::{Conjugable, ConvexMapping, Prox}; |
| 51 use alg_tools::error::DynResult; |
51 use alg_tools::error::DynResult; |
| 52 use alg_tools::iterate::AlgIteratorFactory; |
52 use alg_tools::iterate::AlgIteratorFactory; |
| 53 use alg_tools::linops::{Mapping, AXPY}; |
53 use alg_tools::linops::{Mapping, Space, AXPY}; |
| 54 use alg_tools::mapping::{DataTerm, Instance}; |
54 use alg_tools::mapping::{DataTerm, Instance}; |
| 55 use alg_tools::nalgebra_support::ToNalgebraRealField; |
55 use alg_tools::nalgebra_support::ToNalgebraRealField; |
| 56 use anyhow::ensure; |
56 use anyhow::ensure; |
| 57 use clap::ValueEnum; |
57 use clap::ValueEnum; |
| 58 use numeric_literals::replace_float_literals; |
58 use numeric_literals::replace_float_literals; |
| 138 /// |
138 /// |
| 139 /// For the mathematical formulation, see the [module level](self) documentation and the manuscript. |
139 /// For the mathematical formulation, see the [module level](self) documentation and the manuscript. |
| 140 /// |
140 /// |
| 141 /// Returns the final iterate. |
141 /// Returns the final iterate. |
| 142 #[replace_float_literals(F::cast_from(literal))] |
142 #[replace_float_literals(F::cast_from(literal))] |
| 143 pub fn pointsource_pdps_reg<'a, F, I, A, Phi, Reg, Plot, P, const N: usize>( |
143 pub fn pointsource_pdps_reg<'a, F, U, I, A, Phi, Reg, Plot, P>( |
| 144 f: &'a DataTerm<F, RNDM<N, F>, A, Phi>, |
144 f: &'a DataTerm<F, DiscreteMeasure<U, F>, A, Phi>, |
| 145 reg: &Reg, |
145 reg: &Reg, |
| 146 prox_penalty: &P, |
146 prox_penalty: &P, |
| 147 pdpsconfig: &PDPSConfig<F>, |
147 pdpsconfig: &PDPSConfig<F>, |
| 148 iterator: I, |
148 iterator: I, |
| 149 mut plotter: Plot, |
149 mut plotter: Plot, |
| 150 μ0: Option<RNDM<N, F>>, |
150 μ0: Option<DiscreteMeasure<U, F>>, |
| 151 ) -> DynResult<RNDM<N, F>> |
151 ) -> DynResult<DiscreteMeasure<U, F>> |
| 152 where |
152 where |
| |
153 U: Space + Clone + PartialEq, |
| 153 F: Float + ToNalgebraRealField, |
154 F: Float + ToNalgebraRealField, |
| 154 I: AlgIteratorFactory<IterInfo<F>>, |
155 I: AlgIteratorFactory<IterInfo<F>>, |
| 155 A: ForwardModel<RNDM<N, F>, F>, |
156 A: ForwardModel<DiscreteMeasure<U, F>, F>, |
| 156 for<'b> &'b A::Observable: Instance<A::Observable>, |
157 for<'b> &'b A::Observable: Instance<A::Observable>, |
| 157 A::Observable: AXPY<Field = F>, |
158 A::Observable: AXPY<Field = F>, |
| 158 RNDM<N, F>: SpikeMerging<F>, |
159 DiscreteMeasure<U, F>: SpikeMerging<F>, |
| 159 Reg: RegTerm<Loc<N, F>, F>, |
160 Reg: RegTerm<U, F>, |
| 160 Phi: Conjugable<A::Observable, F>, |
161 Phi: Conjugable<A::Observable, F>, |
| 161 for<'b> Phi::Conjugate<'b>: Prox<A::Observable>, |
162 for<'b> Phi::Conjugate<'b>: Prox<A::Observable>, |
| 162 P: ProxPenalty<Loc<N, F>, A::PreadjointCodomain, Reg, F> + StepLengthBoundPD<F, A, RNDM<N, F>>, |
163 P: ProxPenalty<U, A::PreadjointCodomain, Reg, F> |
| 163 Plot: Plotter<P::ReturnMapping, A::PreadjointCodomain, RNDM<N, F>>, |
164 + StepLengthBoundPD<F, A, DiscreteMeasure<U, F>>, |
| |
165 Plot: Plotter<P::ReturnMapping, A::PreadjointCodomain, DiscreteMeasure<U, F>>, |
| 164 { |
166 { |
| 165 // Check parameters |
167 // Check parameters |
| 166 ensure!( |
168 ensure!( |
| 167 pdpsconfig.τ0 > 0.0 && pdpsconfig.σ0 > 0.0 && pdpsconfig.τ0 * pdpsconfig.σ0 <= 1.0, |
169 pdpsconfig.τ0 > 0.0 && pdpsconfig.σ0 > 0.0 && pdpsconfig.τ0 * pdpsconfig.σ0 <= 1.0, |
| 168 "Invalid step length parameters" |
170 "Invalid step length parameters" |
| 185 let mut ε = tolerance.initial(); |
187 let mut ε = tolerance.initial(); |
| 186 |
188 |
| 187 // Initialise iterates |
189 // Initialise iterates |
| 188 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
190 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new()); |
| 189 let mut y = f.residual(&μ); |
191 let mut y = f.residual(&μ); |
| 190 let full_stats = |μ: &RNDM<N, F>, ε, stats| IterInfo { |
192 let full_stats = |μ: &DiscreteMeasure<U, F>, ε, stats| IterInfo { |
| 191 value: f.apply(μ) + reg.apply(μ), |
193 value: f.apply(μ) + reg.apply(μ), |
| 192 n_spikes: μ.len(), |
194 n_spikes: μ.len(), |
| 193 ε, |
195 ε, |
| 194 // postprocessing: config.postprocessing.then(|| μ.clone()), |
196 // postprocessing: config.postprocessing.then(|| μ.clone()), |
| 195 ..stats |
197 ..stats |