fetish_lib/
linalg_utils.rs

1extern crate ndarray;
2extern crate ndarray_linalg;
3
4use ndarray::*;
5use ndarray_linalg::*;
6
7use std::ops::MulAssign;
8
9///Computes the squared Euclidean distance between two vectors
10pub fn sq_vec_dist(one : ArrayView1<f32>, two : ArrayView1<f32>) -> f32 {
11    let diff = &one - &two;
12    diff.dot(&diff)
13}
14
15///Computes the outer product `ab^T` of vectors `a` and `b`.
16pub fn outer(a : ArrayView1<f32>, b : ArrayView1<f32>) -> Array2<f32> {
17    let a_column = into_col(a.clone());
18    let b_row = into_row(b.clone());
19    a_column.dot(&b_row)
20}
21
22///Computes the Frobenius inner product of two matrices, which
23///is the same as computing the dot product of the vectorized matrices.
24pub fn frob_inner(a : ArrayView2<f32>, b : ArrayView2<f32>) -> f32 {
25    let flat_a = flatten(a.clone());
26    let flat_b = flatten(b.clone());
27    flat_a.dot(&flat_b)
28}
29
30///Scales the rows of `a` by the respective scaling factors in `b`. Useful
31///for efficiently computing left-multiplication by a diagonal matrix.
32pub fn scale_rows(a : ArrayView2<f32>, b : ArrayView1<f32>) -> Array2<f32> {
33    let mut result = a.to_owned();
34    let n = a.shape()[0];
35    for i in 0..n {
36        let scale = b[[i,]];
37        let mut row = result.row_mut(i);
38        row.mul_assign(scale);
39    }
40    result
41}
42///Computes the Kronecker product of matrices.
43pub fn kron(a: ArrayView2<f32>, b: ArrayView2<f32>) -> Array2<f32> {
44    //Pulled from: https://github.com/rust-ndarray/ndarray/issues/652
45    let dima = a.shape()[0];
46    let dimb = b.shape()[0];
47    let dimout = dima * dimb;
48    let mut out = Array2::zeros((dimout, dimout));
49    for (mut chunk, elem) in out.exact_chunks_mut((dimb, dimb)).into_iter().zip(a.iter()) {
50        chunk.assign(&(*elem * &b));
51    }
52    out
53}
54