diff options
Diffstat (limited to 'vendor/num-traits/src/ops/mul_add.rs')
-rw-r--r-- | vendor/num-traits/src/ops/mul_add.rs | 149 |
1 files changed, 0 insertions, 149 deletions
diff --git a/vendor/num-traits/src/ops/mul_add.rs b/vendor/num-traits/src/ops/mul_add.rs deleted file mode 100644 index 51beb55..0000000 --- a/vendor/num-traits/src/ops/mul_add.rs +++ /dev/null @@ -1,149 +0,0 @@ -/// Fused multiply-add. Computes `(self * a) + b` with only one rounding -/// error, yielding a more accurate result than an unfused multiply-add. -/// -/// Using `mul_add` can be more performant than an unfused multiply-add if -/// the target architecture has a dedicated `fma` CPU instruction. -/// -/// Note that `A` and `B` are `Self` by default, but this is not mandatory. -/// -/// # Example -/// -/// ``` -/// use std::f32; -/// -/// let m = 10.0_f32; -/// let x = 4.0_f32; -/// let b = 60.0_f32; -/// -/// // 100.0 -/// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs(); -/// -/// assert!(abs_difference <= 100.0 * f32::EPSILON); -/// ``` -pub trait MulAdd<A = Self, B = Self> { - /// The resulting type after applying the fused multiply-add. - type Output; - - /// Performs the fused multiply-add operation `(self * a) + b` - fn mul_add(self, a: A, b: B) -> Self::Output; -} - -/// The fused multiply-add assignment operation `*self = (*self * a) + b` -pub trait MulAddAssign<A = Self, B = Self> { - /// Performs the fused multiply-add assignment operation `*self = (*self * a) + b` - fn mul_add_assign(&mut self, a: A, b: B); -} - -#[cfg(any(feature = "std", feature = "libm"))] -impl MulAdd<f32, f32> for f32 { - type Output = Self; - - #[inline] - fn mul_add(self, a: Self, b: Self) -> Self::Output { - <Self as crate::Float>::mul_add(self, a, b) - } -} - -#[cfg(any(feature = "std", feature = "libm"))] -impl MulAdd<f64, f64> for f64 { - type Output = Self; - - #[inline] - fn mul_add(self, a: Self, b: Self) -> Self::Output { - <Self as crate::Float>::mul_add(self, a, b) - } -} - -macro_rules! mul_add_impl { - ($trait_name:ident for $($t:ty)*) => {$( - impl $trait_name for $t { - type Output = Self; - - #[inline] - fn mul_add(self, a: Self, b: Self) -> Self::Output { - (self * a) + b - } - } - )*} -} - -mul_add_impl!(MulAdd for isize i8 i16 i32 i64 i128); -mul_add_impl!(MulAdd for usize u8 u16 u32 u64 u128); - -#[cfg(any(feature = "std", feature = "libm"))] -impl MulAddAssign<f32, f32> for f32 { - #[inline] - fn mul_add_assign(&mut self, a: Self, b: Self) { - *self = <Self as crate::Float>::mul_add(*self, a, b) - } -} - -#[cfg(any(feature = "std", feature = "libm"))] -impl MulAddAssign<f64, f64> for f64 { - #[inline] - fn mul_add_assign(&mut self, a: Self, b: Self) { - *self = <Self as crate::Float>::mul_add(*self, a, b) - } -} - -macro_rules! mul_add_assign_impl { - ($trait_name:ident for $($t:ty)*) => {$( - impl $trait_name for $t { - #[inline] - fn mul_add_assign(&mut self, a: Self, b: Self) { - *self = (*self * a) + b - } - } - )*} -} - -mul_add_assign_impl!(MulAddAssign for isize i8 i16 i32 i64 i128); -mul_add_assign_impl!(MulAddAssign for usize u8 u16 u32 u64 u128); - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn mul_add_integer() { - macro_rules! test_mul_add { - ($($t:ident)+) => { - $( - { - let m: $t = 2; - let x: $t = 3; - let b: $t = 4; - - assert_eq!(MulAdd::mul_add(m, x, b), (m*x + b)); - } - )+ - }; - } - - test_mul_add!(usize u8 u16 u32 u64 isize i8 i16 i32 i64); - } - - #[test] - #[cfg(feature = "std")] - fn mul_add_float() { - macro_rules! test_mul_add { - ($($t:ident)+) => { - $( - { - use core::$t; - - let m: $t = 12.0; - let x: $t = 3.4; - let b: $t = 5.6; - - let abs_difference = (MulAdd::mul_add(m, x, b) - (m*x + b)).abs(); - - assert!(abs_difference <= 46.4 * $t::EPSILON); - } - )+ - }; - } - - test_mul_add!(f32 f64); - } -} |