I need to do auto-correlation of a set of numbers, which as I understand it is just the correlation of the set with itself.
I've tried it using numpy's correlate function, but I don't believe the result, as it almost always gives a vector where the first number is not the largest, as it ought to be.
So, this question is really two questions:
To answer your first question,
numpy.correlate(a, v, mode) is performing the convolution of
a with the reverse of
v and giving the results clipped by the specified mode. The definition of convolution, C(t)=∑ -∞ < i < ∞ aivt+i where -∞ < t < ∞, allows for results from -∞ to ∞, but you obviously can't store an infinitely long array. So it has to be clipped, and that is where the mode comes in. There are 3 different modes: full, same, & valid:
vhave some overlap.
vcompletely overlap each other. The documentation for
numpy.convolvegives more detail on the modes.
For your second question, I think
numpy.correlate is giving you the autocorrelation, it is just giving you a little more as well. The autocorrelation is used to find how similar a signal, or function, is to itself at a certain time difference. At a time difference of 0, the auto-correlation should be the highest because the signal is identical to itself, so you expected that the first element in the autocorrelation result array would be the greatest. However, the correlation is not starting at a time difference of 0. It starts at a negative time difference, closes to 0, and then goes positive. That is, you were expecting:
autocorrelation(a) = ∑ -∞ < i < ∞ aivt+i where 0 <= t < ∞
But what you got was:
autocorrelation(a) = ∑ -∞ < i < ∞ aivt+i where -∞ < t < ∞
What you need to do is take the last half of your correlation result, and that should be the autocorrelation you are looking for. A simple python function to do that would be:
def autocorr(x): result = numpy.correlate(x, x, mode='full') return result[result.size/2:]
You will, of course, need error checking to make sure that
x is actually a 1-d array. Also, this explanation probably isn't the most mathematically rigorous. I've been throwing around infinities because the definition of convolution uses them, but that doesn't necessarily apply for autocorrelation. So, the theoretical portion of this explanation may be slightly wonky, but hopefully the practical results are helpful. These pages on autocorrelation are pretty helpful, and can give you a much better theoretical background if you don't mind wading through the notation and heavy concepts.
Auto-correlation comes in two versions: statistical and convolution. They both do the same, except for a little detail: The statistical version is normalized to be on the interval [-1,1]. Here is an example of how you do the statistical one:
def acf(x, length=20): return numpy.array(+[numpy.corrcoef(x[:-i], x[i:])[0,1] \ for i in range(1, length)])