use num::{Num, FromPrimitive};
use basics::pow;
use basics::convert_trait::Convert;
use std::f64;
use error::*;
pub fn get_arithmetic_mean<T>(data: &[T]) -> Result<f64, MatholError>
where T: Num + Convert + Copy
{
let n = data.iter().len();
match n {
0 => Err(MatholError::EmptyVecCause(EmptyVectorError {
message: "Vector or Array is empty".to_string(),
})),
_ => {
let sum = data.iter().fold(T::zero(), |sum, x| sum + *x);
let arithmetic_mean = sum.to_f64() / n.to_f64();
Ok(arithmetic_mean)
},
}
}
pub fn get_harmonic_mean<T>(data: &[T]) -> Result<f64, MatholError>
where T: Num + Convert + Copy + PartialEq
{
let n = data.iter().len();
match n {
0 => Err(MatholError::EmptyVecCause(EmptyVectorError {
message: "Vector or Array is empty".to_string(),
})),
_ => {
if data.contains(&T::zero()) {
return Err(MatholError::ContainsZeroCause(ContainsZeroError {
message: "Vector or Array contains zero".to_string(),
}));
}
let sum = data.iter().fold(0.0, |sum, x| sum + 1.0 / x.to_f64());
let harmonic_mean = 1.0 / (sum / n.to_f64());
Ok(harmonic_mean)
}
}
}
pub fn get_quadratic_mean<T>(data: &[T]) -> Result<f64, MatholError>
where T: Num + Convert + Copy + PartialEq
{
let n = data.iter().len();
match n {
0 => Err(MatholError::EmptyVecCause(EmptyVectorError {
message: "Vector or Array is empty".to_string(),
})),
_ => {
let sum = data.iter().fold(T::zero(), |sum, x| sum + *x * *x);
let quadratic_mean = (sum.to_f64() / n.to_f64()).sqrt();
Ok(quadratic_mean )
}
}
}
pub fn get_variance<T>(data: &[T]) -> Result<f64, MatholError>
where T: Num + Convert + Copy + FromPrimitive
{
let n = data.iter().len();
match n {
0 => Err(MatholError::EmptyVecCause(EmptyVectorError {
message: "Vector or Array is empty".to_string(),
})),
_ => {
let mean = FromPrimitive::from_f64(get_arithmetic_mean(data)?);
let a = data.iter().fold(T::zero(), |sum, x| sum + pow((*x - mean.unwrap()), 2));
Ok(a.to_f64() / (n - 1).to_f64())
}
}
}
pub fn get_standard_deviation<T>(data: &[T]) -> Result<f64, MatholError>
where T: Num + Convert + Copy + FromPrimitive
{
let n = data.iter().len();
match n {
0 => Err(MatholError::EmptyVecCause(EmptyVectorError {
message: "Vector or Array is empty".to_string(),
})),
_ => Ok(get_variance(data)?.sqrt()),
}
}
pub fn get_min<T>(data: &[T]) -> Result<T, MatholError>
where T: Num + Convert + Copy + FromPrimitive + PartialOrd
{
match data.iter().len() {
0 => Err(MatholError::EmptyVecCause(EmptyVectorError {
message: "Vector or Array is empty".to_string(),
})),
_ => {
let min = data.iter().fold(data[0], |mut min, x| {
if *x < min {
min = *x;
}
min
});
Ok(min)
}
}
}
pub fn get_max<T>(data: &[T]) -> Result<T, MatholError>
where T: Num + Convert + Copy + FromPrimitive + PartialOrd
{
match data.iter().len() {
0 => Err(MatholError::EmptyVecCause(EmptyVectorError {
message: "Vector or Array is empty".to_string(),
})),
_ => {
let max = data.iter().fold(data[0], |mut max, x| {
if *x > max {
max = *x;
}
max
});
Ok(max)
}
}
}
pub fn get_span<T>(data: &[T]) -> Result<T, MatholError>
where T: Num + Convert + Copy + FromPrimitive + PartialOrd
{
match data.iter().len() {
0 => Err(MatholError::EmptyVecCause(EmptyVectorError {
message: "Vector or Array is empty".to_string(),
})),
_ => Ok(get_max(data)? - get_min(data)?),
}
}