diff -r efa60bc4f743 -r b087e3eab191 src/pdps.rs
--- a/src/pdps.rs Thu Aug 29 00:00:00 2024 -0500
+++ b/src/pdps.rs Tue Dec 31 09:25:45 2024 -0500
@@ -6,8 +6,7 @@
* Valkonen T. - _Proximal methods for point source localisation_,
[arXiv:2212.02991](https://arxiv.org/abs/2212.02991).
-The main routine is [`pointsource_pdps`]. It is based on specilisatinn of
-[`generic_pointsource_fb_reg`] through relevant [`FBSpecialisation`] implementations.
+The main routine is [`pointsource_pdps_reg`].
Both norm-2-squared and norm-1 data terms are supported. That is, implemented are solvers for
$$
@@ -37,10 +36,6 @@
For $F_0(y)=\frac{1}{2}\|y\|_2^2$ the second part reads $y = Aμ -b$.
For $F_0(y)=\|y\|_1$ the second part reads $y ∈ ∂\|·\|_1(Aμ - b)$.
-
-Based on zero initialisation for $μ$, we use the [`Subdifferentiable`] trait to make an
-initialisation corresponding to the second part of the optimality conditions.
-In the algorithm itself, standard proximal steps are taking with respect to $F\_0^* + ⟨b, ·⟩$.
*/
use numeric_literals::replace_float_literals;
@@ -48,13 +43,10 @@
use nalgebra::DVector;
use clap::ValueEnum;
-use alg_tools::iterate::{
- AlgIteratorFactory,
- AlgIteratorState,
-};
+use alg_tools::iterate::AlgIteratorFactory;
use alg_tools::loc::Loc;
use alg_tools::euclidean::Euclidean;
-use alg_tools::linops::Apply;
+use alg_tools::linops::Mapping;
use alg_tools::norms::{
Linfinity,
Projection,
@@ -69,14 +61,17 @@
SupportGenerator,
LocalAnalysis,
};
-use alg_tools::mapping::RealMapping;
+use alg_tools::mapping::{RealMapping, Instance};
use alg_tools::nalgebra_support::ToNalgebraRealField;
use alg_tools::linops::AXPY;
use crate::types::*;
-use crate::measures::DiscreteMeasure;
+use crate::measures::{DiscreteMeasure, RNDM, Radon};
use crate::measures::merging::SpikeMerging;
-use crate::forward_model::ForwardModel;
+use crate::forward_model::{
+ AdjointProductBoundedBy,
+ ForwardModel
+};
use crate::seminorms::DiscreteMeasureOp;
use crate::plot::{
SeqPlotter,
@@ -87,7 +82,7 @@
FBGenericConfig,
insert_and_reweigh,
postprocess,
- prune_and_maybe_simple_merge
+ prune_with_stats
};
use crate::regularisation::RegTerm;
use crate::dataterm::{
@@ -110,7 +105,30 @@
Full
}
-/// Settings for [`pointsource_pdps`].
+#[replace_float_literals(F::cast_from(literal))]
+impl Acceleration {
+ /// PDPS parameter acceleration. Updates τ and σ and returns ω.
+ /// This uses dual strong convexity, not primal.
+ fn accelerate
(self, τ : &mut F, σ : &mut F, γ : F) -> F {
+ match self {
+ Acceleration::None => 1.0,
+ Acceleration::Partial => {
+ let ω = 1.0 / (1.0 + γ * (*σ)).sqrt();
+ *σ *= ω;
+ *τ /= ω;
+ ω
+ },
+ Acceleration::Full => {
+ let ω = 1.0 / (1.0 + 2.0 * γ * (*σ)).sqrt();
+ *σ *= ω;
+ *τ /= ω;
+ ω
+ },
+ }
+ }
+}
+
+/// Settings for [`pointsource_pdps_reg`].
#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
#[serde(default)]
pub struct PDPSConfig {
@@ -155,9 +173,13 @@
#[replace_float_literals(F::cast_from(literal))]
-impl + AXPY, const N : usize>
-PDPSDataTerm
-for L2Squared {
+impl PDPSDataTerm
+for L2Squared
+where
+ F : Float,
+ V : Euclidean + AXPY,
+ for<'b> &'b V : Instance,
+{
fn some_subdifferential(&self, x : V) -> V { x }
fn factor_of_strong_convexity(&self) -> F {
@@ -166,7 +188,7 @@
#[inline]
fn dual_update(&self, y : &mut V, y_prev : &V, σ : F) {
- y.axpy(1.0 / (1.0 + σ), &y_prev, σ / (1.0 + σ));
+ y.axpy(1.0 / (1.0 + σ), y_prev, σ / (1.0 + σ));
}
}
@@ -210,16 +232,13 @@
iterator : I,
mut plotter : SeqPlotter,
dataterm : D,
-) -> DiscreteMeasure, F>
+) -> RNDM
where F : Float + ToNalgebraRealField,
I : AlgIteratorFactory>,
- for<'b> &'b A::Observable : std::ops::Neg