Tue, 21 Mar 2023 20:31:01 +0200
Implement non-negativity constraints for the conditional gradient methods
/*! Regularisation terms */ use serde::{Serialize, Deserialize}; use alg_tools::norms::Norm; use alg_tools::linops::Apply; use alg_tools::loc::Loc; use crate::types::*; use crate::measures::{ DiscreteMeasure, Radon }; #[allow(unused_imports)] // Used by documentation. use crate::fb::generic_pointsource_fb_reg; /// The regularisation term $α\\|μ\\|\_{ℳ(Ω)} + δ_{≥ 0}(μ)$ for [`generic_pointsource_fb_reg`]. /// /// The only member of the struct is the regularisation parameter α. #[derive(Copy, Clone, Debug, Serialize, Deserialize)] pub struct NonnegRadonRegTerm<F : Float>(pub F /* α */); impl<'a, F : Float> NonnegRadonRegTerm<F> { /// Returns the regularisation parameter pub fn α(&self) -> F { let &NonnegRadonRegTerm(α) = self; α } } impl<'a, F : Float, const N : usize> Apply<&'a DiscreteMeasure<Loc<F, N>, F>> for NonnegRadonRegTerm<F> { type Output = F; fn apply(&self, μ : &'a DiscreteMeasure<Loc<F, N>, F>) -> F { self.α() * μ.norm(Radon) } } /// The regularisation term $α\|μ\|_{ℳ(Ω)}$ for [`generic_pointsource_fb_reg`]. /// /// The only member of the struct is the regularisation parameter α. #[derive(Copy, Clone, Debug, Serialize, Deserialize)] pub struct RadonRegTerm<F : Float>(pub F /* α */); impl<'a, F : Float> RadonRegTerm<F> { /// Returns the regularisation parameter pub fn α(&self) -> F { let &RadonRegTerm(α) = self; α } } impl<'a, F : Float, const N : usize> Apply<&'a DiscreteMeasure<Loc<F, N>, F>> for RadonRegTerm<F> { type Output = F; fn apply(&self, μ : &'a DiscreteMeasure<Loc<F, N>, F>) -> F { self.α() * μ.norm(Radon) } } /// Regularisation term configuration #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] pub enum Regularisation<F : Float> { /// $α \\|μ\\|\_{ℳ(Ω)}$ Radon(F), /// $α\\|μ\\|\_{ℳ(Ω)} + δ_{≥ 0}(μ)$ NonnegRadon(F), } impl<'a, F : Float, const N : usize> Apply<&'a DiscreteMeasure<Loc<F, N>, F>> for Regularisation<F> { type Output = F; fn apply(&self, μ : &'a DiscreteMeasure<Loc<F, N>, F>) -> F { match *self { Self::Radon(α) => RadonRegTerm(α).apply(μ), Self::NonnegRadon(α) => NonnegRadonRegTerm(α).apply(μ), } } }