0
votes

I have two waveforms in the time domain, of which I need to measure the cross-correlation coefficient in MATLAB. I have tried max(abs(xcorr(m,n,'coeff'))) but it doesn't seem to be working properly.

Also I need to measure the cross correlation coefficient for different sections of the waveform, e.g. measure the cross correlation coefficient at 1 minute intervals. And if possible output these values to a matrix or something.

I know this is a lot to ask but I'm a MATLAB novice and find this task daunting!
Any help you could give me on any section of this question would be gratefully received.


EDIT: This is the code I used to test the correlation code:

x = rand(1,14400);
y = rand(1,14400);
r = max( abs(xcorr(x,y,'coeff')) )
4
We need more detail than "it doesn't seem to be working properly". What did you get, and what did you expect to get? - gnovice

4 Answers

5
votes

According to equations in this article you can count the cross-correlation coefficient in this way:

% Assuming: m and n are your signals organized as row vectors
r = cov([m;n]) / (std(m)*std(n));

if you want to compute the coefficient only for some part of the signals, just use:

r = cov([m(1:100);n(1:100)]) / (std(m(1:100))*std(n(1:100)));

Have you also tried the corrcoef function?

Edit Ok, I have checked the corrcoef function and it seems to be working properly, take a look:

>> x = 100*randn(1000,1);
>> y=34*randn(1000,1);
>> corrcoef(x,y)

ans =

    1.0000   -0.0543
   -0.0543    1.0000

So the correlation coefficient is equal -0.0543 - small similarity (as expected).
To check that, let's compute the coefficient for identical signals:

>> y=x;
>> corrcoef(x,y)

ans =

     1     1
     1     1

As expected, it's equal 1.

Edit. As you can see, the result of corrcoef is a matrix of all possible correlation coefficients between these two signals:

       x        y
x    1.0000   -0.0543
y   -0.0543    1.0000

So for cross-correlation you need to select one of the elements outside the main diagonal (there are located self-correlation coefficients, in this case always equal 1).
There is no difference if you would select ans(2,1) or ans(1,2) - there is no difference, if you compute the correlation of x and y, or correlation of y and x.

So the final code should look similar to this:

R = corrcoef(x,y); % Correlation matrix
r = R(2,1); % this is your Cross-Correlation coefficient
2
votes

Try using Cross-Covariance instead

x = rand(1,14400);
y = rand(1,14400);
r = max( abs(xcov(x,y,'coeff')) )

cross-covariance sequence is the cross-correlation of mean-removed sequences. Like Joonas mentioned, rand has a DC offset at 0.5 and will give you an "incorrect" results.

0
votes

I have tried max(abs(xcorr(m,n,'coeff'))) but it doesn't seem to be working properly.

What do you mean by that? What does it output, and what do you expect?

One possible gotcha in cross correlation is that a DC bias in the waveform will corrupt the result. And as far as I know, there's no universal way to do anything about it. You have to somehow ensure that your waveforms do not contain any DC bias.

0
votes

This is the code I used to test the correlation code:

x = rand(1,14400);
y = rand(1,14400);
r = max( abs(xcorr(x,y,'coeff')) )

The problem is that rand returns numbers that are are uniformly distributed in the interval (0,1). In other words, you have a DC bias (mean) of 0.5! That's why you get high correlation coefficient for seemingly random signals: they are not quite random, since each has a similar constant component that shows up in the correlation coefficient.

So, try using randn instead: it returns random numbers whose elements are normally distributed with mean 0, which is what you want here.