如何优化这些FOR循环以节省Matlab脚本中的执行时间

时间:2013-11-23 07:16:56

标签: arrays matlab multidimensional-array indexing nested-loops

我想知道是否有办法在没有for循环的情况下进行大数据集计算。

我的WarpVec是一个包含大量数据的大型五维数组。

我的算法比较当前空间旁边的3个空格(可以是NaN或任何实数值)来检查周围的3个单元格是否与当前空间相对。几乎如果中心空间是NaN并且3个邻居是非NaN值,那么我绘制一个标志,反之亦然,当中心是非NaN值且其3个邻居是NaN值时。

如果有什么选择,我该怎么办?有没有办法更好地索引这个?我可以在某处使用某些矢量分析来缩短运行时间吗?

for X = 1:size(WarpVec, 1)
    for L = 1:size(WarpVec, 2)   
        for k = 1:size(WarpVec,3)
            for i = 2:(size(WarpVec, 4)-1)
                for j = 2:(size(WarpVec, 5)-1)
                    tri1(X, L, k, i, j) = ~isnan(WarpVec(X, L, k, i, j)) && (~isnan(WarpVec(X, L, k, i-1, j-1))...
                                         || ~isnan(WarpVec(X, L, k, i, j-1)) || ~isnan(WarpVec(X, L, k, i-1, j)))...
                                         || (~isnan(WarpVec(X, L, k, i-1, j-1)) && ~isnan(WarpVec(X, L, k, i, j-1))...
                                         && ~isnan(WarpVec(X, L, k, i-1, j)));

                    tri2(X, L, k, i, j) = ~isnan(WarpVec(X, L, k,  i, j)) && (~isnan(WarpVec(X, L, k,  i, j-1))... 
                                          || ~isnan(WarpVec(X, L, k,  i+1, j-1)) || ~isnan(WarpVec(X, L, k,  i+1, j)))...
                                          || (~isnan(WarpVec(X, L, k,  i, j-1)) && ~isnan(WarpVec(X, L, k,  i+1, j-1))...
                                          && ~isnan(WarpVec(X, L, k,  i+1, j)));

                    tri3(X, L, k, i, j) = ~isnan(WarpVec(X, L, k,  i,j)) && (~isnan(WarpVec(X, L, k,  i-1, j))...
                                          || ~isnan(WarpVec(X, L, k,  i-1, j+1)) || ~isnan(WarpVec(X, L, k,  i, j+1)))...
                                          || (~isnan(WarpVec(X, L, k,  i-1, j)) && ~isnan(WarpVec(X, L, k,  i-1, j+1))...
                                          && ~isnan(WarpVec(X, L, k,  i, j+1)));

                    tri4(X, L, k, i, j) = ~isnan(WarpVec(X, L, k,  i,j)) && (~isnan(WarpVec(X, L, k,  i+1, j))...
                                         || ~isnan(WarpVec(X, L, k,  i+1, j+1)) || ~isnan(WarpVec(X, L, k,  i, j+1)))...
                                         || (~isnan(WarpVec(X, L, k,  i+1, j)) && ~isnan(WarpVec(X, L, k,  i+1, j+1))...
                                         && ~isnan(WarpVec(X, L, k,  i, j+1)));
                end
            end
        end 
     end
end

第一次在这里发帖。感谢您的帮助。我非常感激。

1 个答案:

答案 0 :(得分:1)

让我们通过使用布尔索引来取出最后两个for循环:

tri1=true(size(WarpVec, 1), size(WarpVec, 2), size(WarpVec,3), size(WarpVec,4), size(WarpVec,5);
tri2=tri1;% same for tri3 and tri4.
for X = 1:size(WarpVec, 1)
    for L = 1:size(WarpVec, 2)   
        for k = 1:size(WarpVec,3)
                    tri1(X, L, k, ~isnan(WarpVec(X, L, k, :, :)) & (~isnan(WarpVec(X, L, k, [1,1:end-1], [1,1:end-1]))...
                                         | ~isnan(WarpVec(X, L, k, :, [1,1:end-1])) | ~isnan(WarpVec(X, L, k, [1,1:end-1], :)))...
                                         | (~isnan(WarpVec(X, L, k, [1,1:end-1], [1,1:end-1])) & ~isnan(WarpVec(X, L, k, :, [1,1:end-1]))...
                                         & ~isnan(WarpVec(X, L, k, [1,1:end-1], :))))=true;

                    tri2(X, L, k, ~isnan(WarpVec(X, L, k, :, :)) & (~isnan(WarpVec(X, L, k, :, [1,1:end-1]))... 
                                          | ~isnan(WarpVec(X, L, k, [2:end,end], [1,1:end-1])) | ~isnan(WarpVec(X, L, k, [2:end,end], :)))...
                                          | (~isnan(WarpVec(X, L, k, :, [1,1:end-1])) & ~isnan(WarpVec(X, L, k, [2:end,end], [1,1:end-1]))...
                                          & ~isnan(WarpVec(X, L, k,  i+1, j))))=true;

 %same for tri3, tri4.
        end 
     end
end

如果你有足够的内存,你也可以使用更快的形式:

isw=isnan(WarpVec);    
tri1=~isw(:,:,:, :, :) & (~isw(:,:,:, [1,1:end-1], [1,1:end-1])...
| ~isw(:,:,:, :, [1,1:end-1]) | ~isw(:,:,:, [1,1:end-1], :)...
| (~isw(:,:,:, [1,1:end-1], [1,1:end-1])) & ~isw(:,:,:, :, [1,1:end-1])...
                                         & ~isw(:,:,:, [1,1:end-1], :));