def __init__(self, endog, exog=None, order=(1, 0, 0),
                 seasonal_order=(0, 0, 0, 0), trend=None,
                 measurement_error=False, time_varying_regression=False,
                 mle_regression=True, simple_differencing=False,
                 enforce_stationarity=True, enforce_invertibility=True,
                 hamilton_representation=False, **kwargs):

        # Model parameters
        self.k_seasons = seasonal_order[3]
        self.measurement_error = measurement_error
        self.time_varying_regression = time_varying_regression
        self.mle_regression = mle_regression
        self.simple_differencing = simple_differencing
        self.enforce_stationarity = enforce_stationarity
        self.enforce_invertibility = enforce_invertibility
        self.hamilton_representation = hamilton_representation

        # Save given orders
        self.order = order
        self.seasonal_order = seasonal_order

        # Enforce non-MLE coefficients if time varying coefficients is
        # specified
        if self.time_varying_regression and self.mle_regression:
            raise ValueError('Models with time-varying regression coefficients'
                             ' must integrate the coefficients as part of the'
                             ' state vector, so that `mle_regression` must'
                             ' be set to False.')

        # Lag polynomials
        # Assume that they are given from lowest degree to highest, that all
        # degrees except for the constant are included, and that they are
        # boolean vectors (0 for not included, 1 for included).
        if isinstance(order[0], int):
            self.polynomial_ar = np.r_[1., np.ones(order[0])]
        else:
            self.polynomial_ar = np.r_[1., order[0]]
        if isinstance(order[2], int):
            self.polynomial_ma = np.r_[1., np.ones(order[2])]
        else:
            self.polynomial_ma = np.r_[1., order[2]]
        # Assume that they are given from lowest degree to highest, that the
        # degrees correspond to (1*s, 2*s, ..., P*s), and that they are
        # boolean vectors (0 for not included, 1 for included).
        if isinstance(seasonal_order[0], int):
            self.polynomial_seasonal_ar = np.r_[
                1.,  # constant
                ([0] * (self.k_seasons - 1) + [1]) * seasonal_order[0]
            ]
        else:
            self.polynomial_seasonal_ar = np.r_[
                1., [0] * self.k_seasons * len(seasonal_order[0])
            ]
            for i in range(len(seasonal_order[0])):
                self.polynomial_seasonal_ar[(i + 1) * self.k_seasons] = (
                    seasonal_order[0][i]
                )
        if isinstance(seasonal_order[2], int):
            self.polynomial_seasonal_ma = np.r_[
                1.,  # constant
                ([0] * (self.k_seasons - 1) + [1]) * seasonal_order[2]
            ]
        else:
            self.polynomial_seasonal_ma = np.r_[
                1., [0] * self.k_seasons * len(seasonal_order[2])
            ]
            for i in range(len(seasonal_order[2])):
                self.polynomial_seasonal_ma[(i + 1) * self.k_seasons] = (
                    seasonal_order[2][i]
                )

        # Deterministic trend polynomial
        self.trend = trend
        if trend is None or trend == 'n':
            self.polynomial_trend = np.ones((0))
        elif trend == 'c':
            self.polynomial_trend = np.r_[1]
        elif trend == 't':
            self.polynomial_trend = np.r_[0, 1]
        elif trend == 'ct':
            self.polynomial_trend = np.r_[1, 1]
        else:
            self.polynomial_trend = (np.array(trend) > 0).astype(int)

        # Model orders
        # Note: k_ar, k_ma, k_seasonal_ar, k_seasonal_ma do not include the
        # constant term, so they may be zero.
        # Note: for a typical ARMA(p,q) model, p = k_ar_params = k_ar - 1 and
        # q = k_ma_params = k_ma - 1, although this may not be true for models
        # with arbitrary log polynomials.
        self.k_ar = int(1 - self.polynomial_ar.shape[0])
        self.k_ar_params = int(np.sum(self.polynomial_ar) - 1)
        self.k_diff = int(order[1])
        self.k_ma = int(self.polynomial_ma.shape[0] - 1)
        self.k_ma_params = int(np.sum(self.polynomial_ma) - 1)

        self.k_seasonal_ar = int(self.polynomial_seasonal_ar.shape[0] - 1)
        self.k_seasonal_ar_params = (
            int(np.sum(self.polynomial_seasonal_ar) - 1)
        )
        self.k_seasonal_diff = int(seasonal_order[1])
        self.k_seasonal_ma = int(self.polynomial_seasonal_ma.shape[0] - 1)
        self.k_seasonal_ma_params = (
            int(np.sum(self.polynomial_seasonal_ma) - 1)
        )

        # Make internal copies of the differencing orders because if we use
        # simple differencing, then we will need to internally use zeros after
        # the simple differencing has been performed
        self._k_diff = self.k_diff
        self._k_seasonal_diff = self.k_seasonal_diff

        # We can only use the Hamilton representation if differencing is not
        # performed as a part of the state space
        if (self.hamilton_representation and not (self.simple_differencing or
           self._k_diff == self._k_seasonal_diff == 0)):
            raise ValueError('The Hamilton representation is only available'
                             ' for models in which there is no differencing'
                             ' integrated into the state vector. Set'
                             ' `simple_differencing` to True or set'
                             ' `hamilton_representation` to False')

        # Note: k_trend is not the degree of the trend polynomial, because e.g.
        # k_trend = 1 corresponds to the degree zero polynomial (with only a
        # constant term).
        self.k_trend = int(np.sum(self.polynomial_trend))

        # Model order
        # (this is used internally in a number of locations)
        self._k_order = max(self.k_ar + self.k_seasonal_ar,
                            self.k_ma + self.k_seasonal_ma + 1)
        if self._k_order == 1 and self.k_ar + self.k_seasonal_ar == 0:
            self._k_order = 0

        # Exogenous data
        self.k_exog = 0
        if exog is not None:
            exog_is_using_pandas = _is_using_pandas(exog, None)
            if not exog_is_using_pandas:
                exog = np.asarray(exog)

            # Make sure we have 2-dimensional array
            if exog.ndim == 1:
                if not exog_is_using_pandas:
                    exog = exog[:, None]
                else:
                    exog = pd.DataFrame(exog)

            self.k_exog = exog.shape[1]
        # Redefine mle_regression to be true only if it was previously set to
        # true and there are exogenous regressors
        self.mle_regression = (
            self.mle_regression and exog is not None and self.k_exog > 0
        )
        # State regression is regression with coefficients estiamted within
        # the state vector
        self.state_regression = (
            not self.mle_regression and exog is not None and self.k_exog > 0
        )
        # If all we have is a regression (so k_ar = k_ma = 0), then put the
        # error term as measurement error
        if self.state_regression and self._k_order == 0:
            self.measurement_error = True

        # Number of states
        k_states = self._k_order
        if not self.simple_differencing:
            k_states += self.k_seasons * self._k_seasonal_diff + self._k_diff
        if self.state_regression:
            k_states += self.k_exog

        # Number of diffuse states
        k_diffuse_states = k_states
        if self.enforce_stationarity:
            k_diffuse_states -= self._k_order

        # Number of positive definite elements of the state covariance matrix
        k_posdef = int(self._k_order > 0)
        # Only have an error component to the states if k_posdef > 0
        self.state_error = k_posdef > 0
        if self.state_regression and self.time_varying_regression:
            k_posdef += self.k_exog

        # Diffuse initialization can be more sensistive to the variance value
        # in the case of state regression, so set a higher than usual default
        # variance
        if self.state_regression:
            kwargs.setdefault('initial_variance', 1e10)

        # Number of parameters
        self.k_params = (
            self.k_ar_params + self.k_ma_params +
            self.k_seasonal_ar_params + self.k_seasonal_ar_params +
            self.k_trend +
            self.measurement_error + 1
        )
        if self.mle_regression:
            self.k_params += self.k_exog

        # We need to have an array or pandas at this point
        self.orig_endog = endog
        self.orig_exog = exog
        if not _is_using_pandas(endog, None):
            endog = np.asanyarray(endog)

        # Update the differencing dimensions if simple differencing is applied
        self.orig_k_diff = self._k_diff
        self.orig_k_seasonal_diff = self._k_seasonal_diff
        if (self.simple_differencing and
           (self._k_diff > 0 or self._k_seasonal_diff > 0)):
            self._k_diff = 0
            self._k_seasonal_diff = 0

        # Internally used in several locations
        self._k_states_diff = (
            self._k_diff + self.k_seasons * self._k_seasonal_diff
        )

        # Set some model variables now so they will be available for the
        # initialize() method, below
        self.nobs = len(endog)
        self.k_states = k_states
        self.k_posdef = k_posdef

        # By default, do not calculate likelihood while it is controlled by
        # diffuse initial conditions.
        kwargs.setdefault('loglikelihood_burn', k_diffuse_states)

        # Initialize the statespace
        super(SARIMAX, self).__init__(
            endog, exog=exog, k_states=k_states, k_posdef=k_posdef, **kwargs
        )

        # Handle kwargs specified initialization
        if self.ssm.initialization is not None:
            self._manual_initialization = True

        # Initialize the fixed components of the statespace model
        self.ssm.design = self.initial_design
        self.ssm.state_intercept = self.initial_state_intercept
        self.ssm.transition = self.initial_transition
        self.ssm.selection = self.initial_selection

        # If we are estimating a simple ARMA model, then we can use a faster
        # initialization method (unless initialization was already specified).
        if k_diffuse_states == 0 and not self._manual_initialization:
            self.initialize_stationary()

        # update _init_keys attached by super
        self._init_keys += ['order',  'seasonal_order', 'trend',
                            'measurement_error', 'time_varying_regression',
                            'mle_regression', 'simple_differencing',
                            'enforce_stationarity', 'enforce_invertibility',
                            'hamilton_representation'] + list(kwargs.keys())
        # TODO: I think the kwargs or not attached, need to recover from ???
dataset/ETHPy150Open statsmodels/statsmodels/statsmodels/tsa/statespace/sarimax.py/SARIMAX.__init__/swapped operands of `-`