diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/complex.rs | 30 | ||||
-rw-r--r-- | src/num_traits.rs | 124 |
2 files changed, 90 insertions, 64 deletions
diff --git a/src/complex.rs b/src/complex.rs index 1a8bc20..960dba4 100644 --- a/src/complex.rs +++ b/src/complex.rs @@ -1,4 +1,4 @@ -use std::ops::{Add, Sub, Mul}; +use std::ops::{Add, Sub, Mul, Neg}; use ::num_traits::{Trig, Pow}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -12,17 +12,22 @@ impl<T> Complex<T> { Complex{real: real, imag: imag} } } +impl<T> Complex<T> where T: Neg<Output=T> { + pub fn conjugate(self) -> Complex<T> { + Complex::new(self.real, -self.imag) + } +} -impl<T> Complex<T> where T: Trig<T> + Mul<Output=T> + Copy { +impl<T> Complex<T> where T: Trig + Mul<Output=T> + Copy { pub fn from_polar(r: T, theta: T) -> Complex<T> { let real = r*theta.cos(); let imag = r*theta.sin(); Complex::new(real, imag) } } -impl<T> Complex<T> where T: Trig<T> + Pow<T> + Add<Output=T> + Copy { +impl<T> Complex<T> where T: Trig + Pow + Add<Output=T> + Copy { pub fn to_polar(self) -> (T, T) { - let r = (self.real.powi(2) + self.imag.powi(2)).sqrt(); + let r = (self.real.pow(2) + self.imag.pow(2)).sqrt(); let theta = self.imag.atan2(self.real); (r, theta) } @@ -48,6 +53,16 @@ impl<T> Sub for Complex<T> where T: Sub<Output=T> + Copy { } } +impl<T> Mul for Complex<T> where T: Add<Output=T> + Mul<Output=T> + Sub<Output=T> + Copy { + type Output = Complex<T>; + + fn mul(self, other: Self) -> Self { + let real = (self.real * other.real) - (self.imag * other.imag); + let imag = (self.real * other.imag) + (self.imag * other.real); + Complex::new(real, imag) + } +} + #[cfg(test)] mod tests { use super::*; @@ -67,6 +82,13 @@ mod tests { assert_eq!(a-b, Complex::new(4, 3)); } + #[test] + fn multiplication() { + let a = Complex::new(3, 4); + let b = Complex::new(2, 3); + assert_eq!(a*b, Complex::new(-6, 17)); + } + #[test] fn from_polar() { diff --git a/src/num_traits.rs b/src/num_traits.rs index 3e18a4b..1e04cce 100644 --- a/src/num_traits.rs +++ b/src/num_traits.rs @@ -1,4 +1,4 @@ -pub trait Trig<T> { +pub trait Trig { fn sin(self) -> Self; fn cos(self) -> Self; fn tan(self) -> Self; @@ -8,73 +8,77 @@ pub trait Trig<T> { fn atan2(self, other: Self) -> Self; } -impl Trig<f32> for f32 { - fn sin(self) -> Self { - self.sin() - } - fn cos(self) -> Self { - self.cos() - } - fn tan(self) -> Self { - self.tan() - } - fn asin(self) -> Self { - self.asin() - } - fn acos(self) -> Self { - self.acos() - } - fn atan2(self, other: Self) -> Self { - self.atan2(other) - } -} -impl Trig<f64> for f64 { - fn sin(self) -> Self { - self.sin() - } - fn cos(self) -> Self { - self.cos() - } - fn tan(self) -> Self { - self.tan() - } - fn asin(self) -> Self { - self.asin() - } - fn acos(self) -> Self { - self.acos() - } - fn atan2(self, other: Self) -> Self { - self.atan2(other) +macro_rules! impl_float_trig { + ($t: ty) => { + impl Trig for $t { + fn sin(self) -> Self { + self.sin() + } + fn cos(self) -> Self { + self.cos() + } + fn tan(self) -> Self { + self.tan() + } + fn asin(self) -> Self { + self.asin() + } + fn acos(self) -> Self { + self.acos() + } + fn atan2(self, other: Self) -> Self { + self.atan2(other) + } + } } } +impl_float_trig!(f32); +impl_float_trig!(f64); + -pub trait Pow<T> { - fn powi(self, n: i32) -> Self; - fn powf(self, n: T) -> Self; +pub trait Pow { + fn pow(self, n: i32) -> Self; fn sqrt(self) -> Self; } -impl Pow<f32> for f32 { - fn powi(self, n: i32) -> Self { - self.powi(n) - } - fn powf(self, n: Self) -> Self { - self.powf(n) - } - fn sqrt(self) -> Self { - self.sqrt() +macro_rules! impl_float_pow { + ($t: ty) => { + impl Pow for $t { + fn pow(self, n: i32) -> Self { + self.powi(n) + } + fn sqrt(self) -> Self { + self.sqrt() + } + } } } -impl Pow<f64> for f64 { - fn powi(self, n: i32) -> Self { - self.powi(n) - } - fn powf(self, n: Self) -> Self { - self.powf(n) - } - fn sqrt(self) -> Self { - self.sqrt() + +macro_rules! impl_int_pow { + ($t: ty) => { + impl Pow for $t { + fn pow(self, n: i32) -> Self { + if n > 0 { + self.pow(n as u32) + } else { + (self as f64).powi(n) as Self + } + } + fn sqrt(self) -> Self { + (self as f64).sqrt() as Self + } + } } } + +impl_float_pow!(f32); +impl_float_pow!(f64); +impl_int_pow!(i8); +impl_int_pow!(i16); +impl_int_pow!(i32); +impl_int_pow!(i64); +impl_int_pow!(u8); +impl_int_pow!(u16); +impl_int_pow!(u32); +impl_int_pow!(u64); |