将两个矩阵逐行相乘

use*_*290 3 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
Run Code Online (Sandbox Code Playgroud)

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

A=rand(10,4);
B=rand(4,10);
L=rand(10,1);
result=diag(A*B)./L
Run Code Online (Sandbox Code Playgroud)

但这会带来很多不必要的增殖.有没有更好的办法?

Div*_*kar 7

矢量化方法

您可以在之间进行矩阵乘法A和转置B,然后求和dim-2,最后执行元素划分L-

result = sum(A.*B.',2)./L
Run Code Online (Sandbox Code Playgroud)

标杆

本节介绍了proposed approach针对loop-based approach问题早期部分中列出的运行时和加速测试.请注意,diag问题的第二部分中建议的其他方法未在这些测试中涵盖,因为它的运行时间相对较大.

基准代码

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')
Run Code Online (Sandbox Code Playgroud)

相关的功能代码

mult_twomat_loopy.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
Run Code Online (Sandbox Code Playgroud)

mult_twomat_vect.m:

function result = mult_twomat_vect(A,B,L)
result = sum(A.*B.',2)./L;
Run Code Online (Sandbox Code Playgroud)

提议方法的优先级高于循环方法

在此输入图像描述

结论

从加速图可以看出,提出的方法似乎是解决问题的一个非常好的选择.从情节再次有趣的观察结果是,针对循环方法的拟议方法的性能突然下降32K+ datasizes.这种下降背后的原因似乎是系统内存带宽在这么大的数据量上追回性能,但幸运的是,即使对于这样的数据,加速仍然相当保持在超标20x.