我的问题:我注意到很多关于SO的Matlab问题的好答案经常使用这个功能bsxfun
.为什么?
动机:在Matlab文档中bsxfun
,提供了以下示例:
A = magic(5);
A = bsxfun(@minus, A, mean(A))
Run Code Online (Sandbox Code Playgroud)
当然我们可以使用以下方法执行相同的操作:
A = A - (ones(size(A, 1), 1) * mean(A));
Run Code Online (Sandbox Code Playgroud)
事实上,简单的速度测试表明第二种方法的速度提高了约20%.那么为什么要使用第一种方法?我猜测在某些情况下使用bsxfun
将比"手动"方法快得多.我真的很想看到这种情况的一个例子,并解释为什么它更快.
此外,这个问题的最后一个元素,再次来自Matlab文档bsxfun
:"C = bsxfun(fun,A,B)将函数句柄fun指定的逐元素二元运算应用于数组A和B,使用单例扩展已启用." 短语"启用单例扩展"是什么意思?
之前在比较bsxfun
和repmat
表现之间提出的问题很少.
Matlab - bsxfun no longer faster than repmat?
.这个尝试研究repmat
和之间的性能比较bsxfun
,特别是从输入数组本身的列中执行减去输入数组的平均值,因此只会探索与其等价物相对的@minus
部分.bsxfun
repmat
In Matlab, when is it optimal to use bsxfun?
.那个试图通过沿列的平均值进行相同的减法操作,也没有扩展到其他内置操作.在这篇文章中,我试图调查两者之间的性能数据bsxfun
并repmat
覆盖所有bsxfun
内置函数,从而为它提供更广泛的视角,因为这两者都提供了良好的矢量化解决方案.
具体来说,我对这篇文章的问题是:
各种内置操作如何bsxfun
对repmat
等效执行?bsxfun
支持浮点运算一样@plus
,@minus
,@times
等,并且还像关系和逻辑运算@ge
,@and
等等.所以,是否有特定的内置插件,会给我明显的加速与bsxfun
比使用他们的repmat
等价物?
罗兰在她blog post
已经基准repmat
对bsxfun
具有定时@() A - repmat(mean(A),size(A,1),1)
对@() bsxfun(@minus,A,mean(A))
分别.如果我需要涵盖所有内置函数的基准测试,我可以使用一些其他可用于浮点,关系和逻辑运算的比较模型吗?
我很快就会找到一些新学生,他们将编写MATLAB代码.他们是MATLAB的新手,但他们有使用Java和C++编写的经验.
我将让他们浏览MATLAB帮助的入门部分.另外,我想给出一个小教程,目的是防止他们在转换到MATLAB时犯下一些人们常犯的错误(例如"MATLAB从1开始计数"),并向他们展示一些他们可能没有的功能.要知道何时来自其他语言(例如"你可以直接从数组中减去一个标量,而对于向量,则有bsxfun").
我应该告诉他们最重要的事情是什么?
假设我有一个矩阵A
,我对这个矩阵的行进行排序.如何在矩阵上复制相同的顺序B
(当然大小相同)?
例如
A = rand(3,4);
[val ind] = sort(A,2);
B = rand(3,4);
%// Reorder the elements of B according to the reordering of A
Run Code Online (Sandbox Code Playgroud)
这是我提出的最好的
m = size(A,1);
B = B(bsxfun(@plus,(ind-1)*m,(1:m)'));
Run Code Online (Sandbox Code Playgroud)
出于好奇,还有其他选择吗?
0.048524 1.4632 1.4791 1.195 1.0662 1.108 1.0082 0.96335 0.93155 0.90532 0.88976
Run Code Online (Sandbox Code Playgroud)
0.63202 1.3029 1.1112 1.0501 0.94703 0.92847 0.90411 0.8849 0.8667 0.92098 0.85569
Run Code Online (Sandbox Code Playgroud)
它只是表明,由于JITA(或许),循环不再是MATLAB程序员的诅咒.
我试图将我的一些代码从matlab移植到python,其中一些使用bsxfun()函数进行虚拟复制,然后进行乘法或除法(我也将它用于逻辑运算).我希望能够在没有实际复制矢量(使用函数或使用某种对角矩阵)之前执行此操作,然后再进行乘法或除法以节省内存和时间.
如果某个C库中存在等效的bsxfun,那当然也可以.
我正在尝试找到在Matlab中标准化矩阵的最快方法(零均值,单位方差列).这一切都归结为将相同操作应用于矩阵中所有行的最快方法.我读过的每篇文章都得出了相同的结论:使用bsxfun而不是repmat.本文由Mathworks编写,是一个例子:http://blogs.mathworks.com/loren/2008/08/04/comparing-repmat-and-bsxfun-performance/
但是,在我自己的计算机上尝试这个时,repmat总是更快.以下是我使用与文章中相同代码的结果:
m = 1e5;
n = 100;
A = rand(m,n);
frepmat = @() A - repmat(mean(A),size(A,1),1);
timeit(frepmat)
fbsxfun = @() bsxfun(@minus,A,mean(A));
timeit(fbsxfun)
Run Code Online (Sandbox Code Playgroud)
结果:
ans =
0.0349
ans =
0.0391
Run Code Online (Sandbox Code Playgroud)
事实上,无论输入矩阵有多小或多大,我都无法在这种情况下使bsxfun表现得比repmat更好.
有人可以解释一下吗?
我一直想知道这个问题很长一段时间但是找不到参考:Matlab如何快速转置稀疏矩阵,因为它存储在CSC(压缩稀疏列)格式中?
也其文档验证稀疏矩阵转置的效率:
要执行此操作(逐行访问),您可以转置矩阵,对列执行操作,然后重新转换结果...转置矩阵所需的时间可以忽略不计.
后续行动(根据@Mikhail的建议修改):
我同意@Roger和@Milhail的说法,设置一个标志足以支持许多操作,例如BLAS或稀疏BLAS操作的接口.但在我看来,Matlab做了"实际"换位.例如,我有一个稀疏矩阵X,大小为m*n = 7984*12411,我想缩放每一列和每一行:
% scaling each column
t = 0;
for i = 1 : 1000
A = X; t0 = tic;
A = bsxfun(@times, A, rand(1,n));
t = t + toc(t0);
end
Run Code Online (Sandbox Code Playgroud)
t = 0.023636秒
% scaling each row
t = 0;
for i = 1 : 1000
A = X; t0 = tic;
A = bsxfun(@times, A, rand(m,1));
t = t + toc(t0);
end
Run Code Online (Sandbox Code Playgroud)
t = 138.3586秒
% scaling each row by …
Run Code Online (Sandbox Code Playgroud) 这是我在Octave中的代码:
sum(bsxfun(@times, X*Y, X), 2)
Run Code Online (Sandbox Code Playgroud)
代码的bsxfun部分产生了元素乘法,所以我认为这样numpy.multiply(X*Y, X)
可以解决问题,但我得到了一个异常.当我进行一些研究时,我发现元素乘法不适用于Python数组(特别是如果X和Y的类型为"numpy.ndarray").所以我想知道是否有人可以解释这一点 - 即将类型转换为不同类型的对象工作?Octave代码有效,所以我知道我没有线性代数错误.我假设bsxfun和numpy.multiply实际上并不等同,但我不确定为什么所以任何解释都会很好.
我找到了一个网站!这给了Octave到Matlab的函数转换,但在我的情况下似乎没有帮助.
我需要在matlab中计算2个矩阵之间的欧氏距离.目前我正在使用bsxfun并计算距离如下(我附加了一段代码):
for i=1:4754
test_data=fea_test(i,:);
d=sqrt(sum(bsxfun(@minus, test_data, fea_train).^2, 2));
end
Run Code Online (Sandbox Code Playgroud)
fea_test的大小是4754x1024而fea_train是6800x1024,使用他的for循环导致for的执行花费大约12分钟,我认为太高了.有没有办法更快地计算两个矩阵之间的欧氏距离?
我被告知通过删除不必要的for循环,我可以减少执行时间.我也知道pdist2可以帮助减少计算时间,但由于我使用的是matlab版本7.我没有pdist2函数.升级不是一种选择.
任何帮助.
问候,
巴维亚
bsxfun ×10
matlab ×10
arrays ×3
performance ×2
python ×2
benchmarking ×1
c ×1
numpy ×1
octave ×1