use ndarray::Array1;
use ndarray::Array2;
#[derive(Clone, Debug)]
pub struct EmpiricalCopula2D {
pub rank_data: Array2<f64>,
}
impl EmpiricalCopula2D {
pub fn new_from_two_series(x: &Array1<f64>, y: &Array1<f64>) -> Self {
assert_eq!(x.len(), y.len(), "x and y must have the same length!");
let n = x.len();
let mut xv: Vec<(f64, usize)> = x.iter().enumerate().map(|(i, &val)| (val, i)).collect();
let mut yv: Vec<(f64, usize)> = y.iter().enumerate().map(|(i, &val)| (val, i)).collect();
xv.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(std::cmp::Ordering::Equal));
yv.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(std::cmp::Ordering::Equal));
let mut rank_x = vec![0.0; n];
let mut rank_y = vec![0.0; n];
for (rank, &(_val, orig_i)) in xv.iter().enumerate() {
rank_x[orig_i] = rank as f64; }
for (rank, &(_val, orig_i)) in yv.iter().enumerate() {
rank_y[orig_i] = rank as f64;
}
for i in 0..n {
rank_x[i] /= n as f64;
rank_y[i] /= n as f64;
}
let mut rank_data = Array2::<f64>::zeros((n, 2));
for i in 0..n {
rank_data[[i, 0]] = rank_x[i];
rank_data[[i, 1]] = rank_y[i];
}
EmpiricalCopula2D { rank_data }
}
pub fn sample(&self, _n: usize) -> Array2<f64> {
self.rank_data.clone()
}
}