autocorrelate rows of matrix without using a for loop
Mostrar comentarios más antiguos
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
Respuestas (6)
Rick Rosson
el 25 de Ag. de 2011
0 votos
Hi Cody,
Can you please answer the following questions?
- Did you pre-allocate the output array b ?
- 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
el 25 de Ag. de 2011
for m=10:-1:1
b(m,:)=xcorr( a(m,:) );
end
5 comentarios
Rick Rosson
el 25 de Ag. de 2011
Hi Sean,
I am confused: why is this code faster or more efficient than the original code?
Thanks!
Rick
Cody
el 25 de Ag. de 2011
Honglei Chen
el 25 de Ag. de 2011
@Rick, @Cody
When you write it as Sean does, MATLAB knows that it should preallocate the memory for 10 rows at the first iteration, sort of like a preallocation. Otherwise, MATLAB increases memory allocation at each iteration.
Honglei
Sean de Wolski
el 26 de Ag. de 2011
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
el 26 de Ag. de 2011
Rick Rosson
el 25 de Ag. de 2011
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 comentario
Cody
el 25 de Ag. de 2011
Honglei Chen
el 25 de Ag. de 2011
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 comentarios
Cody
el 26 de Ag. de 2011
Sebastian Holmqvist
el 21 de Mzo. de 2013
This is actually what xcorr does. Just my two cents.
Rick Rosson
el 25 de Ag. de 2011
0 votos
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 comentarios
Cody
el 26 de Ag. de 2011
Sean de Wolski
el 26 de Ag. de 2011
0.29 seconds for how big a matrix?
Chaowei Chen
el 27 de Ag. de 2011
0 votos
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)
Categorías
Más información sobre Creating and Concatenating Matrices en Centro de ayuda y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!