在 MATLAB 中,什么时候使用 bsxfun 是最佳的? [英] In MATLAB, when is it optimal to use bsxfun?
问题描述
我注意到很多关于 StackOverflow 的 MATLAB 问题的好答案经常使用函数 bsxfun
.为什么?
I've noticed that a lot of good answers to MATLAB questions on Stack Overflow frequently use the function bsxfun
. Why?
动机:在 bsxfun
的 MATLAB 文档中,提供了以下示例:
Motivation: In the MATLAB documentation for bsxfun
, the following example is provided:
A = magic(5);
A = bsxfun(@minus, A, mean(A))
当然,我们可以使用:
A = A - (ones(size(A, 1), 1) * mean(A));
事实上,一个简单的速度测试表明第二种方法快了大约 20%.那么为什么要使用第一种方法呢?我猜在某些情况下,使用 bsxfun
会比manual"快得多.方法.我真的很想看到这种情况的示例以及它为什么更快的解释.
And in fact a simple speed test demonstrates the second method is about 20% faster. So why use the first method? I'm guessing there are some circumstances where using bsxfun
will be much faster than the "manual" approach. I'd be really interested in seeing an example of such a situation and an explanation as to why it is faster.
另外,这个问题的最后一个元素,同样来自 bsxfun
的 MATLAB 文档:C = bsxfun(fun,A,B) 应用由该函数处理数组 A 和 B 的乐趣,并启用了单例扩展.".短语启用单例扩展"是什么意思?是什么意思?
Also, one final element to this question, again from the MATLAB documentation for bsxfun
: "C = bsxfun(fun,A,B) applies the element-by-element binary operation specified by the function handle fun to arrays A and B, with singleton expansion enabled.". What does the phrase "with singleton expansion enabled" mean?
推荐答案
There are three reasons I use bsxfun
(documentation, blog link)
bsxfun
比repmat
快(见下文)bsxfun
需要更少的输入- 使用
bsxfun
,就像使用accumarray
一样,让我对MATLAB的理解感觉很好.
bsxfun
is faster thanrepmat
(see below)bsxfun
requires less typing- Using
bsxfun
, like usingaccumarray
, makes me feel good about my understanding of MATLAB.
bsxfun
将沿着它们的单一维度"复制输入数组,即数组大小为 1 的维度,以便它们匹配对应维度的大小其他阵列.这就是所谓的单例扩展".顺便说一句,如果您调用 squeeze
,单例维度将被删除.
bsxfun
will replicate the input arrays along their "singleton dimensions", i.e., the dimensions along which the size of the array is 1, so that they match the size of the corresponding dimension of the other array. This is what is called "singleton expansion". As an aside, the singleton dimensions are the ones that will be dropped if you call squeeze
.
对于非常小的问题,repmat
方法可能会更快 - 但在该数组大小下,两种操作都非常快,可能不会对整体性能产生任何影响.bsxfun
更快有两个重要原因:(1) 计算发生在编译代码中,这意味着数组的实际复制永远不会发生,以及 (2) bsxfun
是 MATLAB 的多线程函数之一.
It is possible that for very small problems, the repmat
approach is faster - but at that array size, both operations are so fast that it likely won't make any difference in terms of overall performance. There are two important reasons bsxfun
is faster: (1) the calculation happens in compiled code, which means that the actual replication of the array never happens, and (2) bsxfun
is one of the multithreaded MATLAB functions.
我已经在我相当快的笔记本电脑上使用 MATLAB R2012b 对 repmat
和 bsxfun
之间的速度进行了比较.
I have run a speed comparison between repmat
and bsxfun
with MATLAB R2012b on my decently fast laptop.
对我来说,bsxfun
大约比 repmat
快三倍.如果数组变大,差异会变得更加明显:
For me, bsxfun
is about three times faster than repmat
. The difference becomes more pronounced if the arrays get larger:
repmat
的运行时跳转发生在大约 1 MB 的数组大小,这可能与我的处理器缓存的大小有关 - bsxfun
没有和跳转一样糟糕,因为它只需要分配输出数组.
The jump in runtime of repmat
happens around an array size of 1 MB, which could have something to do with the size of my processor cache - bsxfun
doesn't get as bad of a jump, because it only needs to allocate the output array.
下面是我用于计时的代码:
Below you find the code I used for timing:
n = 300;
k=1; %# k=100 for the second graph
a = ones(10,1);
rr = zeros(n,1);
bb = zeros(n,1);
ntt = 100;
tt = zeros(ntt,1);
for i=1:n;
r = rand(1,i*k);
for it=1:ntt;
tic,
x = bsxfun(@plus,a,r);
tt(it) = toc;
end;
bb(i) = median(tt);
for it=1:ntt;
tic,
y = repmat(a,1,i*k) + repmat(r,10,1);
tt(it) = toc;
end;
rr(i) = median(tt);
end
这篇关于在 MATLAB 中,什么时候使用 bsxfun 是最佳的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!