opensrdk_linear_algebra/matrix/ge/operators/
sub.rs1use 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
42macro_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
67impl<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
91impl<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
126impl<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}