def is_stationary(self): """(bool) Is the reduced autoregressive lag poylnomial stationary.""" validate_basic(self.ar_params, self.k_ar_params, title='AR coefficients') validate_basic(self.seasonal_ar_params, self.k_seasonal_ar_params, title='seasonal AR coefficients') ar_stationary = True seasonal_ar_stationary = True if self.k_ar_params > 0: ar_stationary = is_invertible(self.ar_poly.coef) if self.k_seasonal_ar_params > 0: seasonal_ar_stationary = is_invertible(self.seasonal_ar_poly.coef) return ar_stationary and seasonal_ar_stationary
def is_invertible(self): """(bool) Is the reduced moving average lag poylnomial invertible.""" # Short-circuit if there is no MA component validate_basic(self.ma_params, self.k_ma_params, title='MA coefficients') validate_basic(self.seasonal_ma_params, self.k_seasonal_ma_params, title='seasonal MA coefficients') ma_stationary = True seasonal_ma_stationary = True if self.k_ma_params > 0: ma_stationary = is_invertible(self.ma_poly.coef) if self.k_seasonal_ma_params > 0: seasonal_ma_stationary = is_invertible(self.seasonal_ma_poly.coef) return ma_stationary and seasonal_ma_stationary
def split_params(self, params, allow_infnan=False): """ Split parameter array by type into dictionary. Parameters ---------- params : array_like Array of model parameters. allow_infnan : bool, optional Whether or not to allow `params` to contain -np.Inf, np.Inf, and np.nan. Default is False. Returns ------- split_params : dict Dictionary with keys 'exog_params', 'ar_params', 'ma_params', 'seasonal_ar_params', 'seasonal_ma_params', and (unless `concentrate_scale=True`) 'sigma2'. Values are the parameters associated with the key, based on the `params` argument. Examples -------- >>> spec = SARIMAXSpecification(ar_order=1) >>> spec.split_params([0.5, 4]) {'exog_params': array([], dtype=float64), 'ar_params': array([0.5]), 'ma_params': array([], dtype=float64), 'seasonal_ar_params': array([], dtype=float64), 'seasonal_ma_params': array([], dtype=float64), 'sigma2': 4.0} """ params = validate_basic(params, self.k_params, allow_infnan=allow_infnan, title='joint parameters') ix = [ self.k_exog_params, self.k_ar_params, self.k_ma_params, self.k_seasonal_ar_params, self.k_seasonal_ma_params ] names = [ 'exog_params', 'ar_params', 'ma_params', 'seasonal_ar_params', 'seasonal_ma_params' ] if not self.concentrate_scale: ix.append(1) names.append('sigma2') ix = np.cumsum(ix) out = dict(zip(names, np.split(params, ix))) if 'sigma2' in out: out['sigma2'] = out['sigma2'].item() return out
def test_validate_basic(): # Valid parameters assert_equal(validate_basic([], 0, title='test'), []) assert_equal(validate_basic(0, 1), [0]) assert_equal(validate_basic([0], 1), [0]) assert_equal(validate_basic(np.array([1.2, 0.5 + 1j]), 2), np.array([1.2, 0.5 + 1j])) assert_equal( validate_basic([np.nan, -np.inf, np.inf], 3, allow_infnan=True), [np.nan, -np.inf, np.inf]) # Invalid parameters assert_raises(ValueError, validate_basic, [], 1, title='test') assert_raises(ValueError, validate_basic, 0, 0) assert_raises(ValueError, validate_basic, 'a', 1) assert_raises(ValueError, validate_basic, None, 1) assert_raises(ValueError, validate_basic, np.nan, 1) assert_raises(ValueError, validate_basic, np.inf, 1) assert_raises(ValueError, validate_basic, -np.inf, 1) assert_raises(ValueError, validate_basic, [1, 2], 1)
def ma_poly(self, value): # Convert from the polynomial to the parameters, and set that way if isinstance(value, Polynomial): value = value.coef value = validate_basic(value, self.spec.max_ma_order + 1, title='MA polynomial') if value[0] != 1: raise ValueError('MA polynomial constant must be equal to 1.') ma_params = [] for i in range(1, self.spec.max_ma_order + 1): if i in self.spec.ma_lags: ma_params.append(value[i]) elif value[i] != 0: raise ValueError('MA polynomial includes non-zero values' ' for lags that are excluded in the' ' specification.') self.ma_params = ma_params
def seasonal_ar_poly(self, value): s = self.spec.seasonal_periods # Note: assume that we are given coefficients from the full polynomial # Convert from the polynomial to the parameters, and set that way if isinstance(value, Polynomial): value = value.coef value = validate_basic(value, 1 + s * self.spec.max_seasonal_ar_order, title='seasonal AR polynomial') if value[0] != 1: raise ValueError('Polynomial constant must be equal to 1.') seasonal_ar_params = [] for i in range(1, self.spec.max_seasonal_ar_order + 1): if i in self.spec.seasonal_ar_lags: seasonal_ar_params.append(-value[s * i]) elif value[s * i] != 0: raise ValueError('AR polynomial includes non-zero values' ' for lags that are excluded in the' ' specification.') self.seasonal_ar_params = seasonal_ar_params
def ar_params(self, value): if np.isscalar(value): value = [value] * self.k_ar_params self._params_split['ar_params'] = validate_basic( value, self.k_ar_params, title='AR coefficients') self._params = None
def exog_params(self, value): if np.isscalar(value): value = [value] * self.k_exog_params self._params_split['exog_params'] = validate_basic( value, self.k_exog_params, title='exogenous coefficients') self._params = None
def sigma2(self, params): length = int(not self.spec.concentrate_scale) self._params_split['sigma2'] = validate_basic(params, length, title='sigma2').item() self._params = None
def seasonal_ma_params(self, value): if np.isscalar(value): value = [value] * self.k_seasonal_ma_params self._params_split['seasonal_ma_params'] = validate_basic( value, self.k_seasonal_ma_params, title='seasonal MA coefficients') self._params = None