use crate::matrix::FdMatrix;
#[must_use = "expensive computation whose result should not be discarded"]
pub fn rpd_depth_1d(
data_obj: &FdMatrix,
data_ori: &FdMatrix,
argvals: &[f64],
nproj: usize,
nderiv: usize,
) -> Vec<f64> {
rpd_depth_1d_seeded(data_obj, data_ori, argvals, nproj, nderiv, None)
}
#[must_use = "expensive computation whose result should not be discarded"]
pub fn rpd_depth_1d_seeded(
data_obj: &FdMatrix,
data_ori: &FdMatrix,
argvals: &[f64],
nproj: usize,
nderiv: usize,
seed: Option<u64>,
) -> Vec<f64> {
let m = data_obj.ncols();
if data_obj.nrows() == 0 || data_ori.nrows() == 0 || m == 0 || nproj == 0 {
return Vec::new();
}
if m <= nderiv {
return vec![0.0; data_obj.nrows()];
}
if nderiv == 0 {
return super::random_depth_core(
data_obj,
data_ori,
nproj,
seed,
0.0,
|acc, d| acc + d,
|acc, n| acc / n as f64,
);
}
let aug_dim: usize = (0..=nderiv).map(|k| m - k).sum();
let aug_obj = build_augmented(data_obj, argvals, nderiv, aug_dim);
let aug_ori = build_augmented(data_ori, argvals, nderiv, aug_dim);
super::random_depth_core(
&aug_obj,
&aug_ori,
nproj,
seed,
0.0,
|acc, d| acc + d,
|acc, n| acc / n as f64,
)
}
fn build_augmented(data: &FdMatrix, argvals: &[f64], nderiv: usize, aug_dim: usize) -> FdMatrix {
let n = data.nrows();
let m = data.ncols();
let mut aug_data = vec![0.0; n * aug_dim];
for j in 0..m {
for i in 0..n {
aug_data[i + j * n] = data[(i, j)];
}
}
let mut prev_len = m;
let mut prev_deriv: Vec<f64> = (0..n * m)
.map(|idx| {
let i = idx % n;
let j = idx / n;
data[(i, j)]
})
.collect();
let mut col_offset = m;
for k in 1..=nderiv {
let new_len = m - k;
let mut new_deriv = vec![0.0; n * new_len];
for j in 0..new_len {
let dt = argvals[j + k] - argvals[j + k - 1];
let inv_dt = if dt.abs() < 1e-30 { 0.0 } else { 1.0 / dt };
for i in 0..n {
let val = (prev_deriv[i + (j + 1) * n] - prev_deriv[i + j * n]) * inv_dt;
new_deriv[i + j * n] = val;
aug_data[i + (col_offset + j) * n] = val;
}
}
col_offset += new_len;
prev_deriv = new_deriv;
prev_len = new_len;
}
let _ = prev_len;
FdMatrix::from_column_major(aug_data, n, aug_dim).unwrap()
}