array_matrix/matrix/
mul.rs

1use std::ops::{Mul, Add};
2
3use crate::{matrix_init, Matrix};
4
5pub trait MMul<Rhs>: Matrix
6where
7    Self::Output: Matrix
8{
9    type Output;
10    
11    /// Returns the matrix product
12    /// 
13    /// AB
14    /// 
15    /// # Arguments
16    /// 
17    /// * `rhs` - A scalar or a matrix with height equal this matrix's length
18    /// 
19    /// # Examples
20    /// 
21    /// ```rust
22    /// // Scaling
23    /// let a = [
24    ///     [1.0, 2.0],
25    ///     [3.0, 4.0]
26    /// ];
27    /// let b = 2.0;
28    /// let ab = [
29    ///     [2.0, 4.0],
30    ///     [6.0, 8.0]
31    /// ];
32    /// assert_eq!(a.mul(b), ab)
33    /// 
34    /// // Matrix multiplication
35    /// let a = [
36    ///     [1.0],
37    ///     [2.0],
38    ///     [3.0]
39    /// ];
40    /// let b = [
41    ///     [1.0, 2.0, 3.0]
42    /// ];
43    /// let ab = [
44    ///     [1.0, 2.0, 3.0],
45    ///     [2.0, 4.0, 6.0],
46    ///     [3.0, 6.0, 9.0]
47    /// ];
48    /// assert_eq!(a.mul(b), ab)
49    /// ```
50    fn mul(self, rhs: Rhs) -> Self::Output;
51}
52
53impl<F, const L: usize, const H: usize> MMul<F> for [[F; L]; H]
54where
55    Self: Matrix,
56    [[<F as Mul<F>>::Output; L]; H]: Matrix,
57    F: Clone + Mul<F>
58{
59    type Output = [[<F as Mul<F>>::Output; L]; H];
60    fn mul(self, rhs: F) -> Self::Output
61    {
62        matrix_init(|r, c| self[r][c].clone()*rhs.clone())
63    }
64}
65
66impl<F, const L: usize, const H1: usize, const H2: usize> MMul<[[F; H2]; L]>
67for
68    [[F; L]; H1]
69where
70    Self: Matrix,
71    [[<F as Mul<F>>::Output; H2]; H1]: Matrix,
72    F: Clone + Mul<F>,
73    <F as Mul<F>>::Output: Add<<F as Mul<F>>::Output, Output = <F as Mul<F>>::Output>
74{
75    type Output = [[<F as Mul<F>>::Output; H2]; H1];
76    fn mul(self, rhs: [[F; H2]; L]) -> Self::Output
77    {
78        matrix_init(|r, c| (0..L).map(|i| self[r][i].clone()*rhs[i][c].clone()).reduce(|a, b| a + b).unwrap())
79    }
80}