|  | @@ -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));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 |