GVAR#

class cultivars.multivariate.reduced_form.closed_global.GVAR(units, weights, *, variable_labels, unit_names=None)[source]#

Link fitted conditional units into one closed global system.

An assembler rather than an estimator, and the class says so by exposing solve() instead of fit. Every coefficient in the result was estimated by a unit; what happens here is the algebra that turns a collection of models each missing a law of motion for its own foreign variables into a single model that has one for everything. Unit \(i\) was fitted on \(z_{it} = (y_{it}', y^{*\prime}_{it})'\) with its foreign block the weighted average \(y^*_{it} = \sum_j w_{ij}\, y_{jt}\) of the same variables in the other units; writing \(z_{it} = W_i x_t\) against the global vector and stacking the units gives the square system \(G_0 x_t = d_t + \sum_l G_l x_{t-l} + u_t\) that solve() inverts.

Units may be heterogeneous – different orders, different variable counts, a mixture of levels and error-correction specifications – because the linkage reads each through the levels form it implies rather than through the parameterization it was estimated in. What they may not be is loosely built: the assembly reproduces the data exactly only when each unit’s exogenous block is precisely the aggregate the weight matrix and the variable labels describe – one foreign series per own variable, in the unit’s own variable order, averaged with that unit’s row of weights over the units whose labels match. The identity worth checking after a solve is the fitted one, endog[t] == deterministic + sum_l coefficients[l] @ endog[t - l] + resid[t] on the common sample; it holds to rounding when the aggregates were built as described and fails visibly when they were not.

Variables:
  • _units – The fitted unit results, in global column order.

  • _weights – The validated (n_units, n_units) weight matrix.

  • _labels – One shared variable label per global column.

  • _unit_names – One label per unit, unique.

See also

  • GVARResult – the assembled record solve() returns.

  • VARX – the conditional levels unit.

  • VECMX – the conditional error-correction unit, whose weak-exogeneity assumption the result can test.

References

Pesaran, M. H., Schuermann, T., & Weiner, S. M. (2004). Modeling regional interdependencies using a global error-correcting macroeconometric model. Journal of Business & Economic Statistics, 22(2), 129-162.

Chudik, A., & Pesaran, M. H. (2016). Theory and practice of GVAR modelling. Journal of Economic Surveys, 30(1), 165-197.

Example

Three units, one variable each, linked by a trade-weight matrix with a zero diagonal and unit row sums. Each unit is fitted against the aggregate its own weight row defines, and the assembled system reproduces the panel exactly and inherits the units’ persistence:

>>> import numpy as np
>>> from cultivars.multivariate.reduced_form.vector_autoregression import VARX
>>> rng = np.random.default_rng(0)
>>> y = np.zeros((300, 3))
>>> A = np.array([[0.5, 0.2, 0.1], [0.1, 0.5, 0.2], [0.2, 0.1, 0.5]])
>>> for t in range(1, 300):
...     y[t] = A @ y[t - 1] + rng.standard_normal(3)
>>> weights = np.array([[0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]])
>>> units = [
...     VARX(y[:, [i]], (y @ weights[i])[:, None], order=1).fit() for i in range(3)
... ]
>>> names = ("us", "eu", "jp")
>>> res = GVAR(units, weights, variable_labels=["gdp"] * 3, unit_names=names).solve()
>>> res.names
('us.gdp', 'eu.gdp', 'jp.gdp')
>>> fitted = res.endog[:-1] @ res.coefficients[0].T + res.deterministic[0]
>>> bool(np.allclose(res.endog[1:], fitted + res.resid))
True
>>> res.is_stable, bool(np.all(np.diag(res.coefficients[0]) > 0.35))
(True, True)

Attributes#

unit_of_column

Owning unit index for each global column.

variable_of_column

Variable identity for each global column, as integer codes.

Methods#

solve()

Close the system and return the global result.