reconnect moved files to git repo
This commit is contained in:
@ -0,0 +1,276 @@
|
||||
import numpy as np
|
||||
|
||||
from statsmodels.tsa import arima_process
|
||||
from statsmodels.tsa.statespace.tools import prefix_dtype_map
|
||||
from statsmodels.tools.numdiff import _get_epsilon, approx_fprime_cs
|
||||
from scipy.linalg.blas import find_best_blas_type
|
||||
from . import _arma_innovations
|
||||
|
||||
NON_STATIONARY_ERROR = """\
|
||||
The model's autoregressive parameters (ar_params) indicate that the process
|
||||
is non-stationary. The innovations algorithm cannot be used.
|
||||
"""
|
||||
|
||||
|
||||
def arma_innovations(endog, ar_params=None, ma_params=None, sigma2=1,
|
||||
normalize=False, prefix=None):
|
||||
"""
|
||||
Compute innovations using a given ARMA process.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
endog : ndarray
|
||||
The observed time-series process, may be univariate or multivariate.
|
||||
ar_params : ndarray, optional
|
||||
Autoregressive parameters.
|
||||
ma_params : ndarray, optional
|
||||
Moving average parameters.
|
||||
sigma2 : ndarray, optional
|
||||
The ARMA innovation variance. Default is 1.
|
||||
normalize : bool, optional
|
||||
Whether or not to normalize the returned innovations. Default is False.
|
||||
prefix : str, optional
|
||||
The BLAS prefix associated with the datatype. Default is to find the
|
||||
best datatype based on given input. This argument is typically only
|
||||
used internally.
|
||||
|
||||
Returns
|
||||
-------
|
||||
innovations : ndarray
|
||||
Innovations (one-step-ahead prediction errors) for the given `endog`
|
||||
series with predictions based on the given ARMA process. If
|
||||
`normalize=True`, then the returned innovations have been "whitened" by
|
||||
dividing through by the square root of the mean square error.
|
||||
innovations_mse : ndarray
|
||||
Mean square error for the innovations.
|
||||
"""
|
||||
# Parameters
|
||||
endog = np.require(endog, requirements="WC")
|
||||
squeezed = endog.ndim == 1
|
||||
if squeezed:
|
||||
endog = endog[:, None]
|
||||
|
||||
ar_params = np.atleast_1d([] if ar_params is None else ar_params)
|
||||
ma_params = np.atleast_1d([] if ma_params is None else ma_params)
|
||||
|
||||
nobs, k_endog = endog.shape
|
||||
ar = np.r_[1, -ar_params]
|
||||
ma = np.r_[1, ma_params]
|
||||
|
||||
# Get BLAS prefix
|
||||
if prefix is None:
|
||||
prefix, dtype, _ = find_best_blas_type(
|
||||
[endog, ar_params, ma_params, np.array(sigma2)])
|
||||
dtype = prefix_dtype_map[prefix]
|
||||
|
||||
# Make arrays contiguous for BLAS calls
|
||||
endog = np.asfortranarray(endog, dtype=dtype)
|
||||
ar_params = np.asfortranarray(ar_params, dtype=dtype)
|
||||
ma_params = np.asfortranarray(ma_params, dtype=dtype)
|
||||
sigma2 = dtype(sigma2).item()
|
||||
|
||||
# Get the appropriate functions
|
||||
arma_transformed_acovf_fast = getattr(
|
||||
_arma_innovations, prefix + 'arma_transformed_acovf_fast')
|
||||
arma_innovations_algo_fast = getattr(
|
||||
_arma_innovations, prefix + 'arma_innovations_algo_fast')
|
||||
arma_innovations_filter = getattr(
|
||||
_arma_innovations, prefix + 'arma_innovations_filter')
|
||||
|
||||
# Run the innovations algorithm for ARMA coefficients
|
||||
arma_acovf = arima_process.arma_acovf(ar, ma,
|
||||
sigma2=sigma2, nobs=nobs) / sigma2
|
||||
acovf, acovf2 = arma_transformed_acovf_fast(ar, ma, arma_acovf)
|
||||
theta, v = arma_innovations_algo_fast(nobs, ar_params, ma_params,
|
||||
acovf, acovf2)
|
||||
v = np.array(v)
|
||||
if (np.any(v < 0) or
|
||||
not np.isfinite(theta).all() or
|
||||
not np.isfinite(v).all()):
|
||||
# This is defensive code that is hard to hit
|
||||
raise ValueError(NON_STATIONARY_ERROR)
|
||||
|
||||
# Run the innovations filter across each series
|
||||
u = []
|
||||
for i in range(k_endog):
|
||||
u_i = np.array(arma_innovations_filter(endog[:, i], ar_params,
|
||||
ma_params, theta))
|
||||
u.append(u_i)
|
||||
u = np.vstack(u).T
|
||||
if normalize:
|
||||
u /= v[:, None]**0.5
|
||||
|
||||
# Post-processing
|
||||
if squeezed:
|
||||
u = u.squeeze()
|
||||
|
||||
return u, v
|
||||
|
||||
|
||||
def arma_loglike(endog, ar_params=None, ma_params=None, sigma2=1, prefix=None):
|
||||
"""
|
||||
Compute the log-likelihood of the given data assuming an ARMA process.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
endog : ndarray
|
||||
The observed time-series process.
|
||||
ar_params : ndarray, optional
|
||||
Autoregressive parameters.
|
||||
ma_params : ndarray, optional
|
||||
Moving average parameters.
|
||||
sigma2 : ndarray, optional
|
||||
The ARMA innovation variance. Default is 1.
|
||||
prefix : str, optional
|
||||
The BLAS prefix associated with the datatype. Default is to find the
|
||||
best datatype based on given input. This argument is typically only
|
||||
used internally.
|
||||
|
||||
Returns
|
||||
-------
|
||||
float
|
||||
The joint loglikelihood.
|
||||
"""
|
||||
llf_obs = arma_loglikeobs(endog, ar_params=ar_params, ma_params=ma_params,
|
||||
sigma2=sigma2, prefix=prefix)
|
||||
return np.sum(llf_obs)
|
||||
|
||||
|
||||
def arma_loglikeobs(endog, ar_params=None, ma_params=None, sigma2=1,
|
||||
prefix=None):
|
||||
"""
|
||||
Compute the log-likelihood for each observation assuming an ARMA process.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
endog : ndarray
|
||||
The observed time-series process.
|
||||
ar_params : ndarray, optional
|
||||
Autoregressive parameters.
|
||||
ma_params : ndarray, optional
|
||||
Moving average parameters.
|
||||
sigma2 : ndarray, optional
|
||||
The ARMA innovation variance. Default is 1.
|
||||
prefix : str, optional
|
||||
The BLAS prefix associated with the datatype. Default is to find the
|
||||
best datatype based on given input. This argument is typically only
|
||||
used internally.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ndarray
|
||||
Array of loglikelihood values for each observation.
|
||||
"""
|
||||
endog = np.array(endog)
|
||||
ar_params = np.atleast_1d([] if ar_params is None else ar_params)
|
||||
ma_params = np.atleast_1d([] if ma_params is None else ma_params)
|
||||
|
||||
if prefix is None:
|
||||
prefix, dtype, _ = find_best_blas_type(
|
||||
[endog, ar_params, ma_params, np.array(sigma2)])
|
||||
dtype = prefix_dtype_map[prefix]
|
||||
|
||||
endog = np.ascontiguousarray(endog, dtype=dtype)
|
||||
ar_params = np.asfortranarray(ar_params, dtype=dtype)
|
||||
ma_params = np.asfortranarray(ma_params, dtype=dtype)
|
||||
sigma2 = dtype(sigma2).item()
|
||||
|
||||
func = getattr(_arma_innovations, prefix + 'arma_loglikeobs_fast')
|
||||
return func(endog, ar_params, ma_params, sigma2)
|
||||
|
||||
|
||||
def arma_score(endog, ar_params=None, ma_params=None, sigma2=1,
|
||||
prefix=None):
|
||||
"""
|
||||
Compute the score (gradient of the log-likelihood function).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
endog : ndarray
|
||||
The observed time-series process.
|
||||
ar_params : ndarray, optional
|
||||
Autoregressive coefficients, not including the zero lag.
|
||||
ma_params : ndarray, optional
|
||||
Moving average coefficients, not including the zero lag, where the sign
|
||||
convention assumes the coefficients are part of the lag polynomial on
|
||||
the right-hand-side of the ARMA definition (i.e. they have the same
|
||||
sign from the usual econometrics convention in which the coefficients
|
||||
are on the right-hand-side of the ARMA definition).
|
||||
sigma2 : ndarray, optional
|
||||
The ARMA innovation variance. Default is 1.
|
||||
prefix : str, optional
|
||||
The BLAS prefix associated with the datatype. Default is to find the
|
||||
best datatype based on given input. This argument is typically only
|
||||
used internally.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ndarray
|
||||
Score, evaluated at the given parameters.
|
||||
|
||||
Notes
|
||||
-----
|
||||
This is a numerical approximation, calculated using first-order complex
|
||||
step differentiation on the `arma_loglike` method.
|
||||
"""
|
||||
ar_params = [] if ar_params is None else ar_params
|
||||
ma_params = [] if ma_params is None else ma_params
|
||||
|
||||
p = len(ar_params)
|
||||
q = len(ma_params)
|
||||
|
||||
def func(params):
|
||||
return arma_loglike(endog, params[:p], params[p:p + q], params[p + q:])
|
||||
|
||||
params0 = np.r_[ar_params, ma_params, sigma2]
|
||||
epsilon = _get_epsilon(params0, 2., None, len(params0))
|
||||
return approx_fprime_cs(params0, func, epsilon)
|
||||
|
||||
|
||||
def arma_scoreobs(endog, ar_params=None, ma_params=None, sigma2=1,
|
||||
prefix=None):
|
||||
"""
|
||||
Compute the score (gradient) per observation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
endog : ndarray
|
||||
The observed time-series process.
|
||||
ar_params : ndarray, optional
|
||||
Autoregressive coefficients, not including the zero lag.
|
||||
ma_params : ndarray, optional
|
||||
Moving average coefficients, not including the zero lag, where the sign
|
||||
convention assumes the coefficients are part of the lag polynomial on
|
||||
the right-hand-side of the ARMA definition (i.e. they have the same
|
||||
sign from the usual econometrics convention in which the coefficients
|
||||
are on the right-hand-side of the ARMA definition).
|
||||
sigma2 : ndarray, optional
|
||||
The ARMA innovation variance. Default is 1.
|
||||
prefix : str, optional
|
||||
The BLAS prefix associated with the datatype. Default is to find the
|
||||
best datatype based on given input. This argument is typically only
|
||||
used internally.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ndarray
|
||||
Score per observation, evaluated at the given parameters.
|
||||
|
||||
Notes
|
||||
-----
|
||||
This is a numerical approximation, calculated using first-order complex
|
||||
step differentiation on the `arma_loglike` method.
|
||||
"""
|
||||
ar_params = [] if ar_params is None else ar_params
|
||||
ma_params = [] if ma_params is None else ma_params
|
||||
|
||||
p = len(ar_params)
|
||||
q = len(ma_params)
|
||||
|
||||
def func(params):
|
||||
return arma_loglikeobs(endog, params[:p], params[p:p + q],
|
||||
params[p + q:])
|
||||
|
||||
params0 = np.r_[ar_params, ma_params, sigma2]
|
||||
epsilon = _get_epsilon(params0, 2., None, len(params0))
|
||||
return approx_fprime_cs(params0, func, epsilon)
|
||||
Reference in New Issue
Block a user