matlab中单循环的矢量化(乘法然后加法)

时间:2016-01-26 14:20:43

标签: performance matlab vectorization

我有一个nX2矩阵A和一个3D矩阵K.我想采用逐元素乘法来指定A中每个行向量指定的K的第三维中的2个索引,并对它们求和。

例如当n = 2时的简化示例,

A=[1 2;3 4];%2X2 matrix
K=unifrnd(0.1,0.1,2,2,4);%just random 3D matrix
L=zeros(2,2);%save result to here
for t=1:2
    L=L+prod(K(:,:,A(t,:)),3);
end

在这种情况下,我可以摆脱for循环吗?

2 个答案:

答案 0 :(得分:2)

这是怎么回事?

B = A.'; %'
L = squeeze(sum(prod(...
                  reshape(permute(K(:,:,B(:)),[3 1 2]),2,[],size(K,1),size(K,2)),...
                  1),...
            2));

虽然您的测试用例过于简单,但我无法完全确定它是否正确。

我们的想法是,我们首先按照列主要顺序获取A中的所有索引,然后重新整形K的元素,使前两个维度的大小为[2, n] ,后两个维度是K的原始2。然后我们得到产品,然后是必要维度的总和,最后得到一个必须被挤压得到2d矩阵的矩阵。

使用更具信息性的测试用例:

K = rand(2,3,4);
A = randi(4,4,2);
L = zeros(2,3);%save result to here
for t=1:size(A,1)
    L = L+prod(K(:,:,A(t,:)),3);
end

B = A.'; %'
L2 = squeeze(sum(prod(reshape(permute(K(:,:,B(:)),[3 1 2]),2,[],size(K,1),size(K,2)),1),2));

然后

>> isequal(L,L2)
ans =
     1

答案 1 :(得分:2)

有些reshaping magic -

%// Get sizes
[m1,n1,r1] = size(K);
[m2,n2] = size(A);

%// Index into 3rd dim of K; perform reductions and reshape back
Lout = reshape(sum(prod(reshape(K(:,:,A'),[],n2,m2),2),3),m1,n1);

说明:

  1. 使用K的换位版本转换为A的第三维(换位,因为我们使用A行进行索引)。
  2. 执行prod()sum()操作。
  3. 最后重塑为与K相同的形状,但没有第三个尺寸,因为在之前的缩小步骤中已将其删除。