Repository: statsmodels/statsmodels

Issue:
BUG: Markov Regression with TVTP gives "Arguments do not have compatible shapes" 
I replicated the example code for a Markov Autoregression with time-varying transition probabilities from 
[http://www.chadfulton.com/topics/markov_autoregression.html#filardo-1994-time-varying-transition-probabilities](url)
and tried to change it to a Markov Regression, however, the error message "Arguments do not have compatible shapes" appeared. 

```
import pandas as pd
import numpy as np
import statsmodels.api as sm
df_source = 'http://econ.korea.ac.kr/~cjkim/MARKOV/data/filardo.prn'
dta_filardo = pd.read_table(df_source, delim_whitespace=True, names=('month', 'ip', 'leading'),nrows=520)
dta_filardo.index = pd.date_range('1948-01-01', '1991-04-01', freq='MS')
dta_filardo['dlip'] = np.log(dta_filardo['ip']).diff()*100
std_ratio = dta_filardo['dlip']['1960-01-01':].std() / dta_filardo['dlip'][:'1959-12-01'].std()
dta_filardo['dlip'][:'1959-12-01'] = dta_filardo['dlip'][:'1959-12-01'] * std_ratio
dta_filardo['dlleading'] = np.log(dta_filardo['leading']).diff()*100
dta_filardo['dmdlleading'] = dta_filardo['dlleading'] - dta_filardo['dlleading'].mean()


mod_filardo = sm.tsa.MarkovAutoregression(
    dta_filardo.ix[2:, 'dlip'], k_regimes=2, order=4, switching_ar=False,
    exog_tvtp=sm.add_constant(dta_filardo.ix[1:-1, 'dmdlleading']))

res_filardo = mod_filardo.fit(search_reps=20)
res_filardo.summary()

########

mod_filardo = sm.tsa.MarkovRegression(
     dta_filardo.ix[2:, 'ip'], k_regimes=2,
     exog_tvtp=sm.add_constant(dta_filardo.ix[1:-1, 'leading']))

res_filardo = mod_filardo.fit(search_reps=20)
res_filardo.summary()

```
Also already handed in at 
[https://stackoverflow.com/questions/56893590/how-to-fix-arguments-do-not-have-compatible-shapes-when-running-statsmodels-ma/56894976#56894976](url)



Discussion:
Could you provide a copy-paste example that uses either simulated data or a dataset in statsmodels that shows the issue?
Thanks.
I am new to this and not really sure why but there you go!
```
import pandas as pd
import numpy as np
import statsmodels.api as sm
data = sm.datasets.longley.load_pandas()
dta = data.data
dta['d_UNEMP'] = np.log(dta['UNEMP']).diff()*100
dta['d_GNP'] = np.log(dta['GNP']).diff()*100
dta = dta[1:]
mod_dta = sm.tsa.MarkovAutoregression(
    dta.ix[1:, 'd_UNEMP'], k_regimes=2, order=4, switching_ar=False,
    exog_tvtp=sm.add_constant(dta.ix[1:, 'd_GNP']))
res_dta = mod_dta.fit(search_reps=20)
res_dta.summary()

#########

mod_dta = sm.tsa.MarkovRegression(
     dta.ix[1:, 'd_UNEMP'], k_regimes=2,
     exog_tvtp=sm.add_constant(dta.ix[1:, 'd_GNP']))

res_dta = mod_dta.fit(search_reps=20)
res_dta.summary()

```

Resolving patch:
diff --git a/statsmodels/tsa/regime_switching/markov_switching.py b/statsmodels/tsa/regime_switching/markov_switching.py
--- a/statsmodels/tsa/regime_switching/markov_switching.py
+++ b/statsmodels/tsa/regime_switching/markov_switching.py
@@ -104,7 +104,7 @@ def _partials_logistic(x):
 
 
 def cy_hamilton_filter_log(initial_probabilities, regime_transition,
-                           conditional_loglikelihoods):
+                           conditional_loglikelihoods, model_order):
     """
     Hamilton filter in log space using Cython inner loop.
 
@@ -155,7 +155,7 @@ def cy_hamilton_filter_log(initial_probabilities, regime_transition,
 
     # Check for compatible shapes.
     incompatible_shapes = (
-        regime_transition.shape[-1] not in (1, nobs + order)
+        regime_transition.shape[-1] not in (1, nobs + model_order)
         or regime_transition.shape[:2] != (k_regimes, k_regimes)
         or conditional_loglikelihoods.shape[0] != k_regimes)
     if incompatible_shapes:
@@ -194,7 +194,7 @@ def cy_hamilton_filter_log(initial_probabilities, regime_transition,
 
     # Get appropriate subset of transition matrix
     if regime_transition.shape[-1] > 1:
-        regime_transition = regime_transition[..., order:]
+        regime_transition = regime_transition[..., model_order:]
 
     # Run Cython filter iterations
     prefix, dtype, _ = find_best_blas_type((
@@ -778,7 +778,7 @@ def _filter(self, params, regime_transition=None):
                  conditional_loglikelihoods) +
                 cy_hamilton_filter_log(
                     initial_probabilities, regime_transition,
-                    conditional_loglikelihoods))
+                    conditional_loglikelihoods, self.order))
 
     def filter(self, params, transformed=True, cov_type=None, cov_kwds=None,
                return_raw=False, results_class=None,


Test patch:
diff --git a/statsmodels/tsa/regime_switching/tests/test_markov_regression.py b/statsmodels/tsa/regime_switching/tests/test_markov_regression.py
--- a/statsmodels/tsa/regime_switching/tests/test_markov_regression.py
+++ b/statsmodels/tsa/regime_switching/tests/test_markov_regression.py
@@ -966,7 +966,7 @@ def test_hamilton_filter_order_zero(self):
 
         cy_results = markov_switching.cy_hamilton_filter_log(
             initial_probabilities, regime_transition,
-            np.log(conditional_likelihoods + 1e-20))
+            np.log(conditional_likelihoods + 1e-20), model_order=0)
         assert_allclose(cy_results[0], expected_marginals, atol=1e-15)
 
     def test_hamilton_filter_order_zero_with_tvtp(self):
@@ -1014,7 +1014,7 @@ def test_hamilton_filter_order_zero_with_tvtp(self):
 
         cy_results = markov_switching.cy_hamilton_filter_log(
             initial_probabilities, regime_transition,
-            np.log(conditional_likelihoods + 1e-20))
+            np.log(conditional_likelihoods + 1e-20), model_order=0)
         assert_allclose(cy_results[0], expected_marginals, atol=1e-15)
 
     def test_hamilton_filter_shape_checks(self):
@@ -1029,7 +1029,7 @@ def test_hamilton_filter_shape_checks(self):
         with assert_raises(ValueError):
             markov_switching.cy_hamilton_filter_log(
                 initial_probabilities, regime_transition,
-                conditional_loglikelihoods)
+                conditional_loglikelihoods, model_order=order)
 
 
 class TestFedFundsConstL1(MarkovRegression):
@@ -1274,3 +1274,31 @@ def test_avoid_underflow():
     assert not np.any(np.isnan(res.predicted_joint_probabilities))
     assert not np.any(np.isnan(res.filtered_joint_probabilities))
     assert not np.any(np.isnan(res.smoothed_joint_probabilities))
+
+
+def test_exog_tvtp():
+    exog = np.ones_like(fedfunds)
+
+    mod1 = markov_regression.MarkovRegression(fedfunds, k_regimes=2)
+    mod2 = markov_regression.MarkovRegression(fedfunds, k_regimes=2,
+                                              exog_tvtp=exog)
+
+    params = np.r_[0.98209618, 0.05036498, 3.70877542, 9.55676298, 4.44181911]
+    params_tvtp = params.copy()
+    params_tvtp[0] = mod2._untransform_logistic(
+        np.r_[0.], np.r_[1 - params[0]])
+    params_tvtp[1] = mod2._untransform_logistic(
+        np.r_[0.], np.r_[1 - params[1]])
+
+    res1 = mod1.smooth(params)
+    res2 = mod2.smooth(params_tvtp)
+
+    assert_allclose(res2.llf_obs, res1.llf_obs)
+    assert_allclose(res2.regime_transition - res1.regime_transition, 0,
+                    atol=1e-15)
+    assert_allclose(res2.predicted_joint_probabilities,
+                    res1.predicted_joint_probabilities)
+    assert_allclose(res2.filtered_joint_probabilities,
+                    res1.filtered_joint_probabilities)
+    assert_allclose(res2.smoothed_joint_probabilities,
+                    res1.smoothed_joint_probabilities)