Mercurial > hg > segmentation
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 |