Let's say have have two signals:
import numpy
dt = 0.001
t_steps = np.arange(0, 1, dt)
a_sig = np.sin(2*np.pi*t_steps*4+5)
b_sig = np.sin(2*np.pi*t_steps*4)
I want to shift the first signal to match the second signal. I know this can be completed using cross-correlation, as evidenced by Matlab, but how do I accomplish this with SciPy.
Time-lagged cross-correlation usually refers to the correlation between two time series shifted relatively in time. Time-lagged cross-correlations between time series have been studied and an analytic method has been widely applied in diverse fields [2], [3], [4], [5], [6], [7].
To detect a level of correlation between two signals we use cross-correlation. It is calculated simply by multiplying and summing two-time series together. In the following example, graphs A and B are cross-correlated but graph C is not correlated to either.
Cross correlation and autocorrelation are very similar, but they involve different types of correlation: Cross correlation happens when two different sequences are correlated. Autocorrelation is the correlation between two of the same sequences. In other words, you correlate a signal with itself.
In general, the projection of time series X on time series Y's past is supposed to capture the causal influence from Y to X. However, when X and Y are zero-lag correlated, Y's past is instantaneously related to X's past, which in turn is related to X's present due to serial correlation in X.
See some examples first. Assume we are in unit tests class already.
# Autocorrelation.
y1 = [1, 1, 0, 0, 1, -1, -1]
corr, lag = cross_corr(y1, y1)
self.assertEqual(lag, 0)
y1 = [1, 1, 0 ,1, -1, -1]
y2 = [1, 0, 1, 0, 0, 2]
corr, lag = cross_corr(y1, y2)
self.assertEqual(lag, -2)
here is my code.
import numpy as np
def cross_corr(y1, y2):
"""Calculates the cross correlation and lags without normalization.
The definition of the discrete cross-correlation is in:
https://www.mathworks.com/help/matlab/ref/xcorr.html
Args:
y1, y2: Should have the same length.
Returns:
max_corr: Maximum correlation without normalization.
lag: The lag in terms of the index.
"""
if len(y1) != len(y2):
raise ValueError('The lengths of the inputs should be the same.')
y1_auto_corr = np.dot(y1, y1) / len(y1)
y2_auto_corr = np.dot(y2, y2) / len(y1)
corr = np.correlate(y1, y2, mode='same')
# The unbiased sample size is N - lag.
unbiased_sample_size = np.correlate(
np.ones(len(y1)), np.ones(len(y1)), mode='same')
corr = corr / unbiased_sample_size / np.sqrt(y1_auto_corr * y2_auto_corr)
shift = len(y1) // 2
max_corr = np.max(corr)
argmax_corr = np.argmax(corr)
return max_corr, argmax_corr - shift
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With