def _var_acf(coefs, sig_u): """ Compute autocovariance function ACF_y(h) for h=1,...,p Notes ----- Lutkepohl (2005) p.29 """ p, k, k2 = coefs.shape assert(k == k2) A = util.comp_matrix(coefs) # construct VAR(1) noise covariance SigU = np.zeros((k*p, k*p)) SigU[:k,:k] = sig_u # vec(ACF) = (I_(kp)^2 - kron(A, A))^-1 vec(Sigma_U) vecACF = L.solve(np.eye((k*p)**2) - np.kron(A, A), vec(SigU)) acf = unvec(vecACF) acf = acf[:k].T.reshape((p, k, k)) return acf
def test_causality(self, equation, variables, kind='f', signif=0.05, verbose=True): """Compute test statistic for null hypothesis of Granger-noncausality, general function to test joint Granger-causality of multiple variables Parameters ---------- equation : string or int Equation to test for causality variables : sequence (of strings or ints) List, tuple, etc. of variables to test for Granger-causality kind : {'f', 'wald'} Perform F-test or Wald (chi-sq) test signif : float, default 5% Significance level for computing critical values for test, defaulting to standard 0.95 level Notes ----- Null hypothesis is that there is no Granger-causality for the indicated variables. The degrees of freedom in the F-test are based on the number of variables in the VAR system, that is, degrees of freedom are equal to the number of equations in the VAR times degree of freedom of a single equation. Returns ------- results : dict """ if isinstance(variables, (basestring, int, np.integer)): variables = [variables] k, p = self.neqs, self.k_ar # number of restrictions N = len(variables) * self.k_ar # Make restriction matrix C = np.zeros((N, k ** 2 * p + k), dtype=float) eq_index = self.get_eq_index(equation) vinds = mat([self.get_eq_index(v) for v in variables]) # remember, vec is column order! offsets = np.concatenate([k + k ** 2 * j + k * vinds + eq_index for j in range(p)]) C[np.arange(N), offsets] = 1 # Lutkepohl 3.6.5 Cb = np.dot(C, vec(self.params.T)) middle = L.inv(chain_dot(C, self.cov_params, C.T)) # wald statistic lam_wald = statistic = chain_dot(Cb, middle, Cb) if kind.lower() == 'wald': df = N dist = stats.chi2(df) elif kind.lower() == 'f': statistic = lam_wald / N df = (N, k * self.df_resid) dist = stats.f(*df) else: raise Exception('kind %s not recognized' % kind) pvalue = dist.sf(statistic) crit_value = dist.ppf(1 - signif) conclusion = 'fail to reject' if statistic < crit_value else 'reject' results = { 'statistic' : statistic, 'crit_value' : crit_value, 'pvalue' : pvalue, 'df' : df, 'conclusion' : conclusion, 'signif' : signif } if verbose: summ = output.causality_summary(results, variables, equation, kind) print summ return results
def test_commutation_matrix(): m = np.random.randn(4, 3) K = tools.commutation_matrix(4, 3) assert (np.array_equal(vec(m.T), np.dot(K, vec(m))))
def test_vec(): arr = np.array([[1, 2], [3, 4]]) assert (np.array_equal(vec(arr), [1, 3, 2, 4]))
def test_duplication_matrix(): for k in range(2, 10): m = tools.unvech(np.random.randn(k * (k + 1) // 2)) Dk = tools.duplication_matrix(k) assert (np.array_equal(vec(m), np.dot(Dk, vech(m))))
def test_elimination_matrix(): for k in range(2, 10): m = np.random.randn(k, k) Lk = tools.elimination_matrix(k) assert (np.array_equal(vech(m), np.dot(Lk, vec(m))))
def test_vec(): arr = np.array([[1, 2], [3, 4]]) assert(np.array_equal(vec(arr), [1, 3, 2, 4]))
def test_commutation_matrix(): m = np.random.randn(4, 3) K = tools.commutation_matrix(4, 3) assert(np.array_equal(vec(m.T), np.dot(K, vec(m))))
def test_elimination_matrix(): for k in range(2, 10): m = np.random.randn(k, k) Lk = tools.elimination_matrix(k) assert(np.array_equal(vech(m), np.dot(Lk, vec(m))))
def test_duplication_matrix(): for k in range(2, 10): m = tools.unvech(np.random.randn(k * (k + 1) // 2)) Dk = tools.duplication_matrix(k) assert(np.array_equal(vec(m), np.dot(Dk, vech(m))))
def a_test_causality(self, caused, causing=None, kind='f', signif=0.05): if not (0 < signif < 1): raise ValueError("signif has to be between 0 and 1") allowed_types = (string_types, int) if isinstance(caused, allowed_types): caused = [caused] if not all(isinstance(c, allowed_types) for c in caused): raise TypeError("caused has to be of type string or int (or a " "sequence of these types).") caused = [self.names[c] if type(c) == int else c for c in caused] caused_ind = [util.get_index(self.names, c) for c in caused] if causing is not None: if isinstance(causing, allowed_types): causing = [causing] if not all(isinstance(c, allowed_types) for c in causing): raise TypeError("causing has to be of type string or int (or " "a sequence of these types) or None.") causing = [self.names[c] if type(c) == int else c for c in causing] causing_ind = [util.get_index(self.names, c) for c in causing] if causing is None: causing_ind = [i for i in range(self.neqs) if i not in caused_ind] causing = [self.names[c] for c in caused_ind] k, p = self.neqs, self.k_ar # number of restrictions num_restr = len(causing) * len(caused) * p num_det_terms = self.k_exog # Make restriction matrix C = np.zeros((num_restr, k * num_det_terms + k ** 2 * p), dtype=float) cols_det = k * num_det_terms row = 0 for j in range(p): for ing_ind in causing_ind: for ed_ind in caused_ind: C[row, cols_det + ed_ind + k * ing_ind + k ** 2 * j] = 1 row += 1 # Lutkepohl 3.6.5 Cb = np.dot(C, vec(self.params.T)) middle = scipy.linalg.inv(chain_dot(C, self.cov_params, C.T)) # wald statistic lam_wald = statistic = chain_dot(Cb, middle, Cb) if kind.lower() == 'wald': df = num_restr dist = stats.chi2(df) elif kind.lower() == 'f': statistic = lam_wald / num_restr df = (num_restr, k * self.df_resid) dist = stats.f(*df) else: raise Exception('kind %s not recognized' % kind) pvalue = dist.sf(statistic) crit_value = dist.ppf(1 - signif) # print(pvalue) # print("---====--") return pvalue, CausalityTestResults(causing, caused, statistic, crit_value, pvalue, df, signif, test="granger", method=kind)