'Information criteria
Parameters
criteria : {\'aic\', \'bic\', \'hqic\'}
The information criteria to compute.
method : {\'standard\', \'lutkepohl\'}
The method for information criteria computation. Default is
\'standard\' method; \'lutkepohl\' computes the information criteria
as in LÃŒtkepohl (2007). See Notes for formulas.
Notes
The `\'standard\'` formulas are:
.. math::
AIC & = -2 \log L(Y_n | \hat \psi) + 2 k \\
BIC & = -2 \log L(Y_n | \hat \psi) + k \log n \\
HQIC & = -2 \log L(Y_n | \hat \psi) + 2 k \log \log n \\
where :math:`\hat \psi` are the maximum likelihood estimates of the
parameters, :math:`n` is the number of observations, and `k` is the
number of estimated parameters.
Note that the `\'standard\'` formulas are returned from the `aic`, `bic`,
and `hqic` results attributes.
The `\'lutkepohl\'` formuals are (LÃŒtkepohl, 2010):
.. math::
AIC_L & = \log | Q | + \frac{2 k}{n} \\
BIC_L & = \log | Q | + \frac{k \log n}{n} \\
HQIC_L & = \log | Q | + \frac{2 k \log \log n}{n} \\
where :math:`Q` is the state covariance matrix. Note that the LÃŒtkepohl
definitions do not apply to all state space models, and should be used
with care outside of SARIMAX and VARMAX models.
References
.. [1] LÃŒtkepohl, Helmut. 2007.
New Introduction to Multiple Time Series Analysis.
Berlin: Springer.'

def info_criteria(self, criteria, method='standard'):

    criteria = criteria.lower()
    method = method.lower()
    if (method == 'standard'):
        out = getattr(self, criteria)
    elif (method == 'lutkepohl'):
        if (self.filter_results.state_cov.shape[(-1)] > 1):
            raise ValueError('Cannot    compute    Lutkepohl    statistics    for    models    with    time-varying    state    covariance    matrix.')
        cov = self.filter_results.state_cov[:, :, 0]
        if (criteria == 'aic'):
            out = np.squeeze((np.linalg.slogdet(cov)[1] + ((2 * self.df_model) / self.nobs_effective)))
        elif (criteria == 'bic'):
            out = np.squeeze((np.linalg.slogdet(cov)[1] + ((self.df_model * np.log(self.nobs_effective)) / self.nobs_effective)))
        elif (criteria == 'hqic'):
            out = np.squeeze((np.linalg.slogdet(cov)[1] + (((2 * self.df_model) * np.log(np.log(self.nobs_effective))) / self.nobs_effective)))
        else:
            raise ValueError('Invalid    information    criteria')
    else:
        raise ValueError('Invalid    information    criteria    computation    method')
    return out
