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

19 visualizzazioni (ultimi 30 giorni)
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 Commenti

Accedi per commentare.

Risposte (3)

Matt J
Matt J il 10 Set 2023
Modificato: Matt J il 10 Set 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
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])
  8 Commenti
Matt J
Matt J il 11 Set 2023
Modificato: Matt J il 11 Set 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
Paul il 11 Set 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?

Accedi per commentare.


Matt J
Matt J il 10 Set 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
  1 Commento
Sven Larsen
Sven Larsen il 11 Set 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.

Accedi per commentare.


Matt J
Matt J il 11 Set 2023
Modificato: Matt J il 11 Set 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

Prodotti


Release

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by