def acf(x, unbiased=False, nlags=40, confint=None, qstat=False, fft=False, alpha=None): ''' Autocorrelation function for 1d arrays. Parameters ---------- x : array Time series data unbiased : bool If True, then denominators for autocovariance are n-k, otherwise n nlags: int, optional Number of lags to return autocorrelation for. confint : scalar, optional The use of confint is deprecated. See `alpha`. If a number is given, the confidence intervals for the given level are returned. For instance if confint=95, 95 % confidence intervals are returned where the standard deviation is computed according to Bartlett\'s formula. qstat : bool, optional If True, returns the Ljung-Box q statistic for each autocorrelation coefficient. See q_stat for more information. fft : bool, optional If True, computes the ACF via FFT. alpha : scalar, optional If a number is given, the confidence intervals for the given level are returned. For instance if alpha=.05, 95 % confidence intervals are returned where the standard deviation is computed according to Bartlett\'s formula. Returns ------- acf : array autocorrelation function confint : array, optional Confidence intervals for the ACF. Returned if confint is not None. qstat : array, optional The Ljung-Box Q-Statistic. Returned if q_stat is True. pvalues : array, optional The p-values associated with the Q-statistics. Returned if q_stat is True. Notes ----- The acf at lag 0 (ie., 1) is returned. This is based np.correlate which does full convolution. For very long time series it is recommended to use fft convolution instead. If unbiased is true, the denominator for the autocovariance is adjusted but the autocorrelation is not an unbiased estimtor. ''' nobs = len(x) d = nobs # changes if unbiased if not fft: avf = acovf(x, unbiased=unbiased, demean=True) #acf = np.take(avf/avf[0], range(1,nlags+1)) acf = avf[:nlags + 1] / avf[0] else: #JP: move to acovf x0 = x - x.mean() # ensure that we always use a power of 2 or 3 for zero-padding, # this way we'll ensure O(n log n) runtime of the fft. n = _next_regular(2 * nobs + 1) Frf = np.fft.fft(x0, n=n) # zero-pad for separability if unbiased: d = nobs - np.arange(nobs) acf = np.fft.ifft(Frf * np.conjugate(Frf))[:nobs] / d acf /= acf[0] #acf = np.take(np.real(acf), range(1,nlags+1)) acf = np.real(acf[:nlags + 1]) # keep lag 0 if not (confint or qstat or alpha): return acf if not confint is None: import warnings warnings.warn("confint is deprecated. Please use the alpha keyword", FutureWarning) varacf = np.ones(nlags + 1) / nobs varacf[0] = 0 varacf[1] = 1. / nobs varacf[2:] *= 1 + 2 * np.cumsum(acf[1:-1]**2) interval = stats.norm.ppf(1 - (100 - confint) / 200.) * np.sqrt(varacf) confint = np.array(zip(acf - interval, acf + interval)) if not qstat: return acf, confint if alpha is not None: varacf = np.ones(nlags + 1) / nobs varacf[0] = 0 varacf[1] = 1. / nobs varacf[2:] *= 1 + 2 * np.cumsum(acf[1:-1]**2) interval = stats.norm.ppf(1 - alpha / 2.) * np.sqrt(varacf) confint = np.array(zip(acf - interval, acf + interval)) if not qstat: return acf, confint if qstat: qstat, pvalue = q_stat(acf[1:], nobs=nobs) # drop lag 0 if (confint is not None or alpha is not None): return acf, confint, qstat, pvalue else: return acf, qstat, pvalue
def test_next_regular(): hams = { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 8, 8: 8, 14: 15, 15: 15, 16: 16, 17: 18, 1021: 1024, 1536: 1536, 51200000: 51200000, 510183360: 510183360, 510183360+1: 512000000, 511000000: 512000000, 854296875: 854296875, 854296875+1: 859963392, 196608000000: 196608000000, 196608000000+1: 196830000000, 8789062500000: 8789062500000, 8789062500000+1: 8796093022208, 206391214080000: 206391214080000, 206391214080000+1: 206624260800000, 470184984576000: 470184984576000, 470184984576000+1: 470715894135000, 7222041363087360: 7222041363087360, 7222041363087360+1: 7230196133913600, # power of 5 5**23 11920928955078125: 11920928955078125, 11920928955078125-1: 11920928955078125, # power of 3 3**34 16677181699666569: 16677181699666569, 16677181699666569-1: 16677181699666569, # power of 2 2**54 18014398509481984: 18014398509481984, 18014398509481984-1: 18014398509481984, # above this, int(ceil(n)) == int(ceil(n+1)) 19200000000000000: 19200000000000000, 19200000000000000+1: 19221679687500000, 288230376151711744: 288230376151711744, 288230376151711744+1: 288325195312500000, 288325195312500000-1: 288325195312500000, 288325195312500000: 288325195312500000, 288325195312500000+1: 288555831593533440, # power of 3 3**83 3990838394187339929534246675572349035227-1: 3990838394187339929534246675572349035227, 3990838394187339929534246675572349035227: 3990838394187339929534246675572349035227, # power of 2 2**135 43556142965880123323311949751266331066368-1: 43556142965880123323311949751266331066368, 43556142965880123323311949751266331066368: 43556142965880123323311949751266331066368, # power of 5 5**57 6938893903907228377647697925567626953125-1: 6938893903907228377647697925567626953125, 6938893903907228377647697925567626953125: 6938893903907228377647697925567626953125, # http://www.drdobbs.com/228700538 # 2**96 * 3**1 * 5**13 290142196707511001929482240000000000000-1: 290142196707511001929482240000000000000, 290142196707511001929482240000000000000: 290142196707511001929482240000000000000, 290142196707511001929482240000000000000+1: 290237644800000000000000000000000000000, # 2**36 * 3**69 * 5**7 4479571262811807241115438439905203543080960000000-1: 4479571262811807241115438439905203543080960000000, 4479571262811807241115438439905203543080960000000: 4479571262811807241115438439905203543080960000000, 4479571262811807241115438439905203543080960000000+1: 4480327901140333639941336854183943340032000000000, # 2**37 * 3**44 * 5**42 30774090693237851027531250000000000000000000000000000000000000-1: 30774090693237851027531250000000000000000000000000000000000000, 30774090693237851027531250000000000000000000000000000000000000: 30774090693237851027531250000000000000000000000000000000000000, 30774090693237851027531250000000000000000000000000000000000000+1: 30778180617309082445871527002041377406962596539492679680000000, } for x, y in hams.items(): assert_equal(_next_regular(x), y)