2

在 Matlab 中,我使用“ndgrid”创建一个 6D 矩阵。这是代码:

for i=1:3
    dd{i}=[0 0 0 0 0 0 0 1 1 1 1 1];
    ss{i}=[0 0 0 0 0 0 1 1 1 1 1 1];
end 
[D1 D2 D3 S1 S2 S3] = ndgrid(dd{1},dd{2},dd{3},ss{1},ss{2},ss{3});
out = D1.*S1.*D2.*S2.*D3.*S3;   

我遇到的问题是,虽然我有足够的内存来存储一个或两个 6-D 矩阵,但我没有足够的内存来存储所有 6 个矩阵:

[D1 D2 D3 S1 S2 S3] 

如您所见,矩阵 D1、D2... 和“out”本质上是稀疏的,但 Matlab 中的“稀疏”功能不适用于多维数组。我在 Matlab 中搜索了其他“网格”功能,但找不到可以帮助我避免计算 D1、D2 等中间步骤的“网格”功能。

一般来说,我希望 dd{1} 与 dd{2} 不同。此外,我发布的这个 6-D 案例不会占用太多内存,但 8-D 案例会,这就是我遇到问题的地方。

非常感谢在这种情况下更有效地利用内存的任何帮助。

4

2 回答 2

1

这是一个循环几乎肯定会更快(并且适合!)的情况,因为您受内存限制。只需使用 6 个(或 8 个)嵌套的 for 循环,然后out一次放入 的每个元素。使用嵌套循环索引直接引用源向量,并确保将正确的索引与正确的向量匹配。这将只限制您输出数组的最大大小。

用新思路编辑:

哦,我只是想到了bsxfun,它会做完全正确的事情,除了它只接受两个参数。它本质上是在任何单一维度上根据需要进行复制。成对嵌套bsxfun调用将毫无意义,因为中间结果将恢复为完整大小。但这是将维度减少一半的好方法,这对于幂项来说很重要:

[D1 D2 D3] = ndgrid(dd{1},dd{2},dd{3});
[S1 S2 S3] = ndgrid(ss{1},ss{2},ss{3});
out = bsxfun(@times, D1.*D2.*D3, reshape(S1.*S2.*S3, [1 1 1 12 12 12]));

显然 12s 必须被动态尺寸替换。现在,您只需要 D*N^(D/2),而不是 D*N^D 元素。在您恢复到 14 或 16 维之前,您不会遇到内存问题。

于 2012-11-16T15:45:01.137 回答
0

编辑:我找到了一种使用线性索引快速快速完成的方法。

out=D1(:) %Initialize out to give it the right dimensions, bit ugly perhaps

out(:) = D1(:).*S1(:).*D2(:).*S2(:).*D3(:).*S3(:);  
于 2012-11-16T15:47:45.810 回答