Sun, 25 Sep 2022 21:45:56 +0300
Attempt at directly referring to measure masses as SliceStorageMut
//! Type definitions and re-exports use numeric_literals::replace_float_literals; use colored::ColoredString; use serde::{Serialize, Deserialize}; use clap::ValueEnum; use alg_tools::iterate::LogRepr; use alg_tools::euclidean::Euclidean; use alg_tools::norms::{Norm, L1}; pub use alg_tools::types::*; pub use alg_tools::loc::Loc; pub use alg_tools::sets::Cube; use crate::measures::DiscreteMeasure; /// [`Float`] with extra display and string conversion traits such that [`clap`] doesn't choke up. pub trait ClapFloat : Float + std::str::FromStr<Err=std::num::ParseFloatError> + std::fmt::Display {} impl ClapFloat for f32 {} impl ClapFloat for f64 {} /// Structure for storing iteration statistics #[derive(Debug, Clone, Serialize)] pub struct IterInfo<F : Float, const N : usize> { /// Function value pub value : F, /// Number of speaks pub n_spikes : usize, /// Number of iterations this statistic covers pub this_iters : usize, /// Number of spikes removed by merging since last IterInfo statistic pub merged : usize, /// Number of spikes removed by pruning since last IterInfo statistic pub pruned : usize, /// Number of inner iterations since last IterInfo statistic pub inner_iters : usize, /// Current tolerance pub ε : F, /// Strict tolerance update if one was used pub maybe_ε1 : Option<F>, /// Solve fin.dim problem for this measure to get the optimal `value`. pub postprocessing : Option<DiscreteMeasure<Loc<F, N>, F>>, } impl<F, const N : usize> LogRepr for IterInfo<F, N> where F : LogRepr + Float { fn logrepr(&self) -> ColoredString { let eqsign = match self.maybe_ε1 { Some(ε1) if ε1 < self.ε => '≛', _ => '=', }; format!("{}\t| N = {}, ε {} {:.8}, inner_iters_mean = {}, merged+pruned_mean = {}+{}", self.value.logrepr(), self.n_spikes, eqsign, self.ε, self.inner_iters as float / self.this_iters as float, self.merged as float / self.this_iters as float, self.pruned as float / self.this_iters as float, ).as_str().into() } } /// Branch and bound refinement settings #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] #[serde(default)] pub struct RefinementSettings<F : Float> { /// Function value tolerance multiplier for bisection tree refinement in /// [`alg_tools::bisection_tree::BTFN::maximise`] and related functions. pub tolerance_mult : F, /// Maximum branch and bound steps pub max_steps : usize, } #[replace_float_literals(F::cast_from(literal))] impl<F : Float> Default for RefinementSettings<F> { fn default() -> Self { RefinementSettings { tolerance_mult : 0.1, max_steps : 50000, } } } /// Data term type #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug, ValueEnum)] pub enum DataTerm { /// $\\|z\\|\_2^2/2$ L2Squared, /// $\\|z\\|\_1$ L1, } impl DataTerm { /// Calculate the data term value at residual $z=Aμ - b$. pub fn value_at_residual<F : Float, E : Euclidean<F> + Norm<F, L1>>(&self, z : E) -> F { match self { Self::L2Squared => z.norm2_squared_div2(), Self::L1 => z.norm(L1), } } }