use eunomia::FloatElement;
use crate::application::array::Array;
use crate::application::statistics::covariance::covariance;
use crate::domain::error::Result;
use crate::domain::layout::Layout;
use crate::infrastructure::storage::{Storage, VecStorage};
pub fn pearson_correlation<T, S>(arr: &Array<T, S, 2>) -> Result<Array<T, VecStorage<T>, 2>>
where
T: FloatElement,
S: Storage<T>,
{
let cov = covariance(arr, T::ZERO)?;
let v = cov.shape()[0];
let cov_view = cov.view();
let cov_data = cov_view.data();
let mut std = vec![T::ZERO; v];
for (i, s) in std.iter_mut().enumerate() {
*s = cov_data[i * v + i].sqrt();
}
let mut out = vec![T::ZERO; v * v];
for i in 0..v {
for j in 0..v {
out[i * v + j] = cov_data[i * v + j] / (std[i] * std[j]);
}
}
Array::new(Layout::c_contiguous([v, v])?, VecStorage::new(out))
}