autocorrelate rows of matrix without using a for loop

2 ビュー (過去 30 日間)
Cody
Cody 2011 年 8 月 25 日
Hello, can anyone help me to write 'vectorized' code to compute the autocorrelation of each row of a matrix without using a for loop? My current code computes the autocorrelation of the rows like this:
for m=1:10
b(m,:)=xcorr( a(m,:) );
end
This is slow and inefficient. There must be a better way? Thanks, -Cody

回答 (6 件)

Rick Rosson
Rick Rosson 2011 年 8 月 25 日
Hi Cody,
Can you please answer the following questions?
  1. Did you pre-allocate the output array b ?
  2. Also, have you considered that MATLAB stores arrays column-major, so that your code might be faster and more efficient if you used the transpose of a, even though it is still in a for loop?
Thanks!
Rick

Sean de Wolski
Sean de Wolski 2011 年 8 月 25 日
for m=10:-1:1
b(m,:)=xcorr( a(m,:) );
end
  5 件のコメント
Sean de Wolski
Sean de Wolski 2011 年 8 月 26 日
Honglei explained it well, it dynamically preallocates b to have m rows of length(xcorr(a(m,:))) so basically getting you the speed gain of calling zeros before hand
b = zeros(m,length_of_2nd_dim);
for ii = 1:m
%do stuff
end
A few months ago Matt Fig showed dynamically preallocating, as I did a above, to sometimes be faster than preallocating the conventional way. I can't seem to find that question though :(
Cody
Cody 2011 年 8 月 26 日
Great tip, I didn't know this!

サインインしてコメントする。


Rick Rosson
Rick Rosson 2011 年 8 月 25 日
Also, please check the documentation for xcorr:
>> doc xcorr
It looks like you may be able to accomplish what you want without a for loop if you first transpose a and then consider each column of a as an independent channel.
HTH.
Rick
  1 件のコメント
Cody
Cody 2011 年 8 月 25 日
Rick, thanks for the response. Yes, I have preallocated the output array. I will also transpose the array before calling xcorr() and see if that makes much of a difference, however, my intuition tells me that there is probably a clever way to accomplish this calculation without using a for loop. I've also noticed that cov() or xcov() won't operate on individual rows or columns separately and I find it hard to believe that Mathworks simply overlooked such functionality.
The problem I see with the channel method you mentioned is that the output produces the autocorrelation of each column along with the cross-correlation of each column with every other column. This results in large matrices and lots of wasted output data because I'm only interested in the autocorrelation of each row and not the cross-correlation between the rows.

サインインしてコメントする。


Honglei Chen
Honglei Chen 2011 年 8 月 25 日
You can use FFT if your data is large, e.g.,
ffta = fft(a,NFFT,2);
b = fftshift(ifft(ffta.*conj(ffta),[],2),2)
Choose your NFFT as 2*size(a,2)-1 to match xcorr behavior. You may gain even more if you can transpose your data first to make these function working along columns.
HTH
  2 件のコメント
Cody
Cody 2011 年 8 月 26 日
Nice method Honglei. The Fourier transform of the autocorrelation is the power spectral density... so true. I'll give this a try and see how it works.
Sebastian Holmqvist
Sebastian Holmqvist 2013 年 3 月 21 日
This is actually what xcorr does. Just my two cents.

サインインしてコメントする。


Rick Rosson
Rick Rosson 2011 年 8 月 25 日
Is the issue here that you really need to make this code run faster, or is it that you are just hoping to find a more elegant (e.g. vectorized) way to accomplish this task without resorting to a for loop?
How much time is it taking to run this code now? How fast do you need it to be?
  2 件のコメント
Cody
Cody 2011 年 8 月 26 日
Rick, the speed at which I can perform the autocorrelations is directly related to the resolution of a measurement and also to many other factors. The code currently takes about ~0.29 [s] (calculated using the tic and toc commands). A 10x speed increase would fix my problem.
Sean de Wolski
Sean de Wolski 2011 年 8 月 26 日
0.29 seconds for how big a matrix?

サインインしてコメントする。


Chaowei Chen
Chaowei Chen 2011 年 8 月 27 日
The idea is to convert mat to cell since each row is independent. After processing, convert cell back to mat.
a2=mat2cell(a,ones(1,size(a,1)),size(a,2));
b2=cellfun(@xcorr,a2,'uniformoutput',false);
b2=cell2mat(b2);
isequal(b,b2)

カテゴリ

Help Center および File ExchangePulsed Waveforms についてさらに検索

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by