1pub mod elementary;
2pub mod trigonometric;
3pub mod hyperbolic;
4
5use core::ops::{Add, Div, Mul, Neg, Sub};
6use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign};
7use std::{fmt, cmp::Ordering};
8
9pub use crate::traits::{Number, Signed, Zero, One, Tiny};
10
11pub struct Complex<T> {
12 pub real: T,
14 pub imag: T,
16}
17
18pub type Cmplx = Complex<f64>;
19
20impl<T> Complex<T> {
21 #[inline]
23 pub const fn new(real: T, imag: T) -> Self {
24 Complex { real, imag }
25 }
26}
27
28impl<T: Clone + Signed> Complex<T> {
29 #[inline]
31 pub fn conj(&self) -> Self {
32 Self::new(self.real.clone(), -self.imag.clone())
33 }
34}
35
36impl<T: Clone> Clone for Complex<T> {
37 #[inline]
39 fn clone(&self) -> Self {
40 Self::new(self.real.clone(), self.imag.clone())
41 }
42}
43
44impl<T: Clone + Signed> Neg for Complex<T> {
45 type Output = Self;
46 #[inline]
49 fn neg(self) -> Self::Output {
50 Self::Output::new( -self.real, -self.imag )
51 }
52}
53
54impl<T: Clone + Number> Add<Complex<T>> for Complex<T> {
55 type Output = Self;
56 #[inline]
59 fn add(self, plus: Self) -> Self::Output {
60 Self::Output::new(self.real + plus.real, self.imag + plus.imag)
61 }
62}
63
64impl<T: Clone + Number> Sub<Complex<T>> for Complex<T> {
65 type Output = Self;
66 #[inline]
69 fn sub(self, minus: Self) -> Self::Output {
70 Self::Output::new(self.real - minus.real, self.imag - minus.imag)
71 }
72}
73
74impl<T: Clone + Number> Mul<Complex<T>> for Complex<T> {
75 type Output = Self;
76 #[inline]
79 fn mul(self, times: Self) -> Self::Output {
80 let real = self.real.clone() * times.real.clone() - self.imag.clone() * times.imag.clone();
81 let imag = self.real * times.imag + self.imag * times.real;
82 Self::Output::new( real, imag )
83 }
84}
85
86impl<T: Clone + Number> Div<Complex<T>> for Complex<T> {
87 type Output = Self;
88 #[inline]
91 fn div(self, divisor: Self) -> Self::Output {
92 let denominator = divisor.real.clone() * divisor.real.clone() + divisor.imag.clone() * divisor.imag.clone();
93 let real = self.real.clone() * divisor.real.clone() + self.imag.clone() * divisor.imag.clone();
94 let imag = self.imag * divisor.real - self.real * divisor.imag;
95 Self::Output::new( real / denominator.clone(), imag / denominator )
96 }
97}
98
99impl<T: Number> Add<T> for Complex<T> {
100 type Output = Complex<T>;
101 fn add(self, plus: T) -> Self::Output {
104 Self::Output::new( self.real + plus, self.imag )
105 }
106}
107
108impl<T: Number> Sub<T> for Complex<T> {
109 type Output = Complex<T>;
110 fn sub(self, minus: T) -> Self::Output {
113 Self::Output::new( self.real - minus, self.imag )
114 }
115}
116
117impl<T: Clone + Number> Mul<T> for Complex<T> {
118 type Output = Complex<T>;
119 fn mul(self, scalar: T) -> Self::Output {
122 Self::Output::new( self.real * scalar.clone(), self.imag * scalar )
123 }
124}
125
126impl Mul<Complex<f64>> for f64 {
127 type Output = Complex<f64>;
128 #[inline]
130 fn mul(self, complex: Complex<f64>) -> Self::Output {
131 complex * self
132 }
133}
134
135impl<T: Clone + Number> Div<T> for Complex<T> {
136 type Output = Complex<T>;
137 fn div(self, scalar: T) -> Self::Output {
140 Self::Output::new( self.real / scalar.clone(), self.imag / scalar )
141 }
142}
143
144impl<T: Number> AddAssign for Complex<T> {
145 fn add_assign(&mut self, rhs: Self) {
148 self.real += rhs.real;
149 self.imag += rhs.imag;
150 }
151}
152
153impl<T: Number> SubAssign for Complex<T> {
154 fn sub_assign(&mut self, rhs: Self) {
157 self.real -= rhs.real;
158 self.imag -= rhs.imag;
159 }
160}
161
162impl<T: Clone + Number> MulAssign for Complex<T> {
163 fn mul_assign(&mut self, rhs: Self) {
166 let a = self.real.clone();
167
168 self.real *= rhs.real.clone();
169 self.real -= self.imag.clone() * rhs.imag.clone();
170
171 self.imag *= rhs.real;
172 self.imag += a * rhs.imag;
173 }
174}
175
176impl<T: Clone + Number> DivAssign for Complex<T> {
177 fn div_assign(&mut self, rhs: Self) {
180 let a = self.real.clone();
181 let denominator = rhs.real.clone() * rhs.real.clone() + rhs.imag.clone() * rhs.imag.clone();
182
183 self.real *= rhs.real.clone();
184 self.real += self.imag.clone() * rhs.imag.clone();
185 self.real /= denominator.clone();
186
187 self.imag *= rhs.real;
188 self.imag -= a * rhs.imag;
189 self.imag /= denominator;
190 }
191}
192
193impl<T: Number> AddAssign<T> for Complex<T> {
194 fn add_assign(&mut self, rhs: T) {
197 self.real += rhs;
198 }
199}
200
201impl<T: Number> SubAssign<T> for Complex<T> {
202 fn sub_assign(&mut self, rhs: T) {
205 self.real -= rhs;
206 }
207}
208
209impl<T: Clone + Number> MulAssign<T> for Complex<T> {
210 fn mul_assign(&mut self, rhs: T) {
213 self.real *= rhs.clone();
214 self.imag *= rhs;
215 }
216}
217
218impl<T: Clone + Number> DivAssign<T> for Complex<T> {
219 fn div_assign(&mut self, rhs: T) {
222 self.real /= rhs.clone();
223 self.imag /= rhs;
224 }
225}
226
227impl<T: Clone + Number> Zero for Complex<T> {
228 fn zero() -> Self {
230 Self::new(Zero::zero(), Zero::zero())
231 }
232}
233
234impl<T: Clone + Number> One for Complex<T> {
235 fn one() -> Self {
237 Self::new(One::one(), Zero::zero())
238 }
239}
240
241impl<T: Clone + Number> Tiny for Complex<T> {
242 fn tiny() -> Self {
244 Self::new(T::tiny(), T::tiny())
245 }
246}
247
248impl<T: Clone + Number> PartialEq for Complex<T> {
249 fn eq(&self, other: &Complex<T>) -> bool {
251 self.real == other.real && self.imag == other.imag
252 }
253}
254
255impl<T: Clone + Number + std::cmp::PartialOrd> PartialOrd for Complex<T> {
256 fn partial_cmp(&self, other: &Complex<T>) -> Option<Ordering> {
258 if self.real != other.real {
259 self.real.partial_cmp( &other.real )
260 } else {
261 self.imag.partial_cmp( &other.imag )
262 }
263 }
264}
265
266impl<T: Clone + Number> Complex<T> {
267 #[inline]
269 pub fn abs_sqr(&self) -> T {
270 self.real.clone() * self.real.clone() + self.imag.clone() * self.imag.clone()
271 }
272}
273
274impl Complex::<f64> {
275 #[inline]
277 pub fn abs(&self) -> f64 {
278 f64::sqrt( self.abs_sqr() )
279 }
280}
281
282impl Complex::<f64> {
283 #[inline]
285 pub fn arg(&self) -> f64 {
286 self.imag.atan2(self.real)
287 }
288}
289
290impl<T> fmt::Display for Complex<T> where
291 T: fmt::Display
292{
293 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
295 write!(f, "( {}, {} )", self.real, self.imag )
296 }
297}
298
299impl<T> fmt::Debug for Complex<T> where
300 T: fmt::Debug
301{
302 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
304 write!(f, "( {:?}, {:?} )", self.real, self.imag )
305 }
306}
307
308impl<T: Number + Clone> Number for Complex<T> {
309
310}
311
312impl Signed for Complex<f64> {
313 fn abs(&self) -> Self {
314 let real: f64 = self.abs();
316 let imag: f64 = 0.0;
317 Complex { real, imag }
318 }
319}
320
321impl Copy for Complex<f64> {
322
323}