1#[derive(Debug, Clone, PartialEq)]
3pub struct ScalingOptions {
4 pub enable: bool,
5 pub min_scale: f64,
6 pub max_scale: f64,
7}
8
9impl Default for ScalingOptions {
10 fn default() -> Self {
11 Self {
12 enable: true,
13 min_scale: 1e-4,
14 max_scale: 1e4,
15 }
16 }
17}
18
19#[derive(Debug, Clone, PartialEq)]
21pub struct ClarabelOptions {
22 pub equilibrate_enable: bool,
23 pub equilibrate_max_iter: u32,
24 pub presolve_enable: bool,
25 pub direct_solve_method: Option<String>,
26 pub tol_ktratio: f64,
27 pub reduced_tol_gap_abs: f64,
28 pub reduced_tol_gap_rel: f64,
29 pub reduced_tol_feas: f64,
30 pub reduced_tol_infeas_abs: f64,
31 pub reduced_tol_infeas_rel: f64,
32 pub reduced_tol_ktratio: f64,
33 pub static_regularization_enable: bool,
34 pub static_regularization_constant: f64,
35 pub dynamic_regularization_enable: bool,
36 pub dynamic_regularization_eps: f64,
37 pub dynamic_regularization_delta: f64,
38 pub iterative_refinement_enable: bool,
39 pub iterative_refinement_reltol: f64,
40 pub iterative_refinement_abstol: f64,
41 pub iterative_refinement_max_iter: u32,
42}
43
44impl Default for ClarabelOptions {
45 fn default() -> Self {
46 Self {
47 equilibrate_enable: true,
48 equilibrate_max_iter: 10,
49 presolve_enable: true,
50 direct_solve_method: None,
51 tol_ktratio: 1e-6,
52 reduced_tol_gap_abs: 5e-5,
53 reduced_tol_gap_rel: 5e-5,
54 reduced_tol_feas: 1e-4,
55 reduced_tol_infeas_abs: 5e-12,
56 reduced_tol_infeas_rel: 5e-5,
57 reduced_tol_ktratio: 1e-4,
58 static_regularization_enable: true,
59 static_regularization_constant: 1e-8,
60 dynamic_regularization_enable: true,
61 dynamic_regularization_eps: 1e-13,
62 dynamic_regularization_delta: 2e-7,
63 iterative_refinement_enable: true,
64 iterative_refinement_reltol: 1e-13,
65 iterative_refinement_abstol: 1e-12,
66 iterative_refinement_max_iter: 10,
67 }
68 }
69}
70
71#[derive(Debug, Clone, PartialEq)]
73pub struct SolveOptions {
74 pub tolerance: f64,
75 pub max_iterations: usize,
76 pub verbose: bool,
77 pub scaling: ScalingOptions,
78 pub clarabel: ClarabelOptions,
79 pub retry_on_numerical_failure: bool,
80}
81
82impl Default for SolveOptions {
83 fn default() -> Self {
84 Self {
85 tolerance: 1e-8,
86 max_iterations: 10_000,
87 verbose: false,
88 scaling: ScalingOptions::default(),
89 clarabel: ClarabelOptions::default(),
90 retry_on_numerical_failure: true,
91 }
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn defaults() {
101 let opts = SolveOptions::default();
102 assert!((opts.tolerance - 1e-8).abs() < f64::EPSILON);
103 assert_eq!(opts.max_iterations, 10_000);
104 assert!(!opts.verbose);
105 assert!(opts.scaling.enable);
106 assert!(opts.clarabel.equilibrate_enable);
107 assert!(opts.retry_on_numerical_failure);
108 }
109
110 #[test]
111 fn custom() {
112 let opts = SolveOptions {
113 tolerance: 1e-4,
114 max_iterations: 500,
115 verbose: true,
116 scaling: ScalingOptions {
117 enable: false,
118 min_scale: 1e-3,
119 max_scale: 1e3,
120 },
121 clarabel: ClarabelOptions {
122 presolve_enable: false,
123 direct_solve_method: Some("qdldl".to_string()),
124 ..ClarabelOptions::default()
125 },
126 retry_on_numerical_failure: false,
127 };
128
129 assert!((opts.tolerance - 1e-4).abs() < f64::EPSILON);
130 assert_eq!(opts.max_iterations, 500);
131 assert!(opts.verbose);
132 assert!(!opts.scaling.enable);
133 assert_eq!(opts.clarabel.direct_solve_method.as_deref(), Some("qdldl"));
134 assert!(!opts.retry_on_numerical_failure);
135 }
136
137 #[test]
138 fn clone_and_eq() {
139 let a = SolveOptions::default();
140 assert_eq!(a, a.clone());
141 }
142}