2

I have a 3-dimensional array Array3 of the ndarray crate, and I would like to pass a slice of it as an array (&[T]) to a function, but can't figure out how. I found slice() and as_slice() methods, among similar others, but they require the data to be contiguous, or they return None instead. For instance, something like this:

fn foo<T>(a: &[T], b: &mut [T]) {
    // do stuff
}

fn main() {

    let a = array![
        [
            [1.55, 0.0, 0.45, 0.0, 0.25], 
            [1.0, 0.55, 0.45, 0.0, 0.25], 
            [1.0, 0.55, 0.0, 0.0, 0.25],
        ],
        [
            [1.0, 0.0, 0.45, 0.65, 0.25], 
            [1.0, 0.55, 0.45, 0.65, 0.25], 
            [1.0, 0.55, 0.0, 0.65, 0.25],
        ],
        [
            [1.0, 0.0, 0.45, 0.65, 0.0], 
            [1.0, 0.55, 0.45, 0.65, 0.0], 
            [1.45, 0.55, 0.0, 0.65, 0.0],
        ],
    ];

    let mut b = array![
        [1.0, 0.0, 0.0],
        [1.0, 0.0, 0.0],
        [1.0, 0.0, 0.0],
    ];

    foo(
        a.slice(s![.., 0, 0]).as_slice().unwrap(), 
        b.slice_mut(s![.., 0]).as_slice_mut().unwrap(),
    );
}

How can I pass these slices in order to treat them as an array and mutable array? From the documentation, I am having difficulty finding out.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • To be clear here, is your issue that you can't take a mutable and immutable reference to the same thing simultaneously, or that you the slice methods don't allow capturing the data you like in the order you like? More succinctly, what precisely is the error you're facing here? – naiveai Nov 23 '22 at 16:15
  • @naiveai, the error I get is "panicked at 'called `Option::unwrap()` on a `None` value'". I guess that when I do slice I am getting None since data is not contiguous as described in the documentation (it says: "Return the array’s data as a slice, if it is contiguous and in standard order. Return None otherwise."). – Sergio Cavaleiro Costa Nov 23 '22 at 16:32
  • 2
    A slice *has* to be contiguous in memory. It's impossible to construct a slice of non-contiguous elements without copying the data to a new location, which is expensive and requires allocation. `as_slice` won't do it automatically since `as_` methods are supposed to be low- or zero-cost conversions. – John Kugelman Nov 23 '22 at 16:32
  • You might want to pass a slice of references instead. – cafce25 Nov 23 '22 at 18:34
  • *but they require the data to be contiguous* - just to clarify, that's not a whim of those functions. Slices are contiguous **by definition**. – user4815162342 Nov 23 '22 at 21:52
  • @user4815162342, Isn't the data of the array that must be contiguous so it can return the slice? If the slice is contiguous, why is this returning None? I'm confused! – Sergio Cavaleiro Costa Nov 24 '22 at 07:00
  • @cafce25, I don't understand what you mean. Are you saying to pass `&a.slice...`? – Sergio Cavaleiro Costa Nov 24 '22 at 07:01
  • I mean you want `&[&T]` or `&mut [&mut T]` if your type is not copy or you need to mutate inplace. – cafce25 Nov 24 '22 at 07:22

0 Answers0