xcorr says my signals have near perfect correlation which is impossible

6 views (last 30 days)
I am comparing 2 signals. One signal had to be resampled to equalise the sampling rates. The corrcoef function gives a value of 0.0287 between the raw resampled data. I then filtered both signals to extract a band of interest. This is the raw plot:
xcorr and corrcoef both say correlation is still low. I then applied a moving window 512 samples wide that moved 51 samples every step to the raw resampled data. Each step I calculated an FFT and recorded the summed power in the frequency band of interest. This is the resulting plot of those values:
You can see some visible similarity. I was hoping for maybe a value of 0.4. corrcoef only gave 0.0477 yet xcorr gave a value of 0.9867 at 0 lag, with the plot being a triangle (what you get when you compare two identical signals). I replaced one of the signals with white gaussian noise and it gave a more realistic plot, yet it still says the correlation between the 2 above signals is near perfect. It also gives similar results for plots of the power over time for other frequency bands of interest.
To confirm it's an error I compared the first signal with the other signal shifted over by n samples and it still says perfect correlation with zero lag. Am I using it wrong? Here's the code:
clear all;
load fData.mat
load nData.mat
fsF = 150;
fsN = 512;
time = 60;
fPow = [];
nPow = [];
windowSizeN = fsN*3;
windowUpdateN = 51;
[N1, D1] = rat(fsN/fsF);
freer = resample(fData, N1, D1)'; % resample fData from 150 to 512Hz
[acor,lag] = xcorr(freer,nData); %cross corr of the raw resampled data
[~,I] = max(abs(acor));
lagDiff = lag(I)
timeDiff = lagDiff/fsN
figure(1)
plot(lag,acor)
for i = 1:((time*fsN)/windowUpdateN)-29
data1 = freer(((i-1)*windowUpdateN+1):((i-1)*windowUpdateN)+windowSizeN)'; % for each number of i move the window across by 51 samples
[x2, f] = pwelch(hann(length(windowSizeN)).*data1,fsN,0.5*fsN,2048,fsN); % get the PSD of the window
x2 = 10*log10(x2);
A = sum(x2(33:53));
B = sum(x2(57:121));
T = sum(x2(17:29));
D = sum(x2(3:13));
R = A/B;
fPow = [fPow [A; B; T; D; R]]; % store the power values of the bands of interest for ever window
data2 = nData(((i-1)*windowUpdateN+1):((i-1)*windowUpdateN)+windowSizeN)';
[x2, f] = pwelch(hann(length(windowSizeN)).*data2,fsN,0.5*fsN,2048,fsN);
x2 = 10*log10(x2);
A = sum(x2(33:53));
B = sum(x2(57:121));
T = sum(x2(17:29));
D = sum(x2(3:13));
R = A/B;
nPow = [nPow [A; B; T; D; R]];
end
fs=0.1;
for i = 1:5
fff = fPow(i, :);
nnn = nPow(i, :);
[acor,lag] = xcorr(fff,nnn); % perform xcorr of change in power of each freq band as window moved
[~,I] = max(abs(acor));
lagDiff = lag(I)
timeDiff = lagDiff/fs
figure(2)
plot(lag,acor)
pause;
end
edit:
to get raw correlation for each function values I use
for i = 1:5
[cor,prob] = corrcoef(fPow(i, :),nPow(i, :))
xcorr(fPow(i, :),nPow(i, :), 0, 'coeff')
end
a sample of the results:
cor =
1.0000 0.1208
0.1208 1.0000
prob =
1.0000 0.0038
0.0038 1.0000
ans =
0.9867
cor =
1.0000 0.2799
0.2799 1.0000
prob =
1.0000 0.0000
0.0000 1.0000
ans =
0.9931
However if I do this (all 5 power plots at once)
[cor,prob] = corrcoef(fPow,nPow)
I get corrcoef also giving a super-high result
cor =
1.0000 0.9705
0.9705 1.0000
prob =
1 0
0 1
double edit:
I've uploaded the matrices fPow and nPow if it helps
https://www.mediafire.com/?warubpgijm2f952
fs=0.1;
for i = 1:5
fff = fPow(i, :);
nnn = nPow(i, :);
[acor,lag] = xcorr(fff,nnn); % perform xcorr of change in power of each freq band as window moved
[~,I] = max(abs(acor));
lagDiff = lag(I)
timeDiff = lagDiff/fs
figure(2)
plot(lag,acor)
pause;
end

Answers (1)

Kirby Fears
Kirby Fears on 16 Oct 2015
Read the function documentation for corrcoef and xcorr. In your last example, with [cor,prob] = corrcoef(fPow,nPow), you are invoking the following version of corrcoef:
R = corrcoef(x,y) where x and y are column vectors is the same as corrcoef([x y]). If x and y are not column vectors, corrcoef converts them to column vectors. For example, in this case R=corrcoef(x,y) is equivalent to R=corrcoef([x(:) y(:)]).
This means you're stacking all the columns into a single vector instead of using one pair of column vectors at a time. Working with the transpose of fPow and nPow might make things a little easier to think about.
For xcorr, you should confirm that fPow(i, :) and nPow(i, :) have the same length. According to the documentation, it fills zeros to make them the same length. Anyway, the xcorr documentation should be able to solve your problem.
Hope this helps.
  1 Comment
John Doe
John Doe on 19 Oct 2015
Edited: John Doe on 19 Oct 2015
Thanks. Plotting x and y and their transposes shows the transposed versions are the "right" way round, though it does not impact the coefficient value produced. But as you pointed out it's measuring the wrong thing regardless.
But I still have trouble with my original problem with xcorr giving absurdly high values. I've checked the documentation and can't see why the xcorr of 2 vectors should mess up so. And they're definitely equal length.
I've uploaded the matrices fPow and nPow if it helps
https://www.mediafire.com/?warubpgijm2f952
fs=0.1;
for i = 1:5
fff = fPow(i, :);
nnn = nPow(i, :);
[acor,lag] = xcorr(fff,nnn); % perform xcorr of change in power of each freq band as window moved
[~,I] = max(abs(acor));
lagDiff = lag(I)
timeDiff = lagDiff/fs
figure(2)
plot(lag,acor)
pause;
end

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!