Is it possible to perform circular cross-/auto-correlation on 1D arrays with a numpy/scipy/matplotlib function? I have looked at numpy.correlate() and matplotlib.pyplot.xcorr (based on the numpy function), and both seem to not be able to do circular cross-correlation.
To illustrate the difference, I will use the example of an array of [1, 2, 3, 4]. With circular correlation, a periodic assumption is made, and a lag of 1 looks like [2, 3, 4, 1]. The python functions I've found only seem to use zero-padding, i.e., [2, 3, 4, 0]. Is there a way to get these functions to do circular correlation? If not, is there a standard workaround for circular correlations?
You can implement the periodic (a.k.a. circular) cross correlation using the FFT:
from numpy.fft import fft, ifft def periodic_corr(x, y): """Periodic correlation, implemented using the FFT. x and y must be real sequences with the same length. """ return ifft(fft(x) * fft(y).conj()).real
You can also implement it using
np.correlate, if you don't mind the overhead incurred by
import numpy as np def periodic_corr_np(x, y): """Periodic correlation, implemented using np.correlate. x and y must be real sequences with the same length. """ return np.correlate(x, np.hstack((y[1:], y)), mode='valid')
from numpy import roll, correlate x = [1,2,3,4] roll(x, 1) #[4,1,2,3] roll(x, 2) #[3,4,1,2] roll(x, 3) #[2,3,4,1]
To correlate x with x circularly shifted by k, you could do
k = 2 correlate(x, roll(x,k))