2
votes

Assume that we have two simple sequences with different lengths:

x = rand(3,1);
y = rand(2,1);

I calculated the cross correlation between them and plot it such below:

r_1 = xcorr(x,(y));

tx = 1:length(x);
ty = 1:length(y);
tr = ceil(-(length(x)+length(y)-1)/2) :  floor((length(x)+length(y)-1)/2);

subplot(2,2,1); stem(tr,r_1); title('XC');

I wanted to calculate the cross correlation using convolution and show that it's result is equal to the result when using xcorr(). But when I implemented it like this:

r_2 = conv(x,fliplr(y));

tx = 1:length(x);
ty = 1:length(y);
tr = ceil(-(length(x)+length(y)-1)/2) :  floor((length(x)+length(y)-1)/2);

subplot(2,2,1); stem(tr,r_2); title('XC');

the length of r_1 and r_2 are different and I got this error:

Error using stem (line 43) X must be same length as Y.

Thanks for your helps.

1

1 Answers

2
votes

There are three issues in your code:

  1. You are applying fliplr to y, but y is a column vector, so you are not really flipping it. You should apply flipud; or flip if you want it to work for any vector in general.

  2. From the documentation of xcorr:

    C = xcorr(A,B) [...] > If Aand B are of different length, the shortest one is zero-padded.

    So, to make the result of conv equal to that of xcorr you need to zero-pad the shorter vector.

    In the general case, for column vectors x and y you can use [x; zeros(numel(y)-numel(x),1)] instead of x and [y; zeros(numel(x)-numel(y),1)] instead of y. This will extend the shorter vector and leave the other as is. Note that this works because, according to the documentation of zeros,

    zeros(M,N,P,...) [...] The size inputs M, N, and P... should be nonnegative integers. Negative integers are treated as 0.

  3. The correlation applies a complex conjugate to the second input. You should do the same with convolution. In your example it doesn't matter because inputs are real, but it should be done in general.

Combining the three items above:

r_1 = xcorr(x, y);
r_2 = conv([x; zeros(numel(y)-numel(x),1)], conj(flip([y; zeros(numel(x)-numel(y),1)])));

should give the same result.

Example:

x = [3.1; -4.3; 5.6];
y = [2.6; -8.4];

give

r_1 =
   0.000000000000004
 -26.040000000000006
  44.180000000000000
 -58.219999999999999
  14.559999999999999
r_2 =
                   0
 -26.040000000000003
  44.180000000000000
 -58.219999999999999
  14.559999999999999

which are the same up to numerical precision errors.