def fit_model(x1, x2, order=None, max_order=10, criterion=utils.bayesian_information_criterion): """ Fit the auto-regressive model used in calculation of Granger 'causality'. Parameters ---------- x1,x2: float arrays (n) x1,x2 bivariate combination. order: int (optional) If known, the order of the autoregressive process max_order: int (optional) If the order is not known, this will be the maximal order to fit. criterion: callable A function which defines an information criterion, used to determine the order of the model. """ c_old = np.inf n_process = 2 Ntotal = n_process * x1.shape[-1] # If model order was provided as an input: if order is not None: lag = order + 1 Rxx = utils.autocov_vector(np.vstack([x1, x2]), nlags=lag) coef, ecov = alg.lwr_recursion(np.array(Rxx).transpose(2, 0, 1)) # If the model order is not known and provided as input: else: for lag in xrange(1, max_order): Rxx_new = utils.autocov_vector(np.vstack([x1, x2]), nlags=lag) coef_new, ecov_new = alg.lwr_recursion( np.array(Rxx_new).transpose(2, 0, 1)) order_new = coef_new.shape[0] c_new = criterion(ecov_new, n_process, order_new, Ntotal) if c_new > c_old: # Keep the values you got in the last round and break out: break else: # Replace the output values with the new calculated values and # move on to the next order: c_old = c_new order = order_new Rxx = Rxx_new coef = coef_new ecov = ecov_new else: e_s = ( "Model estimation order did not converge at max_order = %s" % max_order) raise ValueError(e_s) return order, Rxx, coef, ecov
def fit_model(x1, x2, order=None, max_order=10, criterion=utils.bayesian_information_criterion): """ Fit the auto-regressive model used in calculation of Granger 'causality'. Parameters ---------- x1,x2: float arrays (n) x1,x2 bivariate combination. order: int (optional) If known, the order of the autoregressive process max_order: int (optional) If the order is not known, this will be the maximal order to fit. criterion: callable A function which defines an information criterion, used to determine the order of the model. """ c_old = np.inf n_process = 2 Ntotal = n_process * x1.shape[-1] # If model order was provided as an input: if order is not None: lag = order + 1 Rxx = utils.autocov_vector(np.vstack([x1, x2]), nlags=lag) coef, ecov = alg.lwr_recursion(np.array(Rxx).transpose(2, 0, 1)) # If the model order is not known and provided as input: else: for lag in range(1, max_order): Rxx_new = utils.autocov_vector(np.vstack([x1, x2]), nlags=lag) coef_new, ecov_new = alg.lwr_recursion( np.array(Rxx_new).transpose(2, 0, 1)) order_new = coef_new.shape[0] c_new = criterion(ecov_new, n_process, order_new, Ntotal) if c_new > c_old: # Keep the values you got in the last round and break out: break else: # Replace the output values with the new calculated values and # move on to the next order: c_old = c_new order = order_new Rxx = Rxx_new coef = coef_new ecov = ecov_new else: e_s = ("Model estimation order did not converge at max_order = %s" % max_order) raise ValueError(e_s) return order, Rxx, coef, ecov
def MAR_est_LWR(x, order, rxx=None): r""" MAR estimation, using the LWR algorithm, as in Morf et al. Parameters ---------- x : ndarray The sampled autoregressive random process order : int The order P of the AR system rxx : ndarray (optional) An optional, possibly unbiased estimate of the autocovariance of x Returns ------- a, ecov: The system coefficients and the estimated covariance """ Rxx = utils.autocov_vector(x, nlags=order) a, ecov = lwr_recursion(Rxx.transpose(2, 0, 1)) return a, ecov
def MAR_est_LWR(x, order, rxx=None): r""" MAR estimation, using the LWR algorithm, as in Morf et al. Parameters ---------- x : ndarray The sampled autoregressive random process order : int The order P of the AR system rxx : ndarray (optional) An optional, possibly unbiased estimate of the autocovariance of x Returns ------- a, ecov : The system coefficients and the estimated covariance """ Rxx = utils.autocov_vector(x, nlags=order) a, ecov = lwr_recursion(Rxx.transpose(2, 0, 1)) return a, ecov
def test_information_criteria(): """ Test the implementation of information criteria: """ a1 = np.array([[0.9, 0], [0.16, 0.8]]) a2 = np.array([[-0.5, 0], [-0.2, -0.5]]) am = np.array([-a1, -a2]) x_var = 1 y_var = 0.7 xy_cov = 0.4 cov = np.array([[x_var, xy_cov], [xy_cov, y_var]]) #Number of realizations of the process N = 500 #Length of each realization: L = 1024 order = am.shape[0] n_process = am.shape[-1] z = np.empty((N, n_process, L)) nz = np.empty((N, n_process, L)) for i in xrange(N): z[i], nz[i] = utils.generate_mar(am, cov, L) AIC = [] BIC = [] AICc = [] # The total number data points available for estimation: Ntotal = L * n_process for n_lags in range(1, 10): Rxx = np.empty((N, n_process, n_process, n_lags)) for i in xrange(N): Rxx[i] = utils.autocov_vector(z[i], nlags=n_lags) Rxx = Rxx.mean(axis=0) Rxx = Rxx.transpose(2, 0, 1) a, ecov = alg.lwr_recursion(Rxx) IC = utils.akaike_information_criterion(ecov, n_process, n_lags, Ntotal) AIC.append(IC) IC = utils.akaike_information_criterion(ecov, n_process, n_lags, Ntotal, corrected=True) AICc.append(IC) IC = utils.bayesian_information_criterion(ecov, n_process, n_lags, Ntotal) BIC.append(IC) # The model has order 2, so this should minimize on 2: # We do not test this for AIC/AICc, because these sometimes do not minimize # (see Ding and Bressler) # nt.assert_equal(np.argmin(AIC), 2) # nt.assert_equal(np.argmin(AICc), 2) nt.assert_equal(np.argmin(BIC), 2)
R^{xx}_{11}(k) = E( Z_1(t)Z_1^*(t-k) ) Where $E$ is the expected value and $^*$ marks the conjugate transpose. Thus, only $R^{xx}(0)$ is symmetric. This is calculated by using the function :func:`utils.autocov_vector`. Notice that the estimation is done for an assumed known process order. In practice, if the order of the process is unknown, we will have to use some criterion in order to choose an appropriate order, given the data. """ Rxx = np.empty((N, n_process, n_process, n_lags)) for i in range(N): Rxx[i] = utils.autocov_vector(z[i], nlags=n_lags) Rxx = Rxx.mean(axis=0) R0 = Rxx[..., 0] Rm = Rxx[..., 1:] Rxx = Rxx.transpose(2, 0, 1) """ We use the Levinson-Whittle(-Wiggins) and Robinson algorithm, as described in [Morf1978]_ , in order to estimate the MAR coefficients and the covariance matrix: """
for i in range(N): za[i], ea[i] = utils.generate_mar(a, cov, L) zb[i], eb[i] = utils.generate_mar(b, cov, L) """ Try to estimate the 2nd order (m)AR coefficients-- Average together N estimates of auto-covariance at lags k=0,1,2 """ Raxx = np.empty((N, 3, 3, 3)) Rbxx = np.empty((N, 3, 3, 3)) for i in range(N): Raxx[i] = utils.autocov_vector(za[i], nlags=3) Rbxx[i] = utils.autocov_vector(zb[i], nlags=3) """ Average trials together to find autocovariance estimate, and extract pairwise components from the ac sequence: """ Raxx = Raxx.mean(axis=0) xyRa = extract_ij(0, 1, Raxx) xzRa = extract_ij(0, 2, Raxx) yzRa = extract_ij(1, 2, Raxx)
eb = np.empty((N, 3, L)) for i in range(N): za[i], ea[i] = utils.generate_mar(a, cov, L) zb[i], eb[i] = utils.generate_mar(b, cov, L) """ Try to estimate the 2nd order (m)AR coefficients-- Average together N estimates of auto-covariance at lags k=0,1,2 """ Raxx = np.empty((N, 3, 3, 3)) Rbxx = np.empty((N, 3, 3, 3)) for i in range(N): Raxx[i] = utils.autocov_vector(za[i], nlags=3) Rbxx[i] = utils.autocov_vector(zb[i], nlags=3) """ Average trials together to find autocovariance estimate, and extract pairwise components from the ac sequence: """ Raxx = Raxx.mean(axis=0) xyRa = extract_ij(0, 1, Raxx) xzRa = extract_ij(0, 2, Raxx) yzRa = extract_ij(1, 2, Raxx) Rbxx = Rbxx.mean(axis=0) xyRb = extract_ij(0, 1, Rbxx)