手动计算可以获得x100的速度提升.
An=bsxfun(@minus,A,mean(A,1)); %%% zero-mean
Bn=bsxfun(@minus,B,mean(B,1)); %%% zero-mean
An=bsxfun(@times,An,1./sqrt(sum(An.^2,1))); %% L2-normalization
Bn=bsxfun(@times,Bn,1./sqrt(sum(Bn.^2,1))); %% L2-normalization
C=sum(An.*Bn,1); %% correlation
您可以使用该代码进行比较:
A=rand(60,25000);
B=rand(60,25000);
tic;
C=zeros(1,size(A,2));
for i = 1:size(A,2)
C(i)=corr(A(:,i), B(:,i));
end
toc;
tic
An=bsxfun(@minus,A,mean(A,1));
Bn=bsxfun(@minus,B,mean(B,1));
An=bsxfun(@times,An,1./sqrt(sum(An.^2,1)));
Bn=bsxfun(@times,Bn,1./sqrt(sum(Bn.^2,1)));
C2=sum(An.*Bn,1);
toc
mean(abs(C-C2)) %% difference between methods
以下是计算时间:
Elapsed time is 10.822766 seconds.
Elapsed time is 0.119731 seconds.
两个结果之间的差异非常小:
mean(abs(C-C2))
ans =
3.0968e-17
编辑:解释
bsxfun执行逐列操作(或逐行取决于输入).
An=bsxfun(@minus,A,mean(A,1));
该行将删除(@minus)每列的平均值(平均值(A,1))到A的每列.因此,基本上它使A的列为零均值.
An=bsxfun(@times,An,1./sqrt(sum(An.^2,1)));
该行乘以(@times)每列与其规范的倒数.所以它使它们L-2归一化.
一旦列为零均值和L2归一化,为了计算相关性,您只需要将A的每列的点积乘以B的每一列.因此,将元素乘以* Bn乘以你总和每列:sum(An.* Bn);.