Skip to main content

oximo_clarabel/
options.rs

1use oximo_solver::{HasUniversal, UniversalOptions};
2
3// TODO: Enable Pardiso backends
4
5/// Direct linear (KKT) solver method for Clarabel.
6///
7/// Selects the sparse LDL factorization backend. The built-in `qdldl` and the
8/// `auto` default are always present.
9#[cfg_attr(
10    feature = "faer",
11    doc = "The [`Faer`](Self::Faer) backend requires this crate's `faer` feature."
12)]
13#[cfg_attr(
14    not(feature = "faer"),
15    doc = "A `Faer` backend is also available behind this crate's `faer` feature."
16)]
17#[derive(Clone, Copy, Debug, Eq, PartialEq)]
18pub enum ClarabelDirectSolve {
19    /// Let Clarabel choose (`"auto"`). Clarabel default.
20    Auto,
21    /// Built-in QDLDL factorization (`"qdldl"`).
22    Qdldl,
23    /// faer sparse LDL factorization (`"faer"`). Requires the `faer` feature.
24    #[cfg(feature = "faer")]
25    #[cfg_attr(docsrs, doc(cfg(feature = "faer")))]
26    Faer,
27}
28
29/// Declare every scalar [`ClarabelOptions`] option once. Its `Option<T>` field
30/// and its `#[must_use]` builder are generated from the same entry, keeping the
31/// field name identical to the matching `clarabel::solver::CoreSettings` field.
32macro_rules! clarabel_options {
33    ($($(#[$meta:meta])* $name:ident : $ty:ty),* $(,)?) => {
34        /// Clarabel-specific solver options.
35        ///
36        /// A typed mirror of the tunable, non-feature-gated fields of
37        /// `clarabel::solver::CoreSettings`. Every field is `Option`, `None`
38        /// leaves Clarabel's own default in place, so the defaults quoted below
39        /// are informational.
40        ///
41        /// The universal `threads` option maps to Clarabel's `max_threads`,
42        /// which only affects multithreaded KKT solvers. The default `qdldl`
43        /// solver is single-threaded.
44        #[derive(Clone, Debug, Default)]
45        pub struct ClarabelOptions {
46            /// Options shared by every backend.
47            pub universal: UniversalOptions,
48            /// Direct linear (KKT) solver method. Clarabel default `Auto`.
49            pub direct_solve_method: Option<ClarabelDirectSolve>,
50            $(
51                $(#[$meta])*
52                pub $name: Option<$ty>,
53            )*
54        }
55
56        impl ClarabelOptions {
57            /// Select the direct linear (KKT) solver method.
58            #[must_use]
59            pub fn direct_solve_method(mut self, m: ClarabelDirectSolve) -> Self {
60                self.direct_solve_method = Some(m);
61                self
62            }
63
64            $(
65                $(#[$meta])*
66                #[must_use]
67                pub fn $name(mut self, v: $ty) -> Self {
68                    self.$name = Some(v);
69                    self
70                }
71            )*
72        }
73    };
74}
75
76clarabel_options! {
77    /// Interior-point iteration limit. Clarabel default `200`.
78    max_iter: u32,
79    /// Maximum interior-point step length. Clarabel default `0.99`.
80    max_step_fraction: f64,
81    /// Absolute duality-gap tolerance. Clarabel default `1e-8`.
82    tol_gap_abs: f64,
83    /// Relative duality-gap tolerance. Clarabel default `1e-8`.
84    tol_gap_rel: f64,
85    /// Primal/dual feasibility tolerance. Clarabel default `1e-8`.
86    tol_feas: f64,
87    /// Absolute infeasibility tolerance. Clarabel default `1e-8`.
88    tol_infeas_abs: f64,
89    /// Relative infeasibility tolerance. Clarabel default `1e-8`.
90    tol_infeas_rel: f64,
91    /// κ/τ tolerance. Clarabel default `1e-6`.
92    tol_ktratio: f64,
93    /// Reduced (low-accuracy fallback) absolute duality-gap tolerance.
94    /// Clarabel default `5e-5`.
95    reduced_tol_gap_abs: f64,
96    /// Reduced relative duality-gap tolerance. Clarabel default `5e-5`.
97    reduced_tol_gap_rel: f64,
98    /// Reduced feasibility tolerance. Clarabel default `1e-4`.
99    reduced_tol_feas: f64,
100    /// Reduced absolute infeasibility tolerance. Clarabel default `5e-12`.
101    reduced_tol_infeas_abs: f64,
102    /// Reduced relative infeasibility tolerance. Clarabel default `5e-5`.
103    reduced_tol_infeas_rel: f64,
104    /// Reduced κ/τ tolerance. Clarabel default `1e-4`.
105    reduced_tol_ktratio: f64,
106    /// Enable data-equilibration pre-scaling. Clarabel default `true`.
107    equilibrate_enable: bool,
108    /// Maximum equilibration scaling iterations. Clarabel default `10`.
109    equilibrate_max_iter: u32,
110    /// Minimum equilibration scaling allowed. Clarabel default `1e-4`.
111    equilibrate_min_scaling: f64,
112    /// Maximum equilibration scaling allowed. Clarabel default `1e4`.
113    equilibrate_max_scaling: f64,
114    /// Line-search backtracking factor. Clarabel default `0.8`.
115    linesearch_backtrack_step: f64,
116    /// Minimum step for asymmetric cones with PrimalDual scaling.
117    /// Clarabel default `1e-1`.
118    min_switch_step_length: f64,
119    /// Minimum step for symmetric cones / asymmetric cones with Dual scaling.
120    /// Clarabel default `1e-4`.
121    min_terminate_step_length: f64,
122    /// Enable KKT static regularization. Clarabel default `true`.
123    static_regularization_enable: bool,
124    /// KKT static regularization constant. Clarabel default `1e-8`.
125    static_regularization_constant: f64,
126    /// Static regularization proportional to the max abs diagonal term.
127    /// Clarabel default `f64::EPSILON.powi(2)`.
128    static_regularization_proportional: f64,
129    /// Enable KKT dynamic regularization. Clarabel default `true`.
130    dynamic_regularization_enable: bool,
131    /// KKT dynamic regularization threshold. Clarabel default `1e-13`.
132    dynamic_regularization_eps: f64,
133    /// KKT dynamic regularization shift. Clarabel default `2e-7`.
134    dynamic_regularization_delta: f64,
135    /// KKT direct solve with iterative refinement. Clarabel default `true`.
136    iterative_refinement_enable: bool,
137    /// Iterative-refinement relative tolerance. Clarabel default `1e-13`.
138    iterative_refinement_reltol: f64,
139    /// Iterative-refinement absolute tolerance. Clarabel default `1e-12`.
140    iterative_refinement_abstol: f64,
141    /// Iterative-refinement maximum iterations. Clarabel default `10`.
142    iterative_refinement_max_iter: u32,
143    /// Iterative-refinement stalling tolerance. Clarabel default `5.0`.
144    iterative_refinement_stop_ratio: f64,
145    /// Enable presolve constraint reduction. Clarabel default `true`.
146    presolve_enable: bool,
147    /// Drop structural zeros from sparse inputs (disables parametric updating).
148    /// Clarabel default `false`.
149    input_sparse_dropzeros: bool,
150}
151
152impl HasUniversal for ClarabelOptions {
153    fn universal(&self) -> &UniversalOptions {
154        &self.universal
155    }
156
157    fn universal_mut(&mut self) -> &mut UniversalOptions {
158        &mut self.universal
159    }
160}