pub fn normalize(v: &mut [f32], mean: f32, std: f32) {
for x in v.iter_mut() {
*x = (*x - mean) / std;
}
}
pub fn pearson_correlation(x: &[f32], y: &[f32]) -> f32 {
let n = x.len() as f32;
let sum_x: f32 = x.iter().sum();
let sum_y: f32 = y.iter().sum();
let sum_xy: f32 = x.iter().zip(y.iter()).map(|(a, b)| a * b).sum();
let sum_x2: f32 = x.iter().map(|a| a * a).sum();
let sum_y2: f32 = y.iter().map(|a| a * a).sum();
let numerator = n * sum_xy - sum_x * sum_y;
let denominator = ((n * sum_x2 - sum_x * sum_x) * (n * sum_y2 - sum_y * sum_y)).sqrt();
if denominator == 0.0 {
0.0
} else {
numerator / denominator
}
}
pub fn mse(predicted: &[f32], target: &[f32]) -> f32 {
let n = predicted.len() as f32;
predicted.iter()
.zip(target.iter())
.map(|(p, t)| (p - t).powi(2))
.sum::<f32>()
/ n
}
pub fn concordance_correlation_coefficient(predicted: &[f32], target: &[f32]) -> f32 {
let n = predicted.len() as f32;
let mean_p: f32 = predicted.iter().sum::<f32>() / n;
let mean_t: f32 = target.iter().sum::<f32>() / n;
let var_p: f32 = predicted.iter()
.map(|p| (p - mean_p).powi(2))
.sum::<f32>() / n;
let var_t: f32 = target.iter()
.map(|t| (t - mean_t).powi(2))
.sum::<f32>() / n;
let cov: f32 = predicted.iter()
.zip(target.iter())
.map(|(p, t)| (p - mean_p) * (t - mean_t))
.sum::<f32>() / n;
let numerator = 2.0 * cov;
let denominator = var_p + var_t + (mean_p - mean_t).powi(2);
if denominator == 0.0 {
0.0
} else {
numerator / denominator
}
}