我的问题:我注意到很多关于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,使用单例扩展已启用." 短语"启用单例扩展"是什么意思?
array1 = 5*rand(496736,1);
array2 = 25*rand(9286,1);
output = zeros(numel(array1), numel(array2)); % Requires 34GB RAM
output = zeros(numel(array1), numel(array2),'logical'); % Requires 4.3GB RAM
output = abs(bsxfun(@minus, array1.', array2)) <= 2; % Requires 34GB RAM
output = pdist2(array1(:), array2(:)) <= 2; % Requires 34GB RAM
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。包含496736 * 9286个double值的数组应为34GB,而包含相同数量元素的逻辑数组仅需要4.3GB(小8倍)。后两种情况会发生这种情况,因为它们使用的中间矩阵包含双精度的所有距离对,需要完整的34GB,而逻辑矩阵直接作为逻辑直接预分配,并且需要4.3GB。
令人惊讶的部分是:
output = abs(array1.' - array2); % Requires 34GB RAM
output = abs(array1.' - array2) <= 2; % Requires 4.3GB RAM ?!?
Run Code Online (Sandbox Code Playgroud)
什么?!?为什么由于中间双矩阵的创建,隐式扩展不要求相同的34GB RAM output = abs(array1.' - array2)? …