1use crate::impl_from;
3use crate::impl_ops;
4
5#[derive(Clone, Copy, Default, Debug, PartialEq)]
7pub struct Complex {
8 pub re: f64,
10 pub im: f64,
12}
13
14impl Complex {
15 pub fn new(a: f64, b: f64) -> Self {
17 Self { re: a, im: b }
18 }
19
20 pub fn abs(self) -> f64 {
22 (self.re * self.re + self.im * self.im).sqrt()
23 }
24
25 pub fn arg(self) -> f64 {
27 self.im.atan2(self.re)
28 }
29
30 pub fn conjugate(self) -> Self {
32 Self {
33 re: self.re,
34 im: -self.im,
35 }
36 }
37
38 pub fn polar(r: f64, a: f64) -> Self {
40 Self {
41 re: r * a.cos(),
42 im: r * a.sin(),
43 }
44 }
45}
46
47impl_ops!(Add for Complex, |a: Self, b: Self| Self::new(a.re + b.re, a.im + b.im));
48impl_ops!(Sub for Complex, |a: Self, b: Self| Self::new(a.re - b.re, a.im - b.im));
49impl_ops!(Mul for Complex, |a: Self, b: Self| Self::new(
50 a.re * b.re - a.im * b.im,
51 a.re * b.im + a.im * b.re
52));
53impl_ops!(Div for Complex, |a: Self, b: Self| Self::new(
54 (a.re * b.re + a.im * b.im) / (b.re * b.re + b.im * b.im),
55 (a.im * b.re - a.re * b.im) / (b.re * b.re + b.im * b.im)
56));
57impl_ops!(Neg for Complex, |a: Self| Self::new(-a.re, -a.im));
58
59impl_ops!(AddAssign for Complex, |a: &mut Self, b: Self| *a = *a + b);
60impl_ops!(SubAssign for Complex, |a: &mut Self, b: Self| *a = *a - b);
61impl_ops!(MulAssign for Complex, |a: &mut Self, b: Self| *a = *a * b);
62impl_ops!(DivAssign for Complex, |a: &mut Self, b: Self| *a = *a / b);
63
64impl_from!((f64, f64) => Complex, |(a, b)| Self::new(a, b));
65impl_from!(Complex => (f64, f64), |Complex { re, im }| (re, im));
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use std::f64::consts::PI;
71
72 #[test]
73 fn test() {
74 assert_eq!(
75 Complex::new(1.0, 1.0) + Complex::new(3.0, -2.5),
76 Complex::new(4.0, -1.5)
77 );
78
79 assert_eq!(
80 Complex::new(1.0, 1.0) - Complex::new(3.0, -2.5),
81 Complex::new(-2.0, 3.5)
82 );
83
84 assert_eq!(
85 Complex::new(1.0, 1.0) * Complex::new(3.0, -2.5),
86 Complex::new(5.5, 0.5)
87 );
88
89 assert_eq!(
90 Complex::polar(2.0, PI / 4.0) * Complex::polar(4.0, PI / 8.0),
91 Complex::polar(8.0, PI * 3.0 / 8.0)
92 );
93 }
94}