我有一个大矩阵[300000,64](测试(
我需要独立于所有其他的每一行的自相关
结果将是[300000127]
我这样做
for i = 1:rw
xcorrresults(i,:) = xcorr(tests(i,:));
end
但它占用了整个程序的大部分时间。
有没有一种方法可以将循环矢量化?
通过预分配输出(输入越大,效果越显著(,可以节省大量运行时间
xcorrresults2 = zeros(rw,2*cl-1);
for i = 1:rw
xcorrresults2(i,:) = xcorr(tests(i,:));
end
在内部,xcorr
将所有内容作为列数组处理,如果给它一行,则会进行一些额外的操作。提前给它一列(令人惊讶(为我的又节省了35%
xcorrresults3 = zeros(rw,2*cl-1);
for i = 1:rw
xcorrresults3(i,:) = xcorr(tests(i,:).').';
end
如果需要,可以使用profile
深入到xcorr
函数中。例如,对我来说,大约20%的运行时用于该函数的内部循环,以确定转换长度——如果你的数据是固定大小的,那么这可以确定一次,如果你制作了一个类似但自定义的函数,就可以用作输入。
我怀疑长运行时间是由于在单独的调用中对所有样本序列执行xcorr的调用开销。
我试过上面克里斯的建议。
首先,我转换了我的数组,使信号实现在有很多行的列中。然后用零填充,这样FFT将是线性的。
然后对其进行FFT。在倍频程中,矩阵的FFT在列上工作。
然后对FFT结果与其共轭的乘积进行IFFT
测试=[零(rw,64(个测试];%填充
T=fft(测试(;
p=偏移(abs(ifft(T.*conj(T(((';
在每个样本上使用Xcorr,通常需要检查30000个序列,为19秒
使用IFFT(FFT(x(*CONJ(FFT(x((通常在0.35秒左右完成。
现在更像是
这个计算已经很重了,但幸运的是,xcorr
的MATLAB算法足够高效,它在内部使用了fft
。在4核机器上使用并行化仍然可以获得接近4倍的加速。只需使用parfor
而不是for
,并使用转置数组以最佳内存顺序逐列工作。
clc, clear
tests = ones(300000, 64)';
[m, n] = size(tests);
xcorrresults = zeros(2*m-1, n);
parfor i = 1:n
xcorrresults(:,i) = xcorr(tests(:,i));
end