Reputation: 179
I have a question on xcorr
function in MATLAB.
Currently this function can calculate the autocorrelation of a matrix, but cannot calculate the cross-correlation of 2 matrices:
A=[1,2;3,4];
B=[5,6;7,8];
xcorr(A); %% Possible
xcorr(A,A); %% Not Possible
xcorr(A,B); %% Not Possible
Are you aware of any workaround to do this, but without using a for
loop?
Upvotes: 1
Views: 7765
Reputation: 11
In case anyone finds this searching for the same question, here's an implementation of xcorr
that will work for lagged cross-correlation of all columns of matrix A
with all columns of matrix B
. Much like Donda's answer, except it avoids the 4x unnecessary computation of the unwanted column comparisons. This code is mostly stripped out and modified from the built-in MATLAB xcorr
function.
function C = xcorrAB(A, B, maxlag)
% like xcorr but computed between all the columns of A and the columns of B.
% A and B must have the same number of rows
%
% C is 2*maxlag-1 x size(A, 2)*size(B, 2).
% You may want to call reshape(C, [], size(A, 2), size(B, 2)) to make the
% output more straightforward to use
[m,n] = size(A);
assert(size(B, 1) == m, 'A and B must have same number of rows');
if nargin < 3
maxlag = m - 1;
end
mxl = min(maxlag,m - 1);
m2 = findTransformLength(m);
XA = fft(A,m2,1);
XB = fft(B,m2,1);
C = reshape(XA,m2,1,n).*conj(XB(:,:));
% Call IFFT and force real output if x is real.
c1 = ifft(C,[],1,'symmetric');
% c1 is M2-by-N-by-N.
% Keep only the lags we want, and move the negative lags before the
% positive lags. Also flatten the result to 2-D.
C = [c1(m2 - mxl + (1:mxl),:); c1(1:mxl+1,:)];
end
function m = findTransformLength(m)
m = 2*m;
while true
r = m;
for p = [2 3 5 7]
while (r > 1) && (mod(r, p) == 0)
r = r / p;
end
end
if r == 1
break;
end
m = m + 1;
end
end
Hope this helps!
Upvotes: 0
Reputation: 8477
xcorr
has essentially two syntaxes.
c = xcorr(x, y)
computes the cross-correlation function between two scalar signals (given as vectors), and
c = xcorr(x)
computes the auto-correlation function of a signal if x
is a vector, and the auto- and cross-correlation functions between all columns of x
if it is a matrix. If x
is of size n
x p
, then c
is of size 2*n-1
x p^2
.
When you write
c = xcorr(x, y);
with two matrices x
and y
, I assume you want the cross-correlation functions between all signals in x
with all signals in y
. xcorr
can't do this out of the box. However, if the two matrices both have n
rows, you can write
c = xcorr([x, y]);
to get the auto- and cross-correlation functions between all signals that are in x
or y
. c
is of size 2*n-1
x (p1+p2)^2
, where p1
and p2
are the numbers of signals (columns) in the two matrices. You can then reshape and truncate the result:
c = reshape(c, 2*n-1, p1+p2, p1+p2);
c = c(:, 1 : p1, p1+1 : end);
The result is a three-dimensional matrix where the first dimension corresponds to the lag, the second enumerates the signals in x
and the third enumerates the signals in y
; its size is 2*n-1*
x p1
x p2
.
Upvotes: 3