xcorr always gives best aligment of 0 (which by visual inspection is wrong)
19 views (last 30 days)
Show older comments
i have some datacurves, which im trying to align in time. while there is clearly max correlation that can be seen visually (like in image below), corrcoeff(y1,y2) always gives maximum correlation of length(y) i.e. aligment of 0. what i am doing wrong here and how can I find out the index of maximal similarity of two curves? Visually it can be seen that maximum correlation is at aligment ~30000
arrays y1 and y1 are in attachment.
4 Comments
Answers (3)
Matt J
on 10 Sep 2023
Edited: Matt J
on 10 Sep 2023
Visually it can be seen that maximum correlation is at aligment ~30000
I'm afraid not:
load y1y2;
x=1:numel(y1);
y3=interp1(x,y1,x+30000,'linear',0); %y1 shifted by 30000
corr0=y1*y2' %correlation with no shift
cor30000=y3*y2' %correlation when shifted by 30000
plot(x,[y1;y2;y3]'); legend y1 y2 y3;
ylim([70,92])
8 Comments
Matt J
on 11 Sep 2023
Edited: Matt J
on 11 Sep 2023
IMHO there should also be minimal area difference method.
A minimal area difference criterion will always be a local minimum only. The global minima will always be achieved when the shift is so large as to make the signals completely non-overlap. Furthermore, there will be plenty of cases where these extreme global solutions are also the only local solutions, leading to very strange, as well as non-unique, results.
As an example, consider the two sawtooth pulses below. There are two ways to shift y1 so that your "overlap-only" area criterion is minimized. One way is to shift y1 to the left by 1 so that the two signals overlap only at t=0, y=0. The other is to shift y1 to the right by 1 so that both signals overlap only at t=1,y=1. Not only is the solution non-unique, but since they only overlap at one point, it is of questionable value.
t=linspace(-0.5,2,100)';
msk=abs(t-0.5)<=0.5;
y1=(1-t).*msk;
y2=t.*msk;
plot(t,[y1,y2]); axis equal; xlabel t; ylabel y
legend y1 y2
Paul
on 11 Sep 2023
Aren't the figures on the right hand side in this comment also chopping off the points to the left of zero of the shifted red curve?
@Sven Larsen, would you mind posting your code that yields the shifted red curve?
Matt J
on 10 Sep 2023
You could look for an optimal cyclic shift
load y1y2;
N=numel(y1);
r=ifft( fft(y1).*conj(fft(y2)) ,'symmetric');
[~,t]=max(r);
plot([y1;y2;circshift(y1,-t)]')
legend y1 y2 y1-shift
Matt J
on 11 Sep 2023
Edited: Matt J
on 11 Sep 2023
Here's another possible comparison criterion where the signals are pre-normalized so that their minimum values are zero.
load y1y2;
N=numel(y1);
[r,lags]=xcorr(y1-min(y1),y2-min(y2));
subplot(1,2,1)
[~,t]=max(r);
plot([y1;y2; interp1( (1:N) , y1,(1:N)+lags(t) ) ]')
legend('y1', 'y2', 'y1-shift','location','south')
axis square
subplot(1,2,2);
plot(lags,r); axis square
xlim([-4e4,+4e4])
ylabel Correlation; xlabel Lag
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!