# Finding delay where squared error between signal and data is minimal

I have a set of points which correspond to part of a known signal. What I want to do is estimate the delay between the set of points and the known signal.

In this case, I don't think cross correlation is appropriate, since the approach should work even if only a small number of points are available. I think this is an optimization problem that minimizes the error between the data points and the known signal with respect to the delay. Is there any operator similar to cross correlation that achieves this, or does it need to be solved by going through each delay seperately?

• Is the delay fixed or time variant throughout the timeline of the two signals? – A_A Oct 1 '20 at 12:25
• the delay is fixed. The data points represent a partial observation of the delayed signal. and the delay just shifts the entire signal. – Keith Klein Oct 1 '20 at 12:48

## 1 Answer

Just doing something like: $$e_\delta = \sum_{n=0}^{N-1} \left| x[n-\delta] - x_\delta[n]\right|^2$$ for several values of $$\delta$$ and choosing $$\hat{\delta} = \arg \min_{\delta} e_\delta$$ (i.e. the value of delta that minimizes $$e_\delta$$) will probably be good enough.

Example signals below: gives the following error plot The error plot seems to give the right value of about 5.5 samples for this contrived example data.

Code Only Below

from numpy import log10, asarray, polyfit, ceil, arange, exp, sin, pi, log, random, sum, diff
import matplotlib.pyplot as plt
from scipy.signal import kaiserord, lfilter, firwin, freqz

T = 100
time_period = list(arange(1,T))

K1 = 10
K2 = -10
tau = 200
measurement = [K1 + K2*exp(-x/tau) for x in time_period]

fir_filter = [0,0,0,0,0,0.5,0.5,0,0,0,0]
channel_1 = lfilter(fir_filter,1, measurement)

max_delay = 20

def error_calculation(signal, delayed_signal, delay):
error = [ (signal[time-delay]-delayed_signal[time])**2 for time in list(arange(delay,T-delay)) ]
return sum(error)

plt.figure(0)
plt.figure(figsize=(20,20))
plt.plot(time_period, measurement)
plt.plot(time_period, channel_1)
error = []
for delay in arange(1,max_delay):
error.append(error_calculation(measurement,channel_1,delay))

plt.figure(1)
plt.figure(figsize=(20,20))
plt.plot(arange(1,max_delay), error)

• I think this is the correct solution. However, do you think there might be a more efficient way to calculate the error instead of a loop? – Keith Klein Oct 2 '20 at 9:43
• @KeithKlein It's not clear to me that it can be done much more efficiently... the signal needs to be compared with itself delayed for several different delays. Let me think about it a bit today and see if anything presents itself. – Peter K. Oct 3 '20 at 12:51