rustrust-ndarray

Changing the datatype of an Array2 in a function's call in Rust


I just started with Rust. I am trying the ndarray crate, using a Array2 to load a matrix of integers I saved as .npy with type Int8.

This crate has a method for Array2 (although my problem will also happen with other methods, this is just an example) that is .sum(), which returns the sum of the elements of my matrix.

My matrix is 1000x1000, basically of 0's and 1's, and its sum is something like 400k. Now, because the matrix itself is i8, the method tries to return the sum as i8, which causes a overflow since the sum is greater than the range of i8.

I do know that just importing the matrix as another type of integer array will solve this, but I would like to try continuing to use i8 type. I do have a working code, with my Array2 saved as the variable arr:

{
        let arr = arr.map(|x| convert(x)) ;
        println!("{:?}", arr.sum());
}
fn convert(x: &i8) -> i32 {
    *x as i32
}

which is just casting the entire matrix to i32 before doing the sum, so I get the sum as i32. Also, the casted array goes out of scope after the block.

My first question: Is there some other workaround, perhaps a smarter one? I will be needing to get this sum many times, and I feel like casting the array everytime is not the most elegant thing to do. This also brings me to the next question: Is casting the entire Array2 like this slow/not a good thing? The current matrix is 1000x1000 but this is just a initial test, I will be using this to bigger matrices.


Solution

  • You definitely don't want to use map here because it allocates a whole new array. Instead, just iterate and fold as you'd do for any other array:

    let sum = arr.iter().fold(0, |acc, x| acc + (*x as i32));