Tue, 21 Mar 2023 20:31:01 +0200
Implement non-negativity constraints for the conditional gradient methods
/*! Iterative algorithms for solving the finite-dimensional subproblem. */ use serde::{Serialize, Deserialize}; use numeric_literals::replace_float_literals; use alg_tools::iterate::{ AlgIteratorOptions, Verbose, }; use crate::types::*; pub mod nonneg; pub mod unconstrained; #[deprecated(since = "1.0.1", note = "Moved to submodule nonneg")] pub use nonneg::{ quadratic_nonneg, quadratic_nonneg_ssn, quadratic_nonneg_fb }; /// Method for solving finite-dimensional subproblems #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] #[allow(dead_code)] pub enum InnerMethod { /// Forward-backward FB, /// Semismooth Newton SSN, } /// Settings for the solution of finite-dimensional subproblems #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] pub struct InnerSettings<F : Float> { /// Method pub method : InnerMethod, /// Proportional step length (∈ [0, 1) for `InnerMethod::FB`). pub τ0 : F, /// Fraction of `tolerance` given to inner algorithm pub tolerance_mult : F, /// Iterator options #[serde(flatten)] pub iterator_options : AlgIteratorOptions, } #[replace_float_literals(F::cast_from(literal))] impl<F : Float> Default for InnerSettings<F> { fn default() -> Self { InnerSettings { τ0 : 0.99, iterator_options : AlgIteratorOptions { // max_iter cannot be very small, as initially FB needs many iterations, although // on later invocations even one or two tends to be enough max_iter : 2000, // verbose_iter affects testing of sufficient convergence, so we set it to // a small value… verbose_iter : Verbose::Every(1), // … but don't print out anything quiet : true, .. Default::default() }, method : InnerMethod::FB, tolerance_mult : 0.01, } } }