【问题标题】:A memory-efficient replacement for meshgrid网状网格的内存高效替代品
【发布时间】:2019-11-06 10:29:44
【问题描述】:

假设一个简单的例子,我有索引

index_pos = [3,4,5];
index_neg = [1,2];

我想要一个矩阵:

result =

     1     3
     2     3
     1     4
     2     4
     1     5
     2     5

为此,我编写了以下代码:

[X,Y] = meshgrid(index_pos,index_neg);
result = [Y(:) X(:)];

我认为这不是一个非常有效的方法。此外,当我使用大型实例时,这会占用我太多的内存。我收到以下错误:

Error using repmat
Out of memory. Type "help memory" for your options.

Error in meshgrid (line 58)
        xx = repmat(xrow,size(ycol));

Error in FME_funct (line 36)
[X,Y] = meshgrid(index_pos,index_neg);

有没有什么“聪明”的方法可以使用更少的内存来生成这个矩阵?

PS:我注意到我所做的事情也给了here。很可能我是从那里找到这个想法的。

【问题讨论】:

  • 评论:也许这是线性代数中的特殊向量积..
  • 因为result = [Y(:) X(:)];需要将数据复制到一个新的数组,所以效率不高,占用内存太多?如果将其实现为循环,则可以避免复制,这很简单。
  • 哦,meshgrid出现内存不足错误。这意味着您没有足够的内存来存储XY,这意味着您没有足够的内存来存储要构建的矩阵。除了为您的计算机购买更多内存之外,没有其他办法。你必须重新考虑你的算法,这样你就不需要这个非常大的数组了。
  • @CrisLuengo 我认为你是对的。我复制了大小并尝试以该大小启动零矩阵。即使这样也不可能。所以我认为这是由于我的内存:\
  • 您是一次性需要整个矩阵,还是使用单行或多组行进行处理,然后继续下一个?

标签: matlab memory repeat memory-efficient


【解决方案1】:

这里有一个更快的方法来生成这样一个矩阵。它通过直接就地构建矩阵来避免显式的临时数组,

res2 = [ reshape( bsxfun( @times , index_neg.' , ones(size(index_pos)) ) , [] , 1 ) , ...
         reshape( bsxfun( @times , index_pos , ones(size(index_neg)).' ) , [] , 1 ) ] ;

请注意,这需要相同数量的内存来保存主数组,因此不可能生成比您的方法更大的数组(在meshgrid 阶段失败)。此最大大小最终取决于系统可用的 RAM 量。

【讨论】:

  • 我不认为你在这里创建了一个矩阵。 MATLAB 分别计算两个 bsxfun 函数,生成两个中间矩阵,然后将它们连接起来。最终结果与 OP 中的代码相同,需要相同数量的中间内存。
  • @CrisLuengo,是的,我知道,我应该更多地突出显示 explicit 这个词。这只是将临时数组的管理委托给 MATLAB 的一种方式……(希望它们在某些情况下有一些适用的技巧可以节省资源)。
【解决方案2】:

这完全取决于您的两个变量相对于计算机内存量的大小(加上您使用的数字类型)。 试试这个:

res = zeros(numel(index_neg)*numel(index_pos), 2)

如果这给您一个内存不足的错误,那么无论生成器的效率如何,您的计算机中都没有足够的内存来存储结果,所以如果出现上述错误,那么您就被卡住了。如果它没有出错,那么您可以编写一个使用较少临时内存的循环算法。

也就是说,默认情况下,MATLAB 以双精度表示数字,每个数字 8 个字节。如果你的 index_ 变量恰好包含,比如说,只有正整数(都小于 65,536),那么你可以使用 16 位无符号整数。每个数字只有 2 个字节,因此占用的空间比双精度数少 4 倍。您可以使用以下方法进行测试:

res = zeros(numel(index_neg)*numel(index_pos), 2, 'uint16')

最后,您可以使用memory 命令了解 MATLAB 有多少内存可用。

【讨论】:

  • 这是一个很好的答案。我绝对知道向量是数组的索引。所以它们是非负整数。我可以在 meshgrid 函数中替换它吗?
  • @independentvariable:您不需要meshgrid,您可以使用您链接的问答中的任何其他解决方案。例如,this one 使用 uint16uint32 输入很简单。
  • 您可以使用uint16()uint32() 等函数转换双索引。
猜你喜欢
  • 2012-12-22
  • 1970-01-01
  • 2018-06-11
  • 2023-03-25
  • 2011-05-16
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
相关资源
最近更新 更多