diff -r e2953ffd4e0b -r e9a460a0e638 src/lib.rs --- a/src/lib.rs Fri May 15 14:40:02 2026 -0500 +++ b/src/lib.rs Sun Jul 19 07:34:39 2026 +0200 @@ -14,7 +14,6 @@ use alg_tools::parallelism::{set_max_threads, set_num_threads}; use clap::Parser; use serde::{Deserialize, Serialize}; -use serde_json; use serde_with::skip_serializing_none; use std::num::NonZeroUsize; @@ -47,10 +46,9 @@ pub use measures::*; } -use run::{AlgorithmConfig, DefaultAlgorithm, Named, PlotLevel, RunnableExperiment}; +use run::{DefaultAlgorithm, PlotLevel, RunnableExperiment}; use subproblem::InnerMethod; use types::{ClapFloat, Float}; -use DefaultAlgorithm::*; /// Trait for customising the experiments available from the command line pub trait ExperimentSetup: @@ -84,8 +82,7 @@ /// /// Not all algorithms are available for all the experiments. /// In particular, only PDPS is available for the experiments with L¹ data term. - #[arg(value_enum, value_name = "ALGORITHM", long, short = 'a', - default_values_t = [FB, PDPS, SlidingFB, FW, RadonFB])] + #[arg(value_enum, value_name = "ALGORITHM", long, short = 'a')] algorithm: Vec, /// Saved algorithm configration(s) to use on the experiments @@ -144,48 +141,66 @@ /// /// The first parameter is the number of bootstrap insertion iterations, and the second /// the maximum number of iterations on each of them. - bootstrap_insertions: Option>, + pub bootstrap_insertions: Option>, #[arg(long, requires = "algorithm")] /// Primal step length parameter override for --algorithm. /// /// Only use if running just a single algorithm, as different algorithms have different /// regularisation parameters. Does not affect the algorithms fw and fwrelax. - tau0: Option, + pub tau0: Option, #[arg(long, requires = "algorithm")] /// Second primal step length parameter override for SlidingPDPS. /// /// Only use if running just a single algorithm, as different algorithms have different /// regularisation parameters. - sigmap0: Option, + pub sigmap0: Option, #[arg(long, requires = "algorithm")] /// Dual step length parameter override for --algorithm. /// /// Only use if running just a single algorithm, as different algorithms have different /// regularisation parameters. Only affects PDPS. - sigma0: Option, + pub sigma0: Option, #[arg(long)] /// Normalised transport step length for sliding methods. - theta0: Option, + pub theta0: Option, + + #[arg(long)] + /// Unnormalised transport step length for sliding methods, multiplied by tau. + pub tautheta: Option, #[arg(long)] - /// A posteriori transport tolerance multiplier (C_pos) - transport_tolerance_pos: Option, + /// A posteriori transport tolerance multiplier + pub transport_tolerance: Option, + + #[arg(long)] + /// Multiplier for rough estimate of ℓ_{∇v}. Should be ≥ 1. + /// If explicit τθ is given, ℓ_{∇v} is one divided by this number times τθ. + /// Otherwise, if τθ relative to an estimate of ℓ_{∇v}, this number multiplies that estimate. + pub gradv_lipest_mult: Option, #[arg(long)] /// Transport adaptation factor. Must be in (0, 1). - transport_adaptation: Option, + pub transport_adaptation: Option, + + #[arg(long)] + /// Whether partially transported spikes are allowed. + pub allow_partial_transport: Option, + + #[arg(long)] + /// Use an alternative remainder control rule. + pub alt_remainder_control: Option, #[arg(long)] /// Minimal step length parameter for sliding methods. - tau0_min: Option, + pub tau0_min: Option, #[arg(value_enum, long)] /// PDPS acceleration, when available. - acceleration: Option, + pub acceleration: Option, // #[arg(long)] // /// Perform postprocess weight optimisation for saved iterations @@ -196,58 +211,57 @@ /// Merging frequency, if merging enabled (every n iterations) /// /// Only affects FB, FISTA, and PDPS. - merge_every: Option, + pub merge_every: Option, #[arg(long)] /// Enable merging (default: determined by algorithm) - merge: Option, + pub merge: Option, #[arg(long)] /// Merging radius (default: determined by experiment) - merge_radius: Option, + pub merge_radius: Option, #[arg(long)] /// Interpolate when merging (default : determined by algorithm) - merge_interp: Option, + pub merge_interp: Option, #[arg(long)] /// Enable final merging (default: determined by algorithm) - final_merging: Option, + pub final_merging: Option, #[arg(long)] /// Enable fitness-based merging for relevant FB-type methods. /// This has worse convergence guarantees that merging based on optimality conditions. - fitness_merging: Option, + pub fitness_merging: Option, #[arg(long, value_names = &["ε", "θ", "p"])] /// Set the tolerance to ε_k = ε/(1+θk)^p - tolerance: Option>, + pub tolerance: Option>, #[arg(long)] /// Method for solving inner optimisation problems - inner_method: Option, + pub inner_method: Option, #[arg(long)] /// Step length parameter for inner problem - inner_τ0: Option, + pub inner_τ0: Option, #[arg(long, value_names = &["τ0", "σ0"])] /// Dual step length parameter for inner problem - inner_pdps_τσ0: Option>, + pub inner_pdps_τσ0: Option>, #[arg(long, value_names = &["τ", "growth"])] /// Inner proximal point method step length and its growth - inner_pp_τ: Option>, + pub inner_pp_τ: Option>, #[arg(long)] /// Inner tolerance multiplier - inner_tol: Option, + pub inner_tol: Option, } /// A generic entry point for binaries based on this library pub fn common_main() -> DynResult<()> { - let full_cli = FusedCommandLineArgs::::parse(); - let cli = &full_cli.general; + let cli = FusedCommandLineArgs::::parse(); #[cfg(debug_assertions)] { @@ -267,32 +281,16 @@ ); } - if let Some(n_threads) = cli.num_threads { + if let Some(n_threads) = cli.general.num_threads { let n = NonZeroUsize::new(n_threads).expect("Invalid thread count"); set_num_threads(n); } else { - let m = NonZeroUsize::new(cli.max_threads).expect("Invalid maximum thread count"); + let m = NonZeroUsize::new(cli.general.max_threads).expect("Invalid maximum thread count"); set_max_threads(m); } - for experiment in full_cli.experiment_setup.runnables()? { - let mut algs: Vec>> = cli - .algorithm - .iter() - .map(|alg| { - let cfg = alg - .default_config() - .cli_override(&experiment.algorithm_overrides(*alg)) - .cli_override(&full_cli.algorithm_overrides); - alg.to_named(cfg) - }) - .collect(); - for filename in cli.saved_algorithm.iter() { - let f = std::fs::File::open(filename)?; - let alg = serde_json::from_reader(f)?; - algs.push(alg); - } - experiment.runall(&cli, (!algs.is_empty()).then_some(algs))?; + for experiment in cli.experiment_setup.runnables()? { + experiment.runall(&cli.general, &cli.algorithm_overrides)?; } Ok(())