Skip to content

Calling slice on a dynamic size array #501

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kali opened this issue Oct 11, 2018 · 2 comments
Closed

Calling slice on a dynamic size array #501

kali opened this issue Oct 11, 2018 · 2 comments

Comments

@kali
Copy link

kali commented Oct 11, 2018

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 ?

@jturner314
Copy link
Member

jturner314 commented Oct 11, 2018

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.)

@kali
Copy link
Author

kali commented Oct 12, 2018

@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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants