1"""
2Test SVAR estimation
3"""
4from statsmodels.compat.platform import PLATFORM_WIN
5
6import numpy as np
7from numpy.testing import assert_allclose, assert_almost_equal
8import pytest
9
10import statsmodels.datasets.macrodata
11from statsmodels.tsa.vector_ar.svar_model import SVAR
12
13DECIMAL_6 = 6
14DECIMAL_5 = 5
15DECIMAL_4 = 4
16
17
18class TestSVAR(object):
19    @classmethod
20    def setup_class(cls):
21        mdata = statsmodels.datasets.macrodata.load_pandas().data
22        mdata = mdata[['realgdp', 'realcons', 'realinv']]
23        data = mdata.values
24        data = np.diff(np.log(data), axis=0)
25        A = np.asarray([[1, 0, 0], ['E', 1, 0], ['E', 'E', 1]], dtype="U")
26        B = np.asarray([['E', 0, 0], [0, 'E', 0], [0, 0, 'E']], dtype="U")
27        results = SVAR(data, svar_type='AB', A=A, B=B).fit(maxlags=3)
28        cls.res1 = results
29        #cls.res2 = results_svar.SVARdataResults()
30        from .results import results_svar_st
31        cls.res2 = results_svar_st.results_svar1_small
32
33    def _reformat(self, x):
34        return x[[1, 4, 7, 2, 5, 8, 3, 6, 9, 0], :].ravel("F")
35
36    def test_A(self):
37        assert_almost_equal(self.res1.A, self.res2.A, DECIMAL_4)
38
39    def test_B(self):
40        # see issue #3148, adding np.abs to make solution positive
41        # general case will need positive sqrt of covariance matrix
42        assert_almost_equal(np.abs(self.res1.B), self.res2.B, DECIMAL_4)
43
44    def test_basic(self):
45        res1 = self.res1
46        res2 = self.res2
47        assert_allclose(self._reformat(res1.params), res2.b_var, atol=1e-12)
48        bse_st = np.sqrt(np.diag(res2.V_var))
49        assert_allclose(self._reformat(res1.bse), bse_st, atol=1e-12)
50
51    def test_llf_ic(self):
52        res1 = self.res1
53        res2 = self.res2
54        assert_allclose(res1.llf, res2.ll_var, atol=1e-12)
55        # different definition, missing constant term ?
56        corr_const = -8.51363119922803
57        assert_allclose(res1.fpe, res2.fpe_var, atol=1e-12)
58        assert_allclose(res1.aic - corr_const, res2.aic_var, atol=1e-12)
59        assert_allclose(res1.bic - corr_const, res2.sbic_var, atol=1e-12)
60        assert_allclose(res1.hqic - corr_const, res2.hqic_var, atol=1e-12)
61
62    @pytest.mark.smoke
63    def test_irf(self):
64        # mostly SMOKE, API test
65        # this only checks that the methods work and produce the same result
66        res1 = self.res1
67        errband1 = res1.sirf_errband_mc(orth=False, repl=50, steps=10,
68                                        signif=0.05, seed=987123, burn=100,
69                                        cum=False)
70
71        irf = res1.irf()
72        errband2 = irf.errband_mc(orth=False, svar=True, repl=50,
73                                  signif=0.05, seed=987123, burn=100)
74        # Windows precision limits require non-zero atol
75        atol = 1e-6 if PLATFORM_WIN else 1e-8
76        assert_allclose(errband1, errband2, rtol=1e-8, atol=atol)
77