From f5fe4191b2ad9c076c55de4e71f14d3391a480b1 Mon Sep 17 00:00:00 2001 From: rcarter Date: Thu, 8 May 2025 16:39:48 -0400 Subject: [PATCH] remove paste --- Cargo.toml | 1 - src/scalar/complex.rs | 276 +++++++++++++++++++-------------------- src/simd/simd_complex.rs | 135 ++++++++++++++++++- 3 files changed, 267 insertions(+), 145 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 164035e..c285e21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,6 @@ num-complex = { version = "0.4", default-features = false } wide = { version = "0.7", default-features = false, optional = true } fixed = { version = "1", optional = true } cordic = { version = "0.1", optional = true } -paste = "1.0" rand = { version = "0.8", optional = true } serde = { version = "1", default-features = false, optional = true } rkyv = { version = "0.7", optional = true } diff --git a/src/scalar/complex.rs b/src/scalar/complex.rs index e28d94e..4c58ea3 100644 --- a/src/scalar/complex.rs +++ b/src/scalar/complex.rs @@ -11,147 +11,6 @@ use num::Float; //#[cfg(feature = "decimal")] //use decimal::d128; -macro_rules! complex_trait_methods ( - ($RealField: ident $(, $prefix: ident)*) => { - paste::item! { - /// Builds a pure-real complex number from the given value. - fn [](re: Self::$RealField) -> Self; - - /// The real part of this complex number. - fn [<$($prefix)* real>](self) -> Self::$RealField; - - /// The imaginary part of this complex number. - fn [<$($prefix)* imaginary>](self) -> Self::$RealField; - - /// The modulus of this complex number. - fn [<$($prefix)* modulus>](self) -> Self::$RealField; - - /// The squared modulus of this complex number. - fn [<$($prefix)* modulus_squared>](self) -> Self::$RealField; - - /// The argument of this complex number. - fn [<$($prefix)* argument>](self) -> Self::$RealField; - - /// The sum of the absolute value of this complex number's real and imaginary part. - fn [<$($prefix)* norm1>](self) -> Self::$RealField; - - /// Multiplies this complex number by `factor`. - fn [<$($prefix)* scale>](self, factor: Self::$RealField) -> Self; - - /// Divides this complex number by `factor`. - fn [<$($prefix)* unscale>](self, factor: Self::$RealField) -> Self; - - /// The polar form of this complex number: (modulus, arg) - fn [<$($prefix)* to_polar>](self) -> (Self::$RealField, Self::$RealField) { - (self.clone().[<$($prefix)* modulus>](), self.[<$($prefix)* argument>]()) - } - - /// The exponential form of this complex number: (modulus, e^{i arg}) - fn [<$($prefix)* to_exp>](self) -> (Self::$RealField, Self) { - let m = self.clone().[<$($prefix)* modulus>](); - - if !m.is_zero() { - (m.clone(), self.[<$($prefix)* unscale>](m)) - } else { - (Self::$RealField::zero(), Self::one()) - } - } - - /// The exponential part of this complex number: `self / self.modulus()` - fn [<$($prefix)* signum>](self) -> Self { - self.[<$($prefix)* to_exp>]().1 - } - - fn [<$($prefix)* floor>](self) -> Self; - fn [<$($prefix)* ceil>](self) -> Self; - fn [<$($prefix)* round>](self) -> Self; - fn [<$($prefix)* trunc>](self) -> Self; - fn [<$($prefix)* fract>](self) -> Self; - fn [<$($prefix)* mul_add>](self, a: Self, b: Self) -> Self; - - /// The absolute value of this complex number: `self / self.signum()`. - /// - /// This is equivalent to `self.modulus()`. - fn [<$($prefix)* abs>](self) -> Self::$RealField; - - /// Computes (self.conjugate() * self + other.conjugate() * other).sqrt() - fn [<$($prefix)* hypot>](self, other: Self) -> Self::$RealField; - - fn [<$($prefix)* recip>](self) -> Self; - fn [<$($prefix)* conjugate>](self) -> Self; - fn [<$($prefix)* sin>](self) -> Self; - fn [<$($prefix)* cos>](self) -> Self; - fn [<$($prefix)* sin_cos>](self) -> (Self, Self); - #[inline] - fn [<$($prefix)* sinh_cosh>](self) -> (Self, Self) { - (self.clone().[<$($prefix)* sinh>](), self.[<$($prefix)* cosh>]()) - } - fn [<$($prefix)* tan>](self) -> Self; - fn [<$($prefix)* asin>](self) -> Self; - fn [<$($prefix)* acos>](self) -> Self; - fn [<$($prefix)* atan>](self) -> Self; - fn [<$($prefix)* sinh>](self) -> Self; - fn [<$($prefix)* cosh>](self) -> Self; - fn [<$($prefix)* tanh>](self) -> Self; - fn [<$($prefix)* asinh>](self) -> Self; - fn [<$($prefix)* acosh>](self) -> Self; - fn [<$($prefix)* atanh>](self) -> Self; - - /// Cardinal sine - #[inline] - fn [<$($prefix)* sinc>](self) -> Self { - if self.is_zero() { - Self::one() - } else { - self.clone().[<$($prefix)* sin>]() / self - } - } - - #[inline] - fn [<$($prefix)* sinhc>](self) -> Self { - if self.is_zero() { - Self::one() - } else { - self.clone().[<$($prefix)* sinh>]() / self - } - } - - /// Cardinal cos - #[inline] - fn [<$($prefix)* cosc>](self) -> Self { - if self.is_zero() { - Self::one() - } else { - self.clone().[<$($prefix)* cos>]() / self - } - } - - #[inline] - fn [<$($prefix)* coshc>](self) -> Self { - if self.is_zero() { - Self::one() - } else { - self.clone().[<$($prefix)* cosh>]() / self - } - } - - fn [<$($prefix)* log>](self, base: Self::$RealField) -> Self; - fn [<$($prefix)* log2>](self) -> Self; - fn [<$($prefix)* log10>](self) -> Self; - fn [<$($prefix)* ln>](self) -> Self; - fn [<$($prefix)* ln_1p>](self) -> Self; - fn [<$($prefix)* sqrt>](self) -> Self; - fn [<$($prefix)* exp>](self) -> Self; - fn [<$($prefix)* exp2>](self) -> Self; - fn [<$($prefix)* exp_m1>](self) -> Self; - fn [<$($prefix)* powi>](self, n: i32) -> Self; - fn [<$($prefix)* powf>](self, n: Self::$RealField) -> Self; - fn [<$($prefix)* powc>](self, n: Self) -> Self; - fn [<$($prefix)* cbrt>](self) -> Self; - } - } -); - /// Trait shared by all complex fields and its subfields (like real numbers). /// /// Complex numbers are equipped with functions that are commonly used on complex numbers and reals. @@ -176,9 +35,140 @@ SubsetOf + Debug + Display { - type RealField: RealField; - complex_trait_methods!(RealField); + type RealField: RealField;/// Builds a pure-real complex number from the given value. + fn from_real(re: Self::RealField) -> Self; + + /// The real part of this complex number. + fn real(self) -> Self::RealField; + + /// The imaginary part of this complex number. + fn imaginary(self) -> Self::RealField; + + /// The modulus of this complex number. + fn modulus(self) -> Self::RealField; + + /// The squared modulus of this complex number. + fn modulus_squared(self) -> Self::RealField; + + /// The argument of this complex number. + fn argument(self) -> Self::RealField; + + /// The sum of the absolute value of this complex number's real and imaginary part. + fn norm1(self) -> Self::RealField; + + /// Multiplies this complex number by `factor`. + fn scale(self, factor: Self::RealField) -> Self; + + /// Divides this complex number by `factor`. + fn unscale(self, factor: Self::RealField) -> Self; + + /// The polar form of this complex number: (modulus, arg) + fn to_polar(self) -> (Self::RealField, Self::RealField) { + (self.clone().modulus(), self.argument()) + } + + /// The exponential form of this complex number: (modulus, e^{i arg}) + fn to_exp(self) -> (Self::RealField, Self) { + let m = self.clone().modulus(); + + if !m.is_zero() { + (m.clone(), self.unscale(m)) + } else { + (Self::RealField::zero(), Self::one()) + } + } + + /// The exponential part of this complex number: `self / self.modulus()` + fn signum(self) -> Self { + self.to_exp().1 + } + + fn floor(self) -> Self; + fn ceil(self) -> Self; + fn round(self) -> Self; + fn trunc(self) -> Self; + fn fract(self) -> Self; + fn mul_add(self, a: Self, b: Self) -> Self; + + /// The absolute value of this complex number: `self / self.signum()`. + /// + /// This is equivalent to `self.modulus()`. + fn abs(self) -> Self::RealField; + + /// Computes (self.conjugate() * self + other.conjugate() * other).sqrt() + fn hypot(self, other: Self) -> Self::RealField; + + fn recip(self) -> Self; + fn conjugate(self) -> Self; + fn sin(self) -> Self; + fn cos(self) -> Self; + fn sin_cos(self) -> (Self, Self); + #[inline] + fn sinh_cosh(self) -> (Self, Self) { + (self.clone().sinh(), self.cosh()) + } + fn tan(self) -> Self; + fn asin(self) -> Self; + fn acos(self) -> Self; + fn atan(self) -> Self; + fn sinh(self) -> Self; + fn cosh(self) -> Self; + fn tanh(self) -> Self; + fn asinh(self) -> Self; + fn acosh(self) -> Self; + fn atanh(self) -> Self; + + /// Cardinal sine + #[inline] + fn sinc(self) -> Self { + if self.is_zero() { + Self::one() + } else { + self.clone().sin() / self + } + } + + #[inline] + fn sinhc(self) -> Self { + if self.is_zero() { + Self::one() + } else { + self.clone().sinh() / self + } + } + + /// Cardinal cos + #[inline] + fn cosc(self) -> Self { + if self.is_zero() { + Self::one() + } else { + self.clone().cos() / self + } + } + + #[inline] + fn coshc(self) -> Self { + if self.is_zero() { + Self::one() + } else { + self.clone().cosh() / self + } + } + fn log(self, base: Self::RealField) -> Self; + fn log2(self) -> Self; + fn log10(self) -> Self; + fn ln(self) -> Self; + fn ln_1p(self) -> Self; + fn sqrt(self) -> Self; + fn exp(self) -> Self; + fn exp2(self) -> Self; + fn exp_m1(self) -> Self; + fn powi(self, n: i32) -> Self; + fn powf(self, n: Self::RealField) -> Self; + fn powc(self, n: Self) -> Self; + fn cbrt(self) -> Self; fn is_finite(&self) -> bool; fn try_sqrt(self) -> Option; } diff --git a/src/simd/simd_complex.rs b/src/simd/simd_complex.rs index 0d73326..f15b398 100644 --- a/src/simd/simd_complex.rs +++ b/src/simd/simd_complex.rs @@ -31,7 +31,140 @@ SubsetOf { /// Type of the coefficients of a complex number. type SimdRealField: SimdRealField::SimdBool>; - complex_trait_methods!(SimdRealField, simd_); + /// Builds a pure-real complex number from the given value. + fn from_simd_real(re: Self::SimdRealField) -> Self; + + /// The real part of this complex number. + fn simd_real(self) -> Self::SimdRealField; + + /// The imaginary part of this complex number. + fn simd_imaginary(self) -> Self::SimdRealField; + + /// The modulus of this complex number. + fn simd_modulus(self) -> Self::SimdRealField; + + /// The squared modulus of this complex number. + fn simd_modulus_squared(self) -> Self::SimdRealField; + + /// The argument of this complex number. + fn simd_argument(self) -> Self::SimdRealField; + + /// The sum of the absolute value of this complex number's real and imaginary part. + fn simd_norm1(self) -> Self::SimdRealField; + + /// Multiplies this complex number by `factor`. + fn simd_scale(self, factor: Self::SimdRealField) -> Self; + + /// Divides this complex number by `factor`. + fn simd_unscale(self, factor: Self::SimdRealField) -> Self; + + /// The polar form of this complex number: (modulus, arg) + fn simd_to_polar(self) -> (Self::SimdRealField, Self::SimdRealField) { + (self.clone().simd_modulus(), self.simd_argument()) + } + + /// The exponential form of this complex number: (modulus, e^{i arg}) + fn simd_to_exp(self) -> (Self::SimdRealField, Self) { + let m = self.clone().simd_modulus(); + + if !m.is_zero() { + (m.clone(), self.simd_unscale(m)) + } else { + (Self::SimdRealField::zero(), Self::one()) + } + } + + /// The exponential part of this complex number: `self / self.modulus()` + fn simd_signum(self) -> Self { + self.simd_to_exp().1 + } + + fn simd_floor(self) -> Self; + fn simd_ceil(self) -> Self; + fn simd_round(self) -> Self; + fn simd_trunc(self) -> Self; + fn simd_fract(self) -> Self; + fn simd_mul_add(self, a: Self, b: Self) -> Self; + + /// The absolute value of this complex number: `self / self.signum()`. + /// + /// This is equivalent to `self.modulus()`. + fn simd_abs(self) -> Self::SimdRealField; + + /// Computes (self.conjugate() * self + other.conjugate() * other).sqrt() + fn simd_hypot(self, other: Self) -> Self::SimdRealField; + + fn simd_recip(self) -> Self; + fn simd_conjugate(self) -> Self; + fn simd_sin(self) -> Self; + fn simd_cos(self) -> Self; + fn simd_sin_cos(self) -> (Self, Self); + #[inline] + fn simd_sinh_cosh(self) -> (Self, Self) { + (self.clone().simd_sinh(), self.simd_cosh()) + } + fn simd_tan(self) -> Self; + fn simd_asin(self) -> Self; + fn simd_acos(self) -> Self; + fn simd_atan(self) -> Self; + fn simd_sinh(self) -> Self; + fn simd_cosh(self) -> Self; + fn simd_tanh(self) -> Self; + fn simd_asinh(self) -> Self; + fn simd_acosh(self) -> Self; + fn simd_atanh(self) -> Self; + + /// Cardinal sine + #[inline] + fn simd_sinc(self) -> Self { + if self.is_zero() { + Self::one() + } else { + self.clone().simd_sin() / self + } + } + + #[inline] + fn simd_sinhc(self) -> Self { + if self.is_zero() { + Self::one() + } else { + self.clone().simd_sinh() / self + } + } + + /// Cardinal cos + #[inline] + fn simd_cosc(self) -> Self { + if self.is_zero() { + Self::one() + } else { + self.clone().simd_cos() / self + } + } + + #[inline] + fn simd_coshc(self) -> Self { + if self.is_zero() { + Self::one() + } else { + self.clone().simd_cosh() / self + } + } + + fn simd_log(self, base: Self::SimdRealField) -> Self; + fn simd_log2(self) -> Self; + fn simd_log10(self) -> Self; + fn simd_ln(self) -> Self; + fn simd_ln_1p(self) -> Self; + fn simd_sqrt(self) -> Self; + fn simd_exp(self) -> Self; + fn simd_exp2(self) -> Self; + fn simd_exp_m1(self) -> Self; + fn simd_powi(self, n: i32) -> Self; + fn simd_powf(self, n: Self::SimdRealField) -> Self; + fn simd_powc(self, n: Self) -> Self; + fn simd_cbrt(self) -> Self; /// Computes the sum of all the lanes of `self`. fn simd_horizontal_sum(self) -> Self::Element;