pixelator_core/common/
linalg.rs1use 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}