1use std::{
2 fmt::{Debug, Write},
3 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
4};
5
6#[derive(Clone, Copy, Eq, PartialEq)]
7pub struct Complex<T: Copy> {
8 real: T,
9 imaginary: T,
10}
11
12impl<T> Debug for Complex<T>
13where
14 T: Debug + Copy,
15{
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 f.write_char('(')?;
18 self.real.fmt(f)?;
19 f.write_str(", ")?;
20 self.imaginary.fmt(f)?;
21 f.write_char('i')?;
22 f.write_char(')')?;
23 Ok(())
24 }
25}
26
27#[macro_export]
28macro_rules! c {
29 ($real:tt +i $imaginary:tt) => {
30 Complex::new($real, $imaginary)
31 };
32 ($real:tt -i $imaginary:tt) => {
33 Complex::new($real, -($imaginary))
34 };
35 (-$real:tt +i $imaginary:tt) => {
36 Complex::new(-$real, $imaginary)
37 };
38 (-$real:tt -i $imaginary:tt) => {
39 Complex::new(-$real, -($imaginary))
40 };
41}
42
43impl<T> Complex<T>
44where
45 T: Copy,
46{
47 #[inline]
48 pub fn new(r: T, i: T) -> Self {
49 Self {
50 real: r,
51 imaginary: i,
52 }
53 }
54
55 #[inline]
56 pub fn real(&self) -> T {
57 self.real
58 }
59
60 #[inline]
61 pub fn imaginary(&self) -> T {
62 self.imaginary
63 }
64
65 #[inline]
66 pub fn set_real(&mut self, real: T) {
67 self.real = real
68 }
69
70 #[inline]
71 pub fn set_imaginary(&mut self, imaginary: T) {
72 self.imaginary = imaginary
73 }
74}
75
76impl<T> Add<Complex<T>> for Complex<T>
77where
78 T: Add<Output = T> + Copy,
79{
80 type Output = Self;
81
82 fn add(self, rhs: Complex<T>) -> Self::Output {
83 (self.real + rhs.real, self.imaginary + rhs.imaginary).into()
84 }
85}
86
87impl<T> Add<T> for Complex<T>
88where
89 T: Add<Output = T> + Copy,
90{
91 type Output = Self;
92
93 fn add(self, rhs: T) -> Self::Output {
94 (self.real + rhs, self.imaginary).into()
95 }
96}
97
98impl<T> AddAssign<Complex<T>> for Complex<T>
99where
100 T: AddAssign + Copy,
101{
102 fn add_assign(&mut self, rhs: Complex<T>) {
103 self.real += rhs.real;
104 self.imaginary += rhs.imaginary;
105 }
106}
107
108impl<T> AddAssign<T> for Complex<T>
109where
110 T: AddAssign + Copy,
111{
112 fn add_assign(&mut self, rhs: T) {
113 self.real += rhs;
114 }
115}
116
117impl<T> Sub<Complex<T>> for Complex<T>
118where
119 T: Sub<Output = T> + Copy,
120{
121 type Output = Self;
122
123 fn sub(self, rhs: Complex<T>) -> Self::Output {
124 (self.real - rhs.real, self.imaginary - rhs.imaginary).into()
125 }
126}
127
128impl<T> Sub<T> for Complex<T>
129where
130 T: Sub<Output = T> + Copy,
131{
132 type Output = Self;
133
134 fn sub(self, rhs: T) -> Self::Output {
135 (self.real - rhs, self.imaginary).into()
136 }
137}
138
139impl<T> SubAssign<Complex<T>> for Complex<T>
140where
141 T: SubAssign + Copy,
142{
143 fn sub_assign(&mut self, rhs: Complex<T>) {
144 self.real -= rhs.real;
145 self.imaginary -= rhs.imaginary;
146 }
147}
148
149impl<T> SubAssign<T> for Complex<T>
150where
151 T: SubAssign + Copy,
152{
153 fn sub_assign(&mut self, rhs: T) {
154 self.real -= rhs;
155 }
156}
157
158impl<T> Mul<Complex<T>> for Complex<T>
159where
160 T: Mul<Output = T> + Sub<Output = T> + Add<Output = T> + Copy,
161{
162 type Output = Complex<T>;
163 fn mul(self, rhs: Complex<T>) -> Self::Output {
164 let real: T = self.real * rhs.real - (self.imaginary * rhs.imaginary);
165 let imaginary: T = self.imaginary * rhs.real + (rhs.imaginary * self.real);
166 (real, imaginary).into()
167 }
168}
169
170impl<T> Mul<T> for Complex<T>
171where
172 T: Mul<Output = T> + Sub<Output = T> + Add<Output = T> + Copy,
173{
174 type Output = Complex<T>;
175 fn mul(self, rhs: T) -> Self::Output {
176 let real: T = self.real * rhs;
177 let imaginary: T = self.imaginary * rhs;
178 (real, imaginary).into()
179 }
180}
181
182impl<T> MulAssign<Complex<T>> for Complex<T>
183where
184 T: Mul<Output = T> + Sub<Output = T> + Add<Output = T> + Copy,
185{
186 fn mul_assign(&mut self, rhs: Complex<T>) {
187 let real: T = self.real * rhs.real - (self.imaginary * rhs.imaginary);
188 let imaginary: T = self.imaginary * rhs.real + (rhs.imaginary * self.real);
189 self.real = real;
190 self.imaginary = imaginary;
191 }
192}
193
194impl<T> MulAssign<T> for Complex<T>
195where
196 T: Mul<Output = T> + Sub<Output = T> + Add<Output = T> + Copy,
197{
198 fn mul_assign(&mut self, rhs: T) {
199 let real: T = self.real * rhs;
200 let imaginary: T = self.imaginary * rhs;
201 self.real = real;
202 self.imaginary = imaginary;
203 }
204}
205
206impl<T> Div<Complex<T>> for Complex<T>
207where
208 T: Copy + Mul<Output = T> + Add<Output = T> + Div<Output = T> + Sub<Output = T>,
209{
210 type Output = Self;
211 fn div(self, rhs: Complex<T>) -> Self::Output {
212 let a = self.real;
214 let b = self.imaginary;
215 let c = rhs.real;
216 let d = rhs.imaginary;
217
218 let real = ((a * c) + (b * d)) / ((c * c) + (d * d));
219 let imaginary = ((b * c) - (a * d)) / ((c * c) + (d * d));
220 (real, imaginary).into()
221 }
222}
223
224impl<T> Div<T> for Complex<T>
225where
226 T: Copy + Mul<Output = T> + Add<Output = T> + Div<Output = T> + Sub<Output = T>,
227{
228 type Output = Self;
229 fn div(self, rhs: T) -> Self::Output {
230 let a = self.real;
232 let b = self.imaginary;
233 let c = rhs;
234
235 let real = a / c;
236 let imaginary = b / c;
237
238 (real, imaginary).into()
239 }
240}
241
242impl<T> DivAssign<Complex<T>> for Complex<T>
243where
244 T: Copy + Mul<Output = T> + Add<Output = T> + Div<Output = T> + Sub<Output = T>,
245{
246 fn div_assign(&mut self, rhs: Complex<T>) {
247 let a = self.real;
249 let b = self.imaginary;
250 let c = rhs.real;
251 let d = rhs.imaginary;
252
253 let real = ((a * c) + (b * d)) / ((c * c) + (d * d));
254 let imaginary = ((b * c) - (a * d)) / ((c * c) + (d * d));
255
256 self.real = real;
257 self.imaginary = imaginary;
258 }
259}
260
261impl<T> DivAssign<T> for Complex<T>
262where
263 T: Copy + Mul<Output = T> + Add<Output = T> + Div<Output = T> + Sub<Output = T>,
264{
265 fn div_assign(&mut self, rhs: T) {
266 let a = self.real;
268 let b = self.imaginary;
269 let c = rhs;
270
271 let real = a / c;
272 let imaginary = b / c;
273
274 self.real = real;
275 self.imaginary = imaginary;
276 }
277}
278
279impl<T> Neg for Complex<T>
280where
281 T: Neg<Output = T> + Copy,
282{
283 type Output = Self;
284
285 fn neg(self) -> Self::Output {
286 (-self.real, -self.imaginary).into()
287 }
288}
289
290impl<T: Copy> From<(T, T)> for Complex<T> {
291 fn from((r, i): (T, T)) -> Self {
292 Self::new(r, i)
293 }
294}
295
296impl<T> From<T> for Complex<T>
297where
298 T: Copy + Default,
299{
300 fn from(r: T) -> Self {
301 Self::new(r, T::default())
302 }
303}
304
305#[cfg(test)]
306mod tests {
307 use super::*;
308
309 #[test]
310 fn it_works() {
311 let a = c!(3 + i 2);
314 let b = c!(2 - i 3);
315
316 let c = a * b;
317 assert_eq!(c, (12, -9 + 4).into());
318
319 let c = a + b;
320 assert_eq!(c, c!(5 - i 1));
321
322 let c = a - b;
323 assert_eq!(c, c!(1 + i 5));
324
325 assert_eq!(b - a, -c);
326
327 assert_eq!(a / b, (0, 1).into());
328 }
329}