def fit_acf_by_AR1(acf_empir, nlags=None): """Fit an empirical auto cov function (ACF) by that of an AR1 process. - `acf_empir`: auto-corr/cov-function. - `nlags`: length of ACF to use in AR(1) fitting """ if nlags is None: nlags = len(acf_empir) # geometric_mean = ss.mstats.gmean def geometric_mean(xx): return np.exp(np.mean(np.log(xx))) def mean_ratio(xx): return geometric_mean([xx[i] / xx[i - 1] for i in range(1, len(xx))]) # Negative correlation => Truncate ACF neg_ind = find_1st_ind(np.array(acf_empir) <= 0) acf_empir = acf_empir[:neg_ind] if len(acf_empir) == 0: return 0 elif len(acf_empir) == 1: return 0.01 else: return mean_ratio(acf_empir)
def estimate_good_plot_length(xx, chrono=None, mult=100): """Estimate the range of the xx slices for plotting. The length is based on the estimated time scale (wavelength) of the system. Provide sensible fall-backs (better if chrono is supplied). Parameters ---------- xx: ndarray Plotted array chrono: `dapper.tools.chronos.Chronology`, optional object with property dkObS. Defaults: None mult: int, optional Number of waves for plotting. Defaults: 100 Returns ------- K: int length for plotting Example ------- >>> K_lag = estimate_good_plot_length(stats.xx, chrono, mult=80) # doctest: +SKIP """ if xx.ndim == 2: # If mult-dim, then average over dims (by ravel).... # But for inhomogeneous variables, it is important # to subtract the mean first! xx = xx - np.mean(xx, axis=0) xx = xx.ravel(order='F') try: K = mult * series.estimate_corr_length(xx) except ValueError: K = 0 if chrono is not None: t = chrono K = int(min(max(K, t.dkObs), t.K)) T = round2sigfig(t.tt[K], 2) # Could return T; T>tt[-1] K = find_1st_ind(t.tt >= T) if K: return K else: return t.K else: K = int(min(max(K, 1), len(xx))) T = round2sigfig(K, 2) return K