I want to autocorrelate a signal using numpy's correlate method.

Let us consider a 10 minutes long signal sampled at 2,000SPS:

import numpy as np
import random
import matplotlib.pyplot as plt
import scipy.signal as signal

number_of_samples = sampling_rate*duration_in_seconds 

samples = np.arange(number_of_samples)    
test_array = np.sin(2*np.pi*samples/float(number_of_samples/1000))+np.sin(2*np.pi*samples/float(number_of_samples/42))+np.random.random(600*sampling_rate) 

This synthetic test array is displayed below:

enter image description here

Let us autocorrelate the first second of data using correlate's default same mode:

acorr_one_second=np.correlate(test_array[:2000], test_array[:2000], mode='same') 

This yields the following plot:

enter image description here

Now, what happens if we upsample our original data by a factor of x1.25, i.e. if we upsample them to 2,500SPS?

upsampled_samples=np.arange(0,sampling_rate*duration_in_seconds, 1/1.25)
upsampled_test_array = signal.resample(test_array,duration_in_seconds*upsampled_sampling_rate)

Running plt.plot(acorr_upsampled_samples,acorr_one_second_upsampled, color='orange',linewidth=2) yields the following plot:

enter image description here

The amplitude of the autocorrelated upsampled data is exactly 1.25 times greater than that of the original data. Is this the expected behaviour?

I must admit that I have always thought of autocorrelation in terms of the "relative" amplitude variations indicating how well a signal correlates with itself. But what is the meaning of the "absolute" amplitude of the autocorrelated data?


Upsampling is the process of inserting zeros between each sample, and that won't affect the magnitude as the total count will not have changed, but interpolation as the OP is doing which is the combination of upsampling and an interpolation filter will. In this case the zeros have grown through the interpolation filter to the expected values between the original samples, and we have an interpolated waveform as a result with more samples that will contribute to the growth of the autocorrelation function.

Autocorrelation is not the normalized correlation coefficient but simply the sum of products. The autocorrelation at time offset zero will scale by the number of samples.

Generally the autocorrelation for a discrete sequence is given as:

$$r_{ff}[\ell] = \sum_{-\infty}^{\infty}f[n]f^*[n+\ell]$$

When the time index $\ell=0$, this results in:

$$r_{ff}[\ell = 0] = \sum_{-\infty}^{\infty}f[n]f^*[n]$$

Where we see that it is simply a sum of the complex conjugate product for every sample $n$ in $f[n]$

  • 1
    $\begingroup$ Thanks for your detailed answer, Dan! $\endgroup$
    – Sheldon
    Jun 23 at 22:07

Let's take a look at a simple example. Let's just say we have x = [1 1 1 1].

If we resample this by 1.25 we get y = [1 1 1 1 1] (assuming some perfect resampler that doesn't really exist). The signal amplitude is maintained. However since we have got one more sample, the signal energy is NOT maintained, i.e. $\sum x^2 = 4$ whereas $\sum y^2 = 5$.

The autocorrelation at lag 0 corresponds to the signal energy and hence, $r_{yy}[0] = 1.25*r_{xx}[0]$.

If you resample you can either maintain the amplitude/power OR the energy, but not both, since the length of the signal changes. The easiest way to deal with this, is to use the normalized auto (or cross) correlation: normalize by the total signal energy.

  • $\begingroup$ Thanks Hilmar. This simple example hits the spot! $\endgroup$
    – Sheldon
    Jun 23 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.