use molrs::error::MolRsError;
use super::matrix::BoundsMatrix;
pub fn smooth_bounds_tol(bounds: &mut BoundsMatrix, tol: f64) -> Result<(), MolRsError> {
let npt = bounds.len();
for k in 0..npt {
for i in 0..npt.saturating_sub(1) {
if i == k {
continue;
}
let (ii, ik) = if i > k { (k, i) } else { (i, k) };
let u_ik = bounds.raw(ii, ik); let l_ik = bounds.raw(ik, ii); for j in (i + 1)..npt {
if j == k {
continue;
}
let (jj, jk) = if j > k { (k, j) } else { (j, k) };
let u_kj = bounds.raw(jj, jk); let sum_u = u_ik + u_kj;
if bounds.raw(i, j) > sum_u {
bounds.set_raw(i, j, sum_u);
}
let diff_lik_ukj = l_ik - u_kj;
let diff_ljk_uik = bounds.raw(jk, jj) - u_ik; if bounds.raw(j, i) < diff_lik_ukj {
bounds.set_raw(j, i, diff_lik_ukj);
} else if bounds.raw(j, i) < diff_ljk_uik {
bounds.set_raw(j, i, diff_ljk_uik);
}
let l_bound = bounds.raw(j, i); let u_bound = bounds.raw(i, j); if tol > 0.0
&& (l_bound - u_bound) / l_bound > 0.0
&& (l_bound - u_bound) / l_bound < tol
{
bounds.set_raw(i, j, l_bound);
} else if l_bound - u_bound > 0.0 {
return Err(MolRsError::validation(
"distance-geometry bounds are inconsistent (lower > upper) during triangle smoothing",
));
}
}
}
}
Ok(())
}
pub fn smooth_bounds(bounds: &mut BoundsMatrix) -> Result<(), MolRsError> {
smooth_bounds_tol(bounds, 0.0)
}