How to multiply matrix by a view with ndarray?

Viewed 273

Using ndarray. This playground snippet says it all -- I want to multiply a matrix view element-wise with a matrix, and I can't figure out a combination of views and casts and whatnot that'll make it work.

#![allow(unused)]

use ndarray::{Array1, Array2, Axis};

fn main () {
    let bob = Array1::from(vec![1.2, 3.3, 4.]);
    let ralph = Array2::from(vec![[3.3, 1.0, -2.0],[4., 5., 8.], [-9., 2., 1.]]);
    println!("{:?}", ralph.index_axis(Axis(1), 0) * bob);
}

On compilation gives the error:

error[E0369]: cannot multiply `ArrayBase<ViewRepr<&{float}>, Dim<[usize; 1]>>` by `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
 --> src/lib.rs:8:51
  |
8 |     println!("{:?}", ralph.index_axis(Axis(1), 0) * bob);
  |                      ---------------------------- ^ --- ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>
  |                      |
  |                      ArrayBase<ViewRepr<&{float}>, Dim<[usize; 1]>>

Is there a magic finger-ring combination that'll make it do what I want, or do I need to do it by hand?

2 Answers

Adding a & to both elements of the multiplication will prevent either value from being consumed in the process of multiplication:

&ralph.index_axis(Axis(1), 0) * &bob

The following link from the ndarray docs explains allocating a new array vs consuming the array during binary operations: https://docs.rs/ndarray/0.14.0/ndarray/struct.ArrayBase.html#binary-operators-with-two-arrays

I think because the result of index_axis() is a view into another array, it can't be consumed safely, hence the error

Swapping the order of the operations also fixes it:

#![allow(unused)]

use ndarray::{Array1, Array2, Axis};

fn main () {
    let bob = Array1::from(vec![1.2, 3.3, 4.]);
    let ralph = Array2::from(vec![[3.3, 1.0, -2.0],[4., 5., 8.], [-9., 2., 1.]]);
    println!("{:?}", bob * ralph.index_axis(Axis(1), 0));
}
Related