use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum RidgeDeterminantMode {
Full,
PositivePartApproximation,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum RidgePolicy {
ExactFullObjective,
PositivePartApproximateObjective,
SolverOnly,
}
impl RidgePolicy {
pub const fn exact_full_objective() -> Self {
Self::ExactFullObjective
}
pub const fn positive_part_approximate_objective() -> Self {
Self::PositivePartApproximateObjective
}
pub const fn solver_only() -> Self {
Self::SolverOnly
}
#[inline]
pub const fn accounts_for_objective(self) -> bool {
!matches!(self, Self::SolverOnly)
}
#[inline]
pub const fn determinant_mode(self) -> RidgeDeterminantMode {
match self {
Self::ExactFullObjective | Self::SolverOnly => RidgeDeterminantMode::Full,
Self::PositivePartApproximateObjective => {
RidgeDeterminantMode::PositivePartApproximation
}
}
}
#[inline]
pub const fn is_approximation(self) -> bool {
matches!(self, Self::PositivePartApproximateObjective)
}
}
#[cfg(test)]
mod ridge_policy_tests {
use super::*;
#[test]
fn exact_policy_is_homogeneous_and_full() {
let policy = RidgePolicy::exact_full_objective();
assert!(policy.accounts_for_objective());
assert_eq!(policy.determinant_mode(), RidgeDeterminantMode::Full);
assert!(!policy.is_approximation());
}
#[test]
fn positive_part_policy_is_explicitly_approximate() {
let policy = RidgePolicy::positive_part_approximate_objective();
assert!(policy.accounts_for_objective());
assert_eq!(
policy.determinant_mode(),
RidgeDeterminantMode::PositivePartApproximation
);
assert!(policy.is_approximation());
}
#[test]
fn solver_only_policy_cannot_enter_objective_accounting() {
let policy = RidgePolicy::solver_only();
assert!(!policy.accounts_for_objective());
assert_eq!(policy.determinant_mode(), RidgeDeterminantMode::Full);
}
}