lc3_codec/common/
complex.rs

1use core::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
2pub type Scaler = f32;
3
4#[derive(Debug, Clone, Copy, Default)]
5pub struct Complex {
6    pub r: Scaler,
7    pub i: Scaler,
8}
9
10impl Complex {
11    pub fn new(r: Scaler, i: Scaler) -> Self {
12        Self { r, i }
13    }
14}
15
16impl Mul for Complex {
17    type Output = Complex;
18    fn mul(self, rhs: Complex) -> Self::Output {
19        Complex {
20            r: self.r * rhs.r - self.i * rhs.i,
21            i: self.r * rhs.i + self.i * rhs.r,
22        }
23    }
24}
25
26impl Add for Complex {
27    type Output = Complex;
28    fn add(self, rhs: Self) -> Self::Output {
29        Complex {
30            r: self.r + rhs.r,
31            i: self.i + rhs.i,
32        }
33    }
34}
35
36impl Sub for Complex {
37    type Output = Complex;
38    fn sub(self, rhs: Self) -> Self::Output {
39        Complex {
40            r: self.r - rhs.r,
41            i: self.i - rhs.i,
42        }
43    }
44}
45
46impl MulAssign<Scaler> for Complex {
47    fn mul_assign(&mut self, rhs: Scaler) {
48        self.r *= rhs;
49        self.i *= rhs;
50    }
51}
52
53impl AddAssign<Complex> for Complex {
54    fn add_assign(&mut self, rhs: Complex) {
55        self.r += rhs.r;
56        self.i += rhs.i;
57    }
58}
59impl SubAssign<Complex> for Complex {
60    fn sub_assign(&mut self, rhs: Complex) {
61        self.r -= rhs.r;
62        self.i -= rhs.i;
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    extern crate std;
69    use super::*;
70
71    #[test]
72    fn complex_arithmatic() {
73        let mut complex = Complex::new(2.0, 3.0);
74
75        // complex addition
76        complex += Complex::new(1., 2.);
77        assert_eq!(complex.r, 3.0);
78        assert_eq!(complex.i, 5.0);
79        complex = complex + Complex::new(1., 2.);
80        assert_eq!(complex.r, 4.0);
81        assert_eq!(complex.i, 7.0);
82
83        // complex subtraction
84        complex -= Complex::new(9.0, 15.0);
85        assert_eq!(complex.r, -5.0);
86        assert_eq!(complex.i, -8.0);
87        complex = complex - Complex::new(9.0, 15.0);
88        assert_eq!(complex.r, -14.0);
89        assert_eq!(complex.i, -23.0);
90
91        // complex multiplication
92        complex = complex * Complex::new(2.0, 4.0);
93        assert_eq!(complex.r, 64.0);
94        assert_eq!(complex.i, -102.0);
95
96        // scalar multiplication
97        complex *= 2.0;
98        assert_eq!(complex.r, 128.0);
99        assert_eq!(complex.i, -204.0);
100    }
101}