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}