use ::ndarray::{Array, ArrayView, Ix1, Ix2};
use num_traits::{Float, FromPrimitive};
#[allow(dead_code)]
pub fn corrcoef<T>(x: ArrayView<T, Ix1>, y: ArrayView<T, Ix1>) -> Result<T, &'static str>
where
T: Clone + Float + FromPrimitive,
{
if x.is_empty() || y.is_empty() {
return Err("Cannot compute correlation of empty arrays");
}
if x.len() != y.len() {
return Err("Arrays must have the same length");
}
let n = T::from_usize(x.len()).expect("Operation failed");
let mut sum_x = T::zero();
let mut sum_y = T::zero();
for (&x_val, &y_val) in x.iter().zip(y.iter()) {
sum_x = sum_x + x_val;
sum_y = sum_y + y_val;
}
let mean_x = sum_x / n;
let mean_y = sum_y / n;
let mut cov_xy = T::zero();
let mut var_x = T::zero();
let mut var_y = T::zero();
for (&x_val, &y_val) in x.iter().zip(y.iter()) {
let dx = x_val - mean_x;
let dy = y_val - mean_y;
cov_xy = cov_xy + dx * dy;
var_x = var_x + dx * dx;
var_y = var_y + dy * dy;
}
if var_x.is_zero() || var_y.is_zero() {
return Err("Correlation coefficient is not defined when either array has zero variance");
}
Ok(cov_xy / (var_x * var_y).sqrt())
}
#[allow(dead_code)]
pub fn cov<T>(array: ArrayView<T, Ix2>, ddof: usize) -> Result<Array<T, Ix2>, &'static str>
where
T: Clone + Float + FromPrimitive,
{
if array.is_empty() {
return Err("Cannot compute covariance of an empty array");
}
let (n_samples, n_features) = (array.shape()[0], array.shape()[1]);
if n_samples <= ddof {
return Err("Not enough data points for covariance calculation with given ddof");
}
let mut feature_means = Array::<T, Ix1>::zeros(n_features);
for j in 0..n_features {
let mut sum = T::zero();
for i in 0..n_samples {
sum = sum + array[[i, j]];
}
feature_means[j] = sum / T::from_usize(n_samples).expect("Operation failed");
}
let mut covmatrix = Array::<T, Ix2>::zeros((n_features, n_features));
let scale = T::from_usize(n_samples - ddof).expect("Operation failed");
for i in 0..n_features {
for j in 0..=i {
let mut cov_ij = T::zero();
for k in 0..n_samples {
let dev_i = array[[k, i]] - feature_means[i];
let dev_j = array[[k, j]] - feature_means[j];
cov_ij = cov_ij + dev_i * dev_j;
}
cov_ij = cov_ij / scale;
covmatrix[[0, j]] = cov_ij;
if 0 != j {
covmatrix[[j, 0]] = cov_ij;
}
}
}
Ok(covmatrix)
}