Jonatan Öström
Jonatan Öström

Reputation: 2609

How to make a large 2D Matrix

I want to make a large square array, but the dimension limit is 1023. Therefore, I want to make a Vec of 1D-arrays, as suggested in a comment. I tried this as a start:

fn main() { 
    const VMAX: usize = 1000; 
    const ALEN: usize = 32; 
    let mut arr2: Vec<[f64; ALEN]> = vec![[0.0; ALEN]; VMAX];}

which is fine for any value of VMAX, but ALEN larger than 32 gives:

error[E0277]: the trait bound `[f64; 33]: std::clone::Clone` is not satisfied
 --> <std macros>:2:1
  |
2 | $ crate :: vec :: from_elem ( $ elem , $ n ) ) ; ( $ ( $ x : expr ) , * ) => (
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
tes3.rs:4:35: 4:58 note: in this expansion of vec! (defined in <std macros>)
  |
  = help: the following implementations were found:
  = help:   <[T; 0] as std::clone::Clone>
  = help:   <[T; 1] as std::clone::Clone>
  = help:   <[T; 2] as std::clone::Clone>
  = help:   <[T; 3] as std::clone::Clone>
  = help: and 29 others
  = note: required by `std::vec::from_elem`

Something is going wrong and I have problems finding info and interpreting the error message. How can I make my giant square matrix? A different approach would be fine too, performance is important. Of course, I would do something with the array, like looping over the indices and putting some values in it, for example.

Upvotes: 0

Views: 576

Answers (1)

Matthieu M.
Matthieu M.

Reputation: 299730

You are hitting the issue that Rust does not support non-type generic parameters yet, and therefore traits on [T; N] are only implemented for values of N from 0 to 32 (inclusive). Yes, it's annoying.

A simple work-around is to use a loop:

let v: Vec<_> = (0..MAX).map(|_| [0.; MAX]).collect();

which is close to what the vec! macro does under the hood1.

Otherwise it would be possible to wrap your array in a custom type and implement Clone for it (and Index). It's also a possibility.


1 vec![T; N] is a bit smarter and will ensure memory is only allocated once rather than having multiple allocations. However, according to @bluss, who has been contributed an impressive number of quality performance improvements to the library, collect should soon become smart enough to do a single allocation for most common iterators, too.

Upvotes: 2

Related Questions