color_art/utils/
math.rs

1pub type Matrix = Vec<Vec<f64>>;
2
3/// <https://www.w3.org/TR/css-color-4/multiply-matrices.js>
4///
5/// a is m x n. b is n x p. product is m x p.
6///
7/// a:
8/// ```bash
9/// | 1, 2, 3 |
10/// | 4, 5, 6 |
11/// | 7, 8, 9 |
12/// ```
13/// b:
14/// ```bash
15/// | 1 |
16/// | 2 |
17/// | 3 |
18/// ```
19/// product:
20/// ```bash
21/// | 14 |
22/// | 32 |
23/// | 50 |
24/// ```
25pub fn multiply_matrices(a: Matrix, b: Matrix) -> Matrix {
26    // TODO: check if a and b are valid matrices
27    (0..a.len())
28        .map(|i| {
29            (0..b[i].len()).fold(Vec::with_capacity(b[i].len()), |mut acc, j| {
30                acc.push(
31                    (0..a[i].len())
32                        .map(|k| a[i][k] * b[k][j])
33                        .fold(0.0, |acc, x| acc + x),
34                );
35                acc
36            })
37        })
38        .collect()
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn test_multiply_matrices() {
47        let a = vec![vec![1.0, 2.0, 3.0]; 3];
48        let b = vec![vec![1.0], vec![2.0], vec![3.0]];
49        let c = multiply_matrices(a, b);
50        assert_eq!(c, vec![vec![14.0], vec![14.0], vec![14.0]]);
51    }
52}