Pregunta

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?

¿Fue útil?

Solución

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.

Otros consejos

To handle cross correlation between matrices just use the 2d version of it: xcorr2.

So to calculate autocorrelation just do

xcorr2(A)

while to find the cross correlation of two matrices

xcorr2(A,B)

For example, with your A,B the result is:

 8    23    14
30    70    38
18    39    20

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!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top