rust_linear_algebra/matrix/ops/
mul.rs

1use super::super::Matrix;
2use crate::vector::Vector;
3use std::ops::Add;
4use std::ops::Mul;
5
6impl<K, T> Mul<T> for Matrix<K>
7where
8    K: Mul<T, Output = K> + Copy + Default,
9    T: Copy,
10{
11    type Output = Matrix<K>;
12
13    fn mul(self, rhs: T) -> Self::Output {
14        let mut elements = vec![vec![K::default(); self.cols()]; self.rows()];
15
16        for i in 0..self.rows() {
17            for j in 0..self.cols() {
18                elements[i][j] = self.elements[i][j] * rhs;
19            }
20        }
21
22        Matrix { elements }
23    }
24}
25
26impl<K> Mul<Vector<K>> for Matrix<K>
27where
28    K: Copy + Default + Add<Output = K> + Mul<Output = K>,
29{
30    type Output = Vector<K>;
31
32    fn mul(self, rhs: Vector<K>) -> Self::Output {
33        if self.elements.is_empty() || rhs.elements.is_empty() {
34            panic!("Matrix or vector is empty. Cannot perform multiplication.");
35        }
36        if self.cols() != rhs.len() {
37            panic!(
38                "Incompatible dimensions for matrix-vector multiplication. \
39                Matrix has {} columns, but vector has {} elements.",
40                self.cols(),
41                rhs.len()
42            );
43        }
44
45        let mut elements = vec![K::default(); self.rows()];
46
47        for i in 0..self.rows() {
48            for j in 0..self.cols() {
49                elements[i] = elements[i] + self.elements[i][j] * rhs.elements[j];
50            }
51        }
52
53        Vector { elements }
54    }
55}
56
57impl<K> Mul for Matrix<K>
58where
59    K: Mul<Output = K> + Add<Output = K> + Copy + Default,
60{
61    type Output = Matrix<K>;
62
63    fn mul(self, rhs: Self) -> Self::Output {
64        if self.elements.is_empty() || rhs.elements.is_empty() {
65            panic!("One of the matrices is empty. Cannot perform multiplication.");
66        }
67        if self.cols() != rhs.rows() {
68            panic!(
69                "Incompatible dimensions for matrix multiplication. \
70                Left matrix has {} columns, but right matrix has {} rows.",
71                self.cols(),
72                rhs.rows()
73            );
74        }
75
76        let mut elements = vec![vec![K::default(); rhs.cols()]; self.rows()];
77
78        for i in 0..self.rows() {
79            for j in 0..rhs.cols() {
80                for k in 0..self.cols() {
81                    elements[i][j] = elements[i][j] + (self.elements[i][k] * rhs.elements[k][j]);
82                }
83            }
84        }
85
86        Matrix { elements }
87    }
88}
89
90impl<K> Matrix<K>
91where
92    K: Mul<Output = K> + Copy,
93{
94    pub fn scl(&mut self, a: K) {
95        self.iter_mut()
96            .for_each(|row| row.iter_mut().for_each(|v| *v = *v * a));
97    }
98}
99
100impl<K> Matrix<K>
101where
102    K: Mul<Output = K> + Add<Output = K> + Copy + Default,
103{
104    pub fn mul_mat(&self, mat: Matrix<K>) -> Matrix<K> {
105        self.clone() * mat
106    }
107    pub fn mul_vec(&self, vec: Vector<K>) -> Vector<K> {
108        self.clone() * vec
109    }
110}