Skip to content

Calling slice on a dynamic size array #501

Closed

Description

@kali

Hey folks,

I'm struggling to find a way to call slice() on a dynamic ranked array, and can find a way to make it work.

extern crate ndarray;
use ndarray::*;

fn main() {
    let array: ArrayD<f32> = Array::zeros(vec![8, 8, 8]);
    foo(&array.view());
}

fn foo<'a>(a: &'a ArrayViewD<'a, f32>) -> ArrayViewD<'a, f32> {
    let slicer: Vec<SliceOrIndex> = (0..a.ndim())
        .map(|_| SliceOrIndex::Slice {
            start: 2,
            end: Some(6),
            step: 1,
        }).collect();
    let slice = SliceInfo::new(slicer).unwrap();
    a.slice(slice)
}

The gist of the issue is the type of the AsRef<[SliceOrIndex]> in (slicer in the example).

   |
13 |     a.slice(slice)
   |             ^^^^^ expected reference, found struct `ndarray::SliceInfo`
   |
   = note: expected type `&ndarray::SliceInfo<[ndarray::SliceOrIndex], ndarray::Dim<ndarray::IxDynImpl>>`
              found type `ndarray::SliceInfo<std::vec::Vec<ndarray::SliceOrIndex>, _>`

I can't see how to make the typechecker happy here, and I can't instantiate SliceInfo<[ndarray::SliceOrIndex]> because [ndarray::SliceOrIndex] is not sized. Am I missing something obvious ?

Activity

  1. jturner314 commented on Oct 11, 2018

    @jturner314
    Member

    The solution is to call .as_ref() manually on slice to perform the conversion, like this:

    a.slice(slice.as_ref())

    This calls this AsRef implementation (SliceInfo docs):

    impl<T, D> AsRef<SliceInfo<[SliceOrIndex], D>> for SliceInfo<T, D>
    where
        T: AsRef<[SliceOrIndex]>,
        D: Dimension,

    This is a somewhat ugly part of the API. I have a plan to fix this but haven't gotten around to it yet.

    Fwiw, for this particular example, it's simpler to use a series of .slice_axis() or .slice_axis_inplace() calls, like this:

    fn foo<'a>(a: &'a ArrayViewD<'a, f32>) -> ArrayViewD<'a, f32> {
        let mut view = a.clone();
        for axis in 0..view.ndim() {
            view.slice_axis_inplace(Axis(axis), Slice::from(2..6));
        }
        view
    }

    Edit: (Or, if you know the dimension of the array ahead-of-time, you can use the s![] macro.)

  2. kali commented on Oct 12, 2018

    @kali
    Author

    @jturner314 Ha, thanks a lot. for the solution and, and for the slice_axis_inplace tip. Everything is dynamic in my case, s! is not an option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions