Matlab:复制和乘以两个向量的最快方法

Matlab:复制和乘以两个向量的最快方法,matlab,vectorization,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并将其重塑为线向量来轻松而有效地实现。但是有没有更快的办法?这是在拟合函数中发生的,因此可以传递额外的向量,如索引数组。我在过去两天中第五次回答: kron(A'

假设我有两个向量:

    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
并将其重塑为线向量来轻松而有效地实现。但是有没有更快的办法?这是在拟合函数中发生的,因此可以传递额外的向量,如索引数组。

我在过去两天中第五次回答:

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计算机,所以得到了以下结果:

A=rand(14000);
B=兰特(4000,1);
抽搐
对于ii=1:10
D=克朗(A',B);
结束
t1=总有机碳
抽搐
对于ii=1:10
D2=B*A;
D2=D2(:);
结束
t2=总有机碳
抽搐
对于ii=1:10
D3=bsxfun(@次,A,B);
D3=D3(:);
结束
t3=总有机碳
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

事实上,我怀疑在这种情况下是否会有显著的改进,因为众所周知矩阵乘法是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个内核,因此我也不认为这是“问题”。

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

C = bsxfun(@times, A,B);
C = C(:);
一个小比较(Win 7 64位,MATLAB R2010a 64位):

结果:

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(15000);B=兰特(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²)或更差的比例缩放…

实际上,这似乎比最初提出的解决方案慢。编辑:你的计时与我的不匹配,你能显示计时代码吗?@DennisJaheruddin:你能发布你的基准测试结果吗?我没有得到相同的结果…你(两者)使用什么Matlab版本?是
kron
多线程的吗?因为
*
在更高版本上,这意味着体系结构可能会有很大的不同,使用
a=rand(15000)再次进行测试;B=兰特(5000,1)。我打赌结果会完全不同:)你确定这是一个瓶颈,因为这听起来相当有效。特别是在多核机器上……即使它是最耗时的部分,也可能不是最有改进潜力的部分(除非其余部分运行得很快)。我得到的数据可能重复,支持您的数据,
0.000043 s
第一个版本,
0.000167 s
第二个版本。双4芯机器上的R2013b版本+1!我很惊讶
kron
在MATLAB中对于较大的矩阵是如此之慢。我现在离开了我的MATLAB计算机,但是使用,我得到了完全不同的结果。检查我的更新。我得到的结果与这个答案相当一致。令人惊讶的是,
bsxfun
实际上占了上风,在大小为100-10000的范围内,它比常规乘法快得多,同时使用的处理器也少得多。然而,它的伸缩性似乎不太好,所以我认为根据您的硬件,有一个切换到
*
变得更快的地方。
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
Elapsed time is 7.134506 seconds.  %// kron
Elapsed time is 0.119705 seconds.  %// B*A
Elapsed time is 0.162295 seconds.  %// bsxfun