在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案例确实存在,这是我遇到问题的地方。
非常感谢在这种情况下更有效地使用内存的任何帮助。
答案 0 :(得分: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元素,您只需要D * N ^(D / 2)。在你恢复到14或16维之前,你不会有记忆问题。
答案 1 :(得分:0)
编辑:我已经找到了一种方法,可以使用线性索引很好地快速完成。
out=D1(:) %Initialize out to give it the right dimensions, bit ugly perhaps
out(:) = D1(:).*S1(:).*D2(:).*S2(:).*D3(:).*S3(:);