opensrdk_linear_algebra/matrix/ge/operators/
mul.rs1use crate::matrix::ge::Matrix;
2use crate::number::{c64, Number};
3use rayon::prelude::*;
4use std::ops::{Mul, MulAssign};
5
6fn mul_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 mul<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 Mul<Matrix<$t>> for $t {
47 type Output = Matrix<$t>;
48
49 fn mul(self, rhs: Matrix<$t>) -> Self::Output {
50 mul_scalar(self, rhs)
51 }
52 }
53
54 impl Mul<Matrix<$t>> for &$t {
55 type Output = Matrix<$t>;
56
57 fn mul(self, rhs: Matrix<$t>) -> Self::Output {
58 mul_scalar(*self, rhs)
59 }
60 }
61 }
62}
63
64impl_div_scalar! {f64}
65impl_div_scalar! {c64}
66
67impl<T> Mul<T> for Matrix<T>
70where
71 T: Number,
72{
73 type Output = Matrix<T>;
74
75 fn mul(self, rhs: T) -> Self::Output {
76 mul_scalar(rhs, self)
77 }
78}
79
80impl<T> Mul<&T> for Matrix<T>
81where
82 T: Number,
83{
84 type Output = Matrix<T>;
85
86 fn mul(self, rhs: &T) -> Self::Output {
87 mul_scalar(*rhs, self)
88 }
89}
90
91impl<T> Mul<Matrix<T>> for Matrix<T>
94where
95 T: Number,
96{
97 type Output = Matrix<T>;
98
99 fn mul(self, rhs: Matrix<T>) -> Self::Output {
100 mul(self, &rhs)
101 }
102}
103
104impl<T> Mul<&Matrix<T>> for Matrix<T>
105where
106 T: Number,
107{
108 type Output = Matrix<T>;
109
110 fn mul(self, rhs: &Matrix<T>) -> Self::Output {
111 mul(self, rhs)
112 }
113}
114
115impl<T> Mul<Matrix<T>> for &Matrix<T>
116where
117 T: Number,
118{
119 type Output = Matrix<T>;
120
121 fn mul(self, rhs: Matrix<T>) -> Self::Output {
122 mul(rhs, self)
123 }
124}
125
126impl<T> MulAssign<Matrix<T>> for Matrix<T>
129where
130 T: Number,
131{
132 fn mul_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)], 2.0);
148 }
149}