complex_plane/
lib.rs

1pub mod complex_numbers {
2    use std::fmt::Debug;
3    use std::ops::Add;
4    use std::ops::Mul;
5    use std::ops::Sub;
6
7    #[derive(Clone)]
8    pub struct Complex<T> {
9        re: T,
10        im: T,
11    }
12
13    impl<T> Complex<T>
14    where
15        T: Add<Output = T> + Mul<Output = T> + Sub<Output = T> + Clone + Default,
16    {
17        pub fn new(re: T, im: T) -> Self {
18            Complex { re, im }
19        }
20
21        pub fn re(self) -> T {
22            return self.re;
23        }
24
25        pub fn im(self) -> T {
26            return self.im;
27        }
28    }
29
30    impl<T> Add for Complex<T>
31    where
32        T: Add<Output = T> + Mul<Output = T> + Sub<Output = T> + Clone + Default,
33    {
34        type Output = Complex<T>;
35
36        fn add(self, rhs: Complex<T>) -> Self::Output {
37            Complex::new(self.re + rhs.re, self.im + rhs.im)
38        }
39    }
40
41    impl<T> Mul for Complex<T>
42    where
43        T: Add<Output = T> + Mul<Output = T> + Sub<Output = T> + Clone + Default,
44    {
45        type Output = Complex<T>;
46
47        fn mul(self, rhs: Self) -> Self::Output {
48            let real_part: T = self.re.clone() * rhs.re.clone() - self.im.clone() * rhs.im.clone();
49            let imaginary_part: T = self.re * rhs.im + self.im * rhs.re;
50
51            return Complex::new(real_part, imaginary_part);
52        }
53    }
54
55    impl<T> Sub for Complex<T>
56    where
57        T: Add<Output = T> + Mul<Output = T> + Sub<Output = T> + Clone + Default,
58    {
59        type Output = Complex<T>;
60
61        fn sub(self, rhs: Self) -> Self::Output {
62            Complex::new(self.re - rhs.re, self.im - rhs.im)
63        }
64    }
65
66    impl<T> Default for Complex<T>
67    where
68        T: Add<Output = T> + Mul<Output = T> + Sub<Output = T> + Clone + Default,
69    {
70        fn default() -> Self {
71            Self {
72                re: T::default(),
73                im: T::default(),
74            }
75        }
76    }
77
78    impl<T> std::fmt::Debug for Complex<T>
79    where
80        T: Add<Output = T> + Mul<Output = T> + Sub<Output = T> + Clone + Default + Debug,
81    {
82        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83            write!(f, "{:?}+{:?}i", self.re, self.im)
84        }
85    }
86
87    impl<T> PartialEq for Complex<T>
88    where
89        T: PartialEq,
90    {
91        fn eq(&self, other: &Self) -> bool {
92            self.re == other.re && self.im == other.im
93        }
94
95        fn ne(&self, other: &Self) -> bool {
96            !self.eq(other)
97        }
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use crate::complex_numbers::Complex;
104
105    #[test]
106    fn test_complex_initialization() {
107        let _complex_i32: Complex<i32> = Complex::new(1, 2);
108        let _complex_f32: Complex<f32> = Complex::new(2.5, 1.325);
109        let _complex_usize: Complex<usize> = Complex::new(1, 1);
110        let complex_from_default: Complex<i32> = Complex::default();
111
112        assert_eq!(complex_from_default, Complex::<i32>::new(0, 0));
113    }
114
115    #[test]
116    fn test_complex_addition() {
117        let z_1: Complex<i32> = Complex::new(1, 2);
118        let z_2: Complex<i32> = Complex::new(1, -3);
119
120        assert_eq!(z_1 + z_2, Complex::new(2, -1));
121
122        let z_1_f: Complex<f32> = Complex::new(2.12, 6.5);
123        let z_2_f: Complex<f32> = Complex::new(3.5, 2.1);
124
125        assert_eq!(z_1_f + z_2_f, Complex::new(5.62, 8.6));
126    }
127
128    #[test]
129    fn test_complex_multiplication() {
130        let z_1: Complex<i32> = Complex::new(2, -2);
131        let z_2: Complex<i32> = Complex::new(9, 17);
132        assert_eq!(z_1 * z_2, Complex::new(52, 16));
133    }
134}