pub mod types;
use types::F64;
pub fn mean<T: F64>(data: &[T]) -> f64 {
let mut mean = 0.0;
for (i, val) in data.iter().enumerate() {
mean += (val.f64() - mean) / (i + 1) as f64;
}
mean
}
pub fn absdev<T: F64>(data: &[T]) -> f64 {
absdev_mean(data, mean(data))
}
pub fn absdev_mean<T: F64>(data: &[T], mean: f64) -> f64 {
let mut sum = 0.0;
for val in data {
sum += (val.f64() - mean).abs();
}
sum / data.len() as f64
}
fn covariance_nonpub<T: F64>(data1: &[T], data2: &[T], mean1: f64, mean2: f64) -> f64 {
let mut res = 0.0;
for i in 0..data1.len() {
let delta1 = data1[i].f64() - mean1;
let delta2 = data2[i].f64() - mean2;
res += (delta1 * delta2 - res) / (i + 1) as f64;
}
res
}
pub fn covariance_mean<T: F64>(data1: &[T], data2: &[T], mean1: f64, mean2: f64) -> f64 {
let n = data1.len();
let covariance = covariance_nonpub(data1, data2, mean1, mean2);
covariance * (n as f64) / (n - 1) as f64
}
pub fn covariance<T: F64>(data1: &[T], data2: &[T]) -> f64 {
let mean1 = mean(data1);
let mean2 = mean(data2);
covariance_mean(data1, data2, mean1, mean2)
}
pub fn correlation<T: F64>(data1: &[T], data2: &[T]) -> f64 {
let mut sum_xsq = 0.0;
let mut sum_ysq = 0.0;
let mut sum_cross = 0.0;
let mut mean_x = data1[0].f64();
let mut mean_y = data2[0].f64();
for i in 1..data1.len() {
let ratio = i as f64 / (i + 1) as f64;
let delta_x = data1[i].f64() - mean_x;
let delta_y = data2[i].f64() - mean_y;
sum_xsq += delta_x * delta_x * ratio;
sum_ysq += delta_y * delta_y * ratio;
sum_cross += delta_x * delta_y * ratio;
mean_x += delta_x / (i + 1) as f64;
mean_y += delta_y / (i + 1) as f64;
}
sum_cross / (sum_xsq.sqrt() * sum_ysq.sqrt())
}
pub fn kurtosis<T: F64>(data: &[T]) -> f64 {
let mean = mean(data);
let est_sd = sd_mean(data, mean);
kurtosis_main_sd(data, mean, est_sd)
}
pub fn kurtosis_main_sd<T: F64>(data: &[T], mean: f64, sd: f64) -> f64 {
let mut avg = 0.0;
for i in 0..data.len() {
let x = (data[i].f64() - mean) / sd;
avg += (x * x * x * x - avg) / (i + 1) as f64;
}
avg - 3.0 }
pub fn lag1autocorrelation<T: F64>(data: &[T]) -> f64 {
let mean = mean(data);
return lag1autocorrelation_mean(data, mean);
}
pub fn lag1autocorrelation_mean<T: F64>(data: &[T], mean: f64) -> f64 {
let mut q = 0.0;
let mut v = (data[0].f64() - mean) * (data[0].f64() - mean);
for i in 1..data.len() {
let delta0 = data[i - 1].f64() - mean;
let delta1 = data[i].f64() - mean;
q += (delta0 * delta1 - q) / (i + 1) as f64;
v += (delta1 * delta1 - v) / (i + 1) as f64;
}
q / v }
pub fn median_from_sorted_data<T: F64>(sorted_data: &[T]) -> f64 {
let len = sorted_data.len();
let lhs = (len - 1) / 2;
let rhs = len / 2;
if len == 0 {
return 0.0;
}
if lhs == rhs {
sorted_data[lhs].f64()
} else {
(sorted_data[lhs].f64() + sorted_data[rhs].f64()) / 2.0
}
}
pub fn max<T: F64>(data: &[T]) -> (f64, usize) {
let mut max = data[0].f64();
let mut max_index = 0;
for (i, val) in data.iter().enumerate() {
let xi = val.f64();
if xi > max {
max = xi;
max_index = i;
}
if xi.is_nan() {
max = xi;
max_index = i;
return (max, max_index);
}
}
(max, max_index)
}
pub fn min<T: F64>(data: &[T]) -> (f64, usize) {
let mut min = data[0].f64();
let mut min_index = 0;
for (i, val) in data.iter().enumerate() {
let xi = val.f64();
if xi < min {
min = xi;
min_index = i;
}
if xi.is_nan() {
min = xi;
min_index = i;
return (min, min_index);
}
}
(min, min_index)
}
pub fn minmax<T: F64>(data: &[T]) -> (f64, u32, f64, u32) {
let mut min_index: u32 = 0;
let mut max_index: u32 = 0;
let mut min = data[0].f64();
let mut max = data[0].f64();
for i in 0..data.len() {
let xi = data[i].f64();
if xi < min {
min = xi;
min_index = i as u32;
}
if xi > max {
max = xi;
max_index = i as u32;
}
if xi.is_nan() {
min = xi;
max = xi;
min_index = i as u32;
max_index = i as u32;
break;
}
}
(min, min_index, max, max_index)
}
pub fn p_variance<T: F64>(data1: &[T], data2: &[T]) -> f64 {
let n1 = data1.len();
let n2 = data2.len();
let var1 = variance(data1);
let var2 = variance(data2);
(((n1 - 1) as f64 * var1) + ((n2 - 1) as f64 * var2)) / (n1 + n2 - 2) as f64
}
pub fn quantile_from_sorted_data<T: F64>(sorted_data: &[T], f: f64) -> f64 {
let n = sorted_data.len() as i32;
let index = f * (n - 1) as f64;
let lhs = index as i32;
let delta = index - (lhs as f64);
if n == 0 {
return 0.0;
}
if lhs == n - 1 {
return sorted_data[lhs as usize].f64();
} else {
return (1.0 - delta) * sorted_data[lhs as usize].f64() +
delta * sorted_data[lhs as usize + 1].f64();
}
}
pub fn skew<T: F64>(data: &[T]) -> f64 {
let mean = mean(data);
let sd = sd_mean(data, mean);
skew_mean_sd(data, mean, sd)
}
pub fn skew_mean_sd<T: F64>(data: &[T], mean: f64, sd: f64) -> f64 {
let mut skew = 0.0;
for (i, val) in data.iter().enumerate() {
let x = (val.f64() - mean) / sd;
skew += (x * x * x - skew) / (i + 1) as f64;
}
skew
}
pub fn t_test<T: F64>(data1: &[T], data2: &[T]) -> f64 {
let n1 = data1.len() as f64;
let n2 = data2.len() as f64;
let mean1 = mean(data1);
let mean2 = mean(data2);
let pv = p_variance(data1, data2);
(mean1 - mean2) / (pv * ((1.0 / n1) + (1.0 / n2))).sqrt()
}
fn _variance<T: F64>(data: &[T], mean: f64) -> f64 {
let mut variance = 0.0;
for (i, val) in data.iter().enumerate() {
let delta = val.f64() - mean;
variance += ((delta * delta) - variance) / (i + 1) as f64;
}
variance
}
pub fn variance_with_fixed_mean<T: F64>(data: &[T], mean: f64) -> f64 {
_variance(data, mean)
}
pub fn sd_with_fixed_mean<T: F64>(data: &[T], mean: f64) -> f64 {
_variance(data, mean).sqrt()
}
pub fn variance_mean<T: F64>(data: &[T], mean: f64) -> f64 {
let variance = _variance(data, mean);
variance * (data.len() as f64) / (data.len() - 1) as f64
}
pub fn sd_mean<T: F64>(data: &[T], mean: f64) -> f64 {
let variance = _variance(data, mean);
(variance * (data.len() as f64) / (data.len() - 1) as f64).sqrt()
}
pub fn variance<T: F64>(data: &[T]) -> f64 {
let mean = mean(data);
variance_mean(data, mean)
}
pub fn sd<T: F64>(data: &[T]) -> f64 {
let mean = mean(data);
return sd_mean(data, mean);
}
pub fn tss_mean<T: F64>(data: &[T], mean: f64) -> f64 {
let mut res = 0.0;
for val in data {
let delta = val.f64() - mean;
res += delta * delta;
}
res
}
pub fn tss<T: F64>(data: &[T]) -> f64 {
let mean = mean(data);
return tss_mean(data, mean);
}
pub fn w_absdev<T: F64>(w: &[T], data: &[T]) -> f64 {
let wmean = w_mean(w, data);
w_absdev_mean(w, data, wmean)
}
pub fn w_absdev_mean<T: F64>(w: &[T], data: &[T], wmean: f64) -> f64 {
let mut wabsdev = 0.0;
let mut weight = 0.0;
for i in 0..data.len() {
let wi = w[i].f64();
if wi > 0.0 {
let delta = (data[i].f64() - wmean).abs();
weight += wi;
wabsdev += (delta - wabsdev) * (wi / weight);
}
}
wabsdev
}
pub fn w_kurtosis<T: F64>(w: &[T], data: &[T]) -> f64 {
let wmean = w_mean(w, data);
let wsd = w_sd_mean(w, data, wmean);
w_kurtosis_mean_sd(w, data, wmean, wsd)
}
pub fn w_kurtosis_mean_sd<T: F64>(w: &[T], data: &[T], wmean: f64, wsd: f64) -> f64 {
let mut wavg = 0.0;
let mut weight = 0.0;
for (i, val) in data.iter().enumerate() {
let wi = w[i].f64();
if wi > 0.0 {
let x = (val.f64() - wmean) / wsd;
weight += wi;
wavg += (x * x * x * x - wavg) * (wi / weight);
}
}
wavg - 3.0 }
pub fn w_mean<T: F64>(w: &[T], data: &[T]) -> f64 {
let mut wmean = 0.0;
let mut weight = 0.0;
for (i, val) in data.iter().enumerate() {
let wi = w[i].f64();
if wi > 0.0 {
weight += wi;
wmean += (val.f64() - wmean) * (wi / weight);
}
}
wmean
}
pub fn w_skew<T: F64>(w: &[T], data: &[T]) -> f64 {
let wmean = w_mean(w, data);
let wsd = w_sd_mean(w, data, wmean);
return w_skew_mean_sd(w, data, wmean, wsd);
}
pub fn w_skew_mean_sd<T: F64>(w: &[T], data: &[T], wmean: f64, wsd: f64) -> f64 {
let mut wskew = 0.0;
let mut weight = 0.0;
for (i, val) in data.iter().enumerate() {
let wi = w[i].f64();
if wi > 0.0 {
let x = (val.f64() - wmean) / wsd;
weight += wi;
wskew += (x * x * x - wskew) * (wi / weight);
}
}
wskew
}
fn wvariance<T: F64>(w: &[T], data: &[T], wmean: f64) -> f64 {
let mut weight = 0.0;
let mut wvariance = 0.0;
for (i, val) in w.iter().enumerate() {
let wi = val.f64();
if wi > 0.0 {
let delta = data[i].f64() - wmean;
weight += wi;
wvariance += (delta * delta - wvariance) * (wi / weight);
}
}
wvariance
}
fn factor<T: F64>(w: &[T]) -> f64 {
let mut a = 0.0;
let mut b = 0.0;
for val in w {
let wi = val.f64();
if wi > 0.0 {
a += wi;
b += wi * wi;
}
}
(a * a) / ((a * a) - b)
}
pub fn w_variance_with_fixed_mean<T: F64>(w: &[T], data: &[T], wmean: f64) -> f64 {
wvariance(w, data, wmean)
}
pub fn wsd_with_fixed_mean<T: F64>(w: &[T], data: &[T], wmean: f64) -> f64 {
let wvariance = wvariance(w, data, wmean);
wvariance.sqrt()
}
pub fn w_variance_mean<T: F64>(w: &[T], data: &[T], wmean: f64) -> f64 {
let variance = wvariance(w, data, wmean);
let scale = factor(w);
scale * variance
}
pub fn w_sd_mean<T: F64>(w: &[T], data: &[T], wmean: f64) -> f64 {
let variance = wvariance(w, data, wmean);
let scale = factor(w);
(scale * variance).sqrt()
}
pub fn w_sd<T: F64>(w: &[T], data: &[T]) -> f64 {
let wmean = w_mean(w, data);
w_sd_mean(w, data, wmean)
}
pub fn w_variance<T: F64>(w: &[T], data: &[T]) -> f64 {
let wmean = w_mean(w, data);
w_variance_mean(w, data, wmean)
}
pub fn w_tss_mean<T: F64>(w: &[T], data: &[T], wmean: f64) -> f64 {
let mut res = 0.0;
for (i, val) in data.iter().enumerate() {
let wi = w[i].f64();
if wi > 0.0 {
let delta = val.f64() - wmean;
res += wi * delta * delta;
}
}
res
}
pub fn w_tss<T: F64>(w: &[T], data: &[T]) -> f64 {
let wmean = w_mean(w, data);
return w_tss_mean(w, data, wmean);
}