comparison utils/acorr.py @ 0:26838b1f560f

initial commit of a segmenter project
author mi tian
date Thu, 02 Apr 2015 18:09:27 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:26838b1f560f
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 acorr.py
5
6 This function provides similar fuctionality to Matlab's xcorr() but for computing autocorrelation only.
7
8 It gives equivalent results given the following Matlab test script:
9
10 %==== MATLAB ====
11 a=[1,2,3,4,5,1,2,3,4,5,2,3,4,5,6,1,2,3,4,5];
12 [xcr,lag] = xcorr(a,a,20,'unbiased');
13 disp(xcr);
14 plot(lag,xcr);
15 %==== MATLAB ====
16
17 Created by George Fazekas on 2014-02-26.
18 Copyright (c) 2014 . All rights reserved.
19 """
20
21 import sys,os
22 import numpy as np
23 from scipy.fftpack import fft, ifft
24
25 class ACORR(object):
26
27 def nextpow2(self, n):
28 '''Return the next power of 2 such as 2^p >= n'''
29 if np.any(n < 0):
30 raise ValueError("n should be > 0")
31 if np.isscalar(n):
32 f, p = np.frexp(n)
33 if f == 0.5:
34 return p-1
35 elif np.isfinite(f):
36 return p
37 else:
38 return f
39 else:
40 f, p = np.frexp(n)
41 res = f
42 bet = np.isfinite(f)
43 exa = (f == 0.5)
44 res[bet] = p[bet]
45 res[exa] = p[exa] - 1
46 return res
47
48 def acorr_ifft_fft(self, x, nfft, lag, onesided=False, scale='none'):
49 '''Compute the actual autocorrelation via IFFT/FFT '''
50 ra = np.real(ifft(np.abs(fft(x, n=nfft) ** 2)))
51 if onesided:
52 b = ra[..., :lag]
53 else:
54 b = np.concatenate([ra[..., nfft-lag+1:nfft], ra[..., :lag]], axis=-1)
55 #print b, ra[..., 0][..., np.newaxis], b / ra[..., 0][..., np.newaxis]
56 if scale == 'coeff':
57 return b / ra[..., 0][..., np.newaxis]
58 elif scale == 'unbiased':
59 '''scale = len(x)-abs(lags)'''
60 lags = np.array(range(-lag+1,lag))
61 # print lags,len(x)
62 scale = len(x) - abs(lags)
63 scale[scale<=0] = 1.0
64 # print scale
65 return b/scale
66 else:
67 return b
68
69 def acorr(self, x, axis=-1, onesided=False, lag=None, scale='none'):
70 '''Compute autocorrelation of x along given axis.
71 x : array-like
72 signal to correlate.
73 axis : int
74 axis along which autocorrelation is computed.
75 onesided: bool, optional
76 if True, only returns the right side of the autocorrelation.
77 scale: {'none', 'coeff'} scaling mode.
78 If 'coeff', the correlation is normalised such as the 0-lag is equal to 1.
79 if 'unbiased' the correlation is normalised using len(x) - abs(lags) '''
80
81 if not scale in ['none', 'coeff','unbiased']:
82 raise ValueError("scale mode %s not understood" % scale)
83 if not lag :
84 lag = x.shape[axis]
85 lag += 1
86 nfft = 2 ** self.nextpow2(2 * lag - 1)
87 lags = np.array(range(-lag+1, lag))
88 if axis != -1:
89 x = np.swapaxes(x, -1, axis)
90 a = self.acorr_ifft_fft(x, nfft, lag, onesided, scale)
91 if axis != -1:
92 a = np.swapaxes(a, -1, axis)
93 return a,lags
94