#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum PreconditionerType {
Jacobi,
SSOR,
ILU0,
IC0,
AMG,
SPAI,
Polynomial,
None,
}
impl std::fmt::Display for PreconditionerType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Jacobi => write!(f, "Jacobi"),
Self::SSOR => write!(f, "SSOR"),
Self::ILU0 => write!(f, "ILU(0)"),
Self::IC0 => write!(f, "IC(0)"),
Self::AMG => write!(f, "AMG"),
Self::SPAI => write!(f, "SPAI"),
Self::Polynomial => write!(f, "Polynomial"),
Self::None => write!(f, "None"),
#[allow(unreachable_patterns)]
_ => write!(f, "Unknown"),
}
}
}
#[derive(Debug, Clone)]
pub struct MatrixFeatures {
pub n: usize,
pub nnz: usize,
pub density: f64,
pub max_row_nnz: usize,
pub mean_row_nnz: f64,
pub bandwidth: usize,
pub bandwidth_ratio: f64,
pub cond_estimate: f64,
pub spectral_radius: f64,
pub diag_dominance: f64,
pub symmetry_measure: f64,
pub has_positive_diagonal: bool,
}
#[derive(Debug, Clone)]
pub struct SelectionConfig {
pub use_cost_model: bool,
pub max_features: usize,
}
impl Default for SelectionConfig {
fn default() -> Self {
Self {
use_cost_model: true,
max_features: 12,
}
}
}
#[derive(Debug, Clone)]
pub struct SelectionResult {
pub recommended: PreconditionerType,
pub confidence: f64,
pub all_scores: Vec<(PreconditionerType, f64)>,
pub features: MatrixFeatures,
}
#[derive(Debug, Clone)]
pub struct CostEstimate {
pub setup_cost: f64,
pub per_iteration_cost: f64,
pub estimated_iterations: usize,
pub total_cost: f64,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_preconditioner_type_display() {
assert_eq!(format!("{}", PreconditionerType::Jacobi), "Jacobi");
assert_eq!(format!("{}", PreconditionerType::ILU0), "ILU(0)");
assert_eq!(format!("{}", PreconditionerType::None), "None");
}
#[test]
fn test_selection_config_default() {
let cfg = SelectionConfig::default();
assert!(cfg.use_cost_model);
assert_eq!(cfg.max_features, 12);
}
#[test]
fn test_preconditioner_type_eq() {
assert_eq!(PreconditionerType::AMG, PreconditionerType::AMG);
assert_ne!(PreconditionerType::Jacobi, PreconditionerType::SSOR);
}
}