Как создать ndarray ::ArrayView с пользовательскими шагами?

#multidimensional-array #rust

#многомерный массив #Ржавчина

Вопрос:

Я сталкиваюсь с фрагментом чисел и хочу создать ndarray::ArrayView из этого фрагмента (без копирования). В ArrayView я хочу включить 2 числа, затем пропустить одно и так далее. Например:

 use ndarray::{ArrayView1, ShapeBuilder};

let numbers = amp;[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]
 

Есть ли какой-либо способ установить shape достижение желаемого результата?
Обычные шаги не работали, потому что они используют фиксированный размер шага.

Я также пытался создать 2x3 ArrayView2 out of numbers , затем разделить последний столбец, а затем сгладить массив, но это невозможно сделать без копирования, потому что разделение нарушает компоновку памяти.

Я надеюсь, что возможно выполнить то, что я пытаюсь сделать.

Комментарии:

1. Я думаю, что для каждого измерения есть только один шаг, поэтому вам нужно будет использовать ArrayView2, как вы сказали.

2. @nnnmmm как я уже сказал, я не смог получить ArrayView1 из ArrayView2 без копирования

3. Я знаю, просто подтверждая, что если вам нужен ArrayView1, вам не повезло.

4. Так что мне, вероятно, не повезло, проект не позволяет мне так легко менять архитектуру

5. Вам действительно нужно работать с шагами? Если вам нужно взять только два, пропустить один и так далее, то вам, вероятно, лучше использовать итераторы. Самое классное в Rust то, что все действительно оптимизировано по производительности, и вам, вероятно, не стоит беспокоиться о копировании слишком много. Кроме того, даже если вам удалось сделать то, что вы хотите, вам, скорее всего, придется работать со ссылками на числа с плавающей запятой, что стоит столько же, сколько их копирование в new vec, так что да…

Ответ №1:

ArrayView1 является псевдонимом типа для ArrayBase . Определение для ArrayBase:

 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 по сути, это список, поэтому ArrayBase в нем хранится список измерений и список шагов. Для ArrayView1 D в основном заканчивается как [usize; 1] , поэтому вы можете хранить только одну длину и шаг.

Чтобы ответить на ваш вопрос, к сожалению, то, о чем вы просите, невозможно ArrayView1 , ему не хватает места для хранения нескольких шагов.