Performance MATLAB中有效的元素差分法

Performance MATLAB中有效的元素差分法,performance,matlab,difference,Performance,Matlab,Difference,目前有一个关于在MATLAB中高效计算两两距离的方法(有些甚至是我自己做的!)。我想做点不一样的事 而不是计算两个矩阵中成对行之间的总距离,例如X和Y: X = [1 1 1; 2 2 2]; Y = [1 2 3; 4 5 6]; 我想计算一个三维矩阵,存储每对行之间的原始列差异。在上述示例中,该矩阵将有两行(X中的两个观测值)、三列和第三维的两个切片(Y中的两个观测值): 到目前为止,我已经提出了两种实现这一目标的方法,但我希望找到优雅、透明和高效的方法 Repmat+Permute方法

目前有一个关于在MATLAB中高效计算两两距离的方法(有些甚至是我自己做的!)。我想做点不一样的事

而不是计算两个矩阵中成对行之间的总距离,例如
X
Y

X = [1 1 1; 2 2 2];
Y = [1 2 3; 4 5 6];
我想计算一个三维矩阵,存储每对行之间的原始列差异。在上述示例中,该矩阵将有两行(X中的两个观测值)、三列和第三维的两个切片(Y中的两个观测值):

到目前为止,我已经提出了两种实现这一目标的方法,但我希望找到优雅、透明和高效的方法

Repmat+Permute方法

% Set up data
X = rand(100,10);
Y = rand(200,10);

timer = tic;
X_tiled = repmat(X,[1 1 size(Y,1)]);
Y_tiled = repmat(permute(Y,[3,2,1]),[size(X,1),1,1]);
diffs = X_tiled - Y_tiled;
toc(timer)
% Elapsed time is 0.001883 seconds.
用于环路进近

% Set up data
X = rand(100,10);
Y = rand(200,10);

timer = tic;
X_tiled = repmat(X,[1 1 size(Y,1)]);
Y_tiled = repmat(permute(Y,[3,2,1]),[size(X,1),1,1]);
diffs = X_tiled - Y_tiled;
toc(timer)
% Elapsed time is 0.001883 seconds.
还有人有比我更好的吗?

你可以用
置换
引擎盖下的
广播
中凌乱的
repmat
,然后在
Y
上使用
permute
将第一个维度发送到第三个位置,保持第二个维度在其位置以匹配第二个维度
X的尺寸
。这可以通过
permute(Y,[3 2 1]
实现。因此,解决方案是-

diffs = bsxfun(@minus,X,permute(Y,[3 2 1]))

基准测试

基准测试代码-

% Set up data
X = rand(100,10);
Y = rand(200,10);

% Setup number of iterations
num_iter = 500;

%// Warm up tic/toc.
for iter = 1:50000
    tic(); elapsed = toc();
end

disp('---------------- With messy REPMAT')
timer = tic;
for itr = 1:num_iter
    X_tiled = repmat(X,[1 1 size(Y,1)]);
    Y_tiled = repmat(permute(Y,[3,2,1]),[size(X,1),1,1]);
    diffs = X_tiled - Y_tiled;
end
toc(timer)

disp('---------------- With sassy BSXFUN')
timer = tic;
for itr = 1:num_iter
    diffs1 = bsxfun(@minus,X,permute(Y,[3 2 1]));
end
toc(timer)
输出-

---------------- With messy REPMAT
Elapsed time is 3.347060 seconds.
---------------- With sassy BSXFUN
Elapsed time is 0.966760 seconds.
---------------- With messy REPMAT
Elapsed time is 3.347060 seconds.
---------------- With sassy BSXFUN
Elapsed time is 0.966760 seconds.