summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Worthe <justin.worthe@gmail.com>2016-11-27 13:37:22 +0200
committerJustin Worthe <justin.worthe@gmail.com>2016-11-27 13:37:22 +0200
commit2da48d7549e2db3f0e8ba01523095d2f3764ce0a (patch)
tree04ea6f0b726bbfa04d4d14fc7007a891c51242a2
parente4a79af68b2542bec5cd30237869cef0fc911f77 (diff)
Added conjugating and multiplication
-rw-r--r--src/complex.rs30
-rw-r--r--src/num_traits.rs124
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);