将两个矩阵逐行相乘

时间:2015-02-02 17:25:42

标签: matlab matrix vectorization matrix-multiplication

在MATLAB中,我想将Nx4矩阵乘以4xN矩阵,并从中获取Nx1向量。我还将结果元素除以另一个向量。

在一个循环中,它将是:

A=rand(10,4);
B=rand(4,10);
L=rand(10,1);
for i=1:10
    result(i)=A(i,:)*B(:,i)/L(i);
end

我能想到的唯一非循环方法是:

A=rand(10,4);
B=rand(4,10);
L=rand(10,1);
result=diag(A*B)./L

但这会带来很多不必要的增殖。还有更好的方法吗?

1 个答案:

答案 0 :(得分:7)

矢量化方法

你可以在A和[{1}}的转置之间进行矩阵乘法,然后在B之间进行求和,最后用dim-2进行元素划分 -

L

基准

本节介绍result = sum(A.*B.',2)./L 针对proposed approach的运行时和加速测试,如问题的早期部分所列。请注意 在问题的第二部分中提出的另一种基于loop-based approach的方法在这些测试中没有涵盖,因为它的运行时间相对非常 大数字。

基准代码

diag

相关功能代码

mult_twomat_loopy.m:

N_arr = 4000:4000:100000;        %// Datasizes
timeall = zeros(2,numel(N_arr)); %// Array to store runtimes
for iter = 1:numel(N_arr)

    %// Create random inputs
    N = N_arr(iter);
    A=rand(N,4);    B=rand(4,N);    L=rand(N,1);

    %// Time the approaches
    f = @() mult_twomat_loopy(A,B,L);
    timeall(1,iter) = timeit(f); clear f
    f = @() mult_twomat_vect(A,B,L);
    timeall(2,iter) = timeit(f); clear f
end

%// Plot speedups
figure,hold on,grid on
plot(N_arr,timeall(1,:)./timeall(2,:),'-bo')
xlabel('Datasize, N(Rows in A)'),ylabel('Speedup Factor (x)')
title('Speedup Plot')

mult_twomat_vect.m:

function result = mult_twomat_loopy(A,B,L)
N = size(A,1);
result = zeros(N,1);
for i=1:N
    result(i)=A(i,:)*B(:,i)/L(i);
end

提议的方法加速循环

enter image description here

结论

从加速图可以看出,提出的方法似乎是解决问题的一个非常好的选择。从情节中有趣的观察结果是针对function result = mult_twomat_vect(A,B,L) result = sum(A.*B.',2)./L; 的循环方法的拟议方法的性能突然下降。这种下降背后的原因很可能是系统内存带宽在这么大的数据量上追回性能,但幸运的是,即使对于这样的数据,加速仍然保持在32K+ datasizes以上。