use num::{Num, Float};
use crate::utils::compare_floats;
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct MaxMin<T> {
max: T,
min: T,
}
pub fn find_max_min<T: std::cmp::PartialOrd + Copy>(slice: &[T]) -> MaxMin<T> {
let mut max = &slice[0];
let mut min = &slice[0];
for index in 1..slice.len() {
if slice[index] < *min { min = &slice[index];}
if slice[index] > *max { max = &slice[index];}
}
MaxMin{max: *max, min: *min}
}
pub fn norm2<T: Float>(slice: &[T]) -> T {
slice.iter().fold(T::zero(), |n, &i| (i * i) + n).sqrt()
}
pub fn dot<T: Num + Copy + std::iter::Sum>(slice1: &[T], slice2: &[T]) -> T {
slice1.iter().zip(slice2).map(|(&a, &b)| a * b).sum()
}
pub fn normalize<T: Float>(slice: &mut [T]) {
let n = norm2(slice);
slice.iter_mut().for_each(|element| {
*element = *element / n;
})
}
pub fn project_x_over_y<T: Float + std::iter::Sum>(x: &[T], y: &[T]) -> T {
dot(x, y) / dot(y, y)
}
pub fn check_elements<T: Float>(v: &[T], tol: T) -> bool {
let mut result = false;
for num in v.iter() {
result |= compare_floats(*num, T::zero(), tol);
}
result
}
#[cfg(test)]
mod test_slides_methods {
use crate::vector3::V3;
use crate::slices_methods::*;
#[test]
fn find_max_min_test() {
let v = V3::new([1, 10, 37]);
let result = find_max_min(&*v);
let expected = MaxMin{max: 37, min: 1};
assert_eq!(result, expected);
}
#[test]
fn dot_tests() {
let v1 = V3::new([1, 1, 1]);
let v2 = V3::new([1, 1, 3]);
let result = dot(&*v1, &*v2);
let expected = 5;
assert_eq!(result, expected);
}
#[test]
fn normalize_test() {
let mut v1 = V3::new([1.0, 1.0, 1.0]);
normalize(&mut *v1);
let expected = V3::new([0.5773502691896258, 0.5773502691896258, 0.5773502691896258]);
assert_eq!(
&v1[..],
&expected[..],
"\nExpected\n{:?}\nfound\n{:?}",
&v1[..],
&expected[..]
);
}
}