Matlab矢量化
我有一个256x256x20大小的概率矩阵(glcm)。我已将矩阵重塑为 65536x20,这样我可以消除一个循环(沿三维) 我想做下面的计算Matlab矢量化,matlab,loops,probability,vectorization,Matlab,Loops,Probability,Vectorization,我有一个256x256x20大小的概率矩阵(glcm)。我已将矩阵重塑为 65536x20,这样我可以消除一个循环(沿三维) 我想做下面的计算 for y = 1:256 for x = 1:256 if (ismember((x + y),(2:2*256))) p_xplusy((x+y),:) = p_xplusy((x+y),:) + glcm(((y-1)*256+x),:); end end end 因此p_
for y = 1:256
for x = 1:256
if (ismember((x + y),(2:2*256)))
p_xplusy((x+y),:) = p_xplusy((x+y),:) + glcm(((y-1)*256+x),:);
end
end
end
因此p_explucy将是一个511x20矩阵,其中每个元素是原始256x256x20矩阵的nxn子矩阵(其中n属于1:256)的对角线之和
这个代码块使我的程序效率低下,我想把这个循环矢量化。任何帮助都将不胜感激。因为您的
if
语句只是检查x+y
是否小于或等于256,请强制它始终为,并删除多余的循环:
for y = 1:256
for x = 1:256-y
p_xplusy((x+y),:) = p_xplusy((x+y),:) + glcm(((y-1)*256+x),:);
end
end
这将显著提高代码的速度。您可以将复杂性从
O(n^2)
降低到O(2*n)
,从而提高运行效率-
N = 256;
for k1 = 1:N
idx_glcm = k1:N-1:N*(k1-1)+1;
p_xplusy(k1+1,:) = p_xplusy(k1+1,:) + sum(glcm(idx_glcm,:),1);
end
for k1 = 2:N
idx_glcm = k1*N:N-1:N*(N-1)+k1;
p_xplusy(N+k1,:) = p_xplusy(N+k1,:) + sum(glcm(idx_glcm,:),1);
end
一些快速运行时测试似乎也证实了我们的效率理论
ismember
是一个相当昂贵的函数调用。看看这个,看起来你可以用if(ismember((x+y),(2:2*256))
行替换为if x+y1
。我建议的不是矢量化,但它可以大大加快代码的速度。在Matlab中,矢量化不一定更快。在JIT编译中,for循环通常与向量化方法一样快,并且通常可以通过更少的内存使用更好地扩展。当然,这假设您的for循环编写得很合理,@chessofnerd已经提供了一个改进。您说“p\u xplusy将是511x20”
,但它给我带来了一个错误,假设rand
值。我必须让它rand(512,20)
工作。你能澄清一下吗?是的,谢谢你的建议。不需要“if”语句。删除“如果”,现在时间为0.29秒(删除前为2.7秒)。非常感谢您节省了我的时间第二个中的-x
是否需要语句?我甚至不确定它是否有效(但无法测试它,因为我当前的机器上没有MATLAB),您能否澄清一下“删除多余的循环”
是什么意思。如果你说的是删除If
条件语句,那不是循环。@chessford应该是y
,哎呀@Divakar我想我的意思是删除多余的迭代,对x=1:256-y做,而不是对x=1:256
做,因为x
大于y
的迭代是多余的,只需要测试保证为假的逻辑条件。我猜sum
是一种O(N)
方法。这不应该将循环提升到O(n^2)
?再说一次,如果这更快,那么它也更快!(:@chessofnerd我在一次对多个列求和进行guestimation肯定比简单的for循环求和要便宜,而且col的数量从1到Nxsqrt(2),再从Nxsqrt(2)到1。因此,我猜它可能略大于2*N,但肯定小于N^2:)尽管如此,还是提出了一些好的观点!