I have two time series, and i suspect that there is a time shift between them, and i want to estimate this time shift.
This question has been asked before in: Find phase
For the constraints given, namely that the solution is phase-shifted by a small amount less than the sampling method, a simple downhill simplex algorithm works well. I've modified the sample problem of @mgilson to show how to do this. Note that this solution is robust, in that it can handle noise.
Error function: There may be more optimal things to optimize over, but this works surprisingly well:
np.sqrt((X1-X2+delta_x)**2+(Y1-Y2)**2).sum()
That is, minimize the Euclidean distance between the two curves by only adjusting the x-axis (phase).
import numpy as np
def yvals(x):
return np.sin(x)+np.sin(2*x)+np.sin(3*x)
dx = .1
unknown_shift = .03 * np.random.random() * dx
X1 = np.arange(0,2*np.pi,dx) #some X values
X2 = X1 + unknown_shift
Y1 = yvals(X1)
Y2 = yvals(X2) # shifted Y
Y2 += .1*np.random.normal(size=X1.shape) # now with noise
def err_func(p):
return np.sqrt((X1-X2+p[0])**2+(Y1-Y2)**2).sum()
from scipy.optimize import fmin
p0 = [0,] # Inital guess of no shift
found_shift = fmin(err_func, p0)[0]
print "Unknown shift: ", unknown_shift
print "Found shift: ", found_shift
print "Percent error: ", abs((unknown_shift-found_shift)/unknown_shift)
A sample run gives:
Optimization terminated successfully.
Current function value: 4.804268
Iterations: 6
Function evaluations: 12
Unknown shift: 0.00134765446268
Found shift: 0.001375
Percent error: -0.0202912082305