【问题标题】:How to make a large 2D Matrix如何制作大型二维矩阵
【发布时间】:2023-11-08 17:17:02
【问题描述】:

我想做一个大的方形数组,但维度限制是 1023。因此,我想按照建议的in a comment 制作一维数组的Vec。我尝试了这个作为开始:

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

对于VMAX 的任何值都可以,但大于 32 的ALEN 给出:

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`

出了点问题,我在查找信息和解释错误消息时遇到问题。如何制作我的巨型方阵?不同的方法也可以,性能很重要。当然,我会对数组做一些事情,例如循环索引并将一些值放入其中。

【问题讨论】:

  • 尺寸限制为 1023 — 不,不是。这就像说“内存限制”是 4GB,因为这就是您的计算机所拥有的全部。是的,堆栈空间是有限的,但通常可以在一定范围内更改。此外,如果数组中的项目占用 1MB,您不太可能将其中的 1023 个放在一个数组中,如果项目占用一个字节,您可能会放置超过 1023 个。
  • *.com/q/25151890/155423*.com/q/13102786/155423*.com/q/28145732/155423*.com/q/39240360/155423 重复。 尊重回答者的时间,在提问之前先进行搜索。您遇到的具体错误可能由*.com/q/30415354/155423 解释。
  • 另外还有a few crates处理数值和科学计算。这些板条箱的作者已经对这些决定进行了大量思考。我知道的一个是ndarray
  • 我描述了我的问题并给出了我的代码。在此之前,我努力搜索,但不是“克隆”或“板条箱”来创建矩阵。我没有通过不使用他们的库来表现出对任何人的不尊重,我两天前第一次尝试使用我不知道的语言。回想起来,1023的限制被无知地说成是事实,但我只是体验了一下,得到了其他用户的确认。所以,我不是特别抱歉,但感谢您的澄清和提示!
  • 抱歉,我无意暗示您对 crate 作者不尊重。但是,A Google search for "rust 2d" 提供了我刚刚链接的大部分问题。这是我在提出问题之前希望有人做的主要事情。我所说的所有其他内容只是为您提供更多信息。

标签: arrays vector rust


【解决方案1】:

您遇到的问题是 Rust 尚不支持非类型泛型参数,因此 [T; N] 上的特征仅针对从 032(包括)的 N 值实现。是的,这很烦人。

一个简单的解决方法是使用循环:

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

这与 vec! 宏在底层所做的很接近1

否则,可以将您的数组包装在自定义类型中并为其实现Clone(和Index)。这也是一种可能。


1vec![T; N] 更聪明一点,可以确保内存只分配一次,而不是多次分配。然而,据 @bluss 所说,collect 很快就会变得足够聪明,可以为大多数常见的迭代器进行一次分配。

【讨论】:

  • vec! 宏在底层做了什么。 — 不完全是,实际上是 a bit more efficient than that
  • @Shepmaster:怎么样?它调用from_elem,后者本身调用extend_with_element,后者使用循环。某处有专业吗?
  • 抱歉,我的措辞有点快而松散。您所说的vec![X; N] 表单可能基本上是一个循环。 vec![a, b, c] 表单不是循环。
  • 如何,extend_with_element_使用循环体内部没有重新分配条件的循环,因此效率更高。如果可以信任迭代器来告诉它的确切长度,那么管道中有一个 PR 可以将 Vec 的集合修复为等效。
  • @bluss:我责怪 Shepmaster! :D(我在初始版本中使用了reserve,但如果更快的话就很难看...很高兴知道collect 将得到改进,以便我们既优雅又高效)