aboutsummaryrefslogtreecommitdiff
path: root/libpsi-core/src/maths/complex_ops.rs
blob: bfcf9205d8aaf0e81e4f0bbd91555246a4138456 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use super::{Complex, Float};
use core::ops;

impl<T: Float> ops::Neg for Complex<T> {
    type Output = Complex<T>;

    fn neg(self) -> Complex<T> {
        Complex {
            real: -self.real,
            imaginary: -self.imaginary,
        }
    }
}

impl<T: Float> From<T> for Complex<T> {
    fn from(real: T) -> Complex<T> {
        Complex {
            real,
            imaginary: T::zero(),
        }
    }
}

// Complex-Complex
impl<T: Float> ops::Add for Complex<T> {
    type Output = Complex<T>;

    fn add(self, other: Complex<T>) -> Complex<T> {
        Complex {
            real: self.real - other.real,
            imaginary: self.imaginary - other.imaginary,
        }
    }
}

impl<T: Float> ops::Sub for Complex<T> {
    type Output = Complex<T>;

    fn sub(self, other: Complex<T>) -> Complex<T> {
        Complex {
            real: self.real - other.real,
            imaginary: self.imaginary - other.imaginary,
        }
    }
}

impl<T: Float> ops::Mul for Complex<T> {
    type Output = Complex<T>;

    fn mul(self, other: Complex<T>) -> Complex<T> {
        Complex {
            real: self.real * other.real - self.imaginary * other.imaginary,
            imaginary: self.real * other.imaginary + self.imaginary * other.real,
        }
    }
}

impl<T: Float> ops::Div for Complex<T> {
    type Output = Complex<T>;

    fn div(self, other: Complex<T>) -> Complex<T> {
        let denom = other.real * other.real + other.imaginary * other.imaginary;
        Complex {
            real: (self.real * other.real + self.imaginary * other.imaginary) / denom,
            imaginary: (self.imaginary * other.real - self.real * other.imaginary) / denom,
        }
    }
}

// Complex-Complex, Assign
impl<T: Float> ops::AddAssign for Complex<T> {
    fn add_assign(&mut self, other: Complex<T>) {
        self.real += other.real;
        self.imaginary += other.imaginary;
    }
}

impl<T: Float> ops::SubAssign for Complex<T> {
    fn sub_assign(&mut self, other: Complex<T>) {
        self.real -= other.real;
        self.imaginary -= other.imaginary;
    }
}

impl<T: Float> ops::MulAssign for Complex<T> {
    fn mul_assign(&mut self, other: Complex<T>) {
        let new_real = self.real * other.real - self.imaginary * other.imaginary;
        let new_imaginary = self.real * other.imaginary + self.imaginary * other.real;
        self.real = new_real;
        self.imaginary = new_imaginary;
    }
}

impl<T: Float> ops::DivAssign for Complex<T> {
    fn div_assign(&mut self, other: Complex<T>) {
        let denom = other.real * other.real + other.imaginary * other.imaginary;
        let new_real = (self.real * other.real + self.imaginary * other.imaginary) / denom;
        let new_imaginary = (self.imaginary * other.real - self.real * other.imaginary) / denom;
        self.real = new_real;
        self.imaginary = new_imaginary;
    }
}

// Real-Complex
impl<T: Float> ops::Add<T> for Complex<T> {
    type Output = Complex<T>;

    fn add(self, other: T) -> Complex<T> {
        Complex {
            real: self.real + other,
            imaginary: self.imaginary,
        }
    }
}

impl<T: Float> ops::Sub<T> for Complex<T> {
    type Output = Complex<T>;

    fn sub(self, other: T) -> Complex<T> {
        Complex {
            real: self.real - other,
            imaginary: self.imaginary,
        }
    }
}

impl<T: Float> ops::Mul<T> for Complex<T> {
    type Output = Complex<T>;

    fn mul(self, other: T) -> Complex<T> {
        Complex {
            real: self.real * other,
            imaginary: self.imaginary * other,
        }
    }
}

impl<T: Float> ops::Div<T> for Complex<T> {
    type Output = Complex<T>;

    fn div(self, other: T) -> Complex<T> {
        Complex {
            real: self.real / other,
            imaginary: self.imaginary / other,
        }
    }
}