pixelator_core/common/
linalg.rs

1use ndarray::Array1;
2use ndarray::Array2;
3
4use sprs::CsMat;
5
6pub fn outer(a: &Array1<f64>, b: &Array1<f64>) -> Array2<f64> {
7    let dima = a.shape()[0];
8    let dimb = b.shape()[0];
9    let mut out = Array2::zeros((dima, dimb));
10
11    for i in 0..dima {
12        for j in 0..dimb {
13            out[[i, j]] = a[i] * b[j];
14        }
15    }
16
17    out
18}
19
20pub fn trace(matrix: CsMat<f64>) -> f64 {
21    matrix.diag().iter().map(|(_, x)| *x).sum()
22}
23
24#[cfg(test)]
25mod tests {
26    use super::*;
27
28    #[test]
29    fn test_outer_basic() {
30        let a = Array1::from(vec![1.0, 2.0, 3.0]);
31        let b = Array1::from(vec![4.0, 5.0]);
32        let result = outer(&a, &b);
33        let expected =
34            Array2::from_shape_vec((3, 2), vec![4.0, 5.0, 8.0, 10.0, 12.0, 15.0]).unwrap();
35        assert_eq!(result, expected);
36    }
37
38    #[test]
39    fn test_outer_with_zeros() {
40        let a = Array1::from(vec![0.0, 2.0]);
41        let b = Array1::from(vec![0.0, 5.0]);
42        let result = outer(&a, &b);
43        let expected = Array2::from_shape_vec((2, 2), vec![0.0, 0.0, 0.0, 10.0]).unwrap();
44        assert_eq!(result, expected);
45    }
46
47    #[test]
48    fn test_outer_single_element() {
49        let a = Array1::from(vec![7.0]);
50        let b = Array1::from(vec![3.0]);
51        let result = outer(&a, &b);
52        let expected = Array2::from_shape_vec((1, 1), vec![21.0]).unwrap();
53        assert_eq!(result, expected);
54    }
55}