Search code examples
rustrust-ndarray

How to get a zero Array2 copying dimension from another Array2


Just learning some rust. I'm using ndarray and I need to construct a zero matrix copying the dimension from another matrix. I tried

fn make_0(matrix: Array2<i32>) -> Array2<i32> {
        Array2::zeros(matrix.shape())
}

But this does not compile:

error[E0271]: type mismatch resolving `<&[usize] as ShapeBuilder>::Dim == Dim<[usize; 2]>`
   --> src/lib.rs:62:9
    |
62  |         Array2::zeros(matrix.shape())
    |         ^^^^^^^^^^^^^ expected array `[usize; 2]`, found struct `IxDynImpl`
    |
    = note: expected struct `Dim<[usize; 2]>`
               found struct `Dim<IxDynImpl>`

I can solve it with

fn make_0(matrix: Array2<i32>) -> Array2<i32> {
        Array2::zeros((matrix.shape()[0], matrix.shape()[1]))
}

But I guess there's something better and I'm lost with types here.


Solution

  • The documentation for ArrayBase::shape() recommends using .raw_dim() instead:

    Note that you probably don’t want to use this to create an array of the same shape as another array because creating an array with e.g. Array::zeros() using a shape of type &[usize] results in a dynamic-dimensional array. If you want to create an array that has the same shape and dimensionality as another array, use .raw_dim() instead:

    // To get the same dimension type, use `.raw_dim()` instead:
    let c = Array::zeros(a.raw_dim());
    assert_eq!(a, c);
    

    So you probably want to do something like this:

    fn make_0(matrix: Array2<i32>) -> Array2<i32> {
        Array2::zeros(matrix.raw_dim())
    }