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.
There are three issues in your code:
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.
From the documentation of xcorr
:
C = xcorr(A,B)
[...] > IfA
andB
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 inputsM
,N
, andP
... should be nonnegative integers. Negative integers are treated as0
.
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.