1818
1919floatX = pytensor .config .floatX
2020
21+ # TODO: check test for error_var=True, since there are problems with statsmodels, the matrices looks the same by some experiments done in notebooks
22+ # (FAILED tests/statespace/models/test_DFM.py::test_DFM_update_matches_statsmodels[True-2-2-2] - numpy.linalg.LinAlgError: 1-th leading minor of the array is not positive definite)
23+
2124
2225@pytest .fixture (scope = "session" )
2326def data ():
@@ -30,7 +33,9 @@ def data():
3033 return df
3134
3235
33- def create_sm_test_values_mapping (test_values , data , k_factors , factor_order , error_order ):
36+ def create_sm_test_values_mapping (
37+ test_values , data , k_factors , factor_order , error_order , error_var
38+ ):
3439 """Convert PyMC test values to statsmodels parameter format"""
3540 sm_test_values = {}
3641
@@ -59,8 +64,8 @@ def create_sm_test_values_mapping(test_values, data, k_factors, factor_order, er
5964 }
6065 )
6166
62- # 3 . Error AR coefficients: PyMC shape (n_endog, error_order) -> L{lag}.e(var).e(var)
63- if error_order > 0 and "error_ar" in test_values :
67+ # 3a . Error AR coefficients: PyMC shape (n_endog, error_order) -> L{lag}.e(var).e(var)
68+ if error_order > 0 and not error_var and "error_ar" in test_values :
6469 error_ar = test_values ["error_ar" ]
6570 pairs = product (enumerate (data .columns ), range (1 , error_order + 1 ))
6671 sm_test_values .update (
@@ -70,6 +75,24 @@ def create_sm_test_values_mapping(test_values, data, k_factors, factor_order, er
7075 }
7176 )
7277
78+ # 3b. Error AR coefficients: PyMC shape (n_endog, error_order * n_endog) -> L{lag}.e(var).e(var)
79+ elif error_order > 0 and error_var and "error_ar" in test_values :
80+ error_ar = test_values ["error_ar" ]
81+ triplets = product (
82+ enumerate (data .columns ), range (1 , error_order + 1 ), enumerate (data .columns )
83+ )
84+ sm_test_values .update (
85+ {
86+ f"L{ lag } .e({ from_endog_name } ).e({ to_endog_name } )" : error_ar [
87+ from_endog_idx , (lag - 1 ) * data .shape [1 ] + to_endog_idx
88+ ]
89+ for (from_endog_idx , from_endog_name ), lag , (
90+ to_endog_idx ,
91+ to_endog_name ,
92+ ) in triplets
93+ }
94+ )
95+
7396 # 4. Observation error variances:
7497 if "error_sigma" in test_values :
7598 error_sigma = test_values ["error_sigma" ]
@@ -86,22 +109,25 @@ def create_sm_test_values_mapping(test_values, data, k_factors, factor_order, er
86109@pytest .mark .parametrize ("k_factors" , [1 , 2 ])
87110@pytest .mark .parametrize ("factor_order" , [0 , 1 , 2 ])
88111@pytest .mark .parametrize ("error_order" , [0 , 1 , 2 ])
112+ @pytest .mark .parametrize ("error_var" , [False ])
89113@pytest .mark .filterwarnings ("ignore::statsmodels.tools.sm_exceptions.EstimationWarning" )
90114@pytest .mark .filterwarnings ("ignore::FutureWarning" )
91- def test_DFM_update_matches_statsmodels (data , k_factors , factor_order , error_order , rng ):
115+ def test_DFM_update_matches_statsmodels (data , k_factors , factor_order , error_order , error_var , rng ):
92116 mod = BayesianDynamicFactor (
93117 k_factors = k_factors ,
94118 factor_order = factor_order ,
95119 error_order = error_order ,
96120 k_endog = data .shape [1 ],
97121 measurement_error = False ,
122+ error_var = error_var ,
98123 verbose = False ,
99124 )
100125 sm_dfm = DynamicFactor (
101126 endog = data ,
102127 k_factors = k_factors ,
103128 factor_order = factor_order ,
104129 error_order = error_order ,
130+ error_var = error_var ,
105131 )
106132
107133 # Generate test values for PyMC model
@@ -113,14 +139,16 @@ def test_DFM_update_matches_statsmodels(data, k_factors, factor_order, error_ord
113139 if factor_order > 0 :
114140 test_values ["factor_ar" ] = rng .normal (size = (k_factors , factor_order * k_factors ))
115141
116- if error_order > 0 :
142+ if error_order > 0 and error_var :
143+ test_values ["error_ar" ] = rng .normal (size = (data .shape [1 ], error_order * data .shape [1 ]))
144+ elif error_order > 0 and not error_var :
117145 test_values ["error_ar" ] = rng .normal (size = (data .shape [1 ], error_order ))
118146
119147 test_values ["error_sigma" ] = rng .beta (1 , 1 , size = data .shape [1 ])
120148
121149 # Convert to statsmodels format
122150 sm_test_values = create_sm_test_values_mapping (
123- test_values , data , k_factors , factor_order , error_order
151+ test_values , data , k_factors , factor_order , error_order , error_var
124152 )
125153
126154 # Initialize and constrain statsmodels model
0 commit comments