Matlab:最快的方式复制并乘以两个向量

时间:2014-01-15 13:09:12

标签: matlab vectorization

假设我有两个向量:

    A = [1 2 3];
    B = [10;20;30];

它们也可能是两个向量 - 无所谓,我会选择最好的东西。我现在想要通过将B与A:

的每个元素相乘来创建线矢量
    C = [1*10;1*20;1*30;2*20;2*20;2*30;3*10;3*20;3*30];

通过使用张量积B*A并将其重新整形为线矢量,可以轻松高效地完成此操作。但是有更快的方法吗?这发生在拟合函数中,因此可以传递其他向量,如索引数组。

3 个答案:

答案 0 :(得分:4)

我第五次回答过去两天的kron

kron(A',B)
   10
   20
   30
   20
   40
   60
   30
   60
   90

时间比较:

C = B*A;
C = C(:);

给出以下结果:

t1 =  0.21601    % kron
t2 =  0.56776    % C = B*A

更新

我刚刚离开了我的MATLAB计算机,因此获得了这些结果here

A = rand(1,4000);
B = rand(4000,1);

tic
for ii = 1:10
D = kron(A',B);
end
t1 = toc

tic
for ii = 1:10
D2 = B*A;
D2 = D2(:);
end
t2 = toc

tic
for ii = 1:10
D3 = bsxfun(@times, A,B);
D3 = D3(:);
end
t3 = toc

sum(sum(abs(D-D2))) < 1e-10
sum(sum(abs(D-D3))) < 1e-10

t1 =  0.43138
t2 =  0.85762
t3 =  0.43332
ans =  1
ans =  1

答案 1 :(得分:4)

我很惊讶没有人想到过这个:

C = bsxfun(@times, A,B);
C = C(:);

小比较(Win 7 64位,MATLAB R2010a 64位):

A = rand(1,1000);
B = rand(1000,1);

tic
D = kron(A.',B);
toc

tic
D2 = B*A;
D2 = D2(:);
toc

tic
D3 = bsxfun(@times, A,B);
D3 = D3(:);
toc

isequal(D,D2)
isequal(D,D3)

结果:

Elapsed time is 0.123301 seconds.  %// kron
Elapsed time is 0.034271 seconds.  %// B*A
Elapsed time is 0.010617 seconds.  %// bsxfun
ans =
     1
ans =
     1

A = rand(1,5000); B = rand(5000,1);的结果:

Elapsed time is 7.134506 seconds.  %// kron
Elapsed time is 0.119705 seconds.  %// B*A
Elapsed time is 0.162295 seconds.  %// bsxfun

kron下面的算法似乎是O(N²)或更差......

答案 2 :(得分:1)

实际上我怀疑在这种情况下是否可以有显着的改进,因为已知矩阵乘法是Matlab的强度而扁平化数组是微不足道的,这就是我得出的结论,使用kron将无济于事:

A = [1 2 3];
B = [10;20;30];

tic,C = B*A;C = C(:);toc % Typically takes about  0.000012 seconds
tic, C=kron(A',B);toc    % Typically takes about  0.000093 seconds

当然,对于不同的输入大小,这可能会有所改变,但这是我从问题中得到的结果。

我认为matlab版本并不重要,但它在2012b上进行了测试。 它用12个核心进行了测试。当在循环中使用两种解决方案时,似乎每种情况下都使用了6个核心,因此我认为这也不是“问题”。