#' @name .irf.sign.zero
#' @noRd
#' @importFrom MASS Null
.irf.sign.zero <- function(xdat,plag,n.ahead,Amat,Smat,Emat,shockinfo,MaxTries,...){
bigT <- nrow(xdat)
bigK <- ncol(xdat)
varNames <- colnames(xdat)
P0G <- try(t(chol(Smat[,,drop=FALSE])),silent=TRUE)
if(is(P0G,"try-error")) suppressWarnings(P0G <- t(chol(Smat,pivot=TRUE)))
colnames(P0G) <- rownames(P0G) <- varNames
# create dynamic multiplier
PHIx <- array(0,c(bigK,bigK,plag+n.ahead+1)); dimnames(PHIx)[[1]] <- dimnames(PHIx)[[2]] <- varNames
PHIx[,,plag+1] <- diag(bigK)
temp <- .gen_compMat(Amat, bigK, plag)
Cm <- temp$Cm
Jm <- temp$Jm
Cmat <- diag(bigK*plag)
for (ihor in (plag+2):(plag+n.ahead+1)){
Cmat <- Cmat%*%Cm
PHIx[,,ihor] <- t(Jm)%*%Cmat%*%Jm
}
PHI <- PHIx[,,(plag+1):(plag+n.ahead+1)]
#-----------------------------------------------------------------------------
sign.horizon <- unique(shockinfo$horizon)
sign.horizon <- sort(sign.horizon, decreasing=FALSE)
sign.shockvars <- unique(shockinfo$shock)
H.restr <- length(sign.horizon)
N.restr <- bigK*H.restr
S.cube <- array(NA, c(N.restr, N.restr, bigK)) # sign restrictions
Z.cube <- array(NA, c(N.restr, N.restr, bigK)) # zero restrictions
dimnames(S.cube)[[1]] <- dimnames(Z.cube)[[1]] <-
dimnames(S.cube)[[2]] <- dimnames(Z.cube)[[2]] <- paste(rep(varNames,H.restr),".",
rep(sign.horizon,each=bigK),sep="")
dimnames(S.cube)[[3]] <- dimnames(Z.cube)[[3]] <- varNames
for(vv in 1:length(varNames)){
S.temp <- matrix(0, N.restr, N.restr)
Z.temp <- matrix(0, N.restr, N.restr)
if(varNames[vv]%in%sign.shockvars){
idx <- which(shockinfo$shock==varNames[vv])
sign.restr <- shockinfo$restrictions[idx]
sign.signs <- shockinfo$sign[idx]
sign.horiz <- shockinfo$horizon[idx]
s.point <- which(sign.signs=="<"|sign.signs==">")
z.point <- seq(1,length(idx))[-s.point]
if(length(s.point)>0){
for(ss in 1:length(s.point)){
grp <- which(sign.horiz[s.point[ss]] == sign.horizon)
col <- seq(which(sign.restr[s.point[ss]]==varNames),bigK*grp,by=bigK)
for(ii in 1:length(col)){
S.temp[col[ii],col[ii]] <- ifelse(sign.signs[s.point[ss]]=="<",-1,1)
}
}
}
if(length(z.point)>0){
for(zz in 1:length(z.point)){
if(sign.signs[z.point[zz]]=="0"){
grp <- which(sign.horiz[z.point[zz]] == sign.horizon)
row <- (grp-1)*bigK+which(sign.restr[z.point[zz]]==varNames)
Z.temp[row,row] <- 1
}else{ # take row from above
grp <- which(sign.horiz[z.point[zz]] == sign.horizon)
col <- (grp-1)*bigK+which(sign.restr[z.point[zz]]==varNames)
Z.temp[row,col] <- as.numeric(sign.signs[z.point[zz]])
}
}
}
}
S.cube[,,vv] <- S.temp
Z.cube[,,vv] <- Z.temp
}
no.zero.restr <- ifelse(base::sum(abs(Z.cube))>0,FALSE,TRUE)
shock.order <- rep(NA, bigK)
search.Znum <- apply(Z.cube, 3, function(x) base::sum(abs(x)))
search.Snum <- apply(S.cube, 3, function(x) base::sum(abs(x)))
for(mm in 1:bigK){
if(!no.zero.restr){
max.Z <- which(search.Znum==max(search.Znum))
if(length(max.Z)==1){
shock.order[mm] <- max.Z
}else{
shock.order[mm] <- sample(max.Z,1)
}
} else {
shock.order[mm] <- mm
}
search.Znum[shock.order[mm]] <- -1
search.Snum[shock.order[mm]] <- -1
}
shock.order <- varNames[shock.order]
irf.restr <- matrix(NA, N.restr, bigK)
for(hh in 1:H.restr){
# ARRW: Definition 1
if(sign.horizon[hh]!=Inf) irf.hh<-PHI[,,sign.horizon[hh]]%*%P0G
# ARRW: Definition 2
#if(sign.horizon[hh]==Inf) irf.hh <- solve(A0-A0%*%Cm[1:M,]%*%do.call("rbind",rep(list(diag(M)),p)))
irf.restr[((hh-1)*bigK+1):(bigK*hh),1:bigK] <- irf.hh
}
colnames(irf.restr) <- varNames
rownames(irf.restr) <- paste(rep(varNames,H.restr),".",
rep(sign.horizon,each=bigK),sep="")
Z.cube <- Z.cube[,,shock.order]
# draw rotation matrix here
icounter <- 0
condall <- 0
max.counter <- MaxTries
impresp<-Q_bar<-NA
while(condall == 0 && icounter < max.counter){
signCheck <- matrix(NA, bigK, 1)
randMat <- matrix(rnorm(bigK*bigK,0,1),bigK,bigK)
Q <- matrix(0, bigK, bigK)
if(no.zero.restr){
Q <- qr(randMat)
Q <- qr.Q(Q)
}else{
for(mm in 1:bigK){
Z.temp <- Z.cube[,,mm]
Z.temp <- Z.temp[rowSums(abs(Z.temp))!=0,,drop=F]
if(nrow(Z.temp)==0){
Z.temp <- matrix(0, 1, N.restr)
}
if(all(Z.temp==0) && mm>1){
R <- c()
}else{
R <- Z.temp%*%irf.restr
}
if(mm > 1){R <- rbind(R, t(Q[,(1:(mm-1)), drop=FALSE]))}
NU <- Null(t(R))
x_j <- randMat[,mm,drop =FALSE]
q_j <- NU%*%(t(NU)%*%x_j/sqrt(as.numeric(crossprod(t(NU)%*%x_j))))
Q[,mm] <- q_j
}
}
colnames(Q) <- shock.order; rownames(Q) <- varNames
Q <- Q[,varNames]
Q_bar <- Q%*%diag(((diag(Q)>0)-(diag(Q)<0)))
irf.check <- irf.restr%*%Q_bar
colnames(irf.check) <- varNames
rownames(irf.check) <- paste(rep(varNames,H.restr),".",rep(sign.horizon,each=bigK),sep="")
for(ss in 1:bigK){
STemp <- as.matrix(diag(S.cube[,,ss]))
IrfCheckTemp <- irf.check[,ss,drop = FALSE]
signCheck[ss,] <- t(sign(IrfCheckTemp))%*%STemp==sum(abs(STemp))
}
condall <- prod(signCheck)
icounter <- icounter + 1
}
shock <- P0G%*%Q_bar
# computing impulse responses
irfa <- array(0,c(n.ahead,bigK,bigK)); dimnames(irfa)[[2]] <- dimnames(irfa)[[3]] <- varNames
for (ihor in 1:n.ahead){
irfa[ihor,,] <- PHI[,,ihor]%*%shock
}
# computing structural errors
eps <- Emat%*%shock
if(icounter==MaxTries){
irfa <- eps <- NA
}
# end rotation matrix loop ----------------------------------------------------------------------------
return(list(impl=irfa,rot=Q_bar,eps=eps,icounter=icounter))
}
#' @name .irf.chol
#' @noRd
.irf.chol <- function(xdat,plag,n.ahead,Amat,Smat,Emat,type,...){
bigT <- nrow(xdat)
bigK <- ncol(xdat)
varNames <- colnames(xdat)
cons <- FALSE
if(nrow(Amat)%%plag!=0) cons <- TRUE
if(type=="long-run"){
Asum <- matrix(0,bigK,bigK)
for(pp in 1:plag){
Asum <- Asum + Amat[((pp-1)*bigK+1):(pp*bigK),]
}
A1inv <- solve(diag(bigK)-t(Asum))
C1 <- try(t(chol(A1inv%*%Smat%*%t(A1inv))),silent=TRUE)
if(is(C1,"try-error")) suppressWarnings(C1 <- t(chol(A1inv%*%Smat%*%t(A1inv),pivot=TRUE)))
shock <- solve(A1inv)%*%C1
}else if(type=="short-run"){
shock <- try(t(chol(Smat)),silent=TRUE)
if(is(shock,"try-error")) suppressWarnings(shock <- t(chol(Smat,pivot=TRUE)))
}
colnames(shock) <- rownames(shock) <- varNames
diagonal <- diag(diag(shock))
shock <- solve(diagonal)%*%shock
# create dynamic multiplier
PHIx <- array(0,c(bigK,bigK,plag+n.ahead+1)); dimnames(PHIx)[[1]] <- dimnames(PHIx)[[2]] <- varNames
PHIx[,,plag+1] <- diag(bigK)
temp <- .gen_compMat(Amat, bigK, plag)
Cm <- temp$Cm
Jm <- temp$Jm
Cmat <- diag(bigK*plag)
for (ihor in (plag+2):(plag+n.ahead+1)){
Cmat <- Cmat%*%Cm
PHIx[,,ihor] <- t(Jm)%*%Cmat%*%Jm
}
PHI <- PHIx[,,(plag+1):(plag+n.ahead+1)]
# computing impulse response function
irfa <- array(0,c(n.ahead,bigK,bigK)); dimnames(irfa)[[2]] <- dimnames(irfa)[[3]] <- varNames
for (ihor in 1:n.ahead){
irfa[ihor,,] <- PHI[,,ihor]%*%shock
}
# computing structural errors
eps <- Emat%*%shock
out <- list(impl=irfa,rot=shock,eps=eps)
return(out)
}
#' @name .irf.proxy
#' @importFrom stats lm
#' @noRd
.irf.proxy <- function(xdat,plag,n.ahead,Amat,Smat,Emat,proxy,shockinfo,...){
bigT <- nrow(xdat)
bigK <- ncol(xdat)
varNames <- colnames(xdat)
shockvars <- shockinfo$shock
instrvars <- shockinfo$instr
scale <- shockinfo$scale
# create dynamic multiplier
PHIx <- array(0,c(bigK,bigK,plag+n.ahead+1)); dimnames(PHIx)[[1]] <- dimnames(PHIx)[[2]] <- varNames
PHIx[,,plag+1] <- diag(bigK)
temp <- .gen_compMat(Amat, bigK, plag)
Cm <- temp$Cm
Jm <- temp$Jm
Cmat <- diag(bigK*plag)
for (ihor in (plag+2):(plag+n.ahead+1)){
Cmat <- Cmat%*%Cm
PHIx[,,ihor] <- t(Jm)%*%Cmat%*%Jm
}
PHI <- PHIx[,,(plag+1):(plag+n.ahead+1)]
randMat <- matrix(rnorm(bigK*bigK,0,1),bigK,bigK)
Q <- qr(randMat)
Q <- qr.Q(Q)
# identification of shocks
option <- 1
F_stats <- matrix(NA, 4, bigK, dimnames=list(c("F_test","rob-F_test","F_test_lag","rob-F_test_lag"), varNames))
# option 1
if(option == 1){
for(ss in 1:length(shockvars)){
sd <- ifelse(scale[ss]=="sd", TRUE, FALSE)
proxyVar <- proxy[,instrvars[ss],drop=FALSE]
iP <- which(varNames==shockvars[ss])
niP <- (1:bigK)[-iP]
res <- cbind(Emat[,iP],Emat[,niP])
# adjust length in case of NAs
if(any(is.na(proxyVar))){
idx <- which(is.na(proxyVar))
proxyVar <- proxyVar[-idx,,drop=FALSE]
res <- res[-idx,,drop=FALSE]
}
Xdum <- kronecker(diag(bigK), cbind(1,proxyVar))
betaIV <- solve(crossprod(Xdum))%*%crossprod(Xdum,matrix(res,ncol=1))
betaIV <- t(matrix(betaIV,nrow=nrow(betaIV)/bigK,bigK))
beta_11 <- betaIV[1,2]
beta_21 <- betaIV[-1,2,drop=FALSE]
B21B11 <- beta_21/beta_11
# fitted.err <- lm(res[,iP] ~ proxyVar)$fitted
# b21ib11 <- t(lm(res[,niP] ~ fitted.err)$coef)
SigmaU <- Smat[c(iP,niP),c(iP,niP)]
Zeta <- B21B11%*%SigmaU[1,1]%*%t(B21B11) - SigmaU[2:bigK,1]%*%t(B21B11) + B21B11%*%t(SigmaU[1,2:bigK]) + SigmaU[2:bigK,2:bigK]
B12B12 <- t(SigmaU[2:bigK,1]-B21B11%*%SigmaU[1,1])%*%solve(Zeta)%*%(SigmaU[2:bigK,1]-B21B11%*%SigmaU[1,1])
B11B11 <- SigmaU[1,1] - B12B12
if(B11B11<0)
return(list(impl=NA,rot=NA,eps=NA))
B11 <- sqrt(B11B11)
shock <- c(B11, B21B11*c(B11))
if(!sd)
shock <- shock/shock[1]
Q[c(iP,niP),iP] <- shock
# # F stat (regression on instruments of relevant innovations)
# tempX <- cbind(1, proxyVar)
# tempU <- res[,iP] - tempX%*%t(betaIV[iP,,drop=FALSE])
# tempY <- tempX%*%t(betaIV[iP,,drop=FALSE]) - matrix(mean(res[,iP]),nrow(res),1)
# k <- length(betaIV[iP,])-1
# F_stat <- (t(tempY)%*%tempY/k)%*%solve(t(tempU)%*%tempU/(nrow(tempU)-k-1))
# F-test
reg1 <- lm(res[,iP]~proxyVar)
reg0 <- lm(res[,iP]~1)
F_stats[1,iP] = anova(reg0, reg1)$F[2]
F_stats[2,iP] = waldtest(reg0, reg1, vcov=vcovHC(reg1, type="HC3"))$F[2]
# lags as controls
proxyVarlag <- cbind(proxyVar, .mlag(proxyVar, plag))
proxyVarlag <- proxyVarlag[(plag+1):nrow(proxyVarlag),,drop=FALSE]
resuse <- res[(plag+1):nrow(res),iP,drop=FALSE]
reg1 <- lm(resuse~proxyVarlag)
reg0 <- lm(resuse~1)
F_stats[3,iP] = anova(reg0, reg1)$F[2]
F_stats[4,iP] = waldtest(reg0, reg1, vcov=vcovHC(reg1, type="HC3"))$F[2]
}
}
## option 2
if(option == 2){
m <- ncol(proxy)
iP <- which(varNames%in%shockvars)
niP <- (1:bigK)[-iP]
res <- cbind(Emat[,iP],Emat[,niP])
# adjust length in case of NAs
if(any(is.na(proxy))){
idx <- which(is.na(proxy))
proxy <- proxy[-idx,,drop=FALSE]
res <- res[-idx,,drop=FALSE]
}
Xdum <- kronecker(diag(bigK), cbind(1,proxy))
betaIV <- solve(crossprod(Xdum))%*%crossprod(Xdum,matrix(res,ncol=1))
betaIV <- t(matrix(betaIV,nrow=nrow(betaIV)/bigK,bigK))
beta_11 <- betaIV[1:m,2:(m+1)]
beta_21 <- betaIV[(m+1):nrow(betaIV),2:(m+1),drop=FALSE]
B21B11 <- beta_21%*%solve(beta_11)
# fitted.err <- lm(res[,iP] ~ proxyVar)$fitted
# b21ib11 <- t(lm(res[,niP] ~ fitted.err)$coef)
SigmaU <- Smat[c(iP,niP),c(iP,niP)]
Zeta <- B21B11%*%SigmaU[1:m,1:m]%*%t(B21B11) - SigmaU[(m+1):bigK,1:m]%*%t(B21B11) + B21B11%*%t(SigmaU[(m+1):bigK,1:m]) + SigmaU[(m+1):bigK,(m+1):bigK]
B12B12 <- t(SigmaU[(m+1):bigK,1:m]-B21B11%*%SigmaU[1:m,1:m])%*%solve(Zeta)%*%(SigmaU[(m+1):bigK,1:m]-B21B11%*%SigmaU[1:m,1:m])
B11B11 <- SigmaU[1:m,1:m] - B12B12
if(m == 1){
B11 <- sqrt(B11B11)
shock <- c(B11, B21B11*c(B11))
shock <- shock/shock[1]
Q[c(iP,niP),iP] <- shock
}else{
B22B22 <- SigmaU[(m+1):bigK,(m+1):bigK] + B21B11%*%(B12B12 - SigmaU[1:m,1:m])%*%t(B21B11)
B12B22 <- (B12B12%*%t(B21B11) + t(SigmaU[(m+1):bigK,1:m] - B21B11%*%SigmaU[1:m,1:m]))%*%solve(B22B22)
B11S1 <- diag(m) - B12B22%*%B21B11
B21S1 <- B21B11%*%solve(B11S1)
S1S1 <- B11S1%*%B11B11%*%t(B11S1)
S1 <- try(t(chol(S1S1)),silent=TRUE)
if(is(S1,"try-error"))
return(list(impl=NA,rot=NA,eps=NA))
shock <- rbind(solve(B11S1), B21S1)%*%S1
Q[c(iP,niP),iP] <- shock
}
# # F stat (regression on instruments of relevant innovations)
# tempX <- cbind(1, proxy)
# tempU <- res[,1:m] - tempX%*%t(betaIV[1:m,])
# tempY <- tempX%*%t(betaIV[1:m,]) - matrix(mean(res[,1:m]),nrow(res),m); k <- length(betaIV[1:m,])-1
# F_stat <- (t(tempY)%*%tempY/k)%*%solve(t(tempU)%*%tempU/(nrow(tempU)-k-1))
}
# fitted.err <- lm(Eest[,1] ~ proxy)$fitted
# b21ib11 <- t(lm(Eest[,-1] ~ fitted.err-1)$coef)
# Sig11 <- matrix(Smat[1,1], 1, 1)
# Sig21 <- matrix(Smat[2:bigK,1],bigK-1,1)
# Sig12 <- matrix(Smat[1,2:bigK],1,bigK-1)
# Sig22 <- matrix(Smat[2:bigK,2:bigK],bigK-1,bigK-1)
# ZZp <- b21ib11%*%Sig11%*%t(b21ib11) - Sig21%*%t(b21ib11)+b21ib11%*%t(Sig21)+Sig22
# b12b12p <- t(Sig21-b21ib11%*%Sig11)%*%solve(ZZp)%*%(Sig21-b21ib11%*%Sig11)
# b11b11p <- Sig11 - b12b12p
# if(b11b11p<0){
# return(list(impl=NA,rot=NA,eps=NA))
# }
# b11 <- sqrt(b11b11p)
# shock <- c(b11, b21ib11*c(b11))
# shock <- shock/shock[1] # normalize to unit shock
#
# randMat <- matrix(rnorm(bigK*bigK,0,1),bigK,bigK)
# Q <- qr(randMat)
# Q <- qr.Q(Q)
# Q[,1] <- shock
# computing impulse response function
irfa <- array(0,c(n.ahead,bigK,bigK)); dimnames(irfa)[[2]] <- dimnames(irfa)[[3]] <- varNames
for (ihor in 1:n.ahead){
irfa[ihor,,] <- PHI[,,ihor]%*%Q
}
# computing structural errors
eps <- Emat%*%Q
return(list(impl=irfa,rot=Q,eps=eps,F_stats=F_stats))
}
#' @name .irf.girf
#' @noRd
.irf.girf <- function(xdat,plag,n.ahead,Amat,Smat,Emat,...){
bigT <- nrow(xdat)
bigK <- ncol(xdat)
varNames <- colnames(xdat)
# create dynamic multiplier
PHIx <- array(0,c(bigK,bigK,plag+n.ahead+1)); dimnames(PHIx)[[1]] <- dimnames(PHIx)[[2]] <- varNames
PHIx[,,plag+1] <- diag(bigK)
temp <- .gen_compMat(Amat, bigK, plag)
Cm <- temp$Cm
Jm <- temp$Jm
Cmat <- diag(bigK*plag)
for (ihor in (plag+2):(plag+n.ahead+1)){
Cmat <- Cmat%*%Cm
PHIx[,,ihor] <- t(Jm)%*%Cmat%*%Jm
}
PHI <- PHIx[,,(plag+1):(plag+n.ahead+1)]
# computing impulse response function
irfa <- array(0,c(n.ahead,bigK,bigK)); dimnames(irfa)[[2]] <- dimnames(irfa)[[3]] <- varNames
for (ihor in 1:n.ahead){
irfa[ihor,,] <- PHI[,,ihor]%*%Smat
}
# computing structural errors
eps <- Emat%*%Smat
return(list(impl=irfa,rot=Smat,eps=eps))
}
#' @name .impulsdtrf
#' @noRd
.impulsdtrf <- function(B,smat,nstep)
### By: As emerges from rfvar, neqn x nvar x lags array of rf VAR coefficients.
### smat: nshock x nvar matrix of initial shock vectors. To produce "orthogonalized
### impulse responses" it should have the property that crossprod(t(smat))=sigma,
### where sigma is the Var(u(t)) matrix and u(t) is the rf residual vector. One
### way to get such a smat is to set smat=t(chol(sigma)). To get the smat
### corresponding to a different ordering, use
### smat = t(chol(P %*% Sigma %*% t(P)) %*% P), where P is a permutation matrix.
### To get impulse responses for a structural VAR in the form A(L)y=eps, with
### Var(eps)=I, use B(L)=-A_0^(-1)A_+(L) (where A_+ is the coefficients on strictly
### positive powers of L in A), smat=A_0^(-1).
### In general, though, it is not required that smat be invertible.
### response: nvar x nshocks x nstep array of impulse responses.
###
### Code written by Christopher Sims,mat based on 6/03 matlab code. This version 3/27/04.
### Added dimension labeling, 8/02/04.
{
neq <- dim(B)[1]
nvar <- dim(B)[2]
lags <- dim(B)[3]
dimnB <- dimnames(B)
if(dim(smat)[2] != dim(B)[2]) stop("B and smat conflict on # of variables")
response <- array(0,dim=c(neq,nvar,nstep+lags-1));
response[ , , lags] <- smat
response <- aperm(response, c(1,3,2))
irhs <- 1:(lags*nvar)
ilhs <- lags * nvar + (1:nvar)
response <- matrix(response, ncol=neq)
B <- B[, , seq(from=lags, to=1, by=-1)] #reverse time index to allow matrix mult instead of loop
B <- matrix(B,nrow=nvar)
for (it in 1:(nstep-1)) {
response[ilhs, ] <- B %*% response[irhs, ]
irhs <- irhs + nvar
ilhs <- ilhs + nvar
}
dim(response) <- c(nvar, nstep + lags - 1, nvar)
#drop the zero initial conditions; array in usual format
if(lags>1){
response<-response[,-(1:(lags-1)),]
}
response <- aperm(response, c(1, 3, 2))
dimnames(response) <- list(dimnB[[1]], dimnames(smat)[[2]], NULL)
## dimnames(response)[2] <- dimnames(smat)[1]
## dimnames(response)[1] <- dimnames(B)[2]
return(response)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.