Repository: statsmodels/statsmodels

Issue:
BUG: ARMA predict with dynamic and constant breaks
I'm in the middle of an example
ARMA with seasonal dummies and with default trend (constant)

It looks like dynamic predict, does not take into account that the model has added a constant.
not specifying exog raises an exception in concatenation.

using the model exog explicitly raises the same exception

dropping the constant column (first column of exog) works, and based on the plot it looks correct

`pred_dynamic = res_arma.predict(start='2008-12-01', end='2010-12-01', exog=res_arma.model.exog[-3*12:, 1:], dynamic=True)`

the model is

```
from statsmodels.datasets.elnino import load_pandas
​datadf = load_pandas()

temperature = np.asarray(datadf.data.iloc[:, 1:]).ravel()
nobs = len(temperature)
index = pd.date_range("1950-01-01", periods=nobs, freq='MS')
months = np.tile(np.arange(12), nobs // 12)

df_el = pd.DataFrame({'temperature': temperature, 'month': months}, index=index)


import patsy
y, x = patsy.dmatrices('temperature ~ C(month)', df_el, return_type='dataframe')
res_arma = sm.tsa.ARMA(y, order=(2, 1), exog=x.iloc[:, 1:]).fit()
```



Discussion:
this fails, using prediction periods inside the estimation periods
`pred_dynamic2 = res_arma.predict(start='2008-12-01', end='2010-11-01', dynamic=True)`

```
  File "...\statsmodels\base\wrapper.py", line 95, in wrapper
    obj = data.wrap_output(func(results, *args, **kwargs), how)
  File "...\statsmodels\tsa\arima_model.py", line 1501, in predict
    return self.model.predict(self.params, start, end, exog, dynamic)
  File "...\statsmodels\tsa\arima_model.py", line 742, in predict
    exog = np.vstack((self.exog[start - k_ar:, self.k_trend:], exog))
  File "...\python-3.4.4.amd64\lib\site-packages\numpy\core\shape_base.py", line 230, in vstack
    return _nx.concatenate([atleast_2d(_m) for _m in tup], 0)
ValueError: all the input array dimensions except for the concatenation axis must match exactly
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
```

no exception if `dynamic=False`

Resolving patch:
diff --git a/statsmodels/tsa/arima_model.py b/statsmodels/tsa/arima_model.py
--- a/statsmodels/tsa/arima_model.py
+++ b/statsmodels/tsa/arima_model.py
@@ -739,7 +739,11 @@ def predict(self, params, start=None, end=None, exog=None, dynamic=False):
         if dynamic:
             if self.k_exog > 0:
                 # need the last k_ar exog for the lag-polynomial
-                exog = np.vstack((self.exog[start - k_ar:, self.k_trend:], exog))
+                exog_insample = self.exog[start - k_ar:, self.k_trend:]
+                if exog is not None:
+                    exog = np.vstack((exog_insample, exog))
+                else:
+                    exog = exog_insample
             #TODO: now that predict does dynamic in-sample it should
             # also return error estimates and confidence intervals
             # but how? len(endog) is not tot_obs


Test patch:
diff --git a/statsmodels/tsa/tests/test_arima.py b/statsmodels/tsa/tests/test_arima.py
--- a/statsmodels/tsa/tests/test_arima.py
+++ b/statsmodels/tsa/tests/test_arima.py
@@ -2229,6 +2229,12 @@ def test_ARIMA_exog_predict():
                                    dynamic=True)
     assert_allclose(dpredict_002, res_d002[-len(dpredict_002):], rtol=1e-4, atol=1e-6)
 
+    # in-sample dynamic predict should not need exog, #2982
+    predict_3a = res_002.predict(start=100, end=120, dynamic=True)
+    predict_3b = res_002.predict(start=100, end=120,
+                                 exog=exog_full.values[100:120], dynamic=True)
+    assert_allclose(predict_3a, predict_3b, rtol=1e-10)
+
 
 def test_arima_fit_mutliple_calls():
     y = [-1214.360173, -1848.209905, -2100.918158, -3647.483678, -4711.186773]