SpectralCausality#
- class cultivars.spectral.causality.SpectralCausality(result, *, n_frequencies=256)[source]#
Unconditional pairwise Geweke causality of a fitted closed system.
Not an estimator: constructs with a fitted result and decomposes it. The system’s transfer function \(\Psi(\omega) = [I - \sum_l A_l e^{-i\omega l}]^{-1}\) and innovation covariance \(\Sigma\) give its spectral density \(S(\omega) = \Psi \Sigma \Psi^\ast / 2\pi\). For a bivariate system the innovation representation is the model’s own and the measure follows directly; for a larger one each pair’s marginal process
\[S_{\{i,j\}}(\omega) = \Psi_{\{i,j\}\cdot}(\omega)\, \Sigma\, \Psi_{\{i,j\}\cdot}(\omega)^\ast / 2\pi\]is generally VARMA and matches no lag stack, so its own innovation representation \((H, \Sigma_{ij})\) is recovered exactly from the marginal density by Wilson’s spectral factorization – an iterative solve, converging quadratically for the smooth densities stable models produce – and the bivariate measure is computed from that. Nothing is re-estimated.
- Parameters:
result (
ClosedSystemResult) – A fitted closed reduced-form result with at least two variables.n_frequencies (
int) – Grid points on[0, pi], endpoints included.
- Variables:
_result – The fitted result being decomposed.
_n_frequencies – The grid size \(n\).
- Raises:
SpecificationError – If the result is not a closed system, has fewer than two variables, or the grid is too small.
Note
The grid is the caller’s resolution choice, and two things depend on it:
SpectralCausalityResult.band()averages the grid points inside a period band and refuses a band that catches none, so a narrow band needs a fine grid; and the spectral factorization for \(k > 2\) runs on the full circle of \(2(n - 1)\) points, so its cost and its accuracy both grow with \(n\). The default of 256 resolves the quarterly business-cycle band into about forty points.See also
SpectralCausalityResult– the recordcompute()returns.ConditionalSpectralCausality– the conditional measure, which needs a second fitted model.VARResult– a closed system whosegranger_causalityis the time-domain test of the same relation.
References
Geweke, J. (1982). Measurement of linear dependence and feedback between multiple time series. Journal of the American Statistical Association, 77(378), 304-313.
Dhamala, M., Rangarajan, G., & Ding, M. (2008). Estimating Granger causality from Fourier and wavelet transforms of time series data. Physical Review Letters, 100(1), 018701.
Wilson, G. T. (1972). The factorization of matricial spectral densities. SIAM Journal on Applied Mathematics, 23(4), 420-426.
Example
>>> import numpy as np >>> from cultivars.multivariate.reduced_form.vector_autoregression import VAR >>> rng = np.random.default_rng(0) >>> y = np.zeros((500, 2)) >>> for t in range(1, 500): ... y[t, 0] = 0.5 * y[t - 1, 0] + 0.4 * y[t - 1, 1] + rng.standard_normal() ... y[t, 1] = 0.5 * y[t - 1, 1] + rng.standard_normal() >>> spectral = SpectralCausality(VAR(y, order=1).fit(), n_frequencies=64) >>> causal = spectral.compute() >>> forward = causal.integrated()[0, 1] >>> backward = causal.integrated()[1, 0] >>> bool(forward > 10 * backward) True
A third, independent variable enters the system and the pairwise measures involving it stay near zero:
>>> wider = np.column_stack([y, rng.standard_normal(500)]) >>> three = SpectralCausality(VAR(wider, order=1).fit(), n_frequencies=32).compute() >>> three.measure.shape, bool(three.integrated()[:, 2].max() < 0.01) ((32, 3, 3), True)
Methods#
|
Decompose every ordered pair. |