Nothing
#' TARMA Modelling of Time Series
#'
#' @description \loadmathjax
#' Implements a Least Squares fit of full subset two-regime \code{TARMA(p1,p2,q1,q2)} model to a univariate time series
#'
#' @param x A univariate time series.
#' @param tar1.lags Vector of AR lags for the lower regime. It can be a subset of \code{1 ... p1 = max(tar1.lags)}.
#' @param tar2.lags Vector of AR lags for the upper regime. It can be a subset of \code{1 ... p2 = max(tar2.lags)}.
#' @param tma1.lags Vector of MA lags for the lower regime. It can be a subset of \code{1 ... q1 = max(tma1.lags)}.
#' @param tma2.lags Vector of MA lags for the upper regime. It can be a subset of \code{1 ... q2 = max(tma2.lags)}.
#' @param threshold Threshold parameter. If \code{NULL} estimates the threshold over the threshold range specified by
#' \code{pa} and \code{pb}.
#' @param d Delay parameter. Defaults to \code{1}.
#' @param pa Real number in \code{[0,1]}. Sets the lower limit for the threshold search to the \code{100*pa}-th sample percentile.
#' The default is \code{0.25}
#' @param pb Real number in \code{[0,1]}. Sets the upper limit for the threshold search to the \code{100*pb}-th sample percentile.
#' The default is \code{0.75}
#' @param method Optimization/fitting method, can be one of \code{"L-BFGS-B", "solnp", "lbfgsb3c", "robust", "trimmed"}.
#' @param alpha Real positive number. Tuning parameter for robust estimation. Only used if \code{method} is \code{robust}.
#' @param qu Quantiles for (initial) trimmed estimation. Tuning parameter for robust estimation. Only used if \code{method} is either \code{robust} or \code{trimmed}.
#' @param innov Innovation density for robust estimation. can be one of \code{"norm", "student"}. Only used if \code{method} is \code{"robust"}.
#' @param optim.control List of control parameters for the main optimization method.
#' @param irls.control List of control parameters for the irls optimization method (see details).
#' @param \dots Additional arguments.
#'
#' @details
#' Implements the Least Squares fit of the following two-regime \code{TARMA(p1,p2,q1,q2)} process: \cr
#' \mjdeqn{X_{t} = \left\lbrace
#' \begin{array}{ll}
#' \phi_{1,0} + \sum_{i \in I_1} \phi_{1,i} X_{t-i} + \sum_{j \in M_1} \theta_{1,j} \varepsilon_{t-j} + \varepsilon_{t} & \mathrm{if } X_{t-d} \leq \mathrm{thd} \\\\\\
#' &\\\\\\
#' \phi_{2,0} + \sum_{i \in I_2} \phi_{2,i} X_{t-i} + \sum_{j \in M_2} \theta_{2,j} \varepsilon_{t-j} + \varepsilon_{t} & \mathrm{if } X_{t-d} > \mathrm{thd}
#' \end{array}
#' \right. }{X[t] =
#' \phi[1,0] + \Sigma_{i in I_1} \phi[1,i] X[t-i] + \Sigma_{j in M_1} \theta[1,j] \epsilon[t-j] + \epsilon[t] -- if X[t-d] <= thd
#' \phi[2,0] + \Sigma_{i in I_2} \phi[2,i] X[t-i] + \Sigma_{j in M_2} \theta[2,j] \epsilon[t-j] + \epsilon[t] -- if X[t-d] > thd}
#' where \mjeqn{\phi_{1,i}}{\phi[1,i]} and \mjeqn{\phi_{2,i}}{\phi[2,i]} are the TAR parameters for the lower and upper regime, respectively, and
#' \code{I1 = tar1.lags} and \code{I2 = tar2.lags} are the corresponding vectors of TAR lags.
#' \mjeqn{\theta_{1,j}}{\theta[1,j]} and \mjeqn{\theta_{2,j}}{\theta[2,j]} are the TMA parameters
#' and \mjeqn{j \in M_1, M_2}{j in M_1, M_2}, where \code{M1 = tma1.lags} and \code{M2 = tma2.lags}, are the vectors of TMA lags. \cr
#' The most demanding routines have been reimplemented in Fortran and dynamically loaded.
#' @section Fitting methods:
#' \code{method} has the following options: \cr
#' \describe{
#' \item{\code{L-BFGS-B}}{Calls the corresponding method of \code{\link{optim}}. Linear ergodicity constraints are imposed.}
#' \item{\code{solnp}}{Calls the function \code{\link[Rsolnp]{solnp}}. It is a nonlinear optimization using augmented Lagrange method with
#' linear and nonlinear inequality bounds. This allows to impose all the ergodicity constraints so that in theory it always
#' return an ergodic solution. In practice the solution should be checked since this is a local solver and there is no guarantee
#' that the minimum has been reached.}
#' \item{\code{lbfgsb3c}}{Calls the function \code{\link[lbfgsb3c]{lbfgsb3c}} in package \code{lbfgsb3c}. Improved version of the L-BFGS-B in \code{\link{optim}}.}
#' \item{\code{robust}}{Robust M-estimator of Ferrari and La Vecchia \insertCite{Fer12}{tseriesTARMA}. Based on the L-BFGS-B in \code{\link{optim}} and an additional iterative re-weighted least squares step to estimate the robust weights.
#' Uses the tuning parameters \code{alpha} and \code{qu}. Robust standard errors are derived from the sandwich estimator of the variance/covariance matrix of the estimates.
#' The IRLS step can be controlled through the parameters \code{maxiter} (maximum number of iterations) and \code{tol} (target tolerance). These can be passed using \code{irls.control}.}
#' \item{\code{trimmed}}{Experimental: Estimator based on trimming the sample using the tuning parameters \code{qu} (lower and upper quantile).}
#' }
#' Where possible, the conditions for ergodicity and invertibility are imposed to the optimization routines but there is no guarantee that the solution will be ergodic and invertible so that it is
#' advisable to check the fitted parameters.
#' @return
#' A list of class \code{TARMA} with components:
#' \itemize{
#' \item \code{fit} - List with the following components \cr
#' \itemize{
#' \item \code{coef} - Vector of estimated parameters which can be extracted by the coef method.
#' \item \code{sigma2} - Estimated innovation variance.
#' \item \code{var.coef} - The estimated variance matrix of the coefficients coef, which can be extracted by the vcov method
#' \item \code{residuals} - Vector of residuals from the fit.
#' \item \code{nobs} - Effective sample size used for fitting the model.
#' }
#' \item \code{se} - Standard errors for the parameters. Note that they are computed conditionally upon the threshold so that they are generally smaller than the true ones.
#' \item \code{thd} - Estimated threshold.
#' \item \code{aic} - Value of the AIC for the minimised least squares criterion over the threshold range.
#' \item \code{bic} - Value of the BIC for the minimised least squares criterion over the threshold range.
#' \item \code{rss} - Minimised value of the target function. Coincides with the residual sum of squares for ordinary least squares estimation.
#' \item \code{rss.v} - Vector of values of the rss over the threshold range.
#' \item \code{thd.range} - Vector of values of the threshold range.
#' \item \code{d} - Delay parameter.
#' \item \code{phi1} - Estimated AR parameters for the lower regime.
#' \item \code{phi2} - Estimated AR parameters for the upper regime.
#' \item \code{theta1} - Estimated MA parameters for the lower regime.
#' \item \code{theta2} - Estimated MA parameters for the upper regime.
#' \item \code{tlag1} - TAR lags for the lower regime
#' \item \code{tlag2} - TAR lags for the upper regime
#' \item \code{mlag1} - TMA lags for the lower regime
#' \item \code{mlag2} - TMA lags for the upper regime
#' \item \code{method} - Estimation method.
#' \item \code{innov} - Innovation density model.
#' \item \code{alpha} - Tuning parameter for robust estimation.
#' \item \code{qu} - Tuning parameter for robust estimation.
#' \item \code{call} - The matched call.
#' \item \code{convergence} - Convergence code from the optimization routine.
#' \item \code{innovpar} - Parameter vector for the innovation density. Defaults to \code{NULL}.
#'}
#' @author Simone Giannerini, \email{simone.giannerini@@uniud.it}
#' @author Greta Goracci, \email{greta.goracci@@unibz.it}
#' @references
#' * \insertRef{Gia21}{tseriesTARMA}
#' * \insertRef{Cha19}{tseriesTARMA}
#' * \insertRef{Gor23b}{tseriesTARMA}
#' * \insertRef{Fer12}{tseriesTARMA}
#'
#' @importFrom zoo is.zoo zoo index
#' @importFrom methods new
#' @importFrom Rsolnp solnp
#' @importFrom lbfgsb3c lbfgsb3c
#' @importFrom stats is.ts window median quantile end frequency tsp tsp<- pnorm var
#' @importFrom Matrix forceSymmetric
#' @importFrom fitdistrplus fitdist
#' @export
#' @seealso \code{\link{TARMA.fit2}} for Maximum Likelihood estimation of TARMA
#' models with common MA part. \code{\link{print.TARMA}} for print methods for \code{TARMA} fits.
#' \code{\link{predict.TARMA}} for prediction and forecasting. \code{\link{plot.tsfit}} for plotting TARMA fits and forecasts.
#' @examples
#' \donttest{
#' ## a TARMA(1,1,1,1) model
#' set.seed(13)
#' x <- TARMA.sim(n=200, phi1=c(0.5,-0.5), phi2=c(0.0,0.5), theta1=-0.5, theta2=0.7, d=1, thd=0.2)
#' fit1 <- TARMA.fit(x,tar1.lags=1, tar2.lags=1, tma1.lags=1, tma2.lags=1, d=1)
#' }
#' ## --------------------------------------------------------------------------
#' ## In the following examples the threshold is fixed to speed up computations
#' ## --------------------------------------------------------------------------
#'
#' ## --------------------------------------------------------------------------
#' ## Least Squares fit
#' ## --------------------------------------------------------------------------
#'
#' set.seed(26)
#' n <- 200
#' y <- TARMA.sim(n=n, phi1=c(0.6,0.6), phi2=c(-1.0,0.4), theta1=-0.7, theta2=0.5, d=1, thd=0.2)
#'
#' fit1 <- TARMA.fit(y,tar1.lags=1, tar2.lags=1, tma1.lags=1, tma2.lags=1, d=1, threshold=0.2)
#' fit1
#'
#' ## ---------------------------------------------------------------------------
#' ## Contaminate the data with one additive outlier
#' ## ---------------------------------------------------------------------------
#' x <- y # contaminated series
#' x[54] <- x[54] + 10
#'
#' ## ---------------------------------------------------------------------------
#' ## Compare the non-robust LS fit with the robust fit
#' ## ---------------------------------------------------------------------------
#'
#' fitls <- TARMA.fit(x,tar1.lags=1, tar2.lags=1, tma1.lags=1, tma2.lags=1, d=1, threshold=0.2)
#' fitrob <- TARMA.fit(x,tar1.lags=1, tar2.lags=1, tma1.lags=1, tma2.lags=1, d=1,
#' method='robust',alpha=0.7,qu=c(0.1,0.95), threshold=0.2)
#'
#' par.true <- c(0.6,0.6,-1,0.4,-0.7,0.5)
#' pnames <- c("int.1", "ar1.1", "int.2", "ar2.1", "ma1.1", "ma2.1")
#' names(par.true) <- pnames
#'
#' par.ls <- round(fitls$fit$coef,2) # Least Squares
#' par.rob <- round(fitrob$fit$coef,2) # robust
#'
#' rbind(par.true,par.ls,par.rob)
## ***************************************************************************
TARMA.fit <- function(x, tar1.lags = c(1), tar2.lags = c(1), tma1.lags = c(1),
tma2.lags = c(1), threshold = NULL, d = 1, pa = 0.25, pb = 0.75,
method=c("L-BFGS-B","solnp","lbfgsb3c","robust","trimmed"),
alpha=0, qu=c(0.05,0.95), innov = c('norm','student'), optim.control = list(trace=0),
irls.control = list(maxiter=100, tol=1e-4), ...) {
method <- match.arg(method)
innov <- match.arg(innov)
n <- length(x)
n.tar1 <- length(tar1.lags)
n.tar2 <- length(tar2.lags)
t.lags <- sort(unique(c(tar1.lags,tar2.lags)))
n.tma1 <- length(tma1.lags)
n.tma2 <- length(tma2.lags)
m.lags <- sort(unique(c(tma1.lags,tma2.lags)))
if(any(t.lags<=0)||any(m.lags<=0)) stop('lags must be positive integers')
if(!any(is.ts(x)|is.zoo(x))){x <- ts(x)}
ix <- index(x)
p1 <- n.tar1+1 # dimension of the TAR vector (1st regime)
p2 <- n.tar2+1 # dimension of the TAR vector (2nd regime)
q1 <- n.tma1 # dimension of the TMA vector (1st regime)
q2 <- n.tma2 # dimension of the TMA vector (2nd regime)
n.tarp <- p1+p2 # total number of TAR parameters
n.tmap <- q1+q2 # total number of TMA parameters
ptot <- n.tarp+n.tmap # total number of parameters
th <- rep(0,ptot) # parameter vector
k <- max(t.lags,m.lags,d,na.rm=TRUE) # number of discarded observations
neff <- n-k # actual sample size
xth <- c(rep(mean(x),d),x[1:(n-d)]) # threshold variable
indg <- (k+1):n # default, non robust set of indices used to compute the OLS target function and gradient
wt <- rep(1,n) # default, non robust set of weights used to compute the OLS target function and gradient
ng <- length(indg)
## ************************************************
## ** LS criteria and their derivatives
## ************************************************
tarmals.R <- function(th){
# TARMA OLS target function (RECURSIVE VERSION)
# th = (phi1,phi2,th1,th2) parameter vector
# indg : external set of indexes (subset of 1:n) for trimmed estimation
phi1 <- th[1:p1]
phi2 <- th[(p1+1):(p1+p2)]
th1 <- th[(p1+p2+1):(p1+p2+q1)]
th2 <- th[(p1+p2+q1+1):(p1+p2+q1+q2)]
eps <- rep(0,n)
L <- 0
for(i in indg){
eps[i] <- x[i] - (phi1%*%c(1,x[i-tar1.lags])+th1%*%eps[i-tma1.lags])*Ir[i] - (phi2%*%(c(1,x[i-tar2.lags]))+th2%*%eps[i-tma2.lags])*(1-Ir[i])
L <- L + eps[i]^2
}
return(L)
}
## ************************************************
tarmals.f <- function(th){
# TARMA OLS target function (Fortran)
# th = (phi1,phi2,th1,th2) parameter vector
# SUBROUTINE tarmaLS(x,nx,th,k,tlag1,p1,tlag2,p2,mlag1,q1,mlag2,q2,Ir,L)
rss <- .Fortran('tarmals',as.double(x),as.integer(n), as.double(th),
as.integer(k),as.integer(tar1.lags),as.integer(p1),as.integer(tar2.lags),as.integer(p2),
as.integer(tma1.lags),as.integer(q1),as.integer(tma2.lags),as.integer(q2),
as.integer(Ir), L=double(1),PACKAGE='tseriesTARMA')$L
# as.integer(Ir), L=double(1),PACKAGE="tseriesTARMA")$L
return(rss)
}
## ************************************************
tarma.eps.R <- function(x,Ir,th,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags){
# computes the residuals of a TARMA fit
# th = (phi1,phi2,th1,th2) parameter vector
n <- length(x)
p1 <- length(tar1.lags)+1 # dimension of the TAR vector (1st regime)
p2 <- length(tar2.lags)+1 # dimension of the TAR vector (2nd regime)
q1 <- length(tma1.lags) # dimension of the TMA vector (1st regime)
q2 <- length(tma2.lags) # dimension of the TMA vector (2nd regime)
phi1 <- th[1:p1]
phi2 <- th[(p1+1):(p1+p2)]
th1 <- th[(p1+p2+1):(p1+p2+q1)]
th2 <- th[(p1+p2+q1+1):(p1+p2+q1+q2)]
eps <- x
eps[] <- 0
for(i in indg){
eps[i] <- x[i] - (phi1%*%c(1,x[i-tar1.lags])+th1%*%eps[i-tma1.lags])*Ir[i] - (phi2%*%(c(1,x[i-tar2.lags]))+th2%*%eps[i-tma2.lags])*(1-Ir[i])
}
return(eps)
}
## ************************************************
Deps.R <- function(x,eps,Ir,th,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags){
## gradient of eps wrt the TARMA parameters
n <- length(x)
p1 <- length(tar1.lags)+1 # dimension of the TAR vector (1st regime)
p2 <- length(tar2.lags)+1 # dimension of the TAR vector (2nd regime)
q1 <- length(tma1.lags) # dimension of the TMA vector (1st regime)
q2 <- length(tma2.lags) # dimension of the TMA vector (2nd regime)
phi1 <- th[1:p1]
phi2 <- th[(p1+1):(p1+p2)]
th1 <- th[(p1+p2+1):(p1+p2+q1)]
th2 <- th[(p1+p2+q1+1):(p1+p2+q1+q2)]
ptot <- length(th)
deps <- matrix(0,n,ptot)
pnames <- c(paste('phi1',c(0,tar1.lags),sep='.'),paste('phi2',c(0,tar2.lags),sep='.'),
paste('th1',tma1.lags,sep='.'),paste('th2',tma2.lags,sep='.'))
colnames(deps) <- pnames
for(i in indg){
deps[i,1] <- -Ir[i]*(1 + th1%*%deps[i-tma1.lags,1]) - (1-Ir[i])*(th2%*%deps[i-tma2.lags,1])
deps[i,2:p1] <- -Ir[i]*(x[i-tar1.lags] + th1%*%deps[i-tma1.lags,2:p1]) -
(1-Ir[i])*(th2%*%deps[i-tma2.lags,2:p1])
deps[i,(p1+1)] <- -Ir[i]*(th1%*%deps[i-tma1.lags,(p1+1)]) - (1-Ir[i])*(1+th2%*%deps[i-tma2.lags,(p1+1)])
deps[i,(p1+2):(p1+p2)] <- -Ir[i]*(th1%*%deps[i-tma1.lags,(p1+2):(p1+p2)]) -
(1-Ir[i])*(x[i-tar2.lags]+th2%*%deps[i-tma2.lags,(p1+2):(p1+p2)])
deps[i,(p1+p2+1):(p1+p2+q1)] <- -Ir[i]*(eps[i-tma1.lags]+th1%*%deps[i-tma1.lags,(p1+p2+1):(p1+p2+q1)]) -
(1-Ir[i])*(th2%*%deps[i-tma2.lags,(p1+p2+1):(p1+p2+q1)])
deps[i,(p1+p2+q1+1):(p1+p2+q1+q2)] <- -Ir[i]*(th1%*%deps[i-tma1.lags,(p1+p2+q1+1):(p1+p2+q1+q2)]) -
(1-Ir[i])*(eps[i-tma2.lags]+th2%*%deps[i-tma2.lags,(p1+p2+q1+1):(p1+p2+q1+q2)])
}
return(deps)
}
## ************************************************
D2eps.R <- function(x,deps,Ir,th,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags){
## Hessian of eps wrt the TARMA parameters
vaprodsum <- function(v,A){
# multiplies the scalar element of the vector v
# by the sheet of the array A and sums them
# the result is a matrix with the first two dimensions of A
if(length(v)==1){
A <- A[,,1]
res <- v*A
}else{
dimA <- dim(A)
k <- dimA[3]
res <- matrix(0,dimA[1],dimA[2])
for(i in 1:k){
res <- res + v[i]*A[,,i]
}
}
return(res)
}
## Hessian of eps
n <- length(x)
p1 <- length(tar1.lags)+1 # dimension of the TAR vector (1st regime)
p2 <- length(tar2.lags)+1 # dimension of the TAR vector (2nd regime)
q1 <- length(tma1.lags) # dimension of the TMA vector (1st regime)
q2 <- length(tma2.lags) # dimension of the TMA vector (2nd regime)
phi1 <- th[1:p1]
phi2 <- th[(p1+1):(p1+p2)]
th1 <- th[(p1+p2+1):(p1+p2+q1)]
th2 <- th[(p1+p2+q1+1):(p1+p2+q1+q2)]
ptot <- length(th)
d2eps <- array(0,dim=c(ptot,ptot,n))
pnames <- c(paste('phi1',c(0,tar1.lags),sep='.'),paste('phi2',c(0,tar2.lags),sep='.'),
paste('th1',tma1.lags,sep='.'),paste('th2',tma2.lags,sep='.'))
dimnames(d2eps) <- list(pnames,pnames,1:n)
for(i in indg){
d2eps[(p1+p2+1):(p1+p2+q1),1:p1,i] <- Ht1p1 <- # dth1 dphi1
-Ir[i]*(deps[i-tma1.lags,1:p1] + vaprodsum(th1,d2eps[(p1+p2+1):(p1+p2+q1),1:p1,i-tma1.lags,drop=FALSE])) -
(1-Ir[i])*(vaprodsum(th2,d2eps[(p1+p2+1):(p1+p2+q1),1:p1,i-tma2.lags,drop=FALSE]))
d2eps[1:p1,(p1+p2+1):(p1+p2+q1),i] <- t(Ht1p1) # dphi1 dth1
d2eps[(p1+p2+1):(p1+p2+q1),(p1+1):(p1+p2),i] <- Ht1p2 <-
-Ir[i]*(deps[i-tma1.lags,(p1+1):(p1+p2)] + vaprodsum(th1,d2eps[(p1+p2+1):(p1+p2+q1),(p1+1):(p1+p2),i-tma1.lags,drop=FALSE])) -
(1-Ir[i])*(vaprodsum(th2,d2eps[(p1+p2+1):(p1+p2+q1),(p1+1):(p1+p2),i-tma2.lags,drop=FALSE])) # dth1 dphi2
d2eps[(p1+1):(p1+p2),(p1+p2+1):(p1+p2+q1),i] <- t(Ht1p2) # dphi2 dth1
d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),1:p1,i] <- Ht2p1 <-
-Ir[i]*(vaprodsum(th1,d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),1:p1,i-tma1.lags,drop=FALSE])) -
(1-Ir[i])*(deps[i-tma2.lags,1:p1]+ vaprodsum(th2,d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),1:p1,i-tma2.lags,drop=FALSE])) # dth2 dphi1
d2eps[1:p1,(p1+p2+q1+1):(p1+p2+q1+q2),i] <- t(Ht2p1)
d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),(p1+1):(p1+p2),i] <- Ht2p2 <-
-Ir[i]*(vaprodsum(th1,d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),(p1+1):(p1+p2),i-tma1.lags,drop=FALSE])) -
(1-Ir[i])*(deps[i-tma2.lags,(p1+1):(p1+p2)]+
vaprodsum(th2,d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),(p1+1):(p1+p2),i-tma2.lags,drop=FALSE])) # dth2 dphi2
d2eps[(p1+1):(p1+p2),(p1+p2+q1+1):(p1+p2+q1+q2),i] <- t(Ht2p2) # dphi2 dth2
d2eps[(p1+p2+1):(p1+p2+q1),(p1+p2+1):(p1+p2+q1),i] <- -Ir[i]*(
deps[i-tma1.lags,(p1+p2+1):(p1+p2+q1)] + t(deps[i-tma1.lags,(p1+p2+1):(p1+p2+q1)])
+ vaprodsum(th1,d2eps[(p1+p2+1):(p1+p2+q1),(p1+p2+1):(p1+p2+q1),i-tma1.lags,drop=FALSE]))
- (1-Ir[i])*(vaprodsum(th2,d2eps[(p1+p2+1):(p1+p2+q1),(p1+p2+1):(p1+p2+q1),i-tma2.lags,drop=FALSE])) # dth1 dth1
d2eps[(p1+p2+1):(p1+p2+q1),(p1+p2+q1+1):(p1+p2+q1+q2),i] <- Ht1t2 <- -Ir[i]*(
deps[i-tma1.lags,(p1+p2+q1+1):(p1+p2+q1+q2)]
+ vaprodsum(th1,d2eps[(p1+p2+1):(p1+p2+q1),(p1+p2+q1+1):(p1+p2+q1+q2),i-tma1.lags,drop=FALSE]))
- (1-Ir[i])*(t(deps[i-tma2.lags,(p1+p2+1):(p1+p2+q1)]) +
vaprodsum(th2,d2eps[(p1+p2+1):(p1+p2+q1),(p1+p2+q1+1):(p1+p2+q1+q2),i-tma2.lags,drop=FALSE])) # dth1 dth2
d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),(p1+p2+1):(p1+p2+q1),i] <- t(Ht1t2) # dth2 dth1
d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),(p1+p2+q1+1):(p1+p2+q1+q2),i] <- -Ir[i]*(
vaprodsum(th1,d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),(p1+p2+q1+1):(p1+p2+q1+q2),i-tma1.lags,drop=FALSE]))
- (1-Ir[i])*(deps[i-tma2.lags,(p1+p2+q1+1):(p1+p2+q1+q2)] + t(deps[i-tma2.lags,(p1+p2+q1+1):(p1+p2+q1+q2)])
+ vaprodsum(th2,d2eps[(p1+p2+q1+1):(p1+p2+q1+q2),(p1+p2+q1+1):(p1+p2+q1+q2),i-tma2.lags,drop=FALSE])) # dth2 dth2
}
return(d2eps)
}
## ************************************************
#DLeps.R <- function(th){
### Analytical Gradient of the TARMA least squares criterion
# eps <- as.double(tarma.eps.R(x,Ir,th,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags))
# deps <- Deps.R(x,eps,Ir,th,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags)
# res <- colSums(2*eps*deps)
# return(res)
#}
## ************************************************
DLeps.f <- function(th){
## Analytical Gradient of the TARMA least squares criterion
## Fortran version
#SUBROUTINE tarmaDLS(x,nx,th,k,tlag1,p1,tlag2,p2,mlag1,q1,mlag2,q2,Ir,DL)
ptot <- length(th)
res <- .Fortran('tarmadls',as.double(x),as.integer(n), as.double(th),
as.integer(k),as.integer(tar1.lags),as.integer(p1),as.integer(tar2.lags),as.integer(p2),
as.integer(tma1.lags),as.integer(q1),as.integer(tma2.lags),as.integer(q2),
as.integer(Ir), DL=double(ptot),PACKAGE='tseriesTARMA')$DL
return(res)
}
## ************************************************
if(method=='robust'| method=='trimmed'){
## ************************************************
# tarmalsw.R <- function(th,wt){
# # TARMA OLS target function (ROBUST VERSION)
# # th : (phi1,phi2,th1,th2) parameter vector
# # wt : weights (that depend upon alpha)
# # indg : external set of indexes (subset of 1:n) for trimmed estimation
# phi1 <- th[1:p1]
# phi2 <- th[(p1+1):(p1+p2)]
# th1 <- th[(p1+p2+1):(p1+p2+q1)]
# th2 <- th[(p1+p2+q1+1):(p1+p2+q1+q2)]
# eps <- rep(0,n)
# L <- 0
# for(i in indg){
# eps[i] <- x[i] - (phi1%*%c(1,x[i-tar1.lags])+th1%*%eps[i-tma1.lags])*Ir[i] - (phi2%*%(c(1,x[i-tar2.lags]))+th2%*%eps[i-tma2.lags])*(1-Ir[i])
# L <- L + wt[i]*eps[i]^2
# }
# return(L)
# }
## ************************************************
tarmalsw.f <- function(th,wt){
# TARMA OLS target function (ROBUST VERSION, Fortran)
# wt : weights (that depend upon alpha)
# indg : external set of indexes (subset of 1:n) for trimmed estimation
# SUBROUTINE tarmaLSW(x,nx,th,tlag1,p1,tlag2,p2,mlag1,q1,mlag2,q2,Ir,wt,indg,ng,L)
rss <- .Fortran('tarmalsw',as.double(x),as.integer(n), as.double(th),
as.integer(tar1.lags),as.integer(p1),as.integer(tar2.lags),as.integer(p2),
as.integer(tma1.lags),as.integer(q1),as.integer(tma2.lags),as.integer(q2),
as.integer(Ir), as.double(wt), as.integer(indg),as.integer(ng),L=double(1),PACKAGE='tseriesTARMA')$L
# ,PACKAGE="tseriesTARMA")$L
return(rss)
}
## ************************************************
# DLepsw.R <- function(th,wt){
# ## Gradient of the robust TARMA least squares criterion tarmalsw.R
# # wt : weights (that depend upon alpha)
# eps <- as.double(tarma.eps.R(x,Ir,th,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags))
# deps <- Deps.R(x,eps,Ir,th,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags)
# res <- colSums(2*wt*eps*deps)
# return(res)
# }
## ************************************************
DLepsw.f <- function(th,wt){
## Analytical Gradient of the robust TARMA least squares criterion
## Fortran version
# wt : weights (that depend upon alpha)
# SUBROUTINE tarmaDLSW(x,nx,th,tlag1,p1,tlag2,p2,mlag1,q1,mlag2,q2,Ir,wt,indg,ng,DL)
ptot <- length(th)
res <- .Fortran('tarmadlsw',as.double(x),as.integer(n), as.double(th),
as.integer(tar1.lags),as.integer(p1),as.integer(tar2.lags),as.integer(p2),
as.integer(tma1.lags),as.integer(q1),as.integer(tma2.lags),as.integer(q2),
as.integer(Ir), as.double(wt), as.integer(indg),as.integer(ng), DL=double(ptot),PACKAGE='tseriesTARMA')$DL
return(res)
}
## ****************************************************
## Gradient of the rho function
## ****************************************************
Drho <- function(type,alpha){
# first derivative of rho wrt to eps for different densities for the innovations
if(type=='norm'){
function(eps,alpha){
s2t <- mean(eps^2)
# (2*pi)^(-alpha/2)*s2t^(-alpha/2-1)*c(exp(-alpha*eps^2/(2*s2t)))*eps
(2*pi)^(-alpha/2)*s2t^(-1)*c(exp(-alpha*eps^2/(2*s2t)))*eps
}
# }else if(type=='sn'){
# if(alpha>0){
# function(eps,alpha){
# fit <- selm(eps ~ 1, family="SN")
# pa <- fit@param$dp # SN parameters (xi,omega,a)
# # pa[1] <- -pa[2]*sqrt(2/pi)*pa[3]/sqrt(1+pa[3]^2) # to get zero mean
# ec <- (eps-pa[1])/pa[2]
# # drho <- pa[2]^(-3) * exp(-(1+pa[3]^2)/2*ec^2) * (2*pi)^(-alpha/2) * (exp(-ec^2/2) * 2*(pnorm(pa[3]*ec))/pa[2])^(alpha-1)*
# # (-pa[3]*sqrt(2/pi)*pa[2] + exp(pa[3]^2/2 * ec^2) * (eps-pa[1])* 2*pnorm(pa[3]*ec))
# drho <- pa[2]^(-3) * (2*pi)^(-alpha/2)* (2*pnorm(pa[3]*ec)/pa[2])^(alpha) * exp(-alpha*ec^2/2) *
# (pa[2]*(eps-pa[1]) - pa[3]*sqrt(2/pi)*pa[2]^2 *exp(-pa[3]^2 * ec^2/2)*(2*pnorm(pa[3]*ec))^(-1))
# return(drho)
# }
# }else{
# function(eps,alpha){
# fit <- selm(eps ~ 1, family="SN")
# pa <- fit@param$dp # SN parameters (xi,omega,a)
# ec <- (eps-pa[1])/pa[2]
# drho <- (eps - pa[1] - (pa[3]* exp(-(pa[3]*ec)^2/2)*sqrt(2/pi)*pa[2])/((2*pnorm(pa[3]*ec))))/pa[2]^2
# return(drho)
# }
# }
}else if(type=='student'){
function(eps,alpha){
vx <- var(eps)
sdf <- ifelse(vx<=1.3,20,2/(1-1/vx))
f0 <- tryCatch(fitdist(eps, distr='t', method = "mge", start=list(df=sdf)),error=function(x){list(estimate=sdf)})
sdf2 <- as.double(f0$estimate)
f1 <- tryCatch(fitdist(eps, distr='t', method = "mle",start=list(df=sdf2)),error=function(x){list(estimate=sdf2)})
nu <- f1$estimate
gamma((nu+1)/2)^alpha * gamma(nu/2)^(-alpha)*(nu*pi)^(-alpha/2)*(1+eps^2/nu)^(-alpha*(nu+1)/2)*(nu+1)/(2*(nu+eps^2))*2*eps
}
}
}
## ********************************************************
D2rho <- function(type,alpha){
# second derivative of rho wrt to eps for different densities for the innovations
if(type=='norm'){
function(eps,alpha){
s2t <- mean(eps^2)
# (2*pi)^(-alpha/2)*s2t^(-alpha/2-2)* c(exp(-alpha*eps^2/(2*s2t)))*(-alpha*eps^2 + s2t)
(2*pi)^(-alpha/2)*s2t^(-2)* c(exp(-alpha*eps^2/(2*s2t)))*(-alpha*eps^2 + s2t)
}
# }else if(type=='sn'){
# if(alpha>0){
# function(eps,alpha){
# fit <- selm(eps ~ 1, family="SN")
# pa <- fit@param$dp # SN parameters (xi,omega,a)
# # pa[1] <- -pa[2]*sqrt(2/pi)*pa[3]/sqrt(1+pa[3]^2) # to get zero mean
# ec <- (eps-pa[1])/pa[2]
# Phi <- pnorm(pa[3]*ec)
# out <- ((pa[3]^2*(1-alpha))/(2*(pa[2]*Phi)^2) * 2^(-alpha/2) *exp(-(pa[3]*ec)^2)*pi^(-1-alpha/2) +
# pa[3]*(2^((1-alpha)/2)*pi^(-(1+alpha)/2))/(pa[2]^2*2*Phi) * ec*(pa[3]^2 + 2*alpha)* exp(-(pa[3]*ec)^2/2)
# + pa[2]^(-2)*(2*pi)^(-alpha/2)*(1-alpha*ec^2)) * (exp(-ec^2/2) *2*Phi/pa[2])^(alpha)
# return(out)
# }
# }else{
# function(eps,alpha){
# fit <- selm(eps ~ 1, family="SN")
# pa <- fit@param$dp # SN parameters (xi,omega,a)
# ec <- (eps-pa[1])/pa[2]
# out <- pa[2]^(-2)*(1+(1*pa[3]^2*exp(-(pa[3]*ec)^2))/(2*pi*pnorm(pa[3]*ec)^2) +
# (pa[3]^3*exp(-(pa[3]*ec)^2/2)*sqrt(2/pi)*(eps-pa[1]))/(2*pa[2]*pnorm(pa[3]*ec)))
# return(out)
# }
# }
}else if(type=='student'){
function(eps,alpha){
vx <- var(eps)
sdf <- ifelse(vx<=1.3,20,2/(1-1/vx))
f0 <- tryCatch(fitdist(eps, distr='t', method = "mge", start=list(df=sdf)),error=function(x){list(estimate=sdf)})
sdf2 <- as.double(f0$estimate)
f1 <- tryCatch(fitdist(eps, distr='t', method = "mle",start=list(df=sdf2)),error=function(x){list(estimate=sdf2)})
nu <- f1$estimate
-gamma((nu+1)/2)^alpha * gamma(nu/2)^(-alpha)*(nu*pi)^(-alpha/2)*(1+eps^2/nu)^(-alpha*(nu+1)/2)*(nu+1)/(2*(nu+eps^2))*2*
(-nu+eps^2+(1+nu)*eps^2 * alpha)/((nu+eps^2))
}
}
}
drho <- Drho(type=innov,alpha)
d2rho <- D2rho(type=innov,alpha)
## ***********************************************************
wtfun <- function(eps,alpha){
## function to compute the robustness weights
out <- rep(0,length(eps))
ind <- which(abs(eps)>0)
dreps <- drho(eps,alpha) # first derivative of the rho function w.r.t. eps
out[ind] <- dreps[ind]/(2*eps[ind])
# out <- ifelse(abs(out)>1,1,out)
return(out)
}
## ***********************************************************
irls <- function(par, optf, par.opt, control=list()){
# Iteratively Re-weighted Least Squares step
con <- list(maxiter=100, tol=1e-04)
con[names(control)] <- control
maxiter <- con$maxiter
tol <- con$tol
p.old <- par
crit.old <- Inf # starting value for the reduction criterion
eps <- tarma.eps.R(x,Ir,par,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags)
wt <- wtfun(eps,alpha)
par.opt$par <- par
par.opt$wt <- wt
for(j in 1:maxiter){
opt.new <- tryCatch(do.call(optf,par.opt),
error=function(x){list(par=rep(Inf,ptot),value=Inf, convergence=-1)})
## opt.new <- do.call(optf,par.opt)
p.new <- opt.new$par
crit.new <- norm((p.new-p.old)/p.old,'2')
# cat(crit.new,opt.new$value,'\n')
## if((crit.new > crit.old)|(crit.new < tol)) break
if(crit.new < tol) break
if((opt.new$convergence!=0)|(crit.new > crit.old*100)){
p.new <- p.old + rnorm(ptot,sd=0.05)
}else{
opt <- opt.new
crit.old <- crit.new
}
eps <- tarma.eps.R(x,Ir,th=p.new,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags)
wt <- wtfun(eps,alpha)
par.opt$par <- p.new
par.opt$wt <- wt
p.old <- p.new
}
s2t <- sum(eps^2)/(n - k)
opt$iterations <- j
opt$sigma2 <- s2t/(1-alpha/2)
opt$wt <- wt
# cat('IRLS iterations:',j,'------------ \n')
return(opt)
}
}
## **************************************************************************
## Constraints for ergodicity and invertibility
## **************************************************************************
if(all(tar1.lags==1)&all(tar2.lags==1)&all(tma1.lags==1)&all(tma2.lags==1)){
# TARMA(1,1)
tarma.parcheck <- function(th){
# constraints for geometric ergodicity and invertibility
# for a TARMA(1,1) model
phi1 <- th[2]
phi2 <- th[4]
res <- (phi1<1)&(phi2<1)&((phi1*phi2)<1)&(abs(th[5])<1)&(abs(th[6])<1)
return(unname(res))
}
ifun <- function(th){
# inequality constraints for geometric ergodicity and invertibility
# for a TARMA(1,1) model
phi1 <- th[2]
phi2 <- th[4]
res <- c(phi1*phi2)
}
ilow.b <- -Inf
iupp.b <- 1
lowb <- c(-Inf,-Inf,-Inf,-Inf,-1,-1)
uppb <- c(+Inf,1,+Inf,1,1,1)
}else{
# generic TARMA
tarma.parcheck <- function(th){
# constraints for geometric ergodicity
# for a TARMA model
phi1 <- th[2:p1] # without intercepts
phi2 <- th[(p1+2):(p1+p2)] # without intercepts
res <- (sum(abs(phi1))<1)&(sum(abs(phi2))<1)
return(unname(res))
}
ifun <- function(th){
# inequality constraints for geometric ergodicity and invertibility
# for a TARMA model
phi1 <- th[2:p1] # without intercepts
phi2 <- th[(p1+2):(p1+p2)] # without intercepts
th1 <- th[(p1+p2+1):(p1+p2+q1)]
th2 <- th[(p1+p2+q1+1):(p1+p2+q1+q2)]
res <- c(sum(abs(phi1)),sum(abs(phi2)),sum(abs(th1)),sum(abs(th2)))
}
ilow.b <- rep(0,4)
iupp.b <- rep(1,4)
# parameter bounds
lowb <- c(-Inf,rep(-1,p1-1),-Inf,rep(-1,p2-1),rep(-1,q1),rep(-1,q2)) # TARMA(p,q)
uppb <- c(+Inf,rep( 1,p1-1),+Inf,rep(+1,p2-1),rep(+1,q1),rep(+1,q2))
}
## *****************************************************
## OPTIMIZATION METHODS ********************************
## *****************************************************
if(method=='L-BFGS-B'){
optfun <- 'optim'
fobj <- tarmals.f
gobj <- DLeps.f
param <- list(fn=fobj,gr=gobj,method="L-BFGS-B", lower=lowb,upper=uppb,
control=optim.control)
}else if(method=='solnp'){
optfun <- 'solnp'
fobj <- tarmals.f
gobj <- DLeps.f
param <- list(fun=fobj, eqfun = NULL, eqB = NULL, ineqfun = ifun, ineqLB = ilow.b,
ineqUB = iupp.b, LB = lowb, UB = uppb, control=optim.control)
}else if(method=='robust'){
optfun <- 'irls'
optf <- 'optim'
fobj <- tarmalsw.f
gobj <- DLepsw.f
par.opt <- list(fn=fobj,gr=gobj,method="L-BFGS-B", lower=lowb,upper=uppb,
control=optim.control)
param <- list(optf=optf,par.opt=par.opt, control=irls.control)
# ------------
}else if(method=='lbfgsb3c'){
optfun <- 'lbfgsb3c'
fobj <- tarmals.f
gobj <- DLeps.f
param <- list(fn=fobj,gr=gobj,lower=lowb,upper=uppb,control=optim.control)
#}else if(method=='robustc'){
# optfun <- 'lbfgsb3c'
# fobj <- tarmalsw.f
# gobj <- DLepsw.f
# param <- list(fn=fobj,gr=gobj, lower=lowb,upper=uppb,
# control=optim.control)
#}else if(method=='rsolnp'){
# optfun <- 'solnp'
# fobj <- tarmalsw.f
# gobj <- DLepsw.f
# param <- list(fun=fobj, eqfun = NULL, eqB = NULL, ineqfun = ifun, ineqLB = ilow.b,
# ineqUB = iupp.b, LB = lowb, UB = uppb,control=optim.control)
}else if(method=='trimmed'){
quant <- quantile(x,probs=qu)
indg <- intersect(indg,which((quant[1]<x)&(x<quant[2]))) # trimmed set of indices
optfun <- 'optim'
fobj <- tarmalsw.f
gobj <- DLepsw.f
param <- list(fn=fobj,gr=gobj,method="L-BFGS-B", lower=lowb,upper=uppb,
control=optim.control)
}
## *********************************************
if(is.null(threshold)){ # estimates the threshold
a <- ceiling((neff-1)*pa)
b <- floor((neff-1)*pb)
thd.v <- sort(xth)
thd.range <- thd.v[a:b]
nr <- length(thd.range)
pars <- matrix(NA,nr,ptot)
rss.g <- Inf
par.g <- rep(NA,ptot)
rssv <- rep(NA,nr)
ind <- trunc(quantile(1:nr,prob=seq(0,1,by=0.1)))
res <- matrix(NA,nr,ptot+1)
x.t <- x # for the initial fit (either trimmed or not)
if((method=='robust')&(alpha>0)){
quant <- quantile(x,probs=c(qu[1],qu[2]))
indg <- intersect(indg,which((quant[1]<x)&(x<quant[2]))) # trimmed set of indices for robust initial fit
ng <- length(indg)
indb <- setdiff(1:n,indg)
x.t[indb]<- NA; #median(x[indg])
}
fit0 <- TARMA.fit2(x.t, ma.ord = max(m.lags), ar.lags = NULL,
tar1.lags = tar1.lags, tar2.lags=tar2.lags, threshold=quantile(x.t,pa,na.rm=TRUE)
, d = d, include.int = TRUE)
ar1 <- fit0$phi1[c(1,tar1.lags+1)]
ar2 <- fit0$phi2[c(1,tar2.lags+1)]
ma1 <- fit0$theta1[tma1.lags]
ma2 <- fit0$theta2[tma2.lags]
theta0 <- c(ar1,ar2,ma1,ma2)+rnorm(ptot,sd=0.01)
thd <- thd.range[1]
Ir <- (xth<=thd)
sigma2 <- fit0$fit$sigma2
if((method=='robust')&(alpha>0)){ # initial robust fit using trimmed LS
optfun.s <- 'optim'
fobj.s <- tarmalsw.f
gobj.s <- DLepsw.f
param.s <- list(par=theta0, fn=fobj.s,gr=gobj.s,method="L-BFGS-B",lower=lowb,upper=uppb,
control=optim.control,wt=wt)
opt <- tryCatch(do.call(optfun.s,param.s),
error=function(x){list(par=rep(NA,ptot),value=Inf, convergence=-1)})
theta0 <- opt$par
indg <- (k+1):n #
}
param$par <- theta0
opt <- tryCatch(do.call(optfun,param),
error=function(x){list(par=rep(NA,ptot),value=Inf, convergence=-1)})
ntry <- 0
# while(opt$convergence!=0){
while(is.null(opt$convergence)||opt$convergence!=0){ # workaround for the bug in lbfgsb3c
ntry <- ntry+1
theta0 <- theta0+rnorm(ptot,sd=0.05)
param$par <- theta0
opt <- tryCatch(do.call(optfun,param),
error=function(x){list(par=rep(NA,ptot),value=Inf, convergence=-1)})
if(ntry==50) stop('Initial fit failed')
}
res[1,1] <- opt$value[1]
res[1,-1] <- opt$par
theta0 <- opt$par
for(i in 2:nr){
thd <- thd.range[i]
Ir <- (xth<=thd)
param$par <- theta0
opt <- tryCatch(do.call(optfun,param),
error=function(x){list(par=rep(NA,ptot),value=Inf, convergence=-1)})
# if(opt$convergence!=0){
ntry <- 0
while(is.null(opt$convergence)||opt$convergence!=0){ # workaround for the bug in lbfgslb3c
if(ntry>5){theta0 <- res[i-2,-1]; break}
# theta0 <- theta0 + rnorm(ptot,sd=0.05)
theta0 <- res[i-2,-1] + rnorm(ptot,sd=0.03) # uses the last good parameter
param$par <- theta0
opt <- tryCatch(do.call(optfun,param),
error=function(x){list(par=rep(NA,ptot),value=Inf, convergence=-1)})
ntry <- ntry + 1
# cat('ntry: ',ntry,'\n')
}
theta0 <- opt$par
res[i,1] <- opt$value[1]
res[i,-1] <- opt$par
}
igood <- which.min(res[,1])
thd <- thd.range[igood]
rssv <- res[,1]
rss <- res[igood,1]
par.g <- res[igood,-1]
Ir <- (xth<= thd)
}else{ # fixed threshold -----------------------------------------------
thd <- threshold
Ir <- (xth<= thd)
rssv <- NA
thd.range <- NA
if((method=='robust')&(alpha>0)){ # initial robust fit using trimmed LS
quant <- quantile(x,probs=c(qu[1],qu[2]))
indg <- intersect(indg,which((quant[1]<x)&(x<quant[2]))) # trimmed set of indices for robust initial fit
ng <- length(indg)
indb <- setdiff(1:n,indg)
x.t <- x # trimmed x
x.t[indb]<- NA #median(x[indg])
# xth.t <- c(rep(median(x.t),d),x.t[1:(n-d)]) # trimmed threshold variable
fit0 <- TARMA.fit2(x.t, ma.ord=max(m.lags), ar.lags=NULL,
tar1.lags=tar1.lags, tar2.lags=tar2.lags, threshold=thd, d=d,include.int=TRUE)
ar1 <- fit0$phi1[c(1,tar1.lags+1)]
ar2 <- fit0$phi2[c(1,tar2.lags+1)]
ma1 <- fit0$theta1[tma1.lags]
ma2 <- fit0$theta2[tma2.lags]
sigma2 <- fit0$fit$sigma2
theta0 <- c(ar1,ar2,ma1,ma2)+rnorm(ptot,sd=0.05)
optfun.s <- 'optim'
fobj.s <- tarmalsw.f
gobj.s <- DLepsw.f
param.s <- list(par=theta0, fn=fobj.s,gr=gobj.s,method="L-BFGS-B", lower=lowb,upper=uppb,
control=optim.control,wt=wt)
opt <- tryCatch(do.call(optfun.s,param.s),
error=function(x){list(par=rep(NA,ptot),value=Inf, convergence=-1)})
theta0 <- opt$par
indg <- (k+1):n #
}else{
fit0 <- TARMA.fit2(x, ma.ord=max(m.lags), ar.lags=NULL,
tar1.lags=tar1.lags,tar2.lags=tar2.lags,threshold=thd, d=d,include.int=TRUE)
ar1 <- fit0$phi1[c(1,tar1.lags+1)]
ar2 <- fit0$phi2[c(1,tar2.lags+1)]
ma1 <- fit0$theta1[tma1.lags]
ma2 <- fit0$theta2[tma2.lags]
sigma2 <- fit0$fit$sigma2
theta0 <- c(ar1,ar2,ma1,ma2)+rnorm(ptot,sd=0.05)
}
param$par <- theta0
opt <- do.call(optfun,param)
rss <- opt$value[1]
par.g <- opt$par
}
## Standard Errors *******************************************************
innovpar <- NULL # parameter vector for the innovation density (NULL by default)
wt <- NULL # robust weights
eps <- tarma.eps.R(x,Ir,th=par.g,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags)
deps <- Deps.R(x,eps,Ir,th=par.g,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags) # gradient of eps wrt the TARMA parameters
d2eps <- D2eps.R(x,deps,Ir,th=par.g,k,tar1.lags,tar2.lags,tma1.lags,tma2.lags) # Hessian of eps wrt the TARMA parameters
eps <- c(eps[-(1:k)])
Ir <- Ir[-(1:k)]
deps <- unclass(deps[-(1:k),])
d2eps <- unclass(d2eps[,,-(1:k)])
if((method=='robust')|(method=='robustc')|(method=='rsolnp')){
wt <- opt$wt
## Sandwich estimator of the variance/covariance matrix of the estimates
dreps <- unclass(drho(eps,alpha)) # first derivative of the rho function w.r.t. eps
d2reps <- unclass(d2rho(eps,alpha)) # second derivative of the rho function w.r.t. eps
H <- matrix(0,ptot,ptot) # Second derivatives
J <- matrix(0,ptot,ptot) # product of the first derivatives
for(i in 1:(n-k)){
deps2i <- deps[i,]%*%t(deps[i,])
J <- J + dreps[i]^2*deps2i
H <- H + d2reps[i]*deps2i + dreps[i]*d2eps[,,i]
}
if(innov=='student'){
vx <- var(eps)
sdf <- ifelse(vx<=1.3,20,2/(1-1/vx))
f0 <- tryCatch(fitdist(eps, distr='t', method = "mge", start=list(df=sdf)),error=function(x){list(estimate=sdf)})
sdf2 <- as.double(f0$estimate)
f1 <- tryCatch(fitdist(eps, distr='t', method = "mle",start=list(df=sdf2)),error=function(x){list(estimate=sdf2)})
innovpar <- f1$estimate
names(innovpar) <- 'df'
}
}else{
D1L <- 2*c(eps)*deps
H <- 2*t(deps)%*%deps + apply(2*array(rep(eps,each=ptot^2),dim=c(ptot,ptot,(n-k)))*d2eps,FUN=sum,MARGIN=c(1,2))
J <- t(D1L)%*%D1L
}
J <- J/(n-k)
H <- H/(n-k)
Hi <- solve(forceSymmetric(H))
sigmai <- Hi%*%J%*%Hi
s2hat <- mean(eps^2)
eps <- as.ts(zoo(eps,order.by = ix[-(1:k)]))
n1 <- sum(Ir)
n2 <- sum(1-Ir)
np1 <- p1+q1
np2 <- p2+q2
s2hat.1 <- sum(Ir*eps^2)/n1
s2hat.2 <- sum((1-Ir)*eps^2)/n2
aic <- n1*log(s2hat.1) + n2*log(s2hat.2) + neff*(1+log(2*pi)) + 2*(np1+np2+1)
bic <- n1*log(s2hat.1) + n2*log(s2hat.2) + neff*(1+log(2*pi)) + log(neff)*(np1+np2+1)
vcoef <- sigmai/(n-k)
se <- sqrt(diag(vcoef))
ntar1 <- c('int.1',paste('ar1',tar1.lags,sep='.'))
ntar2 <- c('int.2',paste('ar2',tar2.lags,sep='.'))
nma1 <- paste('ma1',tma1.lags,sep='.')
nma2 <- paste('ma2',tma2.lags,sep='.')
names(par.g) <- names(se) <- c(ntar1,ntar2,nma1,nma2)
colnames(vcoef) <- rownames(vcoef) <- names(par.g)
phi1 <- par.g[1:p1]
phi2 <- par.g[(p1+1):(p1+p2)]
th1 <- par.g[(p1+p2+1):(p1+p2+q1)]
th2 <- par.g[(p1+p2+q1+1):(p1+p2+q1+q2)]
Phi1 <- rep(0,max(tar1.lags)+1)
Phi1[c(1,tar1.lags+1)] <- phi1
names(Phi1) <- 0:max(tar1.lags)
Phi2 <- rep(0,max(tar2.lags)+1)
Phi2[c(1,tar2.lags+1)] <- phi2
names(Phi2) <- 0:max(tar2.lags)
Th1 <- rep(0,max(tma1.lags))
Th1[tma1.lags] <- th1
names(Th1) <- 1:max(tma1.lags)
Th2 <- rep(0,max(tma2.lags))
Th2[tma2.lags] <- th2
names(Th2) <- 1:max(tma2.lags)
res <- list(fit=list(coef=par.g,sigma2=s2hat,var.coef=vcoef,
residuals=eps,nobs=n-k),se=se, thd=thd, aic=aic, bic=bic, rss=rss, rss.v=rssv, thd.range=thd.range,
d=d, phi1=Phi1, phi2=Phi2, theta1=Th1, theta2=Th2, tlag1=tar1.lags,
tlag2=tar2.lags, mlag1=tma1.lags, mlag2=tma2.lags, method=method, innov=innov, alpha=alpha, qu=qu,
call = match.call(), convergence=opt$convergence, innovpar=innovpar, wt=wt)
if(!tarma.parcheck(par.g)) warning("The parameters are not in the ergodicity region.
Refit with constrained optimization (method='solnp').")
if(opt$convergence!=0) warning(paste('convergence code:',opt$convergence))
class(res) <- 'TARMA'
return(res)
}
## ****************************************************************************
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.