opensrdk_linear_algebra/matrix/ge/operators/
div.rs

1use crate::matrix::ge::Matrix;
2use crate::number::{c64, Number};
3use rayon::prelude::*;
4use std::ops::{Div, DivAssign};
5
6fn div_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 div<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 Div<Matrix<$t>> for $t {
47            type Output = Matrix<$t>;
48
49            fn div(self, rhs: Matrix<$t>) -> Self::Output {
50                div_scalar(self, rhs)
51            }
52        }
53
54        impl Div<Matrix<$t>> for &$t {
55            type Output = Matrix<$t>;
56
57            fn div(self, rhs: Matrix<$t>) -> Self::Output {
58                div_scalar(*self, rhs)
59            }
60        }
61    }
62}
63
64impl_div_scalar! {f64}
65impl_div_scalar! {c64}
66
67// Matrix and Scalar
68
69impl<T> Div<T> for Matrix<T>
70where
71    T: Number,
72{
73    type Output = Matrix<T>;
74
75    fn div(self, rhs: T) -> Self::Output {
76        div_scalar(rhs, self)
77    }
78}
79
80impl<T> Div<&T> for Matrix<T>
81where
82    T: Number,
83{
84    type Output = Matrix<T>;
85
86    fn div(self, rhs: &T) -> Self::Output {
87        div_scalar(*rhs, self)
88    }
89}
90
91// Matrix and Matrix
92
93impl<T> Div<Matrix<T>> for Matrix<T>
94where
95    T: Number,
96{
97    type Output = Matrix<T>;
98
99    fn div(self, rhs: Matrix<T>) -> Self::Output {
100        div(self, &rhs)
101    }
102}
103
104impl<T> Div<&Matrix<T>> for Matrix<T>
105where
106    T: Number,
107{
108    type Output = Matrix<T>;
109
110    fn div(self, rhs: &Matrix<T>) -> Self::Output {
111        div(self, rhs)
112    }
113}
114
115impl<T> Div<Matrix<T>> for &Matrix<T>
116where
117    T: Number,
118{
119    type Output = Matrix<T>;
120
121    fn div(self, rhs: Matrix<T>) -> Self::Output {
122        div(rhs, self)
123    }
124}
125
126// DivAssign
127
128impl<T> DivAssign<Matrix<T>> for Matrix<T>
129where
130    T: Number,
131{
132    fn div_assign(&mut self, rhs: Matrix<T>) {
133        *self = self as &Self / rhs;
134    }
135}
136
137#[cfg(test)]
138mod tests {
139    use crate::*;
140
141    #[test]
142    fn it_works() {
143        let a = mat!(
144            1.0, 2.0;
145            3.0, 4.0
146        ) / 2.0;
147        assert_eq!(a[(0, 0)], 0.5);
148    }
149}