meshgrid 的内存高效替代品

A memory-efficient replacement for meshgrid

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

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);

有什么'clever'方法可以使用更少的内存生成这个矩阵吗?

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

这是一种更快的方法来生成这样的矩阵。它通过直接在适当的位置构建矩阵来避免显式临时数组,

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

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

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

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

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

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

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

最后,您可以使用 memory 命令找出 MATLAB 可用的内存量。