mod distance;
mod icc;
mod kendall;
mod partial;
mod pearson;
mod spearman;
pub use distance::{distance_cor, distance_cor_test, DistanceCorResult};
pub use icc::{icc, ICCResult, ICCType};
pub use kendall::{kendall, KendallVariant};
pub use partial::{partial_cor, semi_partial_cor, PartialCorResult};
pub use pearson::pearson;
pub use spearman::spearman;
use crate::error::{Result, StatError};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CorrelationMethod {
Pearson,
Spearman,
Kendall,
}
impl std::fmt::Display for CorrelationMethod {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CorrelationMethod::Pearson => write!(f, "Pearson"),
CorrelationMethod::Spearman => write!(f, "Spearman"),
CorrelationMethod::Kendall => write!(f, "Kendall"),
}
}
}
#[derive(Debug, Clone)]
pub struct CorrelationConfInt {
pub lower: f64,
pub upper: f64,
pub conf_level: f64,
}
#[derive(Debug, Clone)]
pub struct CorrelationResult {
pub estimate: f64,
pub statistic: f64,
pub df: Option<f64>,
pub p_value: f64,
pub conf_int: Option<CorrelationConfInt>,
pub method: CorrelationMethod,
pub n: usize,
}
pub(crate) fn validate_correlation_input(x: &[f64], y: &[f64]) -> Result<usize> {
if x.is_empty() || y.is_empty() {
return Err(StatError::EmptyData);
}
if x.len() != y.len() {
return Err(StatError::InvalidParameter(format!(
"x and y must have the same length: {} vs {}",
x.len(),
y.len()
)));
}
let n = x.len();
if n < 3 {
return Err(StatError::InsufficientData { needed: 3, got: n });
}
for (i, (&xi, &yi)) in x.iter().zip(y.iter()).enumerate() {
if !xi.is_finite() || !yi.is_finite() {
return Err(StatError::InvalidParameter(format!(
"non-finite value at index {}: x={}, y={}",
i, xi, yi
)));
}
}
Ok(n)
}
pub(crate) fn mean(data: &[f64]) -> f64 {
data.iter().sum::<f64>() / data.len() as f64
}
pub(crate) fn variance(data: &[f64], mean: f64) -> f64 {
let n = data.len() as f64;
data.iter().map(|&x| (x - mean).powi(2)).sum::<f64>() / (n - 1.0)
}
pub(crate) fn std_dev(data: &[f64], mean: f64) -> f64 {
variance(data, mean).sqrt()
}