complex: implement real ops directly
It's more efficient to implement these without creating an intermediate complex value -- at the least, we don't have to rely on the compiler optimizing out zero-ops.
This commit is contained in:
parent
ebc36b3e55
commit
f06f5c548e
|
@ -587,38 +587,91 @@ macro_rules! real_arithmetic {
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
);
|
);
|
||||||
(@implement $imp:ident::$method:ident for $($real:ident),*) => (
|
|
||||||
impl<T: Clone + Num> $imp<T> for Complex<T> {
|
|
||||||
type Output = Complex<T>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn $method(self, other: T) -> Complex<T> {
|
|
||||||
self.$method(Complex::from(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$(
|
|
||||||
impl $imp<Complex<$real>> for $real {
|
|
||||||
type Output = Complex<$real>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn $method(self, other: Complex<$real>) -> Complex<$real> {
|
|
||||||
Complex::from(self).$method(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
);
|
|
||||||
($($real:ident),*) => (
|
($($real:ident),*) => (
|
||||||
real_arithmetic!(@forward Add::add for $($real),*);
|
real_arithmetic!(@forward Add::add for $($real),*);
|
||||||
real_arithmetic!(@forward Sub::sub for $($real),*);
|
real_arithmetic!(@forward Sub::sub for $($real),*);
|
||||||
real_arithmetic!(@forward Mul::mul for $($real),*);
|
real_arithmetic!(@forward Mul::mul for $($real),*);
|
||||||
real_arithmetic!(@forward Div::div for $($real),*);
|
real_arithmetic!(@forward Div::div for $($real),*);
|
||||||
real_arithmetic!(@implement Add::add for $($real),*);
|
|
||||||
real_arithmetic!(@implement Sub::sub for $($real),*);
|
$(
|
||||||
real_arithmetic!(@implement Mul::mul for $($real),*);
|
impl Add<Complex<$real>> for $real {
|
||||||
real_arithmetic!(@implement Div::div for $($real),*);
|
type Output = Complex<$real>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: Complex<$real>) -> Complex<$real> {
|
||||||
|
Complex::new(self + other.re, other.im)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<Complex<$real>> for $real {
|
||||||
|
type Output = Complex<$real>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: Complex<$real>) -> Complex<$real> {
|
||||||
|
Complex::new(self - other.re, $real::zero() - other.im)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<Complex<$real>> for $real {
|
||||||
|
type Output = Complex<$real>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: Complex<$real>) -> Complex<$real> {
|
||||||
|
Complex::new(self * other.re, self * other.im)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<Complex<$real>> for $real {
|
||||||
|
type Output = Complex<$real>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, other: Complex<$real>) -> Complex<$real> {
|
||||||
|
// a / (c + i d) == [a * (c - i d)] / (c*c + d*d)
|
||||||
|
let norm_sqr = other.norm_sqr();
|
||||||
|
Complex::new(self * other.re / norm_sqr.clone(),
|
||||||
|
$real::zero() - self * other.im / norm_sqr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Clone + Num> Add<T> for Complex<T> {
|
||||||
|
type Output = Complex<T>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: T) -> Complex<T> {
|
||||||
|
Complex::new(self.re + other, self.im)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone + Num> Sub<T> for Complex<T> {
|
||||||
|
type Output = Complex<T>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: T) -> Complex<T> {
|
||||||
|
Complex::new(self.re - other, self.im)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone + Num> Mul<T> for Complex<T> {
|
||||||
|
type Output = Complex<T>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: T) -> Complex<T> {
|
||||||
|
Complex::new(self.re * other.clone(), self.im * other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone + Num> Div<T> for Complex<T> {
|
||||||
|
type Output = Complex<T>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, other: T) -> Complex<T> {
|
||||||
|
Complex::new(self.re / other.clone(), self.im / other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
real_arithmetic!(usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32, f64);
|
real_arithmetic!(usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32, f64);
|
||||||
|
|
||||||
/* constants */
|
/* constants */
|
||||||
|
|
Loading…
Reference in New Issue