Multiply an ndarray Array by a view

It seems straightforward -- I want to multiply a view elementwise by an array of the same dimensions, and return an array. It ain't working.

I'm trying to avoid doing this with iterators and map(), if possible.

#![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);
}

(Playground)

Errors:

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

error: aborting due to previous error

For more information about this error, try `rustc --explain E0369`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

How about you just swap the order of ralph.index_axis(Axis(1), 0) and bob?

OK. I'm very slightly offended at Rust that swapping the order makes a difference.

But that sense of outrage is completely subsumed at my joy that this is straightened out. (And why didn't I think of trying that?).

For the curious: this is the new version

I believe the problem is that the left hand side array is not owned, but ndarray requires it to be owned.

It’s less Rust’s fault and more the responsibility of the ndarray crate. I feel like there might be a convention in that crate that the first argument to multiplication has to be owned; but I really don’t know the crate very well. Further test seems to indicate that e.g. both arguments being views or references doesn’t work either and you’d probably have to add something like an into_owned or to_owned call on the first argument if you were to get into such a scenario.

Edit: Currently staring at this implementation I’m doubting if there is such a convention after all...

Edit2: Division doesn’t work either, and that’s not even commutative. Also, if you borrow both arguments it works again, of course this can lead to unnecessary extra allocations. Maybe there’s potential for improvind ndarray here after all. Maybe this kind of improvement is prevented by overlapping implementations though.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.