1use crate::{pow::Pow, sqrt::Sqrt};
2use std::{
3 fmt::{self, Display},
4 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub},
5};
6
7pub trait ComplexNumberRequiredTraits<T>:
14 Add<Output = T>
15 + Sub<Output = T>
16 + Mul<Output = T>
17 + Div<Output = T>
18 + Add<Output = T>
19 + AddAssign
20 + MulAssign
21 + DivAssign
22 + Clone
23 + Copy
24 + Display
25 + PartialOrd<T>
26 + Neg<Output = T>
27 + Default
28 + Sqrt
29 + Pow
30 + From<u8>
31{
32}
33
34impl<
35 T: Add<Output = T>
36 + Sub<Output = T>
37 + Mul<Output = T>
38 + Div<Output = T>
39 + Add<Output = T>
40 + AddAssign
41 + MulAssign
42 + DivAssign
43 + Clone
44 + Copy
45 + Display
46 + PartialOrd<T>
47 + Neg<Output = T>
48 + Default
49 + Sqrt
50 + Pow
51 + From<u8>
52 + ?Sized,
53 > ComplexNumberRequiredTraits<T> for T
54{
55}
56
57#[derive(PartialEq, Debug, PartialOrd, Copy, Clone)]
58pub struct ComplexNumber<T: ComplexNumberRequiredTraits<T>> {
59 pub real: T,
60 pub complex: T,
61}
62
63impl<T: ComplexNumberRequiredTraits<T>> ComplexNumber<T> {
64 pub fn new(real: T, complex: T) -> ComplexNumber<T> {
65 ComplexNumber { real, complex }
66 }
67
68 pub fn complex_conjugate(&self) -> Self {
84 ComplexNumber {
85 real: self.real,
86 complex: -self.complex,
87 }
88 }
89
90 pub fn magnitude(&self) -> T {
99 ((self.real * self.real) + (self.complex * self.complex)).square_root()
100 }
101
102 pub fn normalized(&self) -> Self {
113 let magnitude = self.magnitude();
114
115 ComplexNumber::new(self.real / magnitude, self.complex / magnitude)
116 }
117
118 pub fn square_root(&self) -> Self {
126 let magnitude = self.magnitude();
127 let real = ((magnitude + self.real) / 2.into()).square_root();
128 let complex = if self.complex < T::default() {
129 -((magnitude - self.real) / 2.into()).square_root()
130 } else {
131 ((magnitude - self.real) / 2.into()).square_root()
132 };
133 ComplexNumber::new(real, complex)
134 }
135
136 pub fn powf(&self, n: T) -> Self {
139 if n == T::default() {
140 return ComplexNumber::new(T::from(1), T::default());
141 } else {
142 *self * self.powf(n - T::from(1))
143 }
144 }
145}
146
147impl<T: ComplexNumberRequiredTraits<T>> Neg for ComplexNumber<T> {
148 type Output = Self;
149
150 fn neg(self) -> Self::Output {
151 ComplexNumber {
152 real: -self.real,
153 complex: -self.complex,
154 }
155 }
156}
157
158impl<T: ComplexNumberRequiredTraits<T>> Default for ComplexNumber<T> {
159 fn default() -> Self {
160 Self {
161 real: Default::default(),
162 complex: Default::default(),
163 }
164 }
165}
166
167fn complex_number_add<T: ComplexNumberRequiredTraits<T>>(
168 lhs: &ComplexNumber<T>,
169 rhs: &ComplexNumber<T>,
170) -> ComplexNumber<T> {
171 ComplexNumber {
172 real: lhs.real + rhs.real,
173 complex: lhs.complex + rhs.complex,
174 }
175}
176
177impl<T: ComplexNumberRequiredTraits<T>> Add for ComplexNumber<T> {
178 type Output = Self;
179
180 fn add(self, other: Self) -> Self {
181 complex_number_add(&self, &other)
182 }
183}
184
185impl<T: ComplexNumberRequiredTraits<T>> From<u8> for ComplexNumber<T> {
186 fn from(value: u8) -> Self {
187 ComplexNumber {
188 real: T::from(value),
189 complex: T::from(0),
190 }
191 }
192}
193
194fn complex_number_sub<T: ComplexNumberRequiredTraits<T>>(
195 lhs: &ComplexNumber<T>,
196 rhs: &ComplexNumber<T>,
197) -> ComplexNumber<T> {
198 ComplexNumber {
199 real: lhs.real - rhs.real,
200 complex: lhs.complex - rhs.complex,
201 }
202}
203
204impl<T: ComplexNumberRequiredTraits<T>> Sub for ComplexNumber<T> {
205 type Output = Self;
206
207 fn sub(self, other: Self) -> Self {
208 complex_number_sub(&self, &other)
209 }
210}
211
212fn complex_number_multiply<T: ComplexNumberRequiredTraits<T>>(
213 lhs: &ComplexNumber<T>,
214 rhs: &ComplexNumber<T>,
215) -> ComplexNumber<T> {
216 ComplexNumber {
217 real: (lhs.real * rhs.real) - (lhs.complex * rhs.complex),
218 complex: (lhs.real * rhs.complex) + (rhs.real * lhs.complex),
219 }
220}
221
222impl<T: ComplexNumberRequiredTraits<T>> Mul for ComplexNumber<T> {
223 type Output = Self;
224
225 fn mul(self, rhs: Self) -> Self {
226 complex_number_multiply::<T>(&self, &rhs)
227 }
228}
229
230fn complex_number_divide<T: ComplexNumberRequiredTraits<T>>(
231 lhs: &ComplexNumber<T>,
232 rhs: &ComplexNumber<T>,
233) -> ComplexNumber<T> {
234 let rhs_complex_conjugate = rhs.complex_conjugate();
235 let numerator = *lhs * rhs_complex_conjugate;
236 let denominator = *rhs * rhs_complex_conjugate;
237
238 if denominator.complex != T::default() {
239 panic!(
240 "Something went wrong. Denominator has complex element: {}",
241 denominator
242 );
243 }
244
245 ComplexNumber {
246 real: numerator.real / denominator.real,
247 complex: numerator.complex / denominator.real,
248 }
249}
250
251impl<T: ComplexNumberRequiredTraits<T>> Div for ComplexNumber<T> {
252 type Output = Self;
253
254 fn div(self, rhs: Self) -> Self::Output {
255 complex_number_divide::<T>(&self, &rhs)
256 }
257}
258
259fn complex_number_add_assign<T: ComplexNumberRequiredTraits<T>>(
260 lhs: &ComplexNumber<T>,
261 rhs: &ComplexNumber<T>,
262) -> ComplexNumber<T> {
263 complex_number_add(lhs, rhs)
264}
265
266impl<T: ComplexNumberRequiredTraits<T>> AddAssign for ComplexNumber<T> {
267 fn add_assign(&mut self, rhs: Self) {
268 *self = complex_number_add_assign::<T>(self, &rhs);
269 }
270}
271
272fn complex_number_mul_assign<T: ComplexNumberRequiredTraits<T>>(
273 lhs: &ComplexNumber<T>,
274 rhs: &ComplexNumber<T>,
275) -> ComplexNumber<T> {
276 complex_number_multiply(lhs, rhs)
277}
278
279impl<T: ComplexNumberRequiredTraits<T>> MulAssign for ComplexNumber<T> {
280 fn mul_assign(&mut self, rhs: Self) {
281 *self = complex_number_mul_assign::<T>(self, &rhs)
282 }
283}
284
285fn complex_number_div_assign<T: ComplexNumberRequiredTraits<T>>(
286 lhs: &ComplexNumber<T>,
287 rhs: &ComplexNumber<T>,
288) -> ComplexNumber<T> {
289 complex_number_divide(lhs, rhs)
290}
291
292impl<T: ComplexNumberRequiredTraits<T>> DivAssign for ComplexNumber<T> {
293 fn div_assign(&mut self, rhs: Self) {
294 *self = complex_number_div_assign::<T>(self, &rhs)
295 }
296}
297
298fn format_complex_number_component<T: ComplexNumberRequiredTraits<T>>(
299 input: &T,
300 complex: bool,
301) -> String {
302 if *input == T::default() {
303 return "".to_owned();
304 } else if complex {
305 if *input > T::default() {
306 return "+".to_owned() + &input.to_string() + "i";
307 } else {
308 return input.to_string() + "i";
309 }
310 } else {
311 input.to_string()
312 }
313}
314
315impl<T: ComplexNumberRequiredTraits<T>> fmt::Display for ComplexNumber<T> {
316 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
317 let display_string = format_complex_number_component(&self.real, false)
318 + " "
319 + &format_complex_number_component(&self.complex, true);
320 let _ = fmt.write_str(&display_string);
321 Ok(())
322 }
323}
324
325impl<T: ComplexNumberRequiredTraits<T>> Sqrt for ComplexNumber<T> {
326 fn square_root(&self) -> Self {
327 self.square_root()
328 }
329}
330
331impl<T: ComplexNumberRequiredTraits<T>> Pow for ComplexNumber<T> {
332 fn pow(&self, n: ComplexNumber<T>) -> Self {
333 self.powf(n.real)
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use crate::complex_number::ComplexNumber;
340 use rand::prelude::*;
341
342 #[test]
343 fn test_complex_number_add() {
344 let mut rng = rand::thread_rng();
345 let real_one = rng.gen_range(1.0..=100.0);
346 let complex_one = rng.gen_range(1.0..=100.0);
347 let real_two = rng.gen_range(1.0..=100.0);
348 let complex_two = rng.gen_range(1.0..=100.0);
349
350 let lhs = ComplexNumber::new(real_one, complex_one);
351 let rhs = ComplexNumber::new(real_two, complex_two);
352
353 assert_eq!(
354 lhs + rhs,
355 ComplexNumber::new(real_one + real_two, complex_one + complex_two)
356 );
357 }
358
359 #[test]
360 fn test_complex_number_sub() {
361 let mut rng = rand::thread_rng();
362 let real_one = rng.gen_range(1.0..=100.0);
363 let complex_one = rng.gen_range(1.0..=100.0);
364 let real_two = rng.gen_range(1.0..=100.0);
365 let complex_two = rng.gen_range(1.0..=100.0);
366
367 let lhs = ComplexNumber::new(real_one, complex_one);
368 let rhs = ComplexNumber::new(real_two, complex_two);
369
370 assert_eq!(
371 lhs - rhs,
372 ComplexNumber::new(real_one - real_two, complex_one - complex_two)
373 );
374 }
375
376 #[test]
377 fn test_complex_number_multiply() {
378 let mut rng = rand::thread_rng();
379 let real_one = rng.gen_range(1.0..=100.0);
380 let complex_one = rng.gen_range(1.0..=100.0);
381 let real_two = rng.gen_range(1.0..=100.0);
382 let complex_two = rng.gen_range(1.0..=100.0);
383
384 let lhs = ComplexNumber::new(real_one, complex_one);
385 let rhs = ComplexNumber::new(real_two, complex_two);
386
387 assert_eq!(
388 lhs * rhs,
389 ComplexNumber::new(
390 (real_one * real_two) - (complex_one * complex_two),
391 (complex_one * real_two) + (complex_two * real_one)
392 )
393 );
394 }
395
396 #[test]
397 fn test_complex_conjugate() {
398 let mut rng = rand::thread_rng();
399 let real = rng.gen_range(1.0..=100.0);
400 let complex = rng.gen_range(1.0..=100.0);
401 let complex_number = ComplexNumber::new(real, complex);
402
403 assert_eq!(
404 complex_number.complex_conjugate(),
405 ComplexNumber::new(real, -complex,)
406 );
407 }
408
409 #[test]
410 fn test_complex_number_divide() {
411 let mut rng = rand::thread_rng();
412 let real_one = rng.gen_range(1.0..=100.0);
413 let complex_one = rng.gen_range(1.0..=100.0);
414 let real_two = rng.gen_range(1.0..=100.0);
415 let complex_two = rng.gen_range(1.0..=100.0);
416
417 let lhs = ComplexNumber::new(real_one, complex_one);
418 let rhs = ComplexNumber::new(real_two, complex_two);
419
420 assert_eq!(
421 lhs / rhs,
422 ComplexNumber::new(
423 ((real_one * real_two) + (complex_one * complex_two))
424 / (real_two * real_two + complex_two * complex_two),
425 ((complex_one * real_two) - (complex_two * real_one))
426 / (real_two * real_two + complex_two * complex_two),
427 )
428 );
429 }
430
431 #[test]
432 fn test_complex_number_sqrt() {
433 let complex = ComplexNumber::new(3.0, 4.0);
434
435 assert_eq!(complex.square_root(), ComplexNumber::new(2.0, 1.0));
436 }
437}