# xcorr always gives best aligment of 0 (which by visual inspection is wrong)

8 views (last 30 days)
Sven Larsen on 10 Sep 2023
Edited: Matt J on 11 Sep 2023
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.
Sven Larsen on 10 Sep 2023
Moved: Matt J on 10 Sep 2023
Sven Larsen on 10 Sep 2023

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:
x=1:numel(y1);
y3=interp1(x,y1,x+30000,'linear',0); %y1 shifted by 30000
corr0=y1*y2' %correlation with no shift
corr0 = 1.4636e+09
cor30000=y3*y2' %correlation when shifted by 30000
cor30000 = 1.2789e+09
plot(x,[y1;y2;y3]'); legend y1 y2 y3;
ylim([70,92])
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
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
Sven Larsen on 11 Sep 2023
Thanks, this seems to work and its fast!
it produces weird artefacts tho, because of circle shift. I wonder if your idea could be adjusted so there is no cyclic looping but instead cycled part is omitted from comparison.

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.
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

### Categories

Find more on Correlation and Convolution in Help Center and File Exchange

R2021a

### Community Treasure Hunt

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

Start Hunting!