# Estimate changing time lag between signals

Suppose I have two timeseries $x_1(t)$ and $x_2(t)$, shown in the image that I drew below. They look almost identical in general form, except some features are shifted slightly in time from one series to the other by an about $\delta t$. Sometimes they are measured first in $x_1$, and sometimes in $x_2$, so sometimes $\delta t$ is positive and sometimes negative. The change in lag between features is random, but constrained to be of a small range so that shifts never overlap and cancel.

I want to know, what is the mean time lag between the two signals?

Even better, would be to know the distribution of time lags so I could estimate the mean, variance and range.

Does anyone have ideas or suggestions for how to do this? My own thoughts so far are: I can imagine calculating the cross correlation between signals $x_1$ and $x_2$. However, I would expect the result to be strong correlation at zero time lag, because the time lags can be both positive and negative, so that the average lag is zero. However, the width/stretching of the zero peak, must be related to the average time lag, however, I can't figure out how exactly at the moment.

Another thought I have had is to create a moving correlation estimator. In a similar way to how wavelet analysis can be used to estimate how the power of certain frequency components changes as a function of time. I could develop a function that measures the lag correlation as a function of time by breaking one of the signals into smaller chunks and convolving it across the second signal while stepping along.

All suggestions appreciated.

• Welcome to DSP.SE! Nice question! – Peter K. Nov 24 '15 at 21:27
• It seems you have three levels. Are 1's always in the vicinity of 1's (and same with -1's)? – Moti Nov 26 '15 at 6:12
• @Moti, yes because although the lag can change in time, it doesn't change by very much, so steps in one signal will not be very far away from steps in the other. I think another way of saying it is that the mean time-lag is typically shorter than time between steps. I included three steps as an illustration, in principle the signal could have many more, but always with the condition that the time between discontinuities or steps is longer than the mean time-lag. – JesseC Nov 26 '15 at 15:57
• based on the specifics (such as: "period length", "variation in lagging", "variation of quire periods"...) You may use auto correlation in sections of the signal (that could play nicely in using FFT for the process). – Moti Nov 27 '15 at 23:26

If the signals are as you've drawn them (flat, with abrupt changes), then perhaps this approach might work:

• Take the absolute value of the differences between successive time samples.
• The non-zero entries are the transition times.
• Find these times for both signals.
• Subtract the two.

I've made an attempt to do this in the R code below.

Example output:

 > print(differences_in_delay)
  2 -5  2 -4 -1  5 -4  3 -3  0
> print(t[which(abs(diff(x2))>0)] - t[which(abs(diff(x1))>0)])
  2 -5  2 -4 -1  5 -4  3 -3  0


It breaks down when the transitions are within a sample or two of each other, but otherwise seems to work OK.

Will also probably break down if there's noise on your signals.

R Code Below

T <- 1024
t <- seq(1,T,1)
Nchanges <- 10
times_for_changes_for_x1 <- sort(runif(Nchanges,T/10,9*T/10))
differences_in_delay <- round(runif(Nchanges,-5,5))
times_for_changes_for_x2 <- times_for_changes_for_x1 + differences_in_delay
changes_for_x1 <- runif(Nchanges,-5,5)

x1 <- 0*t
x2 <- 0*t
change_no_x1 <- 1
change_no_x2 <- 1

for (tm in t)
{
if ( (change_no_x1 <= Nchanges) && (tm > times_for_changes_for_x1[change_no_x1]))
{
x1[tm] <- x1[tm] + changes_for_x1[change_no_x1]
change_no_x1 <- change_no_x1 + 1
}
else
{
if (tm > 1)
{
x1[tm] = x1[tm-1]
}
}
if ( (change_no_x2 <= Nchanges) && (tm > times_for_changes_for_x2[change_no_x2]))
{
x2[tm] <- x2[tm] + changes_for_x1[change_no_x2]
change_no_x2 <- change_no_x2 + 1
}
else
{
if (tm > 1)
{
x2[tm] = x2[tm-1]
}
}
}

plot(x1,type='l')
lines(x2,col="red")

plot(abs(diff(x1)>0)*1, type='l')
lines(abs(diff(x2)>0)*1, col="red")

print(differences_in_delay)
print(t[which(abs(diff(x2))>0)] - t[which(abs(diff(x1))>0)])


May be if you substract both signals and take the absolute value you will have the segments that lag, then you can take an average

• if the two signals are scaled the same, that will work. you need to do that for different offsets or "lags" and pick the lag that gets you a minimum. it has a name, sorta: Average Magnitude Difference Function (AMDF) if they are scaled differently, you might have trouble. if you replace "take the absolute vaue" with "square", you will get something like Average Squared Difference Function (ASDF) which would be an upside-down version of cross-correlation. – robert bristow-johnson Nov 27 '15 at 0:28
• You are getting zeros that are sometimes signals and some times no signals. – Moti Nov 27 '15 at 23:30

cross-correlation:

$$R_{x_1 x_2}(\tau) = \int x_1(t) \cdot x_2(t+\tau) \ dt$$

you'll have to figure out what the appropriate limits for $t$ are in the integral. evaluate $R_{x_1 x_2}(\tau)$ for a variety of lags, $\tau$, both positive and negative. see which lag gives you a maximum. (assuming there is no polarity reversal on one of the signals.)

• The use of autocorrelation is kind of trivial - the challenge is how to set the parameters. The variability of the signal requires to set the range right and start right, and may be add a step... not trivial – Moti Nov 27 '15 at 23:29
• @Moti feel free to write an answer describing the parameters that must be set. – robert bristow-johnson Nov 28 '15 at 5:01