1use std::{ops::{Add, Sub, Mul, Div}, fmt::{Display, Debug}, f64::consts::PI};
2
3pub trait Complex: Add + Sub + Mul + Div + Display + Debug + Sized {
4 fn conjugate(&self) -> Self;
5}
6
7 #[derive(Debug)]
8pub struct Rectangular {
9 real: f64,
10 imag: f64,
11}
12
13impl Rectangular {
14 pub fn new(real: f64, imag: f64) -> Self {
15 Self { real, imag }
16 }
17
18 pub fn get_polar(&self) -> Polar {
19 let modulus = (self.real.powf(2.) + self.imag.powf(2.)).sqrt();
20 let mut arg = (self.real/self.imag).atan();
21
22
23 if self.real.is_sign_negative() && self.imag.is_sign_negative() {
24 arg += PI;
26 } else if self.real.is_sign_positive() && self.imag.is_sign_negative() {
27 arg += PI
29 } else if arg.is_sign_negative() {
30 arg += 2.*PI;
31 }
32
33 Polar::new(arg, modulus)
34 }
35
36 pub fn real(&self) -> f64 {
37 self.real
38 }
39
40 pub fn imag(&self) -> f64 {
41 self.imag
42 }
43}
44
45impl Complex for Rectangular {
46 fn conjugate(&self) -> Self {
47 Self { real: self.real, imag: -self.imag }
48 }
49}
50
51impl Add for Rectangular {
52 type Output = Self;
53 fn add(self, rhs: Self) -> Self::Output {
54 let real = self.real + rhs.real;
55 let imag = self.imag + rhs.imag;
56 Self { real, imag }
57 }
58}
59
60impl Add<f64> for Rectangular {
61 type Output = Self;
62 fn add(self, rhs: f64) -> Self::Output {
63 let real = self.real + rhs;
64 Self { real, imag: self.imag }
65 }
66}
67
68impl Sub for Rectangular {
69 type Output = Self;
70 fn sub(self, rhs: Self) -> Self::Output {
71 let real = self.real - rhs.real;
72 let imag = self.imag - rhs.imag;
73 Self { real, imag }
74 }
75}
76
77impl Sub<f64> for Rectangular {
78 type Output = Self;
79 fn sub(self, rhs: f64) -> Self::Output {
80 let real = self.real - rhs;
81 Self { real, imag: self.imag }
82 }
83}
84
85impl Mul for Rectangular {
88 type Output = Self;
89 fn mul(self, rhs: Self) -> Self::Output {
90 let real = self.real * rhs.real - self.imag * rhs.imag;
91 let imag = self.imag * rhs.real + self.real * rhs.imag;
92 Self { real, imag }
93 }
94}
95
96impl Mul<f64> for Rectangular {
97 type Output = Self;
98 fn mul(self, rhs: f64) -> Self::Output {
99 let real = self.real * rhs;
100 let imag = self.imag * rhs;
101 Self { real, imag }
102 }
103}
104
105impl Div for Rectangular {
107 type Output = Self;
108 fn div(self, rhs: Self) -> Self::Output {
109 let numerator = self * Self { real: rhs.real, imag: -rhs.imag };
110 let denomenator = rhs.real.powf(2.) + rhs.imag.powf(2.);
111 let real = numerator.real / denomenator;
112 let imag = numerator.imag / denomenator;
113
114 Self { real, imag }
115 }
116
117}
118
119impl Div<f64> for Rectangular {
120 type Output = Self;
121 fn div(self, rhs: f64) -> Self::Output {
122 let real = self.real / rhs;
123 let imag = self.real / rhs;
124 Self { real, imag }
125 }
126}
127
128impl Display for Rectangular {
129 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130 write!(f, "{} + {}i", self.real, self.imag)
131 }
132
133}
134
135#[derive(Debug)]
136pub struct Polar {
137 arg: f64,
138 modulus: f64,
139}
140
141impl Polar {
142 pub fn new(arg: f64, modulus: f64) -> Self {
143 Self { arg, modulus }
144 }
145
146 pub fn get_rectangular(&self) -> Rectangular {
147 let real = self.modulus * self.arg.cos();
148 let imag = self.modulus * self.arg.sin();
149 Rectangular::new(real, imag)
150 }
151
152 pub fn arg(&self) -> f64 {
153 self.arg
154 }
155
156 pub fn modulus(&self) -> f64 {
157 self.modulus
158 }
159}
160
161impl Complex for Polar {
162 fn conjugate(&self) -> Self {
163 Self { arg: 2.*PI - self.arg, modulus: self.modulus }
164 }
165}
166
167impl Add for Polar {
168 type Output = Self;
169
170 fn add(self, rhs: Self) -> Self::Output {
171 let rect_self = self.get_rectangular();
172 let rect_rhs = rhs.get_rectangular();
173
174 (rect_self + rect_rhs).get_polar()
175 }
176}
177
178impl Sub for Polar {
179 type Output = Self;
180 fn sub(self, rhs: Self) -> Self::Output {
181 let rect_self = self.get_rectangular();
182 let rect_rhs = rhs.get_rectangular();
183
184 (rect_self - rect_rhs).get_polar()
185 }
186}
187
188impl Mul for Polar {
189 type Output = Self;
190 fn mul(self, rhs: Self) -> Self::Output {
191 let modulus = self.modulus * rhs.modulus;
192 let mut arg = self.arg + rhs.arg;
193
194 if arg > 2.*PI {
195 arg -= 2.* PI;
196 }
197
198 Self { arg, modulus }
199 }
200}
201
202impl Div for Polar {
203 type Output = Self;
204 fn div(self, rhs: Self) -> Self::Output {
205 let modulus = self.modulus / rhs.modulus;
206 let mut arg = self.arg - rhs.arg;
207
208 if arg < 0. {
209 arg += 2.*PI;
210 }
211
212 Self { arg, modulus }
213 }
214}
215
216impl Display for Polar {
217 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
218 write!(f, "{}*e^{}i", self.modulus, self.arg)
219 }
220}