Arrays with run-time-known-length and multi-dimensional arrays


#1

Apologies first for putting a user question on the “internals” board, but it seems the “user” board doesn’t exist yet.

Question 1: is there some way of making arrays with a length known at run-time? Something like:

fn make_arr(len: usize) -> Box<[i32]>{
    Box::new([0u32; len])
}

Question 2: are there any libraries for multi-dimensional arrays? I have seen comments about such things but not any real code, yet.

What I’d prefer not to use is Vec<Vec<Vec<f64>>>, but at the moment it might be either that or a crude wrapper holding strides and un-sugared index function.


#2

If you’re looking for things like mathematical vectors and matrices, I would look into nalgebra… I find it quite useful.


#3

nalgebra apparently has dynamically-sized matrices which, for my purposes, can be used as a two-dimensional array. But I need three dimensions.


#4

You can create Vec<T> and turn it into Box<[T]> (i.e. throw away capacity) with Vec::into_boxed_slice


#5

Q1,

You could create a Vec<T> and then turn it into a Box<[T]>. I don’t see another way to create a dynamic Box<[T]> with safe code.

pub fn make_arr(len: usize) -> Box<[i32]> {
    use std::iter::repeat;
    repeat(0).take(len).collect::<Vec<i32>>().into_boxed_slice()
}

The code above is pretty slow with the current rustc though. With unsafe code it is 9× faster:

pub fn make_arr_unsafe(len: usize) -> Box<[i32]> {
    use std::rt::heap::allocate;
    use std::mem::{min_align_of, transmute};
    use std::ptr::set_memory;
    use std::raw::Slice;
    use std::i32;

    let size = len * i32::BYTES;
    unsafe {
        let mem = allocate(size, min_align_of::<i32>());
        set_memory(mem, 0, size);
        let slice = Slice { data: mem as *const i32, len: len };
        transmute(slice)
    }
}

#6

I’ve written rust-ndarray (docs) but mostly to learn how numpy’s ndarray works! It’s a real multidimensional array. The most useful part of it (for me) is multidimensional slices. I would be happy to hear feedback, and be wary, I’m sure it is not well optimized yet.


#7

Looks quite cool blake! Question, why not fix the dimensions of the array in the struct, i.e. Array2, Array3, etc.?


#8

Well the dimension is fixed by the type, it’s in the second type parameter. Array2 would be Array<A, (Ix, Ix)>. You’re free to type alias this in your own code, I think that’s the best anyway.