我可以在MATLAB中对这个矩阵任务进行矢量化吗?

时间:2017-04-27 19:54:48

标签: matlab matrix vectorization

我有一个方阵A,我想用矩阵D进行操作。结果将是矩阵B。条目B(i, j)将是来自A(:, j)的多个元素的总和,由D确定。

让我展示代码中的内容 -

A = magic(3); % initial matrix
D = [1, 2, 3; 2, 2, 3; 1, 3, 1]; % map matrix
B = zeros(3); % resultant matrix
for i = 1:3
    for j = 1:3
        B(D(i, j), j) = B(D(i, j), j) + A(i, j);
    end
end

现在,我要解释一下D为:

D = [1, 2, 3; 
     2, 2, 3; 
     1, 3, 1];

这些D值基本上作为行索引累积到输出数组B,而列索引本身就是迭代数字 -

col = [1 2 3;
       1 2 3;
       1 2 3];

因此,总结如下:

B(1,1) += A(1,1)  % Indices from first row from D to select B
B(2,2) += A(1,2)
B(3,3) += A(1,3)

B(2,1) += A(2,1)  % Indices from second row from D to select B
B(2,2) += A(2,2)
B(3,3) += A(2,3)

B(1,1) += A(3,1)  % Indices from third row from D to select B
B(3,2) += A(3,2)
B(1,3) += A(3,3)

因此,在B(1,1),我们会积累来自AA(1,1)A(3,1)的两个值,依此类推。

当矩阵很大时,这个过程需要很长时间。有没有办法对这个计算进行矢量化?

1 个答案:

答案 0 :(得分:3)

以下是使用accumarraybsxfun -

的一种方法
[m,n] = size(A);

% Generate all linear indices corresponding to D
idx = bsxfun(@plus,D,m*(0:n-1))

% Use accumarray to accumulate values for each of those indices.
% We need some reshaping to get a final 2D output after feeding in column
% vectors for using accumarray
Bout = reshape(accumarray(idx(:),A(:),[m*n,1]),[m,n])

示例运行 -

>> % Setup inputs and run loopy version
A = randi(9,4,6);
D = randi(size(A,1),4,6);
B = zeros(size(A));
for i = 1:size(A,1)
    for j = 1:size(A,2)
        B(D(i, j), j) = B(D(i, j), j) + A(i, j);
    end
end

% Proposed vectorized method
>> [m,n] = size(A);
>> idx = bsxfun(@plus,D,m*(0:n-1));
>> Bout = reshape(accumarray(idx(:),A(:),[m*n,1]),[m,n]);

% Verify results
>> max(abs(Bout(:)-B(:)))
ans =
     0