Yannick Funk
Yannick Funk

Reputation: 1581

How to create ndarray::ArrayView with custom strides?

I am facing a slice of numbers and want to create an ndarray::ArrayView out of this slice (without copying). In the ArrayView, I want to include 2 numbers, then skip one, and so on. For example:

use ndarray::{ArrayView1, ShapeBuilder};

let numbers = &[0.0, 1.0, 10.0, 2.0, 3.0, 10.0];
let shape = // Some shape
let view = ArrayView1::from_shape(shape, numbers);

// Expected output for `view`:
// [0.0, 1.0, 2.0, 3.0]

Is there any way to set shape reaching the desired output? Normal strides didn't work because they use a fix step size.

I also tried creating a 2x3 ArrayView2 out of numbers, then splitting the last column, and then flattening the array, but this cannot be done without copying because splitting breaks the memory layout.

I hope that it's possible to accomplish what I am trying to do.

Upvotes: 4

Views: 661

Answers (1)

Coder-256
Coder-256

Reputation: 5618

ArrayView1 is a type alias for ArrayBase. The definition for ArrayBase is:

pub struct ArrayBase<S, D>
where
    S: RawData,
{
    /// Data buffer / ownership information. (If owned, contains the data
    /// buffer; if borrowed, contains the lifetime and mutability.)
    data: S,
    /// A non-null pointer into the buffer held by `data`; may point anywhere
    /// in its range. If `S: Data`, this pointer must be aligned.
    ptr: std::ptr::NonNull<S::Elem>,
    /// The lengths of the axes.
    dim: D,
    /// The element count stride per axis. To be parsed as `isize`.
    strides: D,
}

D is essentially a list, so ArrayBase stores a list of dimensions and a list of strides. For ArrayView1, D basically ends up as [usize; 1], so you can only store a single length and stride.

To answer your question, sadly what you are asking for is not possible with ArrayView1, it lacks the storage space to hold multiple strides.

Upvotes: 1

Related Questions