Search code examples
rustmultidimensional-array

ndarray add to a part of an array


I am trying to add to a part of an ndarray, however, my current approach:

fn test() {
    let a = nd::array![
        [ 1, 2, 3 ],
        [ 4, 5, 6 ],
    ];
    let b = nd::array![
        [ 3, 2, 1], 
        [ 6, 5, 4],
    ];

    println!("{}", a.slice_mut(nd::s![0, ..]) + b.slice(nd::s![0, ..]));

    // desired outcome 
    // a = [
    //     [ 4, 4, 4 ],
    //     [ 6, 5, 4 ],
    // ];
}

This doesn't compile:

error[E0369]: cannot add `ArrayBase<ViewRepr<&{integer}>, _>` to `ArrayBase<ViewRepr<&mut {integer}>, _>`
  --> src/main.rs:27:49
   |
27 |     println!("{:?}", a.slice_mut(nd::s![0, ..]) + b.slice(nd::s![0, ..]))
   |                      -------------------------- ^ ---------------------- ArrayBase<ViewRepr<&{integer}>, _>
   |                      |
   |                      ArrayBase<ViewRepr<&mut {integer}>, _>

For more information about this error, try `rustc --explain E0369`.

How can I do what I'm trying to do here?


Solution

  • As far as I can tell, you can't use + to update a mutable view. But you can use += on them.

    let mut slice = a.slice_mut(nd::s![0, ..]);
    slice += &b.slice(nd::s![0, ..]);
    println!("{}", slice); // [4, 4, 4]
    

    If you don't need slice, it can be written in one line:

    *&mut a.slice_mut(nd::s![0, ..]) += &b.slice(nd::s![0, ..]);
    

    Then the original array will be as you expect.

    println!("{}", a);
    // [[4, 4, 4],
    //  [4, 5, 6]]