dsalgo/
complex_number_f64.rs1#[derive(Debug, Clone, Copy, PartialEq)]
3
4pub struct Complex(pub f64, pub f64);
5
6impl From<f64> for Complex {
7 fn from(real: f64) -> Self {
8 Self(real, 0.0)
9 }
10}
11
12impl From<(f64, f64)> for Complex {
13 fn from(rect: (f64, f64)) -> Self {
14 Self(rect.0, rect.1)
15 }
16}
17
18impl Complex {
19 pub fn rint(&self) -> f64 {
22 self.0.round()
23 }
24
25 pub fn zero() -> Self {
26 Self(0.0, 0.0)
27 }
28
29 pub fn one() -> Self {
30 Self(1.0, 0.0)
31 }
32
33 pub fn i() -> Self {
34 Self(0.0, 1.0)
35 }
36
37 pub fn norm_square(&self) -> f64 {
38 self.0 * self.0 + self.1 * self.1
39 }
40
41 pub fn conjugate(&self) -> Self {
42 Self(self.0, -self.1)
43 }
44
45 pub fn mul_inv(&self) -> Self {
46 let ns = self.norm_square();
47
48 Self(self.0 / ns, -self.1 / ns)
49 }
50
51 pub fn argument(&self) -> f64 {
52 self.1.atan2(self.0)
53 }
54
55 pub fn norm(&self) -> f64 {
56 self.0.hypot(self.1)
57 }
58
59 pub fn polar(&self) -> (f64, f64) {
60 (self.norm(), self.argument())
61 }
62
63 pub fn from_polar(
64 r: f64,
65 theta: f64,
66 ) -> Self {
67 Self::rectangular(r, theta)
68 }
69
70 pub fn rectangular(
71 r: f64,
72 theta: f64,
73 ) -> Self {
74 Self(r * theta.cos(), r * theta.sin())
75 }
76
77 pub fn exp(&self) -> Self {
80 Self(self.1.cos(), self.1.sin()) * self.0.exp()
81 }
82
83 pub fn ln(&self) -> Self {
88 Self(self.norm().ln(), self.argument())
89 }
90
91 pub fn sqrt(&self) -> Complex {
92 let (r, theta) = self.polar();
93
94 Self::rectangular(r, theta / 2.0)
95 }
96
97 pub fn sin(&self) -> Complex {
100 Self(self.0.sin() * self.1.cosh(), self.0.cos() * self.1.sinh())
101 }
102
103 pub fn cos(&self) -> Complex {
106 Self(self.0.cos() * self.1.cosh(), -self.0.sin() * self.1.sinh())
107 }
108
109 pub fn tan(&self) -> Complex {
112 let Self(a, b) = *self * 2.0;
113
114 Self(a.sin(), b.sinh()) / (a.cos() + b.cosh())
115 }
116}
117
118use std::ops::*;
119
120impl MulAssign<f64> for Complex {
121 fn mul_assign(
122 &mut self,
123 x: f64,
124 ) {
125 self.0 *= x;
126
127 self.1 *= x;
128 }
129}
130
131impl Mul<f64> for Complex {
132 type Output = Self;
133
134 fn mul(
135 mut self,
136 x: f64,
137 ) -> Self::Output {
138 self *= x;
139
140 self
141 }
142}
143
144impl DivAssign<f64> for Complex {
145 fn div_assign(
146 &mut self,
147 x: f64,
148 ) {
149 self.0 /= x;
150
151 self.1 /= x;
152 }
153}
154
155impl Div<f64> for Complex {
156 type Output = Self;
157
158 fn div(
159 mut self,
160 x: f64,
161 ) -> Self::Output {
162 self /= x;
163
164 self
165 }
166}
167
168impl AddAssign for Complex {
169 fn add_assign(
170 &mut self,
171 rhs: Self,
172 ) {
173 self.0 += rhs.0;
174
175 self.1 += rhs.1;
176 }
177}
178
179impl Add for Complex {
180 type Output = Self;
181
182 fn add(
183 mut self,
184 rhs: Self,
185 ) -> Self::Output {
186 self += rhs;
187
188 self
189 }
190}
191
192impl MulAssign for Complex {
193 fn mul_assign(
194 &mut self,
195 rhs: Self,
196 ) {
197 *self = *self * rhs;
198 }
199}
200
201impl Mul for Complex {
202 type Output = Self;
203
204 fn mul(
205 self,
206 rhs: Self,
207 ) -> Self::Output {
208 Self(self.0 * rhs.0 - self.1 * rhs.1, self.0 * rhs.1 + self.1 * rhs.0)
209 }
210}
211
212impl Neg for Complex {
213 type Output = Self;
214
215 fn neg(self) -> Self::Output {
216 Self(-self.0, -self.1)
217 }
218}
219
220impl SubAssign for Complex {
221 fn sub_assign(
222 &mut self,
223 rhs: Self,
224 ) {
225 *self += -rhs;
226 }
227}
228
229impl Sub for Complex {
230 type Output = Self;
231
232 fn sub(
233 mut self,
234 rhs: Self,
235 ) -> Self::Output {
236 self -= rhs;
237
238 self
239 }
240}
241
242impl DivAssign for Complex {
243 fn div_assign(
244 &mut self,
245 rhs: Self,
246 ) {
247 *self *= rhs.mul_inv();
248 }
249}
250
251impl Div for Complex {
252 type Output = Self;
253
254 fn div(
255 mut self,
256 rhs: Self,
257 ) -> Self::Output {
258 self /= rhs;
259
260 self
261 }
262}
263
264#[cfg(test)]
265
266mod tests {
267
268 #[test]
269
270 fn test() {}
271}