1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub enum RidgeDeterminantMode {
10 Full,
12 PositivePartApproximation,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
23pub enum RidgePolicy {
24 ExactFullObjective,
27 PositivePartApproximateObjective,
30 SolverOnly,
33}
34
35impl RidgePolicy {
36 pub const fn exact_full_objective() -> Self {
37 Self::ExactFullObjective
38 }
39
40 pub const fn positive_part_approximate_objective() -> Self {
41 Self::PositivePartApproximateObjective
42 }
43
44 pub const fn solver_only() -> Self {
45 Self::SolverOnly
46 }
47
48 #[inline]
49 pub const fn accounts_for_objective(self) -> bool {
50 !matches!(self, Self::SolverOnly)
51 }
52
53 #[inline]
54 pub const fn determinant_mode(self) -> RidgeDeterminantMode {
55 match self {
56 Self::ExactFullObjective | Self::SolverOnly => RidgeDeterminantMode::Full,
57 Self::PositivePartApproximateObjective => {
58 RidgeDeterminantMode::PositivePartApproximation
59 }
60 }
61 }
62
63 #[inline]
64 pub const fn is_approximation(self) -> bool {
65 matches!(self, Self::PositivePartApproximateObjective)
66 }
67}
68
69#[cfg(test)]
70mod ridge_policy_tests {
71 use super::*;
72
73 #[test]
74 fn exact_policy_is_homogeneous_and_full() {
75 let policy = RidgePolicy::exact_full_objective();
76 assert!(policy.accounts_for_objective());
77 assert_eq!(policy.determinant_mode(), RidgeDeterminantMode::Full);
78 assert!(!policy.is_approximation());
79 }
80
81 #[test]
82 fn positive_part_policy_is_explicitly_approximate() {
83 let policy = RidgePolicy::positive_part_approximate_objective();
84 assert!(policy.accounts_for_objective());
85 assert_eq!(
86 policy.determinant_mode(),
87 RidgeDeterminantMode::PositivePartApproximation
88 );
89 assert!(policy.is_approximation());
90 }
91
92 #[test]
93 fn solver_only_policy_cannot_enter_objective_accounting() {
94 let policy = RidgePolicy::solver_only();
95 assert!(!policy.accounts_for_objective());
96 assert_eq!(policy.determinant_mode(), RidgeDeterminantMode::Full);
97 }
98}