如何在matlab中“矢量化”corrcoeff?

时间:2016-11-29 03:17:34

标签: matlab vectorization

因为我听说matlab中的循环很糟糕,所以我尝试对代码进行矢量化。

我有以下代码:

find_nb(24723578342962)

这会创建一个大小为1 x useDPs的delta矩阵,其中useDPs上升到1.000.000

它计算每列的相关系数并将其保存为delta,因此它是一个非常长的循环,我想为matlab优化它。

我尝试了什么:

for dp_point = 1:useDPs
    cc = corrcoef(Traces(:,dp_point), hws(:,dp_point));
    delta(dp_point) = cc(2);
end;

但这会产生一个2 x 2矩阵(它计算整个矩阵的corr系数,而不是每列)。所以这显然是一次错误的尝试。

所以我的问题是,是否有可能对这个循环进行“矢量化”(或以其他方式优化)呢?

1 个答案:

答案 0 :(得分:2)

由于您的问题只有2个变量,您可以这样写:

m = size(X,1);

Xc = bsxfun(@minus, X, sum(X)/m);
Yc = bsxfun(@minus, Y, sum(Y)/m);

xy = sum(Xc.*Yc) / (m-1);
xx = sum(Xc.*Xc) / (m-1);
yy = sum(Yc.*Yc) / (m-1);

delta = xy ./ sqrt(xx.*yy);

但是,我花时间去弄清楚这个,加上这个事实:

clc

N = 1e4;
M = 1e3;

X = rand(N,M);
Y = rand(N,M);

% Loopy version    
tic
D = zeros(N,1);
for ii = 1:M
    cc = corrcoef(X(:,ii), Y(:,ii));
    D(ii) = cc(2);
end
toc


% "Vectorized" version 
m = N;
tic    

Xc = bsxfun(@minus, X, sum(X)/m);
Yc = bsxfun(@minus, Y, sum(Y)/m);

xy = sum(Xc.*Yc) / (m-1);
xx = sum(Xc.*Xc) / (m-1);
yy = sum(Yc.*Yc) / (m-1);

delta = xy ./ sqrt(xx.*yy);

toc

给予

Elapsed time is 0.272682 seconds. % loop 
Elapsed time is 0.384599 seconds. % non-loop

确实表明你不应该相信在MATLAB中循环不好的语句。