如何在MATLAB中对索引为矩阵的矩阵进行矢量化?

时间:2013-05-08 17:26:49

标签: matlab for-loop lookup vectorization

我在代码中嵌入了两个for循环,这些循环重复多次。我想加快速度:

for i = 1:10
 for j = 1:10
  A(i,j) = B(i,j,D(i,j))*C(i,j); 
 end 
end 

这里D由作为B的索引的整数组成。不依赖于D,for循环可以用元素矩阵乘法代替。 问题是如何以优雅的方式评估B.我搜索了SO和mathworks-pages并尝试了线性索引,但这会产生错误:

d = reshape(D, 100, []);
b = reshape(B, 100, []);
arrayfun(@(x) b(x,d(x)), 1:100);

我做错了什么?有没有办法替换这两个for循环?

2 个答案:

答案 0 :(得分:1)

您可以将D转换为线性索引:

[rows,cols]=ndgrid(1:10,1:10);
idx = sub2ind(size(B),rows(:),cols(:),D(:));

A = zeros(10,10); %# initialize A to the right size
A(:) = B(idx).*C(:);

答案 1 :(得分:0)

您可以使用B的元素乘法对A中的索引所排序的D中的图层进行排序(请注意,您首先沿着行循环,然后是列,这意味着你去了一直到行的末尾,然后到下一行等...这就是我转置并重塑为D列的原因。

一种简单的方法是使用bsxfun()

out = bsxfun(@times, A(:,:,reshape(D',[],1)), B);

其中每一层都是:

out(:,:,1)   = A(:,:,D(1,1)).*B(:,:)
out(:,:,2)   = A(:,:,D(1,2)).*B(:,:)
...
out(:,:,ncols*(i-1) + j) = A(:,:,D(i,j)).*B(:,:)

如果这不是你想要的,我的不好。我会删除答案。