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}