|
@@ -0,0 +1,128 @@
|
|
|
+use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
|
|
+
|
|
|
+use crate::{Float, Numeric, Primitive};
|
|
|
+
|
|
|
+/// Struct representing a complex number.
|
|
|
+#[derive(Debug, Copy, Clone)]
|
|
|
+pub struct Complex<T: Float + Numeric + Primitive> {
|
|
|
+ real: T,
|
|
|
+ imag: T,
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> Add for Complex<T> {
|
|
|
+ type Output = Self;
|
|
|
+
|
|
|
+ fn add(self, rhs: Self) -> Self::Output {
|
|
|
+ Self {
|
|
|
+ real: self.real + rhs.real,
|
|
|
+ imag: self.imag + rhs.imag,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> AddAssign for Complex<T> {
|
|
|
+ fn add_assign(&mut self, rhs: Self) {
|
|
|
+ self.real += rhs.real;
|
|
|
+ self.imag += rhs.imag;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> Sub for Complex<T> {
|
|
|
+ type Output = Self;
|
|
|
+
|
|
|
+ fn sub(self, rhs: Self) -> Self::Output {
|
|
|
+ Self {
|
|
|
+ real: self.real - rhs.real,
|
|
|
+ imag: self.imag - rhs.imag,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> SubAssign for Complex<T> {
|
|
|
+ fn sub_assign(&mut self, rhs: Self) {
|
|
|
+ self.real -= rhs.real;
|
|
|
+ self.imag -= rhs.imag;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> Mul for Complex<T> {
|
|
|
+ type Output = Self;
|
|
|
+
|
|
|
+ fn mul(self, rhs: Self) -> Self::Output {
|
|
|
+ Complex {
|
|
|
+ real: self.real * rhs.real - self.imag * rhs.imag,
|
|
|
+ imag: self.real * rhs.imag + self.imag * rhs.real,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> MulAssign for Complex<T> {
|
|
|
+ fn mul_assign(&mut self, rhs: Self) {
|
|
|
+ *self = *self * rhs;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> Div for Complex<T> {
|
|
|
+ type Output = Self;
|
|
|
+
|
|
|
+ fn div(self, rhs: Self) -> Self::Output {
|
|
|
+ let divisor = rhs.real * rhs.real + rhs.imag * rhs.imag;
|
|
|
+ let mut result = self * Self { real: rhs.real, imag: -rhs.imag };
|
|
|
+ result.real /= divisor;
|
|
|
+ result.imag /= divisor;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> DivAssign for Complex<T> {
|
|
|
+ fn div_assign(&mut self, rhs: Self) {
|
|
|
+ *self = *self / rhs;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> Neg for Complex<T> {
|
|
|
+ type Output = Self;
|
|
|
+
|
|
|
+ fn neg(self) -> Self::Output {
|
|
|
+ Self {
|
|
|
+ real: -self.real,
|
|
|
+ imag: -self.imag,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> PartialEq for Complex<T> {
|
|
|
+ fn eq(&self, other: &Self) -> bool {
|
|
|
+ self.real == other.real && self.imag == other.imag
|
|
|
+ }
|
|
|
+
|
|
|
+ fn ne(&self, other: &Self) -> bool {
|
|
|
+ self.real != other.real || self.imag != other.imag
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> Float for Complex<T> {}
|
|
|
+
|
|
|
+impl<T: Float + Numeric + Primitive> Numeric for Complex<T> {
|
|
|
+ fn zero() -> Self {
|
|
|
+ Self { real: T::zero(), imag: T::zero() }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn one() -> Self {
|
|
|
+ Self { real: T::one(), imag: T::zero() }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(test)]
|
|
|
+mod tests {
|
|
|
+ use crate::types::complex::Complex;
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn division() {
|
|
|
+ let mut a: Complex<f32> = Complex { real: 3.0, imag: 2.0 };
|
|
|
+ let b: Complex<f32> = Complex { real: 4.0, imag: -5.0 };
|
|
|
+ let expected: Complex<f32> = Complex { real: 2.0 / 41.0, imag: 23.0 / 41.0 };
|
|
|
+ a /= b;
|
|
|
+ assert_eq!(format!("{:?}", a), format!("{:?}", expected));
|
|
|
+ }
|
|
|
+}
|