use num::{Float, FromPrimitive};
use std::ops::{AddAssign, SubAssign};
use crate::moments::CentralMoments;
use crate::stats::Univariate;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct Skew<F: Float + FromPrimitive + AddAssign + SubAssign> {
pub central_moments: CentralMoments<F>,
pub bias: bool,
}
impl<F: Float + FromPrimitive + AddAssign + SubAssign> Skew<F> {
pub fn new(bias: bool) -> Self {
Self {
central_moments: CentralMoments::new(),
bias,
}
}
}
impl<F> Default for Skew<F>
where
F: Float + FromPrimitive + AddAssign + SubAssign,
{
fn default() -> Self {
Self {
central_moments: CentralMoments::new(),
bias: false,
}
}
}
impl<F: Float + FromPrimitive + AddAssign + SubAssign> Univariate<F> for Skew<F> {
fn update(&mut self, x: F) {
self.central_moments.count.update(x);
self.central_moments.update_delta(x);
self.central_moments.update_m1(x);
self.central_moments.update_sum_delta();
self.central_moments.update_m3();
self.central_moments.update_m2();
}
fn get(&self) -> F {
let n = self.central_moments.count.get();
let mut skew: F = F::from_f64(0.).unwrap();
if self.central_moments.m2 != F::from_f64(0.).unwrap() {
skew += n.powf(F::from_f64(0.5).unwrap()) * self.central_moments.m3
/ self.central_moments.m2.powf(F::from_f64(1.5).unwrap());
}
if (!self.bias) && n > F::from_f64(2.).unwrap() {
return ((n - F::from_f64(1.).unwrap()) * n).powf(F::from_f64(0.5).unwrap())
/ (n - F::from_f64(2.).unwrap())
* skew;
}
skew
}
}