重复向量的最有效方法是什么?
我目前的印象repmat
是优于任何其他方法?还是我的这种心态大错特错?
是否有可能使用不同的技术产生完全相同的结果repmat
?也许是普通的矩阵乘法?
我要对您的所有兴趣和支持性回答表示最衷心的感谢!
AER
重复向量的最有效方法是什么?
我目前的印象repmat
是优于任何其他方法?还是我的这种心态大错特错?
是否有可能使用不同的技术产生完全相同的结果repmat
?也许是普通的矩阵乘法?
我要对您的所有兴趣和支持性回答表示最衷心的感谢!
AER
bsxfun
如果起始向量很长或重复次数足够大(见下文),底线比您要求的两个要快,否则矩阵乘法更有效。在您问过的两者之间,看起来矩阵乘法+整形在效率上的优势是 ~3 over repmat
。我使用timeit
了以下方式,我创建了一个包含 1e5 个元素的随机向量,并检查了创建 100 次重复它需要多长时间:
v=rand(1e5,1);
f1=@()repmat(v,[100,1])
f2=@() reshape(v*ones(1,100),[],1);
timeit(f1)
ans =
0.1675
timeit(f2)
ans =
0.0516
然而bsxfun
更快:
f3=@() reshape(bsxfun(@times,v,ones(1,100)),[],1)
timeit(f3)
ans =
0.0374
以下是对这一观察结果的更仔细研究:
给定一个向量的长度为 1000 个元素,重复它 10 到 1e5 次会产生以下性能时间:
对于较小的重复次数,矩阵乘法之间几乎没有区别,bsxfun
但是随着重复次数通过~1e3,bsxfun
明显获胜。
但是,仅采用具有相同重复范围的 10 个元素长向量,表明矩阵乘法更有效。bsxfun
只有在 10^5 次重复后才开始变得更好,但即便如此,它也只快了 ~5%(未显示):
所以这取决于你所追求的。在Loren 的 MATLAB 艺术博客中可以找到进一步的讨论。
这真的取决于你想要什么样的 verctor。例如,如果你想要一个专门的向量,比如一行,那么
tic
repmat([1],3,5)
toc
tic
ones(3,5)
toc
会告诉你使用“ones”大约快 3 倍(至少在我的机器上)。您始终可以使用 tic 和 toc 来衡量哪种方法更快。让我们再试试...
tic
repmat([1,2,3],1,2)
toc
tic
cat(2,[1,2,3],[1,2,3])
toc
现在 cat 再次快了 3 倍,但它有其明显的局限性。希望这可以帮助
不,目前repmat
大多数情况下比普通索引要慢,其工作原理如下:
分类repmat
:
a = [ 1 2 3 ];
repmat(a,4,1)
>>
[1 2 3;
1 2 3;
1 2 3;
1 2 3];
这个的索引版本:
a(ones(4,1),:);
这给出了相同的结果。