opensrdk_linear_algebra/matrix/ge/operators/
sub.rs

1use crate::matrix::ge::Matrix;
2use crate::number::{c64, Number};
3use rayon::prelude::*;
4use std::ops::{Sub, SubAssign};
5
6fn sub_scalar<T>(lhs: T, rhs: Matrix<T>) -> Matrix<T>
7where
8    T: Number,
9{
10    let mut rhs = rhs;
11
12    rhs.elems
13        .par_iter_mut()
14        .map(|r| {
15            *r -= lhs;
16        })
17        .collect::<Vec<_>>();
18
19    rhs
20}
21
22fn sub<T>(lhs: Matrix<T>, rhs: &Matrix<T>) -> Matrix<T>
23where
24    T: Number,
25{
26    if !lhs.is_same_size(rhs) {
27        panic!("Dimension mismatch.")
28    }
29    let mut lhs = lhs;
30
31    lhs.elems
32        .par_iter_mut()
33        .zip(rhs.elems.par_iter())
34        .map(|(l, &r)| {
35            *l -= r;
36        })
37        .collect::<Vec<_>>();
38
39    lhs
40}
41
42// Scalar and Matrix
43
44macro_rules! impl_div_scalar {
45    {$t: ty} => {
46        impl Sub<Matrix<$t>> for $t {
47            type Output = Matrix<$t>;
48
49            fn sub(self, rhs: Matrix<$t>) -> Self::Output {
50                sub_scalar(self, rhs)
51            }
52        }
53
54        impl Sub<Matrix<$t>> for &$t {
55            type Output = Matrix<$t>;
56
57            fn sub(self, rhs: Matrix<$t>) -> Self::Output {
58                sub_scalar(*self, rhs)
59            }
60        }
61    }
62}
63
64impl_div_scalar! {f64}
65impl_div_scalar! {c64}
66
67// Matrix and Scalar
68
69impl<T> Sub<T> for Matrix<T>
70where
71    T: Number,
72{
73    type Output = Matrix<T>;
74
75    fn sub(self, rhs: T) -> Self::Output {
76        -sub_scalar(rhs, self)
77    }
78}
79
80impl<T> Sub<&T> for Matrix<T>
81where
82    T: Number,
83{
84    type Output = Matrix<T>;
85
86    fn sub(self, rhs: &T) -> Self::Output {
87        -sub_scalar(*rhs, self)
88    }
89}
90
91// Matrix and Matrix
92
93impl<T> Sub<Matrix<T>> for Matrix<T>
94where
95    T: Number,
96{
97    type Output = Matrix<T>;
98
99    fn sub(self, rhs: Matrix<T>) -> Self::Output {
100        sub(self, &rhs)
101    }
102}
103
104impl<T> Sub<&Matrix<T>> for Matrix<T>
105where
106    T: Number,
107{
108    type Output = Matrix<T>;
109
110    fn sub(self, rhs: &Matrix<T>) -> Self::Output {
111        sub(self, rhs)
112    }
113}
114
115impl<T> Sub<Matrix<T>> for &Matrix<T>
116where
117    T: Number,
118{
119    type Output = Matrix<T>;
120
121    fn sub(self, rhs: Matrix<T>) -> Self::Output {
122        -sub(rhs, self)
123    }
124}
125
126// SubAssign
127
128impl<T> SubAssign<Matrix<T>> for Matrix<T>
129where
130    T: Number,
131{
132    fn sub_assign(&mut self, rhs: Matrix<T>) {
133        *self = self as &Self - rhs;
134    }
135}
136
137#[cfg(test)]
138mod tests {
139    use crate::*;
140    #[test]
141    fn it_works() {
142        let a = mat!(
143            5.0, 6.0;
144            7.0, 8.0
145        ) - mat!(
146            1.0, 3.0;
147            5.0, 7.0
148        );
149        assert_eq!(a[(0, 0)], 4.0);
150        assert_eq!(a[(0, 1)], 3.0);
151        assert_eq!(a[(1, 0)], 2.0);
152        assert_eq!(a[(1, 1)], 1.0);
153    }
154}