How to create multiple slices or views of the same array

I would like to create two slices or views from one ndarray array. Later on I would like to use those slices or views in a Zip function. However, my minimal example of this idea fails. What am I doing wrong? Do I have to use array views here or explicitly copy the values? What is a correct way to do it?

extern crate ndarray;

use ndarray::{Array1, s};

fn main() {

    const N: usize = 10;

    let mut a  = Array1::<f32>::zeros(N);
    let mut v1 = a.slice_mut(s![..N/2]);
    let     v2 = a.slice    (s![N/2..]);

    dbg!(a);
    dbg!(v1);
    dbg!(v2);
}
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
  --> src/main.rs:11:18
   |
10 |     let mut v1 = a.slice_mut(s![..N/2]);
   |                  ---------------------- mutable borrow occurs here
11 |     let     v2 = a.slice    (s![N/2..]);
   |                  ^^^^^^^^^^^^^^^^^^^^^^ immutable borrow occurs here
...
14 |     dbg!(v1);
   |          -- mutable borrow later used here

error[E0505]: cannot move out of `a` because it is borrowed
  --> src/main.rs:13:5
   |
9  |     let mut a  = Array1::<f32>::zeros(N);
   |         ----- binding `a` declared here
10 |     let mut v1 = a.slice_mut(s![..N/2]);
   |                  ---------------------- borrow of `a` occurs here
...
13 |     dbg!(a);
   |     ^^^^^^^ move out of `a` occurs here
14 |     dbg!(v1);
   |          -- borrow later used here
   |

I'm not sure about ndarray, but with ordinary Rust slices you can do this with split_at_mut(N/2).

2 Likes

I’m not super familiar with ndarray, but I just spotted promising methods called “multi_slice_mut” and “multi_slice_move”.

Edit: An ArrayViewMut also has a split_at!

2 Likes

Thank you! I will look into multi_slice_mut methods. I'm not as much interested in a split. It was just a convenient demo example. In reality I need to create two 2D views/slices of one and the same 3D array. Then I would like to use those views in a Zip function.

This is my attempt to use the multi_slice_mut method:

extern crate ndarray;

use ndarray::{Array1, s};

fn main() {

    const N: usize = 10;

    let mut a = Array1::<f32>::zeros(N);

    let (v1, v2) = a.multi_slice_mut( (s![..N/2], s![N/2..]) );

    dbg!(v1);
    dbg!(v2);
}
-->
[src/main.rs:13] v1 = [0.0, 0.0, 0.0, 0.0, 0.0], shape=[5], strides=[1], layout=CFcf (0xf), const ndim=1
[src/main.rs:14] v2 = [0.0, 0.0, 0.0, 0.0, 0.0], shape=[5], strides=[1], layout=CFcf (0xf), const ndim=1

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.