#[derive(Debug, Clone, PartialEq)]
pub struct ScalingOptions {
pub enable: bool,
pub min_scale: f64,
pub max_scale: f64,
}
impl Default for ScalingOptions {
fn default() -> Self {
Self {
enable: true,
min_scale: 1e-4,
max_scale: 1e4,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ClarabelOptions {
pub equilibrate_enable: bool,
pub equilibrate_max_iter: u32,
pub presolve_enable: bool,
pub direct_solve_method: Option<String>,
pub tol_ktratio: f64,
pub reduced_tol_gap_abs: f64,
pub reduced_tol_gap_rel: f64,
pub reduced_tol_feas: f64,
pub reduced_tol_infeas_abs: f64,
pub reduced_tol_infeas_rel: f64,
pub reduced_tol_ktratio: f64,
pub static_regularization_enable: bool,
pub static_regularization_constant: f64,
pub dynamic_regularization_enable: bool,
pub dynamic_regularization_eps: f64,
pub dynamic_regularization_delta: f64,
pub iterative_refinement_enable: bool,
pub iterative_refinement_reltol: f64,
pub iterative_refinement_abstol: f64,
pub iterative_refinement_max_iter: u32,
}
impl Default for ClarabelOptions {
fn default() -> Self {
Self {
equilibrate_enable: true,
equilibrate_max_iter: 10,
presolve_enable: true,
direct_solve_method: None,
tol_ktratio: 1e-6,
reduced_tol_gap_abs: 5e-5,
reduced_tol_gap_rel: 5e-5,
reduced_tol_feas: 1e-4,
reduced_tol_infeas_abs: 5e-12,
reduced_tol_infeas_rel: 5e-5,
reduced_tol_ktratio: 1e-4,
static_regularization_enable: true,
static_regularization_constant: 1e-8,
dynamic_regularization_enable: true,
dynamic_regularization_eps: 1e-13,
dynamic_regularization_delta: 2e-7,
iterative_refinement_enable: true,
iterative_refinement_reltol: 1e-13,
iterative_refinement_abstol: 1e-12,
iterative_refinement_max_iter: 10,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct SolveOptions {
pub tolerance: f64,
pub max_iterations: usize,
pub verbose: bool,
pub scaling: ScalingOptions,
pub clarabel: ClarabelOptions,
pub retry_on_numerical_failure: bool,
}
impl Default for SolveOptions {
fn default() -> Self {
Self {
tolerance: 1e-8,
max_iterations: 10_000,
verbose: false,
scaling: ScalingOptions::default(),
clarabel: ClarabelOptions::default(),
retry_on_numerical_failure: true,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defaults() {
let opts = SolveOptions::default();
assert!((opts.tolerance - 1e-8).abs() < f64::EPSILON);
assert_eq!(opts.max_iterations, 10_000);
assert!(!opts.verbose);
assert!(opts.scaling.enable);
assert!(opts.clarabel.equilibrate_enable);
assert!(opts.retry_on_numerical_failure);
}
#[test]
fn custom() {
let opts = SolveOptions {
tolerance: 1e-4,
max_iterations: 500,
verbose: true,
scaling: ScalingOptions {
enable: false,
min_scale: 1e-3,
max_scale: 1e3,
},
clarabel: ClarabelOptions {
presolve_enable: false,
direct_solve_method: Some("qdldl".to_string()),
..ClarabelOptions::default()
},
retry_on_numerical_failure: false,
};
assert!((opts.tolerance - 1e-4).abs() < f64::EPSILON);
assert_eq!(opts.max_iterations, 500);
assert!(opts.verbose);
assert!(!opts.scaling.enable);
assert_eq!(opts.clarabel.direct_solve_method.as_deref(), Some("qdldl"));
assert!(!opts.retry_on_numerical_failure);
}
#[test]
fn clone_and_eq() {
let a = SolveOptions::default();
assert_eq!(a, a.clone());
}
}