use std::error::Error;
use ndarray::Array1;
use crate::traits::BivariateExt;
pub fn couple_marginals<C: BivariateExt>(
s1: &Array1<f64>,
s2: &Array1<f64>,
copula: &mut C,
) -> Result<ndarray::Array2<f64>, Box<dyn Error>> {
let n = s1.len();
assert_eq!(n, s2.len(), "marginals must have equal length");
assert!(n >= 2, "need at least two observations");
let cop_sample = copula.sample(n)?;
let mut out = ndarray::Array2::<f64>::zeros((n, 2));
let mut sorted1 = s1.to_vec();
sorted1.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let mut sorted2 = s2.to_vec();
sorted2.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
for i in 0..n {
let u = cop_sample[[i, 0]].clamp(f64::EPSILON, 1.0 - f64::EPSILON);
let v = cop_sample[[i, 1]].clamp(f64::EPSILON, 1.0 - f64::EPSILON);
let idx_u = ((u * n as f64) as usize).min(n - 1);
let idx_v = ((v * n as f64) as usize).min(n - 1);
out[[i, 0]] = sorted1[idx_u];
out[[i, 1]] = sorted2[idx_v];
}
Ok(out)
}