1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
//------------------------------------------------------------------------- // @file slices_methods.rs // // @date 06/24/20 21:48:21 // @author Martin Noblia // @email mnoblia@disroot.org // // @brief // // @detail // // Licence MIT: // Copyright <2020> <Martin Noblia> // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. //------------------------------------------------------------------------- use num::{Num, Float}; #[derive(Copy, Clone, Debug, PartialEq)] pub struct MaxMin<T> { max: T, min: T, } /// generic function to fin min and max values in a slice 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} } /// calculate the euclidean norm of the slice pub fn norm2<T: Num + Copy + Float>(slice: &[T]) -> T { slice.iter().fold(T::zero(), |n, &i| (i * i) + n).sqrt() } /// calculate the dot product of two slices pub fn dot<T: Num + Copy + std::iter::Sum>(slice1: &[T], slice2: &[T]) -> T { slice1.iter().zip(slice2).map(|(&a, &b)| a * b).sum() } /// normalize the slice pub fn normalize<T: Float>(slice: &mut [T]) { let n = norm2(slice); for element in slice.iter_mut() { *element = *element / n; } } /// project x in the direction of y pub fn project_x_over_y<T: Float + std::iter::Sum>(x: &[T], y: &[T]) -> T { dot(x, y) / dot(y, y) } //------------------------------------------------------------------------- // tests //------------------------------------------------------------------------- #[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); } }