pub fn compute_baseline_mean(
healthy_data: &[f64],
num_signals: usize,
num_windows: usize,
mean_out: &mut [f64],
) {
let mut s = 0;
while s < num_signals && s < mean_out.len() {
let mut sum = 0.0;
let mut count: usize = 0;
let mut w = 0;
while w < num_windows {
let idx = w * num_signals + s;
if idx < healthy_data.len() {
let v = healthy_data[idx];
if !v.is_nan() { sum += v;
count += 1;
}
}
w += 1;
}
mean_out[s] = if count > 0 { sum / count as f64 } else { 0.0 };
s += 1;
}
}
pub fn compute_baseline_envelope(
healthy_data: &[f64],
baseline_mean: &[f64],
num_signals: usize,
num_windows: usize,
rho_out: &mut [f64],
) {
let mut s = 0;
while s < num_signals && s < rho_out.len() {
let mean = if s < baseline_mean.len() { baseline_mean[s] } else { 0.0 };
let mut var_sum = 0.0;
let mut count: usize = 0;
let mut w = 0;
while w < num_windows {
let idx = w * num_signals + s;
if idx < healthy_data.len() {
let v = healthy_data[idx];
if !v.is_nan() {
let d = v - mean;
var_sum += d * d;
count += 1;
}
}
w += 1;
}
let sigma = if count > 1 {
crate::envelope::sqrt_approx_pub(var_sum / (count - 1) as f64)
} else {
1.0
};
rho_out[s] = if 3.0 * sigma > 1e-10 { 3.0 * sigma } else { 1e-10 };
s += 1;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_baseline_mean() {
let data = [1.0, 10.0, 2.0, 20.0, 3.0, 30.0];
let mut mean = [0.0; 2];
compute_baseline_mean(&data, 2, 3, &mut mean);
assert!((mean[0] - 2.0).abs() < 1e-12);
assert!((mean[1] - 20.0).abs() < 1e-12);
}
}