src/prox_penalty.rs

branch
dev
changeset 37
c5d8bd1a7728
child 39
6316d68b58af
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/prox_penalty.rs	Thu Jan 23 23:35:28 2025 +0100
@@ -0,0 +1,158 @@
+/*!
+Proximal penalty abstraction
+*/
+
+use numeric_literals::replace_float_literals;
+use alg_tools::types::*;
+use serde::{Serialize, Deserialize};
+
+use alg_tools::mapping::RealMapping;
+use alg_tools::nalgebra_support::ToNalgebraRealField;
+use alg_tools::iterate::{
+    AlgIteratorIteration,
+    AlgIterator,
+};
+use crate::measures::{
+    RNDM,
+};
+use crate::types::{
+    RefinementSettings,
+    IterInfo,
+};
+use crate::subproblem::{
+    InnerSettings,
+    InnerMethod,
+};
+use crate::tolerance::Tolerance;
+use crate::measures::merging::SpikeMergingMethod;
+use crate::regularisation::RegTerm;
+
+pub mod wave;
+pub mod radon_squared;
+pub use radon_squared::RadonSquared;
+
+/// Settings for the solution of the stepwise optimality condition.
+#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
+#[serde(default)]
+pub struct FBGenericConfig<F : Float> {
+    /// Tolerance for point insertion.
+    pub tolerance : Tolerance<F>,
+
+    /// Stop looking for predual maximum (where to isert a new point) below
+    /// `tolerance` multiplied by this factor.
+    ///
+    /// Not used by [`super::radon_fb`].
+    pub insertion_cutoff_factor : F,
+
+    /// Settings for branch and bound refinement when looking for predual maxima
+    pub refinement : RefinementSettings<F>,
+
+    /// Maximum insertions within each outer iteration
+    ///
+    /// Not used by [`super::radon_fb`].
+    pub max_insertions : usize,
+
+    /// Pair `(n, m)` for maximum insertions `m` on first `n` iterations.
+    ///
+    /// Not used by [`super::radon_fb`].
+    pub bootstrap_insertions : Option<(usize, usize)>,
+
+    /// Inner method settings
+    pub inner : InnerSettings<F>,
+
+    /// Spike merging method
+    pub merging : SpikeMergingMethod<F>,
+
+    /// Tolerance multiplier for merges
+    pub merge_tolerance_mult : F,
+
+    /// Spike merging method after the last step
+    pub final_merging : SpikeMergingMethod<F>,
+
+    /// Iterations between merging heuristic tries
+    pub merge_every : usize,
+
+    // /// Save $μ$ for postprocessing optimisation
+    // pub postprocessing : bool
+}
+
+#[replace_float_literals(F::cast_from(literal))]
+impl<F : Float> Default for FBGenericConfig<F> {
+    fn default() -> Self {
+        FBGenericConfig {
+            tolerance : Default::default(),
+            insertion_cutoff_factor : 1.0,
+            refinement : Default::default(),
+            max_insertions : 100,
+            //bootstrap_insertions : None,
+            bootstrap_insertions : Some((10, 1)),
+            inner : InnerSettings {
+                method : InnerMethod::Default,
+                .. Default::default()
+            },
+            merging : SpikeMergingMethod::None,
+            //merging : Default::default(),
+            final_merging : Default::default(),
+            merge_every : 10,
+            merge_tolerance_mult : 2.0,
+            // postprocessing : false,
+        }
+    }
+}
+
+impl<F : Float> FBGenericConfig<F> {
+    /// Check if merging should be attempted this iteration
+    pub fn merge_now<I : AlgIterator>(&self, state : &AlgIteratorIteration<I>) -> bool {
+        state.iteration() % self.merge_every == 0
+    }
+}
+
+
+/// Trait for proximal penalties
+pub trait ProxPenalty<F, PreadjointCodomain, Reg, const N : usize>
+where
+    F : Float + ToNalgebraRealField,
+    Reg : RegTerm<F, N>,
+{
+    type ReturnMapping : RealMapping<F, N>;
+
+    /// Insert new spikes into `μ` to approximately satisfy optimality conditions
+    /// with the forward step term fixed to `τv`.
+    ///
+    /// May return `τv + w` for `w` a subdifferential of the regularisation term `reg`,
+    /// as well as an indication of whether the tolerance bounds `ε` are satisfied.
+    ///
+    /// `μ_base + ν_delta` is the base point, where `μ` and `μ_base` are assumed to have the same
+    /// spike locations, while `ν_delta` may have different locations.
+    ///
+    /// `τv` is mutable to allow [`alg_tools::bisection_tree::btfn::BTFN`] refinement.
+    /// Actual values of `τv` are not supposed to be mutated.
+    fn insert_and_reweigh<I>(
+        &self,
+        μ : &mut RNDM<F, N>,
+        τv : &mut PreadjointCodomain,
+        μ_base : &RNDM<F, N>,
+        ν_delta: Option<&RNDM<F, N>>,
+        τ : F,
+        ε : F,
+        config : &FBGenericConfig<F>,
+        reg : &Reg,
+        state : &AlgIteratorIteration<I>,
+        stats : &mut IterInfo<F, N>,
+    ) -> (Option<Self::ReturnMapping>, bool)
+    where
+        I : AlgIterator;
+
+
+    /// Merge spikes, if possible.
+    fn merge_spikes(
+        &self,
+        μ : &mut RNDM<F, N>,
+        τv : &mut PreadjointCodomain,
+        μ_base : &RNDM<F, N>,
+        τ : F,
+        ε : F,
+        config : &FBGenericConfig<F>,
+        reg : &Reg,
+    ) -> usize;
+}

mercurial