R/MTS.R

### An MTS package by Ruey S. Tsay
##library(mvtnorm)
###
"MTSplot" <- function(data,caltime=NULL){
   ## plot the multivariate time series
   ### caltime: calendar time
   if(!is.matrix(data))data=as.matrix(data)
   if(is.ts(data)){
      plot(data)
   }
   else{
      nT=dim(data)[1]
      tdx=c(1:nT)
      if(length(caltime) > 1)tdx=caltime
      k=dim(data)[2]
      if(k < 4){
       par(mfcol=c(k,1))
       for (j in 1:k){
        plot(tdx,data[,j],xlab='time',ylab=colnames(data)[j],type='l')
        }
       }
      if(k == 4){
         par(mfcol=c(2,2))
         for (j in 1:k){
          plot(tdx,data[,j],xlab='time',ylab=colnames(data)[j],type='l')
          }
      }
      if((k > 4) && (k < 13)){
         par(mfcol=c(3,2),mai=c(0.3,0.3,0.3,0.3))
         k1=6
        jcnt=0
        for (j in 1:k){
         plot(tdx,data[,j],xlab='time',ylab=colnames(data)[j],type='l',cex.axis=0.8)
         jcnt=jcnt+1
         if((jcnt == k1) && (k > 6)){
            jcnt=0
            cat("Hit return for more plots: ","\n")
            readline()
         }
      }
    }
    if(k > 12){
     par(mfcol=c(1,1))
     yl=range(data)*1.05
     plot(tdx,data[,1],xlab='time',ylab=' ',type='l',ylim=yl)
     for (j in 2:k){
      lines(tdx,data[,j],lty=j,col=j)
      }
    }
   #end of the program
   }
   par(mfcol=c(1,1))
}

####
"VAR" <- function(x,p=1,output=T,include.mean=T,fixed=NULL){
   # Fits a vector AR(p) model, computes AIC, and residuals
   # fixed[i,j] = 1 denotes the parameter needs estimation, = 0, means fixed to 0.
   if(!is.matrix(x))x=as.matrix(x)
   Tn=dim(x)[1]
   k=dim(x)[2]
   if(p < 1)p=1
   idm=k*p
   ne=Tn-p
   ist=p+1
   y=x[ist:Tn,]
   if(include.mean){
      idm=idm+1
      xmtx=cbind(rep(1,ne),x[p:(Tn-1),])
   }
   else {
      xmtx=x[p:(Tn-1),]
   }
   if(p > 1){
      for (i in 2:p){
         xmtx=cbind(xmtx,x[(ist-i):(Tn-i),])
      }
   }
   #
   ndim=ncol(xmtx)
   if(length(fixed)==0){
      paridx=matrix(1,ndim,k)
   }
   else {
      paridx=fixed
   }
   #perform estimation component-by-component
   res=NULL
   beta=matrix(0,ndim,k)
   sdbeta=matrix(0,ndim,k)
   npar=0
   for (i in 1:k){
      idx=c(1:ndim)[paridx[,i]==1]
      resi=y[,i]
      if(length(idx)> 0){
         xm=as.matrix(xmtx[,idx])
         npar=npar+dim(xm)[2]
         xpx=t(xm)%*%xm
         xpxinv=solve(xpx)
         xpy=t(xm)%*%as.matrix(y[,i],ne,1)
         betai=xpxinv%*%xpy
         beta[idx,i]=betai
         resi=y[,i]-xm%*%betai
         nee=dim(xm)[2]
         sse=sum(resi*resi)/(Tn-p-nee)
         dd=diag(xpxinv)
         sdbeta[idx,i]=sqrt(dd*sse)
      }
      res=cbind(res,resi)
   }
   sse=t(res)%*%res/(Tn-p)
   ###cat("npar =",npar,"\n")
   #
   aic=0
   bic=0
   hq=0
   Phi=NULL
   Ph0=NULL
   #
   jst=0
   if(include.mean) {
      Ph0=beta[1,]
      se=sdbeta[1,]
      if(output){
         cat("Constant term:","\n")
         cat("Estimates: ",Ph0,"\n")
         cat("Std.Error: ",se,"\n")
      }
      jst=1
   }
   ### adjustment npar for computing information criterion
   if(include.mean){
      for (i in 1:k){
         if(abs(Ph0[i]) > 0.00000001)npar=npar-1
      }
   }
   ####cat("adjusted npar = ",npar,"\n")
   if(output)cat("AR coefficient matrix","\n")
   ### Phi is a storage for AR coefficient matrices
   for (i in 1:p){
      phi=t(beta[(jst+1):(jst+k),])
      se=t(sdbeta[(jst+1):(jst+k),])
      if(output){
         cat("AR(",i,")-matrix","\n")
         print(phi,digits=3)
         cat("standard error","\n")
         print(se,digits=3)
      }
      jst=jst+k
      Phi=cbind(Phi,phi)
   }
   if(output){
      cat(" ","\n")
      cat("Residuals cov-mtx:","\n")
      print(sse)
      cat(" ","\n")
   }
   dd=det(sse)
   d1=log(dd)
   aic=d1+(2*npar)/Tn
   bic=d1+log(Tn)*npar/Tn
   hq=d1+2*log(log(Tn))*npar/Tn
   if(output){
      cat("det(SSE) = ",dd,"\n")
      cat("AIC = ",aic,"\n")
      cat("BIC = ",bic,"\n")
      cat("HQ  = ",hq,"\n")
      # end of if(output)
   }

   VAR<-list(data=x,cnst=include.mean,order=p,coef=beta,aic=aic,bic=bic,hq=hq,residuals=res,secoef=sdbeta,Sigma=sse,Phi=Phi,Ph0=Ph0,fixed=fixed)
}

#####
"refVAR" <- function(model,fixed=NULL,thres=1.0){
   # This program automatically refines the "model" by removing estimates
   # with abs(t-ration) < thres.
   #
   # model is an VAR output object.
   #
   x=as.matrix(model$data)
   nT=dim(x)[1]
   k=dim(x)[2]
   p=model$order
   if(p < 1)p=1
   cnst=model$cnst
   fix=fixed
   if(length(fixed)== 0){
      coef=as.matrix(model$coef)
      secoef=as.matrix(model$secoef)
      nr=dim(coef)[1]
      nc=dim(coef)[2]
      for (i in 1:nr){
         for (j in 1:nc){
            if(secoef[i,j] < 10^(-8))secoef[i,j]=1
         }
      }
      fix=matrix(1,nr,k)
      # use Backward elimination to simplify the model: equation by equation
      ### First: setup the regressor matrix
      xmtx=NULL
      ist=p+1
      y=x[ist:nT,]
      ne=nT-p
      if(cnst)xmtx=matrix(1,ne,1)
      for (j in 1:p){
         xmtx=cbind(xmtx,x[(ist-j):(nT-j),])
      }
      xmtx=as.matrix(xmtx)
      ### perform first elimination based on the previous estimation
      for(j in 1:k){
         tt=abs(coef[,j]/secoef[,j])
         idx=c(1:nr)[tt == min(tt)]
         idx1=idx[1]
         if(tt[idx1] < thres)fix[idx,j]=0
      }
      ### Perform further elimination
      for (j in 1:k){
         npar=sum(fix[,j])
         while(npar > 0){
            jdx=c(1:nr)[fix[,j]==1]
            xp=as.matrix(xmtx[,jdx])
            nxp=dim(xp)[2]
            m1=lm(y[,j]~-1+xp)
            m2=summary(m1)
            est=m1$coefficients
            se1=sqrt(diag(m2$cov.unscaled))*m2$sigma
            tt=abs(est/se1)
            idx=c(1:nxp)[tt == min(tt)]
            idx1=idx[1]
            if(tt[idx1] < thres){
               fix[jdx[idx],j]=0
               npar=sum(fix[,j])
            }
            else {
               npar=0
            }
            ### end of while-statement
         }
         ## end of the j-loop
      }
      ## end of the if(length(fixed)==0) statement
   }

   mm=VAR(x,p,output=T,include.mean=cnst,fixed=fix)

   refVAR <- list(data=mm$data,order=p,cnst=cnst,coef=mm$coef,aic=mm$aic,bic=mm$bic,hq=mm$hq,residuals=mm$residuals,secoef=mm$secoef,Sigma=mm$Sigma,Phi=mm$Phi,Ph0=mm$Ph0,fixed=fix)
}

######
"VARs" <- function(x,lags,include.mean=T,output=T,fixed=NULL){
   # Fits a vector AR model with selected lags, computes its AIC, BIC, and residuals
   # Created on March 30, 2009 by Ruey S. Tsay
   #
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(x)[1]; k=dim(x)[2]
   nlags=length(lags)
   #
   if(nlags < 0){
      lags=c(1)
      nlags=1
   }
   #
   lags=sort(lags)
   idm=k*nlags+1
   p=lags[nlags]
   if(p < 1)p=1
   ne=nT-p
   ist=p+1
   y=x[ist:nT,]
   jj=lags[1]
   if(include.mean){
      xmtx=cbind(rep(1,ne),x[(ist-jj):(nT-jj),])
   }
   else {
      xmtx=x[(ist-jj):(nT-jj),]
   }
   if(nlags > 1){
      for (i in 2:nlags){
         jj=lags[i]
         xmtx=cbind(xmtx,x[(ist-jj):(nT-jj),])
      }
   }
   xmtx=as.matrix(xmtx)
   ndim=dim(xmtx)[2]
   #
   if(length(fixed)==0){
      paridx=matrix(1,ndim,k)
   }
   else {
      paridx=fixed
   }
   #perform estimation component-by-component
   res=NULL
   beta=matrix(0,ndim,k)
   sdbeta=matrix(0,ndim,k)
   for (i in 1:k){
      idx=c(1:ndim)[paridx[,i]==1]
      resi=y[,i]
      if(length(idx) > 0){
         xm=as.matrix(xmtx[,idx])
         xpx = t(xm)%*%xm
         xpxinv=solve(xpx)
         xpy=t(xm)%*%as.matrix(y[,i],ne,1)
         betai=xpxinv%*%xpy
         beta[idx,i]=betai
         resi=y[,i]-xm%*%betai
         sse=sum(resi*resi)/nT
         dd=diag(xpxinv)
         sdbeta[idx,i]=sqrt(sse*dd)
      }
      res=cbind(res,resi)
   }
   sse=t(res)%*%res/nT
   Phi=NULL
   Ph0=rep(0,k)
   if(output){
      jst=0
      if(include.mean){
         Ph0=beta[1,]
         se=sdbeta[1,]
         cat("Constant term:","\n")
         print(Ph0,digits=4)
         cat("Std error:","\n")
         print(se,digits=4)
         jst=1
      }
      cat("AR coefficient matrix:","\n")
      ### Phi is a storage for the AR coefficient matrices
      Phi=matrix(0,k,p*k)
      for (i in 1:nlags){
         ord=lags[i]
         cat("AR(",ord,")-matrix:","\n")
         phi=t(beta[(jst+1):(jst+k),])
         se=t(sdbeta[(jst+1):(jst+k),])
         print(phi,digits=3)
         cat("Standard error:","\n")
         print(se,digits=3)
         jst=jst+k
         cat("      ","\n")
         kdx=(ord-1)*k
         Phi[,(kdx+1):(kdx+k)]=phi
      }
      cat("Residuals cov-mtx:","\n")
      print(sse)

      cat("       ","\n")
      dd=det(sse)
      cat("det(SSE) = ",dd,"\n")
      d1=log(dd)
      aic=d1+(2*nlags*k*k)/nT
      bic=d1+log(nT)*nlags*k*k/nT
      cat("AIC = ",aic,"\n")
      cat("BIC = ",bic,"\n")
      # end of if(output)
   }

   VARs<-list(data=x,lags=lags,order=p,cnst=include.mean,coef=beta,aic=aic,bic=bic,residuals=res,secoef=sdbeta,Sigma=sse,Phi=Phi,Ph0=Ph0,fixed=fixed)

}

#####
"refVARs" <- function(model,fixed=NULL,thres=1.0){
   #This program either (1) automatically refines a fitted VARs model by setting
   # parameters with abs(t-ratio) < thres to zero, or uses manually specified "fixed" to
   # simplied the VARs model.
   #
   # model: an VARs output object.
   #
   x=as.matrix(model$data)
   nT=dim(x)[1]; k=dim(x)[2]; p=model$order
   lags=sort(model$lags)
   nlags = length(lags)
   cnst=model$cnst
   fix=fixed
   if(length(fixed)==0){
      p=lags[nlags]
      coef=as.matrix(model$coef)
      secoef=as.matrix(model$secoef)
      nr=dim(coef)[1]
      fix=matrix(1,nr,k)
      nc=dim(coef)[2]
      for (i in 1:nr){
         for (j in 1:nc){
            if(secoef[i,j] < 10^(-8))secoef[i,j]=1.0
         }
      }
      # use Backward elimination to simplify the model: equation by equation
      ### First: setup the regressor matrix
      xmtx=NULL
      ist=p+1
      y=x[ist:nT,]
      ne=nT-p
      if(cnst)xmtx=cbind(xmtx,rep(1,ne))
      for (j in 1:nlags){
         xmtx=cbind(xmtx,x[(ist-lags[j]):(nT-lags[j]),])
      }
      xmtx=as.matrix(xmtx)
      ### perform first elimination based on the previous estimation
      for(j in 1:k){
         tt=abs(coef[,j]/secoef[,j])
         idx=c(1:nr)[tt == min(tt)]
         if(tt[idx] < thres)fix[idx,j]=0
      }
      ### Perform further elimination
      for (j in 1:k){
         npar=sum(fix[,j])
         while(npar > 0){
            jdx=c(1:nr)[fix[,j]==1]
            xp=as.matrix(xmtx[,jdx])
            nxp=dim(xp)[2]
            m1=lm(y[,j]~-1+xp)
            m2=summary(m1)
            est=m1$coefficients
            se1=sqrt(diag(m2$cov.unscaled))*m2$sigma
            tt=abs(est/se1)
            idx=c(1:nxp)[tt == min(tt)]
            if(tt[idx] < thres){
               fix[jdx[idx],j]=0
               npar=sum(fix[,j])
            }
            else {
               npar=0
            }
            ### end of while-statement
         }
         ## end of the j-loop
      }
      ## end of the if(length(fixed)==0) statement
   }

   mm=VARs(x,lags,include.mean=cnst,output=T,fixed=fix)

   refVARs <- list(data=x,lags=lags,cnst=cnst,coef=mm$coef,aic=mm$aic,bic=mm$bic,residuals=mm$residuals,secoef=mm$secoef,Sigma=mm$Sigma,Phi=mm$Phi,Ph0=mm$Ph0,fixed=fix)
}


#####
"ccm" <- function(x,lags=12,level=FALSE,output=T){
   # Compute and plot the cross-correlation matrices.
   # lags: number of lags used.
   # level: logical unit for printing.
   #
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(x)[1]; k=dim(x)[2]
   if(lags < 1)lags=1
   # remove the sample means
   y=scale(x,center=TRUE,scale=FALSE)
   V1=cov(y)
   if(output){
      print("Covariance matrix:")
      print(V1,digits=3)
   }
   se=sqrt(diag(V1))
   SD=diag(1/se)
   S0=SD%*%V1%*%SD
   ## S0 used later
   ksq=k*k
   wk=matrix(0,ksq,(lags+1))
   wk[,1]=c(S0)
   j=0
   if(output){
      cat("CCM at lag: ",j,"\n")
      print(S0,digits=3)
      cat("Simplified matrix:","\n")
   }
   y=y%*%SD
   crit=2.0/sqrt(nT)
   for (j in 1:lags){
      y1=y[1:(nT-j),]
      y2=y[(j+1):nT,]
      Sj=t(y2)%*%y1/nT
      Smtx=matrix(".",k,k)
      for (ii in 1:k){
         for (jj in 1:k){
            if(Sj[ii,jj] > crit)Smtx[ii,jj]="+"
            if(Sj[ii,jj] < -crit)Smtx[ii,jj]="-"
         }
      }
      #
      if(output){
         cat("CCM at lag: ",j,"\n")
         for (ii in 1:k){
            cat(Smtx[ii,],"\n")
         }
         if(level){
            cat("Correlations:","\n")
            print(Sj,digits=3)
         }
         ## end of if-(output) statement
      }
      wk[,(j+1)]=c(Sj)
   }
   ##
   if(output){
      par(mfcol=c(k,k))
      #### Set k0 = 4 for plotting purpose
      k0=4
      if(k > k0)par(mfcol=c(k0,k0))
      tdx=c(0,1:lags)
      jcnt=0
      if(k > 10){
         print("Skip the plots due to high dimension!")
      }
      else{
         for (j in 1:ksq){
            plot(tdx,wk[j,],type='h',xlab='lag',ylab='ccf',ylim=c(-1,1))
            abline(h=c(0))
            crit=2/sqrt(nT)
            abline(h=c(crit),lty=2)
            abline(h=c(-crit),lty=2)
            jcnt=jcnt+1
            if((jcnt==k0^2) && (k > k0)){
               jcnt=0
               cat("Hit Enter for more plots:","\n")
               readline()
            }
         }
       }
      par(mfcol=c(1,1))
      cat("Hit Enter for p-value plot of individual ccm: ","\n")
      readline()
      ## end of if-(output) statement
   }
   ## The following p-value plot was added on May 16, 2012 by Ruey Tsay.
   ### Obtain a p-value plot of ccm matrix
   r0i=solve(S0)
   R0=kronecker(r0i,r0i)
   pv=rep(0,lags)
   for (i in 1:lags){
      tmp=matrix(wk[,(i+1)],ksq,1)
      tmp1=R0%*%tmp
      ci=crossprod(tmp,tmp1)*nT*nT/(nT-i)
      pv[i]=1-pchisq(ci,ksq)
    }
   if(output){
      plot(pv,xlab='lag',ylab='p-value',ylim=c(0,1))
      abline(h=c(0))
      abline(h=c(0.05),col="blue")
      title(main="Significance plot of CCM")
    }
   ccm <- list(ccm=wk,pvalue=pv)
}


"VARorder" <- function(x,maxp=13,output=T){
   # Compute the AIC, BIC, HQ values and M-stat
   ##### Use the same number of data points in model comparison
   x1=as.matrix(x)
   nT=nrow(x1)
   k=ncol(x1)
   ksq=k*k
   if(maxp < 1)maxp=1
   enob=nT-maxp
   y=x1[(maxp+1):nT, , drop=FALSE]
   ist=maxp+1
   xmtx=cbind(rep(1,enob),x1[maxp:(nT-1),])
   if(maxp > 1){
      for (i in 2:maxp){
         xmtx=cbind(xmtx,x1[(ist-i):(nT-i),])
      }
   }
   #### in the above, y is the dependent variable, xmtx is the x-matrix
   chidet=rep(0,(maxp+1))
   s=cov(y)*(enob-1)/enob
   chidet[1]=log(det(s))
   aic=rep(0,(maxp+1))
   aic[1]=chidet[1]
   bic=aic
   hq=aic
   y=as.matrix(y)
   #
   for (p in 1:maxp){
      idm=k*p+1
      xm=xmtx[,1:idm]
      xm=as.matrix(xm)
      xpx <- crossprod(xm,xm)
      xpy <- crossprod(xm,y)
      beta <- solve(xpx,xpy)
      yhat <- xm%*%beta
      resi <- y-yhat
      sse <- crossprod(resi,resi)/enob
      #print(paste("For p = ",p,"residual variance is", sse))
      d1=log(det(sse))
      aic[p+1]=d1+(2*p*ksq)/nT
      bic[p+1]=d1+(log(nT)*p*ksq)/nT
      hq[p+1]=d1+(2*log(log(nT))*p*ksq)/nT
      chidet[p+1]=d1
   }
   maic=min(aic)
   aicor=c(1:(maxp+1))[aic==maic]-1
   mbic=min(bic)
   bicor=c(1:(maxp+1))[bic==mbic]-1
   mhq=min(hq)
   hqor=c(1:(maxp+1))[hq==mhq]-1

   Mstat=rep(0,maxp)
   pv=rep(0,maxp)
   for (j in 1:maxp){
      Mstat[j]=(nT-maxp-k*j-1.5)*(chidet[j]-chidet[j+1])
      pv[j]=1-pchisq(Mstat[j],ksq)
   }
   if(output){
      cat("selected order: aic = ",aicor,"\n")
      cat("selected order: bic = ",bicor,"\n")
      cat("selected order: hq = ",hqor,"\n")
      #cat("M statistic and its p-value","\n") ## comment out as
      #tmp=cbind(Mstat,pv)                     ## results shown in summary
      ##print(tmp,digits=4)
      #print(round(tmp,4))
   }
   if(output){
      n1=length(aic)-1
      ### print summary table
      cri=cbind(c(0:n1),aic,bic,hq,c(0,Mstat),c(0,pv))
      colnames(cri) <- c("p","AIC","BIC","HQ","M(p)","p-value")
      cat("Summary table: ","\n")
      ##print(cri,digits=5)
      print(round(cri,4))
   }

   VARorder <- list(aic=aic,aicor=aicor,bic=bic,bicor=bicor,hq=hq,hqor=hqor,Mstat=Mstat,Mpv=pv)
}
################

"VARorderI" <- function(x,maxp=13,output=T){
   # Compute the AIC, BIC, HQ values and M-stat
   ##### This is a modified version of the old program in "VARorder",
   ##### which uses the same number of data points.
   #####  This version was adopted on September 8, 2012 in Singapore.
   #####
   x1=as.matrix(x)
   nT=nrow(x1)
   k=ncol(x1)
   ksq=k*k
   if(maxp < 1)maxp=1
   ### initialization
   chidet=rep(0,(maxp+1))
   ### start with VAR(0) model, which uses just the sample means.
   s=cov(x1)*(nT-1)/nT
   chidet[1]=log(det(s))
   aic=chidet; bic=aic; hq=aic
   #
   for (p in 1:maxp){
      idm=k*p+1
      ist=p+1
      enob=nT-p
      y=as.matrix(x1[ist:nT, , drop=FALSE])
      xmtx=rep(1,enob)
      for (j in 1:p){
         xmtx=cbind(xmtx,x1[(ist-j):(nT-j),])
      }
      xm=as.matrix(xmtx)
      xpx <- crossprod(xm,xm)
      xpy <- crossprod(xm,y)
      beta <- solve(xpx,xpy)
      yhat <- xm%*%beta
      resi <- y-yhat
      sse <- crossprod(resi,resi)/enob
      #print(paste("For p = ",p,"residual variance is", sse))
      d1=log(det(sse))
      aic[p+1]=d1+(2*p*ksq)/enob
      bic[p+1]=d1+(log(enob)*p*ksq)/enob
      hq[p+1]=d1+(2*log(log(enob))*p*ksq)/enob
      chidet[p+1]=d1
   }
   maic=min(aic)
   aicor=c(1:(maxp+1))[aic==maic]-1
   mbic=min(bic)
   bicor=c(1:(maxp+1))[bic==mbic]-1
   mhq=min(hq)
   hqor=c(1:(maxp+1))[hq==mhq]-1

   Mstat=rep(0,maxp)
   pv=rep(0,maxp)
   for (j in 1:maxp){
      Mstat[j]=(nT-maxp-k*j-1.5)*(chidet[j]-chidet[j+1])
      pv[j]=1-pchisq(Mstat[j],ksq)
   }

   if(output){
      cat("selected order: aic = ",aicor,"\n")
      cat("selected order: bic = ",bicor,"\n")
      cat("selected order: hq = ",hqor,"\n")
      cat("M statistic and its p-value","\n")
      tmp=cbind(Mstat,pv)
      print(tmp,digits=4)
      ##
      n1=length(aic)-1
      ### print summary table
      cri=cbind(c(0:n1),aic,bic,hq,c(0,Mstat),c(0,pv))
      colnames(cri) <- c("p","AIC","BIC","HQ","M(p)","p-value")
      cat("Summary table: ","\n")
      print(cri,digits=5)
   }

   VARorderI <- list(aic=aic,aicor=aicor,bic=bic,bicor=bicor,hq=hq,hqor=hqor,Mstat=Mstat,Mpv=pv)
}
##############################


"VARpsi" <- function(Phi,lag=5){
   # Computes the psi-weight matrices of a VAR(p) model.
   # Phi=[phi1,phi2,phi3, ....] coefficient matrix
   # Created by Ruey S. Tsay, April 2009 & modified on April 2011.
   #
   # Compute MA representions
   k=nrow(Phi)
   m=ncol(Phi)
   p=floor(m/k)
   Si=diag(rep(1,k))
   if(p < 1) p =1
   if(lag < 1) lag=1
   #
   for (i in 1:lag){
      if (i <= p){
         idx=(i-1)*k
         tmp=Phi[,(idx+1):(idx+k)]
      }
      else{
         tmp=matrix(0,k,k)
      }
      #
      jj=i-1
      jp=min(jj,p)
      if(jp > 0){
         for(j in 1:jp){
            jdx=(j-1)*k
            idx=(i-j)*k
            w1=Phi[,(jdx+1):(jdx+k)]
            w2=Si[,(idx+1):(idx+k)]
            tmp=tmp+w1%*%w2
            ##print(tmp,digits=4)
         }
      }
      Si=cbind(Si,tmp)
   }

   VARpsi <- list(psi=Si)
}

"VARpred" <- function(model,h=1,orig=0,Out.level=FALSE,output=TRUE){
   # Computes the i=1, 2, ..., h-step ahead predictions of a VAR(p) model.
   # Phi=[phi1,phi2,phi3, ....] coefficient matrix
   # cnst= constant term
   # Created by Ruey S. Tsay in April 2011.
   #
   # Modified on April 20, 2011
   # It needs the program VARpsi.R to obtain the psi-weights
   # First compute the psi-weights of the VAR(p) model.
   #
   # Modifed on March 29, 2012 to include MSE of using
   #  estimated parameters.
   #
   # model is a VAR output object.
   # Out.level : control the details of output.
   # output: Control printing forecast results
   x=model$data
   Phi=model$Phi
   sig=model$Sigma
   Ph0=model$Ph0
   p=model$order
   cnst=model$cnst
   np=dim(Phi)[2]
   k=dim(x)[2]
   #
   nT=dim(x)[1]
   k=dim(x)[2]
   if(orig <= 0)orig=nT
   if(orig > nT)orig=nT
   psi=VARpsi(Phi,h)$psi
   beta=t(Phi)
   if(length(Ph0) < 1)Ph0=rep(0,k)
   if(p > orig){
      cat("Too few data points to produce forecasts","\n")
   }
   pred=NULL
   se=NULL
   MSE=NULL
   mse=NULL
   px=as.matrix(x[1:orig,])
   Past=px[orig,]
   if(p > 1){
      for (j in 1:(p-1)){
         Past=c(Past,px[(orig-j),])
      }
   }
   #
   # Setup to compute MSE (due to estimated parameters.
   # Compute G-matrix and construct P-matrix
   cat("orig ",orig,"\n")
   ne=orig-p
   xmtx=NULL
   P=NULL
   if(cnst)xmtx=rep(1,ne)
   xmtx=cbind(xmtx,x[p:(orig-1),])
   ist=p+1
   if(p > 1){
      for (j in 2:p){
         xmtx=cbind(xmtx,x[(ist-j):(orig-j),])
      }
   }
   xmtx=as.matrix(xmtx)
   G=t(xmtx)%*%xmtx/ne
   Ginv=solve(G)
   ##cat("G-matrix: ","\n")
   ##print(G)
   ##cat("Ginv","\n")
   ##print(Ginv)
   #
   P = Phi
   vv=Ph0
   if(p > 1){
      II=diag(rep(1,k*(p-1)))
      II=cbind(II,matrix(0,(p-1)*k,k))
      P=rbind(P,II)
      vv=c(vv,rep(0,(p-1)*k))
   }
   if(cnst){
      c1=c(1,rep(0,np))
      P=cbind(vv,P)
      P=rbind(c1,P)
   }
   ##
   ##cat("P-matrix","\n")
   ##print(P)
   #
   Sig=sig
   n1=dim(P)[2]
   MSE= (n1/orig)*sig
   for (j in 1:h){
      tmp=Ph0+matrix(Past,1,np)%*%beta
      px=rbind(px,tmp)
      if(np > k){
         Past=c(tmp,Past[1:(np-k)])
      }else{
         Past=tmp
      }
      #
      #### Compute variance of forecast errors for j > 1.
      if(j > 1){
         idx=(j-1)*k
         wk=psi[,(idx+1):(idx+k)]
         Sig=Sig+wk%*%sig%*%t(wk)
      }
      ##### Compute MSE of forecast errors for j > 1.
      if(j > 1){
         for (ii in 0:(j-1)){
            psii=diag(rep(1,k))
            if(ii > 0){
               idx=ii*k
               psii=psi[,(idx+1):(idx+k)]
            }
            P1=P^(j-1-ii)%*%Ginv
            for (jj in 0:(j-1)){
               psij=diag(rep(1,k))
               if(jj > 0){
                  jdx=jj*k
                  psij=psi[,(jdx+1):(jdx+k)]
               }
               P2=P^(j-1-jj)%*%G
               k1=sum(diag(P1%*%P2))
               MSE=(k1/orig)*psii%*%sig%*%t(psij)
            }
         }
         #
      }
      #
      se=rbind(se,sqrt(diag(Sig)))
      if(Out.level){
         cat("Covariance matrix of forecast errors at horizon: ",j,"\n")
         print(Sig)
         cat("Omega matrix at horizon: ",j,"\n")
         print(MSE)
      }
      #
      MSE=MSE+Sig
      mse=rbind(mse,sqrt(diag(MSE)))
   }
  if(output){
   cat("Forecasts at origin: ",orig,"\n")
   print(px[(orig+1):(orig+h),],digits=4)
   cat("Standard Errors of predictions: ","\n")
   print(se[1:h,],digits=4)
   pred=px[(orig+1):(orig+h),]
   cat("Root mean square errors of predictions: ","\n")
   print(mse[1:h,],digits=4)
   }
   if(orig < nT){
      cat("Observations, predicted values,     errors, and MSE","\n")
      tmp=NULL
      jend=min(nT,(orig+h))
      for (t in (orig+1):jend){
         case=c(t,x[t,],px[t,],x[t,]-px[t,])
         tmp=rbind(tmp,case)
      }
      colnames(tmp) <- c("time",rep("obs",k),rep("fcst",k),rep("err",k))
      idx=c(1)
      for (j in 1:k){
         idx=c(idx,c(0,1,2)*k+j+1)
      }
      tmp = tmp[,idx]
      #print(tmp,digits=3)
      print(round(tmp,4))
   }

   VARpred <- list(pred=pred,se.err=se,rmse=mse)
}

"VARfore" <- function(model,h=1,orig=0){
   # Computes the i=1, 2, ..., h-step ahead predictions of a VAR(p) model.
   # Phi=[phi1,phi2,phi3, ....] coefficient matrix
   # cnst= constant term
   # model is a VAR output object.
   #
   x=model$data
   Phi=model$Phi
   sig=model$Sigma
   Ph0=model$Ph0
   p=model$order
   np=dim(Phi)[2]
   #
   nT=dim(x)[1]
   k=dim(x)[2]
   if(orig <= 0)orig=nT
   if(orig > nT)orig=nT
   psi=VARpsi(Phi,h)$psi
   beta=t(Phi)
   if(length(Ph0) < 1)Ph0=rep(0,k)
   if(p > orig){
      cat("Too few data points to produce forecasts","\n")
   }
   pred=NULL
   se=NULL
   px=as.matrix(x[1:orig,])
   Past=px[orig,]
   if(p > 1){
      for (j in 1:(p-1)){
         Past=c(Past,px[(orig-j),])
      }
   }
   #
   for (j in 1:h){
      tmp=Ph0+matrix(Past,1,np)%*%beta
      px=rbind(px,tmp)
      if(np > k){
         Past=c(tmp,Past[1:(np-k)])
      }else{
         Past=tmp
      }
      Sig=sig
      if (j > 1){
         for (ii in 1:(j-1)){
            idx=ii*k
            wk=psi[,(idx+1):(idx+k)]
            Sig=Sig+wk%*%sig%*%t(wk)
         }
      }
      se=rbind(se,sqrt(diag(Sig)))
   }
   cat("Forecasts at origin: ",orig,"\n")
   print(px[(orig+1):(orig+h),],digits=4)
   cat("Standard Errors of predictions: ","\n")
   print(se[1:h,],digits=4)
   pred=px[(orig+1):(orig+h),]
   if(orig < nT){
      cat("Observations, predicted values, and errors","\n")
      tmp=NULL
      jend=min(nT,(orig+h))
      for (t in (orig+1):jend){
         case=c(t,x[t,],px[t,],x[t,]-px[t,])
         tmp=rbind(tmp,case)
      }
      colnames(tmp) <- c("time",rep("obs",k),rep("fcst",k),rep("err",k))
      idx=c(1)
      for (j in 1:k){
         idx=c(idx,c(0,1,2)*k+j+1)
      }
      tmp = tmp[,idx]
      ##print(tmp,digits=3)
      print(round(tmp,4))
   }
   VARfore <- list(pred=pred,se.err=se)
 }

"VARMAsim" <- function(nobs,arlags=NULL,malags=NULL,cnst=NULL,phi=NULL,theta=NULL,skip=200,sigma){
   # Generate VARMA(p,q) time series using Gaussian innovations.
   # p: ar order (lags can be skipped)
   # q: ma order (lags can be skipped)
   # nobs: sample size
   # cnst: constant vector
   # phi: store AR coefficient matrices [phi1,phi2,...]
   # theta: store MA coefficient matrices [theta1,theta2,...]
   # arlags: order for each AR coefficient matrix
   # malags: order for each MA coefficient matrix.
   #
   if(!is.matrix(sigma))sigma=as.matrix(sigma)
   k=nrow(sigma)
   nT=nobs+skip
   at=rmvnorm(nT,rep(0,k),sigma)
   nar=length(arlags)
   p=0
   if(nar > 0){
      arlags=sort(arlags)
      p=arlags[nar]
   }
   q=0
   nma=length(malags)
   if(nma > 0){
      malags=sort(malags)
      q=malags[nma]
   }
   ist=max(p,q)+1
   zt=matrix(0,nT,k)
   if(length(cnst)==0)cnst=rep(0,k)

   for (it in ist:nT){
      tmp=matrix(at[it,],1,k)
      if(nma > 0){
         for (j in 1:nma){
            jdx=(j-1)*k
            thej=theta[,(jdx+1):(jdx+k)]
            atm=matrix(at[it-malags[j],],1,k)
            tmp=tmp-atm%*%t(thej)
         }
      }
      if(nar > 0){
         for (i in 1:nar){
            idx=(i-1)*k
            phj = phi[,(idx+1):(idx+k)]
            ztm=matrix(zt[it-arlags[i],],1,k)
            tmp=tmp+ztm%*%t(phj)
         }
      }
      zt[it,]=cnst+tmp
   }
   # skip the first "skip" points
   zt=zt[(1+skip):nT,]
   at=at[(1+skip):nT,]

   VARMAsim <- list(series=zt,noises=at)
}

"VARirf" <- function(Phi,Sig,lag=12,orth=TRUE){
   # Computes impulse response function of a given VAR(p) model.
   # Phi: k by kp matrix of AR ceofficients, i.e. [AR1,AR2,AR3, ..., ARp]
   # Sig: residual covariance matrix
   # Output: (a) Plot and (b) Impulse response function [Psi1,Psi2, ....]
   if(!is.matrix(Phi))Phi=as.matrix(Phi)
   if(!is.matrix(Sig))Sig=as.matrix(Sig)
   # Compute MA representions: This gives impulse response function without considering Sigma.
   k=nrow(Phi)
   m=ncol(Phi)
   p=floor(m/k)
   Si=diag(rep(1,k))
   wk=c(Si)
   ## acuwk: accumulated response
   awk=c(wk)
   acuwk=c(awk)
   if(p < 1) p =1
   if(lag < 1) lag=1
   #
   for (i in 1:lag){
      if (i <= p){
         idx=(i-1)*k
         tmp=Phi[,(idx+1):(idx+k)]
      }
      else{
         tmp=matrix(0,k,k)
      }
      #
      jj=i-1
      jp=min(jj,p)
      if(jp > 0){
         for(j in 1:jp){
            jdx=(j-1)*k
            idx=(i-j)*k
            w1=Phi[,(jdx+1):(jdx+k)]
            w2=Si[,(idx+1):(idx+k)]
            tmp=tmp+w1%*%w2
            ##print(tmp,digits=4)
         }
      }
      Si=cbind(Si,tmp)
      wk=cbind(wk,c(tmp))
      awk=awk+c(tmp)
      acuwk=cbind(acuwk,awk)
      ##print(Si,digits=3)
   }
   # Compute the impulse response of orthogonal innovations
   orSi=NULL
   wk1=NULL
   awk1=NULL
   acuwk1=NULL
   if(orth){
      m1=chol(Sig)
      P=t(m1)
      wk1=cbind(wk1,c(P))
      awk1=wk1
      acuwk1=wk1
      orSi=cbind(orSi,P)
      for(i in 1:lag){
         idx=i*k
         w1=Si[,(idx+1):(idx+k)]
         w2=w1%*%P
         orSi=cbind(orSi,w2)
         wk1=cbind(wk1,c(w2))
         awk1=awk1+c(w2)
         acuwk1=cbind(acuwk1,awk1)
      }
   }

   tdx=c(1:(lag+1))-1
   par(mfcol=c(k,k),mai=c(0.3,0.3,0.3,0.3))
   if(orth){
      gmax=max(wk1)
      gmin=min(wk1)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for (j in 1:k^2){
         plot(tdx,wk1[j,],type='l',xlab='lag',ylab='IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,wk1[j,],pch='*',cex=0.8)
         title(main='Orth. innovations')
      }
      cat("Press return to continue ","\n")
      readline()
      gmax=max(acuwk1)
      gmin=min(acuwk1)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for (j in 1:k^2){
         plot(tdx,acuwk1[j,],type='l',xlab='lag',ylab="Acu-IRF",ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,acuwk1[j,],pch="*",cex=0.8)
         title(main='Orth. innovations')
      }
   }
   else{
      gmax=max(wk)
      gmin=min(wk)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k^2){
         plot(tdx,wk[j,],type='l',xlab='lag',ylab='IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,wk[j,],pch='*',cex=0.8)
         title(main="Orig. innovations")
      }
      cat("Press return to continue ","\n")
      readline()
      gmax=max(acuwk)
      gmin=min(acuwk)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k^2){
         plot(tdx,acuwk[j,],type='l',xlab='lag',ylab='Acu-IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,acuwk[j,],pch='*',cex=0.8)
         title(main="Orig. innovations")
      }
   }

   VARirf <- list(irf=Si,orthirf=orSi)
}

"mq" <- function(x,lag=24,adj=0){
   # Compute multivariate Ljung-Box test statistics
   #
   # adj: adjustment for the degrees of freedomm in the chi-square distribution.
   # adj is the number of coefficient parameters used in the fitted model, if any.
   #
   if(!is.matrix(x))x=as.matrix(x)
   nr=nrow(x)
   nc=ncol(x)
   g0=var(x)
   ginv=solve(g0)
   qm=0.0
   QM=NULL
   df = 0
   for (i in 1:lag){
      x1=x[(i+1):nr,]
      x2=x[1:(nr-i),]
      g = cov(x1,x2)
      g = g*(nr-i-1)/(nr-1)
      h=t(g)%*%ginv%*%g%*%ginv
      qm=qm+nr*nr*sum(diag(h))/(nr-i)
      df=df+nc*nc
      dff= df-adj
      mindeg=nc^2-1
      pv = 1
      if(dff > mindeg)pv=1-pchisq(qm,dff)
      QM=rbind(QM,c(i,qm,dff,pv))
   }
   pvs=QM[,4]
   dimnames(QM) = list(names(pvs),c("  m  ","    Q(m) ","   df  "," p-value"))
   cat("Ljung-Box Statistics: ","\n")
   printCoefmat(QM,digits = 3)
   #
   par(mfcol=c(1,1))
   plot(pvs,ylim=c(0,1),xlab="m",ylab="prob",main="p-values of Ljung-Box statistics")
   abline(h=c(0))
   lines(rep(0.05,lag),lty=2,col='blue')
}

###
"VMAorder" <- function(x,lag=20){
   # Compute multivariate Ljung-Box test statistics
   # to identify the VMA order.
   #
   if(!is.matrix(x))x=as.matrix(x)
   nr=dim(x)[1]
   nc=dim(x)[2]
   g0=var(x)
   ginv=solve(g0)
   qm=NULL
   for (i in 1:lag){
      x1=x[(i+1):nr,]
      x2=x[1:(nr-i),]
      g = cov(x1,x2)
      g = g*(nr-i-1)/(nr-1)
      h=t(g)%*%ginv%*%g%*%ginv
      qmi=nr*nr*sum(diag(h))/(nr-i)
      qm=c(qmi,qm)
   }
   tst=rev(cumsum(qm))
   ksq=nc*nc; df=ksq*lag
   QM=NULL
   for (i in 1:lag){
      pv=1-pchisq(tst[i],df)
      QM=rbind(QM,c(i,tst[i],pv))
      df=df-ksq
   }
   pvs=QM[,3]
   dimnames(QM) = list(names(pvs),c("  j  ","  Q(j,m) "," p-value"))
   cat("Q(j,m) Statistics: ","\n")
   printCoefmat(QM,digits = 3)
   ## Plot
   par(mfcol=c(1,1))
   plot(pvs,ylim=c(0,1),xlab='j',ylab='prob',main="p-values: Q(j,m) Statistics")
   abline(h=c(0))
   lines(rep(0.05,lag),lty=2,col='blue')
   #
}


#### VMA programs
"VMA" <- function(da,q=1,include.mean=T,fixed=NULL,beta=NULL,sebeta=NULL,prelim=F,details=F,thres=2.0){
   # Estimation of a vector MA model using conditional MLE (Gaussian dist)
   #
   # April 18: add subcommand "prelim" to see simplification after the AR approximation.
   # When prelim=TRUE, fixed is assigned based on the results of AR approximation.
   # Here "thres" is used only when prelim = TRUE.
   ##
   ### Create the "mFilter" program to simplify computation of residuals. April 8, 2012.
   #
   if(!is.matrix(da))da=as.matrix(da)
   nT=dim(da)[1]
   k=dim(da)[2]
   if(q < 1)q=1
   kq=k*q
#
 THini <- function(y,x,q,include.mean){
   # use residuals of a long VAR model to obtain initial estimates of
   # VMA coefficients.
   if(!is.matrix(y))y=as.matrix(y)
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(y)[1]
   k=dim(y)[2]
   ist=1+q
   ne=nT-q
   if(include.mean){
      xmtx=matrix(1,ne,1)
   }
   else {
      xmtx=NULL
   }
   ymtx=y[ist:nT,]
   for (j in 1:q){
      xmtx=cbind(xmtx,x[(ist-j):(nT-j),])
   }
   xtx=crossprod(xmtx,xmtx)
   xty=crossprod(xmtx,ymtx)
   xtxinv=solve(xtx)
   beta=xtxinv%*%xty
   resi= ymtx - xmtx%*%beta
   sse=crossprod(resi,resi)/ne
   dd=diag(xtxinv)
   sebeta=NULL
   for (j in 1:k){
      se=sqrt(dd*sse[j,j])
      sebeta=cbind(sebeta,se)
   }
    THini <- list(estimates=beta,se=sebeta)
  }

   if(length(fixed) < 1){
    m1=VARorder(da,q+12,output=FALSE)
    porder=m1$aicor
    if(porder < 1)porder=1
    m2=VAR(da,porder,output=FALSE)
    y=da[(porder+1):nT,]
    x=m2$residuals
    m3=THini(y,x,q,include.mean)
    beta=m3$estimates
    sebeta=m3$se
    nr=dim(beta)[1]
   ### Preliminary simplification
   if(prelim){
      fixed = matrix(0,nr,k)
      for (j in 1:k){
         tt=beta[,j]/sebeta[,j]
         idx=c(1:nr)[abs(tt) >= thres]
         fixed[idx,j]=1
       }
     }
   #
    if(length(fixed) < 1){fixed=matrix(1,nr,k)}
   }
   else{
    nr=dim(beta)[1]
   }
   #
   par=NULL
   separ=NULL
   fix1=fixed
   #
   #
   VMAcnt=0
   ist=0
   if(include.mean){
      jdx=c(1:k)[fix1[1,]==1]
      VMAcnt=length(jdx)
      if(VMAcnt > 0){
         par=beta[1,jdx]
         separ=sebeta[1,jdx]
      }
      TH=-beta[2:(kq+1),]
      seTH=sebeta[2:(kq+1),]
      ist=1
   }
   else {
      TH=-beta
      seTH=sebeta
   }
   #########
   for (j in 1:k){
      idx=c(1:(nr-ist))[fix1[(ist+1):nr,j]==1]
      if(length(idx) > 0){
         par=c(par,TH[idx,j])
         separ=c(separ,seTH[idx,j])
      }
   }
   #
   ParMA <- par

 LLKvma <- function(par,zt=zt,q=q,fixed=fix1,include.mean=include.mean){
   ## the model used is
   ## x_t' = mu' + a_t' -a_{t-1}'theta_1' - a_{t-2}'theta_2' - ...
   ## a_t' = x_t' - mu' + a_{t-1}'theta_1'+a_{t-2}'theta_2' + ....
   k=ncol(zt)
   nT=nrow(zt)
   mu=rep(0,k)
   icnt=0; VMAcnt <- 0
   fix <- fixed
   #
   iist=0
   if(include.mean){
      iist=1
      jdx=c(1:k)[fix[1,]==1]
      icnt=length(jdx); VMAcnt <- icnt
      if(icnt > 0)
      mu[jdx]=par[1:icnt]
   }
   ### remove the mean
   for (j in 1:k){
      zt[,j]=zt[,j]-mu[j]
   }
   ## recursively compute the residual series: at
   kq=k*q
   Theta=matrix(0,kq,k)
   for (j in 1:k){
      idx=c(1:kq)[fix[(iist+1):(iist+kq),j]==1]
      jcnt=length(idx)
      if(jcnt > 0){
         Theta[idx,j]=par[(icnt+1):(icnt+jcnt)]
         icnt=icnt+jcnt
      }
   }
   # Theta = rbind[theta_1',theta_2', ..., theta_q']
   ### Checking the invertibility of t(Theta)
   TH=t(Theta)
   if(q > 1){
      tmp=cbind(diag(rep(1,(q-1)*k)),matrix(0,(q-1)*k,k))
      TH=rbind(TH,tmp)
   }
   mm=eigen(TH)
   V1=mm$values
   P1=mm$vectors
   v1=Mod(V1)
   ich=0
   for (i in 1:kq){
      if(v1[i] > 1)V1[i]=1/V1[i]
      ich=1
   }
   if(ich > 0){
      ###cat("Invertibility checked and adjusted: ","\n")
      P1i=solve(P1)
      GG=diag(V1)
      TH=Re(P1%*%GG%*%P1i)
      Theta=t(TH[1:k,])
      ##cat("adjusted Theta","\n")
      ##print(TH[1:k,])
      ### re-adjust the MA parameter
      ist=0
      if(VMAcnt > 0)ist=1
      for (j in 1:k){
         idx=c(1:kq)[fix[(ist+1):(ist+kq),j]==1]
         jcnt=length(idx)
         if(jcnt > 0){
            par[(icnt+1):(icnt+jcnt)]=TH[j,idx]
            icnt=icnt+jcnt
         }
      }
      ##
   }
   ##
   at=mFilter(zt,t(Theta))
   #
   sig=t(at)%*%at/nT
   ##ll=dmnorm(at,rep(0,k),sig)
   ll=dmvnorm(at,rep(0,k),sig)
   LLKvma=-sum(log(ll))
   LLKvma
  }
   #
   cat("Number of parameters: ",length(par),"\n")
   cat("initial estimates: ",round(par,4),"\n")
   ### Set up lower and upper bounds
   lowerBounds=par; upperBounds=par
   npar=length(par)
   mult=2.0
   if((npar > 10)||(q > 2))mult=1.2
   for (j in 1:npar){
      lowerBounds[j] = par[j]-mult*separ[j]
      upperBounds[j] = par[j]+mult*separ[j]
   }
   cat("Par. Lower-bounds: ",round(lowerBounds,4),"\n")
   cat("Par. Upper-bounds: ",round(upperBounds,4),"\n")
   ###mm=optim(par,LLKvma,method=c("L-BFGS-B"),lower=lowerBounds,upper=upperBounds,hessian=TRUE)
   ###mm=optim(par,LLKvma,method=c("BFGS"),hessian=TRUE)
   ##est=mm$par
   ##H=mm$hessian
   # Step 5: Estimate Parameters and Compute Numerically Hessian:
   if(details){
      fit = nlminb(start = ParMA, objective = LLKvma,zt=da,fixed=fixed,include.mean=include.mean,q=q,
      lower = lowerBounds, upper = upperBounds, control = list(trace=3))
   }
   else {
      fit = nlminb(start = ParMA, objective = LLKvma, zt=da, fixed=fixed, include.mean=include.mean, q=q,
       lower = lowerBounds, upper = upperBounds)
   }
   epsilon = 0.0001 * fit$par
   npar=length(par)
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] = (LLKvma(x1,zt=da,q=q,fixed=fixed,include.mean=include.mean)
                          -LLKvma(x2,zt=da,q=q,fixed=fixed,include.mean=include.mean)
                          -LLKvma(x3,zt=da,q=q,fixed=fixed,include.mean=include.mean)
                          +LLKvma(x4,zt=da,q=q,fixed=fixed,include.mean=include.mean))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   est=fit$par
   cat("Final   Estimates: ",est,"\n")
   # Step 6: Create and Print Summary Report:
   se.coef = sqrt(diag(solve(Hessian)))
   tval = fit$par/se.coef
   matcoef = cbind(fit$par, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)
   #
   ### recover to the format of unconstrained case for printing purpose.
   cat("---","\n")
   cat("Estimates in matrix form:","\n")
   icnt=0
   ist=0
   cnt=NULL
   if(include.mean){
      ist=1
      cnt=rep(0,k)
      secnt=rep(1,k)
      jdx=c(1:k)[fix1[1,]==1]
      icnt=length(jdx)
      if(icnt > 0){
         cnt[jdx]=est[1:icnt]
         secnt[jdx]=se.coef[1:icnt]
         cat("Constant term: ","\n")
         cat("Estimates: ",cnt,"\n")
      }
   }
   cat("MA coefficient matrix","\n")
   TH=matrix(0,kq,k)
   seTH=matrix(1,kq,k)
   for (j in 1:k){
      idx=c(1:kq)[fix1[(ist+1):nr,j]==1]
      jcnt=length(idx)
      if(jcnt > 0){
         TH[idx,j]=est[(icnt+1):(icnt+jcnt)]
         seTH[idx,j]=se.coef[(icnt+1):(icnt+jcnt)]
         icnt=icnt+jcnt
      }
   }
   icnt=0
   for (i in 1:q){
      cat("MA(",i,")-matrix","\n")
      theta=t(TH[(icnt+1):(icnt+k),])
      print(theta,digits=3)
      icnt=icnt+k
   }
   ## Compute the residuals
   zt=da
   if(include.mean){
      for (i in 1:k){
         zt[,i]=zt[,i]-cnt[i]
      }
   }
   ### Use mFilter to compute residuals (April 18, 2012)
   at=mFilter(zt,t(TH))
   sig=t(at)%*%at/nT
   cat(" ","\n")
   cat("Residuals cov-matrix:","\n")
   print(sig)
   dd=det(sig)
   d1=log(dd)
   aic=d1+2*npar/nT
   bic=d1+log(nT)*npar/nT
   cat("----","\n")
   cat("aic= ",aic,"\n")
   cat("bic= ",bic,"\n")
   ### prepare for output storage
   Theta=t(TH)
   if(include.mean){
      TH=rbind(cnt,TH)
      seTH=rbind(secnt,seTH)
   }

   VMA <- list(data=da,MAorder=q,cnst=include.mean,coef=TH,secoef=seTH,residuals=at,Sigma=sig,Theta=Theta,mu=cnt,aic=aic,bic=bic)
}


####
"refVMA" <- function(model,thres=1.0){
   # This program refines the fitted models of VMA output by removing
   # insigificant parameters with abs(t-ratio) < thres.
   # model: output object from VMA
   # thres: threshold value
   #
   x = model$data
   q = model$MAorder
   cnst = model$cnst
   coef=as.matrix(model$coef)
   secoef=as.matrix(model$secoef)
   nr=dim(coef)[1]
   nc=dim(coef)[2]
   for (i in 1:nc){
      idx=is.na(secoef[,i])
      jdx=c(1:nr)[idx==T]
      secoef[jdx,i]=0.01
   }
   fix=matrix(0,nr,nc)
   for (j in 1:nc){
      tt=coef[,j]/secoef[,j]
      idx=c(1:nr)[abs(tt) >= thres]
      fix[idx,j]=1
   }
   ### Try to keep the constant if the t-ratio is greater than 1.
   if(cnst){
      tt=coef[1,]/secoef[1,]
      idx=c(1:nc)[abs(tt) > 1.0]
      if(length(idx) > 0)fix[1,idx]=1
   }

   mm=VMA(x,q=q,include.mean=cnst,fixed=fix,beta=coef,sebeta=secoef)

   refVMA <- list(data=x,MAorder=q,cnst=cnst,coef=mm$coef,secoef=mm$secoef,residuals=mm$residuals,Sigma=mm$Sigma,aic=mm$aic,bic=mm$bic,mu=mm$mu,Theta=mm$Theta,fixed=fix)
  }

####
"VMAs" <- function(da,malags,include.mean=T,fixed=NULL,prelim=F,details=F,thres=2.0){
   # Estimation of a vector MA model using conditional MLE (Gaussian dist)
   # The MA lags are given specifically.
   #
   if(!is.matrix(da))da=as.matrix(da)
   nT <- dim(da)[1]; k <- dim(da)[2]
   nlags=length(malags)
   if(nlags < 1){
      malags=c(1)
      nlags=1
     }
   MAlag <- sort(malags)
   kq=k*nlags
   # find the maximum MA order
   q=MAlag[nlags]
 #
 THinis <- function(y,x,MAlag,include.mean){
   # use residuals of a long VAR model to obtain initial estimates of
   # VMA coefficients.
   if(!is.matrix(y))y=as.matrix(y)
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(y)[1]
   k=dim(y)[2]
   nlags=length(MAlag)
   q=MAlag[nlags]
   ist=1+q
   ne=nT-q
   if(include.mean){
      xmtx=matrix(1,ne,1)
   }
   else {
      xmtx=NULL
   }
   ymtx=y[ist:nT,]
   for (j in 1:nlags){
      jj=MAlag[j]
      xmtx=cbind(xmtx,x[(ist-jj):(nT-jj),])
   }
   xtx=crossprod(xmtx,xmtx)
   xty=crossprod(xmtx,ymtx)
   xtxinv=solve(xtx)
   beta=xtxinv%*%xty
   # compute standard errors
   resi=ymtx - xmtx%*%beta
   sse=crossprod(resi,resi)/ne
   dd=diag(xtxinv)
   sebeta=NULL
   for (j in 1:k){
      se=sqrt(dd*sse[j,j])
      sebeta=cbind(sebeta,se)
     }
   THinis <- list(estimates=beta, se=sebeta)
  }

   # Obtain initial parameter estimates
   ### Use VAR approximation to obtain initial parameter estimates
   m1=VARorder(da,q+10,output=FALSE)
   porder=m1$aicor
   m2=VAR(da,porder,output=FALSE)
   y=da[(porder+1):nT,]
   x=m2$residuals
   m3=THinis(y,x,MAlag,include.mean)
   beta=m3$estimates
   sebeta=m3$se
   nr=dim(beta)[1]
   #
   if(prelim){
      fixed=matrix(0,nr,k)
      for (j in 1:k){
         tt=beta[,j]/sebeta[,j]
         idx=c(1:nr)[abs(tt) >= thres]
         fixed[idx,j]=1
      }
   }
   ####
   if(length(fixed)==0){fixed=matrix(1,nr,k)}
   #
   par=NULL
   separ=NULL
   ist=0
   if(include.mean){
      jdx=c(1:k)[fixed[1,]==1]
      if(length(jdx) > 0){
         par=beta[1,jdx]
         separ=sebeta[1,jdx]
      }
      TH=-beta[2:(kq+1),]
      seTH=sebeta[2:(kq+1),]
      ist=1
   }
   else {
      TH=-beta
      seTH=sebeta
   }
   #####
   for (j in 1:k){
      idx=c(1:(nr-ist))[fixed[(ist+1):nr,j]==1]
      if(length(idx)>0){
         par=c(par,TH[idx,j])
         separ=c(separ,seTH[idx,j])
      }
   }
   cat("Initial estimates: ",round(par,4),"\n")
   ### Set up lower and upper bounds
   lowerBounds=par; upperBounds=par
   for (j in 1:length(par)){
      lowerBounds[j] = par[j]-2*separ[j]
      upperBounds[j] = par[j]+2*separ[j]
   }
   cat("Par. lower-bounds: ",round(lowerBounds,4),"\n")
   cat("Par. upper-bounds: ",round(upperBounds,4),"\n")
###
LLKvmas <- function(par,zt=da, include.mean=include.mean, MAlag=MAlag, fixed=fixed){
   ## the model used is
   ## x_t' = mu' + a_t' -a_{t-1}'theta_1' - a_{t-2}'theta_2' - ...
   ## a_t' = x_t' - mu' + a_{t-1}'theta_1'+a_{t-2}'theta_2' + ....
   k=ncol(zt)
   nT=nrow(zt)
   nlags=length(MAlag)
   q=MAlag[nlags]
   fix <- fixed
   #
   mu=rep(0,k)
   ist=0
   icnt=0; VMAcnt <- 0
   if(include.mean){
      ist=1
      jdx=c(1:k)[fix[1,]==1]
      icnt=length(jdx); VMAcnt <- icnt
      mu[jdx]=par[1:icnt]
      ### remove the mean
      for (j in 1:k){
         zt[,j]=zt[,j]-mu[j]
      }
   }
   ## recursively compute the residual series: at
   kq=k*nlags
   Theta=matrix(0,kq,k)
   for (j in 1:k){
      idx=c(1:kq)[fix[(ist+1):(ist+kq),j]==1]
      jcnt=length(idx)
      if(jcnt > 0){
         Theta[idx,j]=par[(icnt+1):(icnt+jcnt)]
         icnt=icnt+jcnt
      }
   }

   # Theta = rbind[theta_1',theta_2', ..., theta_q']
   at=zt[1:MAlag[1],]
   if(MAlag[1]==1)at=matrix(at,1,k)
   if(q >= (MAlag[1]+1)){
      for(t in (MAlag[1]+1):q){
         Past=NULL
         for (ii in 1:nlags){
            jj=MAlag[ii]
            if((t-jj) > 0){
               Past=c(Past,at[t-jj,])
            }
            else {
               Past=c(Past,rep(0,k))
            }
         }
         tmp=zt[t,]+matrix(Past,1,kq)%*%Theta
         at=rbind(at,tmp)
      }
      #end of if(q >= (MAlag[1]+1)) statement
   }
   for(t in (q+1):nT){
      Past=NULL
      for (ii in 1:nlags){
         jj=MAlag[ii]
         Past=c(Past,at[t-jj,])
      }
      tmp=zt[t,]+matrix(Past,1,kq)%*%Theta
      at=rbind(at,tmp)
   }
   #
   sig=t(at)%*%at/nT
   ##ll=dmnorm(at,rep(0,k),sig)
   ll=dmvnorm(at,rep(0,k),sig)
   LLKvmas=-sum(log(ll))
   LLKvmas
  }

   # Step 5: Estimate Parameters and Compute Numerically Hessian:
   if(details){
      fit = nlminb(start = par, objective = LLKvmas, zt=da, include.mean=include.mean, MAlag=MAlag, fixed=fixed,
      lower = lowerBounds, upper = upperBounds, control = list(trace=3))
   }
   else {
      fit = nlminb(start = par, objective = LLKvmas, zt=da, include.mean=include.mean, MAlag=MAlag, fixed=fixed,
        lower = lowerBounds, upper = upperBounds)
   }
   epsilon = 0.0001 * fit$par
   npar=length(par)
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] = (LLKvmas(x1,zt=da,include.mean=include.mean,MAlag=MAlag,fixed=fixed)
                         -LLKvmas(x2,zt=da,include.mean=include.mean,MAlag=MAlag,fixed=fixed)
                         -LLKvmas(x3,zt=da,include.mean=include.mean,MAlag=MAlag,fixed=fixed)
                         +LLKvmas(x4,zt=da,include.mean=include.mean,MAlag=MAlag,fixed=fixed))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   est=fit$par
   cat("Final    Estimates: ",est,"\n")
   # Step 6: Create and Print Summary Report:
   se.coef = sqrt(diag(solve(Hessian)))
   tval = fit$par/se.coef
   matcoef = cbind(fit$par, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)

   cat("---","\n")
   cat("Estimates in matrix form:","\n")
   icnt=0
   ist=0
   cnt=rep(0,k)
   secnt=rep(1,k)
   # handle the mean,if any.
   if(include.mean){
      ist=1
      jdx=c(1:k)[fixed[1,]==1]
      icnt=length(jdx)
      if(icnt > 0){
         cnt[jdx]=est[1:icnt]
         secnt=se.coef[1:icnt]
         cat("Constant term: ","\n")
         cat("Estimates: ",cnt,"\n")
      }
   }
   cat("MA coefficient matrix","\n")
   TH=matrix(0,kq,k)
   seTH=matrix(1,kq,k)
   for (j in 1:k){
      idx=c(1:kq)[fixed[(ist+1):nr,j]==1]
      jcnt=length(idx)
      if(jcnt > 0){
         TH[idx,j]=est[(icnt+1):(icnt+jcnt)]
         seTH[idx,j]=se.coef[(icnt+1):(icnt+jcnt)]
         icnt=icnt+jcnt
      }
   }
   #
   ####print(TH)
   #
   icnt=0
   for (i in 1:nlags){
      ii=MAlag[i]
      cat("MA(",ii,")-matrix","\n")
      theta=t(TH[(icnt+1):(icnt+k),])
      print(theta,digits=3)
      icnt=icnt+k
   }
   ## Compute the residuals
   zt=da
   if(include.mean){
      for (i in 1:k){
         zt[,i]=zt[,i]-cnt[i]
      }
   }
   at=zt[1:MAlag[1],]
   if(MAlag[1]==1)at=matrix(at,1,k)
   if(q >= (MAlag[1]+1)){
      for(t in (MAlag[1]+1):q){
         Past=NULL
         for (ii in 1:nlags){
            jj=MAlag[ii]
            if((t-jj) > 0){
               Past=c(Past,at[t-jj,])
            }
            else {
               Past=c(Past,rep(0,k))
            }
         }
         tmp=zt[t,]+matrix(Past,1,kq)%*%TH
         at=rbind(at,tmp)
      }
      #end of the statement if(q > (MAlag[1]+1)
   }
   for(t in (q+1):nT){
      Past=NULL
      for (ii in 1:nlags){
         jj=MAlag[ii]
         Past=c(Past,at[t-jj,])
      }
      tmp=zt[t,]+matrix(Past,1,kq)%*%TH
      at=rbind(at,tmp)
   }
   #
   sig=t(at)%*%at/nT
   cat(" ","\n")
   cat("Residuals cov-matrix:","\n")
   print(sig)
   dd=det(sig)
   d1=log(dd)
   aic=d1+2*npar/nT
   bic=d1+log(nT)*npar/nT
   cat("---","\n")
   cat("aic = ",aic,"\n")
   cat("bic = ",bic,"\n")
   ###
   Theta=t(TH)
   if(include.mean){
      TH=rbind(cnt,TH)
      seTH=rbind(secnt,seTH)
   }

   VMAs <- list(data=da,MAlags=MAlag,cnst=include.mean,coef=TH,secoef=seTH,residuals=at,aic=aic,bic=bic,Sigma=sig,Theta=Theta,mu=cnt,MAorder=q,fixed=fixed)
}


####
"refVMAs" <- function(model,thres=2){
   # This program refines a fittd VMAs model by removing insignificant parameters defined as
   # abs(t-ratio) < thres.
   #
   # model: an output object from VMAs program
   # thres: threshold
   #
   x = model$data
   malags = model$MAlags
   cnst = model$cnst
   coef=model$coef
   secoef=model$secoef
   nr=dim(coef)[1]
   nc=dim(coef)[2]
   for (i in 1:nr){
      for (j in 1:nc){
         if(secoef[i,j] < 10^(-8))secoef[i,j]=1.0
      }
   }
   k=dim(x)[2]
   nr=dim(coef)[1]
   nc=dim(coef)[2]
   fix=matrix(0,nr,k)
   for (j in 1:k){
      tt=coef[,j]/secoef[,j]
      idx=c(1:nr)[abs(tt) >= thres]
      if(length(idx) > 0)fix[idx,j]=1
   }
   ### Try to keep the constant if the t-ratio is greater then 1.
   if(cnst){
      tt=coef[1,]/secoef[1,]
      idx=c(1:nc)[abs(tt) > 1.0]
      if(length(idx) > 0)fix[1,idx]=1
   }

   mm=VMAs(x,malags,include.mean=cnst,fixed=fix)

   refVMAs <- list(data=x,MAlags=malags,cnst=cnst,coef=mm$coef,secoef=mm$secoef,residuals=mm$residuals,aic=mm$aic,bic=mm$bic,Sigma=mm$Sigma,Theta=mm$Theta,mu=mm$mu,MAorder=mm$MAorder,fixed=fix)
}

#####
"VMApred" <- function(model,h=1,orig=0){
   # Computes the i=1, 2, ..., h-step ahead predictions of a VMA(q) model.
   #
   # model is a VMA output object.
   # created on April 20, 2011
   #
   x=model$data
   resi=model$residuals
   Theta=model$Theta
   sig=model$Sigma
   mu=model$mu
   q=model$MAorder
   np=dim(Theta)[2]
   psi=-Theta
   #
   nT=dim(x)[1]
   k=dim(x)[2]
   if(orig <= 0)orig=nT
   if(orig > T)orig=nT
   if(length(mu) < 1)mu=rep(0,k)
   if(q > orig){
      cat("Too few data points to produce forecasts","\n")
   }
   pred=NULL
   se=NULL
   px=as.matrix(x[1:orig,])
   for (j in 1:h){
      fcst=mu
      t=orig+j
      for (i in 1:q){
         jdx=(i-1)*k
         t1=t-i
         if(t1 <= orig){
            theta=Theta[,(jdx+1):(jdx+k)]
            fcst=fcst-matrix(resi[t1,],1,k)%*%t(theta)
         }
      }
      px=rbind(px,fcst)
      #
      Sig=sig
      if (j > 1){
         jj=min(q,(j-1))
         for (ii in 1:jj){
            idx=(ii-1)*k
            wk=psi[,(idx+1):(idx+k)]
            Sig=Sig+wk%*%sig%*%t(wk)
         }
      }
      se=rbind(se,sqrt(diag(Sig)))
   }
   cat("Forecasts at origin: ",orig,"\n")
   print(px[(orig+1):(orig+h),],digits=4)
   cat("Standard Errors of predictions: ","\n")
   print(se[1:h,],digits=4)
   pred=px[(orig+1):(orig+h),]
   if(orig < nT){
      cat("Observations, predicted values, and errors","\n")
      tmp=NULL
      jend=min(nT,(orig+h))
      for (t in (orig+1):jend){
         case=c(t,x[t,],px[t,],x[t,]-px[t,])
         tmp=rbind(tmp,case)
      }
      colnames(tmp) <- c("time",rep("obs",k),rep("fcst",k),rep("err",k))
      idx=c(1)
      for (j in 1:k){
         idx=c(idx,c(0,1,2)*k+j+1)
      }
      tmp = tmp[,idx]
      print(tmp,digits=3)
   }

   VMApred <- list(pred=pred,se.err=se)
}

####
"VARMA" <- function(da,p=0,q=0,include.mean=T,fixed=NULL,beta=NULL,sebeta=NULL,prelim=F,details=F,thres=2.0){
   # Estimation of a vector ARMA model using conditional MLE (Gaussian dist)
   #
   # When prelim=TRUE, fixed is assigned based on the results of AR approximation.
   # Here "thres" is used only when prelim = TRUE.
   #
   if(!is.matrix(da))da=as.matrix(da)
   nT=dim(da)[1];   k=dim(da)[2]
   # basic setup.
   if(p < 0)p=0
   if(q < 0)q=0
   if((p+q) < 1)p=1
   pqmax=max(p,q)
   kq=k*q
   kp=k*p
#
 iniEST <- function(y,x,p,q,include.mean){
   # use residuals of a long VAR model to obtain initial estimates of
   # VARMA coefficients.
   if(!is.matrix(y))y=as.matrix(y)
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(y)[1]
   k=dim(y)[2]
   pq=max(p,q)
   ist=1+pq
   ne=nT-pq
   if(include.mean){
      xmtx=matrix(1,ne,1)
     }
     else {
      xmtx=NULL
     }
   ymtx=as.matrix(y[ist:nT,])
   if(p > 0){
      for (j in 1:p){
         xmtx=cbind(xmtx,y[(ist-j):(nT-j),])
       }
    }
   if(q > 0){
      for (j in 1:q){
         xmtx=cbind(xmtx,x[(ist-j):(nT-j),])
      }
     }
   xmtx=as.matrix(xmtx)
   xtx=crossprod(xmtx,xmtx)
   xty=crossprod(xmtx,ymtx)
   xtxinv=solve(xtx)
   beta=xtxinv%*%xty
   resi= ymtx - xmtx%*%beta
   sse=crossprod(resi,resi)/ne
   dd=diag(xtxinv)
   sebeta=NULL
   for (j in 1:k){
      se=sqrt(dd*sse[j,j])
      sebeta=cbind(sebeta,se)
   }
   iniEST <- list(estimates=beta,se=sebeta)
  }

  if(length(fixed) < 1){
   m1=VARorder(da,p+q+9,output=FALSE)
   porder=m1$aicor
   if(porder < 1)porder=1
   m2=VAR(da,porder,output=FALSE)
   y=da[(porder+1):nT,]
   x=m2$residuals
   m3=iniEST(y,x,p,q,include.mean)
   beta=m3$estimates
   sebeta=m3$se
   nr=dim(beta)[1]
   ### Preliminary simplification
   if(prelim){
      fixed = matrix(0,nr,k)
      for (j in 1:k){
         tt=beta[,j]/sebeta[,j]
         idx=c(1:nr)[abs(tt) >= thres]
         fixed[idx,j]=1
       }
     }
    if(length(fixed)==0){fixed=matrix(1,nr,k)}
   }
   # Identify parameters to be estimated.
   par=NULL
   separ=NULL
   ist=0
   if(include.mean){
      jdx=c(1:k)[fixed[1,]==1]
      if(length(jdx) > 0){
         par=beta[1,jdx]
         separ=sebeta[1,jdx]
      }
      ist=1
   }
   if(p > 0){
      for (j in 1:k){
         idx=c(1:kp)[fixed[(ist+1):(ist+kp),j]==1]
         if(length(idx) > 0){
            tmp=beta[(ist+1):(ist+kp),j]
            setmp=sebeta[(ist+1):(ist+kp),j]
            par=c(par,tmp[idx])
            separ=c(separ,setmp[idx])
         }
         #end of j-loop
      }
      ist=ist+kp
   }
   #
   if(q > 0){
      for (j in 1:k){
         idx=c(1:kq)[fixed[(ist+1):(ist+kq),j]==1]
         if(length(idx) > 0){
            tmp=beta[(ist+1):(ist+kq),j]
            setmp=sebeta[(ist+1):(ist+kq),j]
            par=c(par,tmp[idx])
            separ=c(separ,setmp[idx])
         }
       }
   }
   #########
   cat("Number of parameters: ",length(par),"\n")
   cat("initial estimates: ",round(par,4),"\n")
   ### Set up lower and upper bounds
   lowerBounds=par; upperBounds=par
   for (j in 1:length(par)){
      lowerBounds[j] = par[j]-2*separ[j]
      upperBounds[j] = par[j]+2*separ[j]
   }
   cat("Par. lower-bounds: ",round(lowerBounds,4),"\n")
   cat("Par. upper-bounds: ",round(upperBounds,4),"\n")

   # Step 5: Estimate Parameters and Compute Numerically Hessian:
   if(details){
      fit = nlminb(start = par, objective = LLKvarma,zt=da,p=p,q=q,include.mean=include.mean,fixed=fixed,
      lower = lowerBounds, upper = upperBounds, control = list(trace=3))
   }
   else {
      fit = nlminb(start = par, objective = LLKvarma, zt=da,p=p,q=q,include.mean=include.mean,fixed=fixed,
      lower = lowerBounds, upper = upperBounds)
   }
   epsilon = 0.0001 * fit$par
   npar=length(par)
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] = (LLKvarma(x1,zt=da,p=p,q=q,include.mean=include.mean,fixed=fixed)
                         -LLKvarma(x2,zt=da,p=p,q=q,include.mean=include.mean,fixed=fixed)
                         -LLKvarma(x3,zt=da,p=p,q=q,include.mean=include.mean,fixed=fixed)
                         +LLKvarma(x4,zt=da,p=p,q=q,include.mean=include.mean,fixed=fixed))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   est=fit$par
   cat("Final   Estimates: ",est,"\n")
   # Step 6: Create and Print Summary Report:
   se.coef = sqrt(diag(solve(Hessian)))
   tval = fit$par/se.coef
   matcoef = cbind(fit$par, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)
   #
   ### restore estimates to the format of unconstrained case for printing purpose.
   #### icnt: parameter count
   #### ist: location count
   ist=0
   icnt = 0
   Ph0=rep(0,k)
   sePh0=rep(0,k)
   beta=NULL
   sebeta=NULL
   if(include.mean){
      idx=c(1:k)[fixed[1,]==1]
      icnt=length(idx)
      if(icnt > 0){
         Ph0[idx]=est[1:icnt]
         sePh0[idx]=se.coef[1:icnt]
      }
      ist=1
      beta=rbind(beta,Ph0)
      sebeta=rbind(sebeta,sePh0)
   }
   PH=NULL
   sePH=NULL
   if(p > 0){
      PH=matrix(0,kp,k)
      sePH=matrix(0,kp,k)
      for (j in 1:k){
         idx=c(1:kp)[fixed[(ist+1):(ist+kp),j]==1]
         jdx=length(idx)
         if(jdx > 0){
            PH[idx,j]=est[(icnt+1):(icnt+jdx)]
            sePH[idx,j]=se.coef[(icnt+1):(icnt+jdx)]
            icnt=icnt+jdx
         }
         # end of j-loop
      }
      #end of if (p > 0)
      ist=ist+kp
      beta=rbind(beta,PH)
      sebeta=rbind(sebeta,sePH)
   }
   #
   TH=NULL
   seTH=NULL
   if(q > 0){
      TH=matrix(0,kq,k)
      seTH=matrix(0,kq,k)
      for (j in 1:k){
         idx=c(1:kq)[fixed[(ist+1):(ist+kq),j]==1]
         jdx=length(idx)
         if(jdx > 0){
            TH[idx,j]=est[(icnt+1):(icnt+jdx)]
            seTH[idx,j]=se.coef[(icnt+1):(icnt+jdx)]
            icnt=icnt+jdx
         }
         # end of j-loop
      }
      # end of if(q > 0).
      beta=rbind(beta,TH)
      sebeta=rbind(sebeta,seTH)
   }
   #########
   cat("---","\n")
   cat("Estimates in matrix form:","\n")
   if(include.mean){
      cat("Constant term: ","\n")
      cat("Estimates: ",Ph0,"\n")
   }
   if(p > 0){
      cat("AR coefficient matrix","\n")
      jcnt=0
      for (i in 1:p){
         cat("AR(",i,")-matrix","\n")
         ph=t(PH[(jcnt+1):(jcnt+k),])
         print(ph,digits=3)
         jcnt=jcnt+k
      }
      # end of if (p > 0)
   }
   if(q > 0){
      cat("MA coefficient matrix","\n")
      icnt=0
      for (i in 1:q){
         cat("MA(",i,")-matrix","\n")
         theta=-t(TH[(icnt+1):(icnt+k),])
         print(theta,digits=3)
         icnt=icnt+k
      }
      # end of the statement if(q > 0)
   }
   ##### Compute the residuals
   zt=da
   ist=pqmax+1
   #### consider the case t from 1 to pqmatx
   at=matrix((zt[1,]-Ph0),1,k)
   if(pqmax > 1){
      for (t in 2:pqmax){
         tmp=matrix((zt[t,]-Ph0),1,k)
         if(p > 0){
            for (j in 1:p){
               if((t-j) > 0){
                  jdx=(j-1)*k
                  tmp1=matrix(zt[(t-j),],1,k)%*%as.matrix(PH[(jdx+1):(jdx+k),])
                  tmp=tmp-tmp1
               }
               # end of j-loop
            }
            # end of if(p > 0) statement
         }
         #
         if(q > 0){
            for (j in 1:q){
               jdx=(j-1)*k
               if((t-j)>0){
                  tmp2=matrix(at[(t-j),],1,k)%*%as.matrix(TH[(jdx+1):(jdx+k),])
                  tmp=tmp-tmp2
               }
               #end of j-loop
            }
            #end of if(q > 0) statement
         }
         at=rbind(at,tmp)
         # end of for(t in 2:pqmax)
      }
      # end of if(pqmax > 1) statement
   }

   ### for t from ist on
   Pcnt = NULL
   idim=kp+kq
   if(include.mean){
      Pcnt=c(1)
      idim=idim+1
   }
   #
   for (t in ist:nT){
      Past=NULL
      if(p > 0){
         for (j in 1:p){
            Past=c(Past,zt[(t-j),])
         }
      }
      if(q > 0){
         for (j in 1:q){
            Past=c(Past,at[(t-j),])
         }
      }
      tmp = matrix(c(Pcnt,Past),1,idim)%*%beta
      tmp3=zt[t,]-tmp
      at=rbind(at,tmp3)
   }
   #### skip the first max(p,q) residuals.
   at=at[(ist:nT),]
   sig=t(at)%*%at/(nT-pqmax)
   ##
   cat(" ","\n")
   cat("Residuals cov-matrix:","\n")
   print(sig)
   dd=det(sig)
   d1=log(dd)
   aic=d1+2*npar/nT
   bic=d1+log(nT)*npar/nT
   cat("----","\n")
   cat("aic= ",aic,"\n")
   cat("bic= ",bic,"\n")
   if(length(PH) > 0)PH=t(PH)
   if(length(TH) > 0)TH=-t(TH)

   VARMA <- list(data=da,ARorder=p,MAorder=q,cnst=include.mean,coef=beta,secoef=sebeta,residuals=at,Sigma=sig,aic=aic,bic=bic,Phi=PH,Theta=TH,Ph0=Ph0)
}


####
"refVARMA" <- function(model,thres=1.5){
   # This program refines the fitted models of VARMA output by removing
   # insigificant parameters with abs(t-ratio) < thres.
   # model: output object from VARMA
   # thres: threshold value
   #
   x = model$data
   p1 = model$ARorder
   q1 = model$MAorder
   cnst = model$cnst
   coef=as.matrix(model$coef)
   secoef=as.matrix(model$secoef)
   nr=dim(coef)[1]
   nc=dim(coef)[2]
   for (j in 1:nc){
      idx=is.na(secoef[,j])
      jdx=c(1:nr)[idx==T]
      secoef[jdx,j]=0.01
   }
   fix=matrix(0,nr,nc)
   for (j in 1:nc){
      tt=coef[,j]/secoef[,j]
      idx=c(1:nr)[abs(tt) >= thres]
      fix[idx,j]=1
   }
   ### Try to keep the constant if the t-ratio is greater then 1.
   if(cnst){
      tt=coef[1,]/secoef[1,]
      idx=c(1:nc)[abs(tt) > 1.0]
      if(length(idx) > 0)fix[1,idx]=1
   }

   mm=VARMA(x,p=p1,q=q1,include.mean=cnst,fixed=fix,beta=coef,sebeta=secoef)

   refVARMA <- list(data=x,coef=mm$coef,secoef=mm$secoef,ARorder=p1,MAorder=q1,cnst=cnst,residuals=mm$residuals,Ph0=mm$Ph0,Phi=mm$Phi,Theta=mm$Theta,Sigma=mm$Sigma,aic=mm$aic,bic=mm$bic)
}
######
"VARMApred" <- function(model,h=1,orig=0){
   ## Compute forecasts and forecast error covariance of a VARMA mdoel.
   ## created April 21, 2011 by Ruey S. Tsay
   #
   # model: an output from VARMA command.
   #
   x=as.matrix(model$data)
   resi=as.matrix(model$residuals)
   sig=model$Sigma
   Phi=model$Phi
   Theta=model$Theta
   Ph0=model$Ph0
   p=model$ARorder
   q=model$MAorder
   #
   if(p < 0)p=0
   if(q < 0)q=0
   if(h < 1)h=1
   nT=dim(x)[1]
   k=dim(x)[2]
   T1=dim(resi)[1]
   ## In case the residuals is shorter due to conditional MLE estimation.
   if(nT > T1){
      r1=matrix(0,(nT-T1),k)
      resi=rbind(r1,resi)
   }
   #
   if(length(Ph0) < 1)Ph0=rep(0,k)
   if(orig < 1)orig=nT
   if(orig > T)orig=nT
   px=x[1:orig,]
   presi=resi[1:orig,]
   # Compute the psi-weights for the variance of forecast errors.
   psi=diag(rep(1,k))
   wk=c(psi)
   lag=max(1,h)
   #
   for (i in 1:lag){
      if (i <= p){
         idx=(i-1)*k
         tmp=Phi[,(idx+1):(idx+k)]
      }
      else{
         tmp=matrix(0,k,k)
      }
      if(i <= q){
         mdx=(i-1)*k
         tmp=tmp-Theta[,(mdx+1):(mdx+k)]
      }
      #
      jj=i-1
      jp=min(jj,p)
      if(jp > 0){
         for(j in 1:jp){
            jdx=(j-1)*k
            idx=(i-j)*k
            w1=Phi[,(jdx+1):(jdx+k)]
            w2=psi[,(idx+1):(idx+k)]
            tmp=tmp+w1%*%w2
            ##print(tmp,digits=4)
         }
      }
      psi=cbind(psi,tmp)
      wk=cbind(wk,c(tmp))
      ##print(psi,digits=3)
   }
   ### Compute the forecasts and their standard errors
   sefcst=NULL
   for (j in 1:h){
      fcst=Ph0
      Sig=sig
      t=orig+j
      ### AR part
      if(p > 0){
         for (ii in 1:p){
            idx=(ii-1)*k
            ph=Phi[,(idx+1):(idx+k)]
            fcst=fcst + matrix(px[(t-ii),],1,k)%*%t(ph)
         }
         #end of AR part
      }
      ### MA part
      if(q > 0){
         for (jj in 1:q){
            idx=(jj-1)*k
            if((t-jj) <= orig){
               th=Theta[,(idx+1):(idx+k)]
               fcst=fcst - matrix(resi[(t-jj),],1,k)%*%t(th)
            }
            # end of jj-loop
         }
         # end of MA part
      }
      px=rbind(px,fcst)
      # compute standard errors of forecasts
      if(j > 1){
         Sig=sig
         for (jj in 2:j){
            jdx=(jj-1)*k
            wk=psi[,(jdx+1):(jdx+k)]
            Sig=Sig + wk%*%sig%*%t(wk)
         }
      }
      sefcst=rbind(sefcst,sqrt(diag(Sig)))
   }
   cat("Predictions at origin ",orig,"\n")
   print(px[(orig+1):(orig+h),],digits=4)
   cat("Standard errors of predictions","\n")
   if(h == 1){
      print(sefcst,digits=4)
   }
   else {
      print(sefcst[1:h,],digits=4)
   }
   #### if orig < nT, print out actual values.
   if(orig < nT){
      cat("Observations, predictions, and errors: ","\n")
      tmp=NULL
      jend=min(nT,orig+h)
      for (t in (orig+1):jend){
         case=c(t,x[t,],px[t,],x[t,]-px[t,])
         tmp=rbind(tmp,case)
      }
      colnames(tmp) <- c("time",rep("obs",k),rep("fcst",k),rep("err",k))
      idx=c(1)
      for (j in 1:k){
         idx=c(idx,c(0,1,2)*k+j+1)
      }
      tmp = tmp[,idx]
      print(tmp,digits=4)
   }

   VARMApred <- list(pred=px[(orig+1):(orig+h),],se.err=sefcst,orig=orig)
   #end of the program
}


###
"VARecm" <- function(x,p=1,wt,include.const=FALSE){
   # Fits an error-correction VAR model.
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(x)[1]
   k=dim(x)[2]
   dx=x[2:nT,]-x[1:(nT-1),]
   dx=rbind(rep(0,k),dx)
   wtadj=wt-mean(wt)
   idm=k*(p-1)+1
   if(include.const)idm=idm+1
   # effective sample size
   ist=max(1,p)
   ne=nT-ist+1
   y=dx[ist:nT,]
   xmtx=wtadj[(ist-1):(nT-1)]
   if(include.const)xmtx=cbind(xmtx,rep(1,(nT-ist+1)))
   if(p > 1){
      for (i in 2:p){
         ii=i-1
         xmtx=cbind(xmtx,dx[(ist-ii):(nT-ii),])
      }
   }
   y=as.matrix(y)
   xmtx=as.matrix(xmtx)
   xpx = t(xmtx)%*%xmtx
   xpxinv=solve(xpx)
   xpy=t(xmtx)%*%y
   beta=xpxinv%*%xpy
   yhat=xmtx%*%beta
   resi=y-yhat
   sse=(t(resi)%*%resi)/ne
   alpha=beta[1,]
   icnt=1
   if(include.const){
      c=beta[2,]
      icnt=2
   }
   dd=diag(xpxinv)
   sdbeta=matrix(0,idm,k)
   for (i in 1:k){
      sdbeta[,i]=sqrt(sse[i,i]*dd)
   }
   se=sdbeta[1,]
   cat("alpha: ","\n")
   print(alpha,digits=3)
   cat("standard error","\n")
   print(se,digits=3)
   if(include.const){
      cat("constant term:","\n")
      print(c,digits=3)
      se=sdbeta[2,]
      cat("standard error","\n")
      print(se,digits=3)
   }

   cat("AR coefficient matrix","\n")
   jst=icnt
   for (i in 1:(p-1)){
      cat("AR(",i,")-matrix","\n")
      phi=t(beta[(jst+1):(jst+k),])
      se=t(sdbeta[(jst+1):(jst+k),])
      print(phi,digits=3)
      cat("standard error","\n")
      print(se,digits=3)
      jst=jst+k
      ###cat("      ","\n")
   }
   cat("-----","\n")
   cat("Residuals cov-mtx:","\n")
   print(sse)
   #sse=sse*ne/T
   cat("      ","\n")
   dd=det(sse)
   cat("det(sse) = ",dd,"\n")
   d1=log(dd)
   aic=d1+(2*idm*k)/nT
   bic=d1+log(nT)*idm*k/nT
   cat("AIC = ",aic,"\n")
   cat("BIC = ",bic,"\n")

   VARecm<-list(coef=beta,aic=aic,bic=bic,residuals=resi,secoef=sdbeta,Sigma=sse)
}

##### Mmodel checking
"MTSdiag" <- function(model,gof=24,adj=0,level=F){
   # perform model checking for a multivariate time series model.
   # m1 is a VARMA, VMA, VAR type of models.
   #
   # adj: number of coefficient parameters in the fitted model.(without counting
   #       those in the mean and covariance matrix)
   # level: switch to print residual CCM matrices.
   ###
   resi=model$residuals
   colnames(resi) <- colnames(model$data)
   ccm(resi,lags=gof,level=level)
   cat("Hit Enter to compute MQ-statistics:","\n")
   readline()
   mq(resi,lag=gof,adj=adj)
   cat("Hit Enter to obtain residual plots:","\n")
   readline()
   MTSplot(resi)
 }

####
"tfm" <- function(y,x,b=0,s=1,p=0,q=0){
   # Estimate a special transfer function model. Specifically,
   # fit an ARMA(p,q) model to [y -(w0+w1*B+w2*B**2+...+ws*B**s)B**b x].
   # b: delay
   # s: order of the transfer function polynomial.
   # note: Length(y) == length(x) & Missing values are not allowed.
   #
   # Created by R.S. Tsay, March 2009
   #
   nT=length(y)
   T1=length(x)
   nT=min(nT,T1)
   mx=b+s
   ist=mx+1
   y1=y[ist:nT]
   X=x[(s+1):(nT-b)]
   if(s > 0){
      for (i in 1:s){
         X=cbind(X,x[(s+1-i):(nT-b-i)])
      }
     nx=ncol(X)
     m1=arima(y1,order=c(p,0,q),xreg=X)
    }
   if(s == 0){
    nx = 1
    m1 = arima(y1,order=c(p,0,q),xreg=X)
   }
   se=sqrt(diag(m1$var.coef))
   coef.arma=NULL
   se.arma=NULL
   pq=p+q
   if(pq > 0){
      coef.arma=m1$coef[1:pq]
      se.arma=se[1:pq]
      p1=cbind(coef.arma,se.arma)
      cat("ARMA coefficients & s.e.:","\n")
      print(t(p1),digits=3)
   }
   v=m1$coef[(pq+1):(pq+1+nx)]
   se.v=se[(pq+1):(pq+1+nx)]
   pr=cbind(v,se.v)
   cat("Transfer function coefficients & s.e.:","\n")
   print(t(pr),digits=3)
   res=m1$residuals
   beta=matrix(v[2:(nx+1)],nx,1)
   nt=y1-v[1]-X%*%beta

   tfm <- list(coef=v,se.coef=se.v,coef.arma=coef.arma,se.arma=se.arma,nt=nt,residuals=res)
  }



####
"tfm1" <- function(y,x,orderN,orderX){
   ## Estimation of a transfer function model with ONE exogenous variable
   ### The model is Y_t -c0 -w(B)/d(B)X_t = theta(B)/phi(B)a_t.
   ### orderN = c(p,d,q) for the ARMA part
   ### orderX = c(r,s,b) where d(B) = 1 - d_1B - ... - d_r B^r
   ###            and w(B) = w_0+w_1B + ... + w_s B^s and b is the delay.
   ###
   ### par=c(c0,w0,w1,...,ws,d1,...,dr,phi,theta); Feb. 2012.
   ###
   dify = orderN[2]; dY=y; dX=x
   if(dify > 0){
      dY <- y[(dify+1):length(y)]-y[1:(length(y)-dify)]
      dX <- x[(dify+1):length(x)]-x[1:(length(x)-dify)]
    }
   N = length(dY); N1=length(dX)
   if(N < N1) N1=N; if(N1 < N)N=N1
   phi=NULL; theta=NULL; ome=NULL; del=NULL
   r=orderX[1]; s=orderX[2]; b=orderX[3]; p=orderN[1]; q=orderN[3]
   r=max(r,0); s=max(0,s); b=max(0,b); p=max(0,p); q=max(0,q)
### subroutines used
 Nlike <- function(par,dY=dY,dX=dX,orderN=orderN,orderX=orderX){
   resi = Gaulike(par,dY=dY,dX=dX,orderN=orderN,orderX=orderX)
   sig=sqrt(var(resi))
   n1=length(resi)
   Nlike=-sum(log(dnorm(resi,mean=rep(0,n1),sd=sig)))
  }

 Gaulike <- function(par,dY=dY,dX=dX,orderN=orderN,orderX=orderX){
   p=orderN[1]; q=orderN[3]; r=orderX[1]; s=orderX[2]; b=orderX[3]
   c0=par[1]
   ome=par[2:(2+s)]
   #
   if(r > 0)del=par[(2+s+1):(2+s+r)]
   if(p > 0)phi=par[(3+r+s):(r+s+2+p)]
   if(q > 0)theta=par[(3+r+s+p):(2+r+s+p+q)]
   N=length(dY)
   ist=r+1
   N1t=dY-c0
   Nt = dX
   if(r > 0){
     Nt=filter(dX,del,method="r",init=rep(mean(dX),r))
     }
   ##
   ist=b+s+1
   N=length(Nt)
   N1t=N1t[ist:N]-ome[1]*Nt[(ist-b):(N-b)]
   if(s > 0){
      for (j in 1:s){
         N1t=N1t-ome[j+1]*Nt[(ist-j-b):(N-j-b)]
       }
    }
   N1=length(N1t)
   resi=N1t[(p+1):N1]
   if(p > 0){
      for (j in 1:p){
         resi=resi-phi[j]*N1t[(p+1-j):(N1-j)]
        }
     }
   #
   if(q > 0)resi=filter(resi,theta,method="r",init=rep(0,q))
   Gaulike = resi
 }

### Obtain the N(t) series
 Nts <- function(par,dY=dY,dX=dX,orderN=orderN,orderX=orderX){
   p=orderN[1]; q=orderN[3]; r=orderX[1]; s=orderX[2]; b=orderX[3]
   c0=par[1]
   ome=par[2:(2+s)]
   #
   if(r > 0)del=par[(2+s+1):(2+s+r)]
   N=length(dY)
   ist=r+1
   N1t=dY-c0
   Nt=dX
   if(r > 0){
     Nt=filter(dX,del,method="r",init=rep(mean(dX),r))
    }
   ##
   ist=b+s+1
   N=length(Nt)
   N1t=N1t[ist:N]-ome[1]*Nt[(ist-b):(N-b)]
   if(s > 0){
      for (j in 1:s){
         N1t=N1t-ome[j+1]*Nt[(ist-j-b):(N-j-b)]
        }
     }
   Nts=N1t
  }
####
   ## r = 0, the model can be fitted by the regular "arima" command.
   if(r==0){
      nobe=N-s-b
      Y=dY[(s+1+b):N]
      X=dX[(s+1):(N-b)]
      if(s > 0){
         for (j in 1:s){
            X=cbind(X,dX[(s+1-j):(N-b-j)])
         }
      }
      m1=arima(Y,order=c(p,0,q),xreg=X)
      est=m1$coef; sigma2=m1$sigma2; residuals=m1$residuals; varcoef=m1$var.coef
      nx=dim(X)[2]
      se=sqrt(diag(m1$var.coef))
      coef.arma=NULL
      se.arma=NULL
      pq=p+q
      if(pq > 0){
         coef.arma=est[1:pq]
         se.arma=se[1:pq]
         p1=cbind(coef.arma,se.arma)
         cat("ARMA coefficients & s.e.:","\n")
         print(t(p1),digits=3)
      }
      v=est[(pq+1):(pq+1+nx)]
      se.v=se[(pq+1):(pq+1+nx)]
      pr=cbind(v,se.v)
      cat("Transfer function coefficients & s.e.:","\n")
      print(t(pr),digits=3)
   }
   else{
      ist=max(r,s)+1+b
      par=c(mean(dY[ist:N]))
      par=c(par,rep(0.1,s+1))
      par=c(par,rep(0.1,r))
      if(p > 0)par=c(par,rep(0.1,p))
      if(q > 0)par=c(par,rep(0.01,q))
      m11=nlm(Nlike,par,hessian=TRUE,dY=dY,dX=dX,orderN=orderN,orderX=orderX)
      est=m11$estimate
      varcoef=solve(m11$hessian)
      se=sqrt(diag(varcoef))
      residuals=Gaulike(est,dY=dY,dX=dX,orderN=orderN,orderX=orderX)
      sigma2=var(residuals)
      pq=p+q
      npar=length(est)
      v=est[1:(npar-pq)]
      se.v=se[1:(npar-pq)]
      pr=cbind(v,se.v)
      cat("Delay: ",b,"\n")
      cat("Transfer function coefficients & s.e.:","\n")
      cat("in the order: constant, omega, and delta:",c(1,s+1,r),"\n")
      print(t(pr),digits=3)
      if(pq > 0){
         coef.arma=est[(npar-pq+1):npar]
         se.arma=se[(npar-pq+1):npar]
         p1=cbind(coef.arma,se.arma)
         cat("ARMA order:","\n")
         print(c(p,dify,q))
         cat("ARMA coefficients & s.e.:","\n")
         print(t(p1),digits=3)
      }
      #
   }
   Nt = Nts(est,dY=dY,dX=dX,orderN=orderN,orderX=orderX)

   tfm1 <- list(estimate=est,sigma2=sigma2,residuals=residuals,varcoef=varcoef, Nt=Nt)
}

"tfm2" <- function(y,x,x2=NULL,ct=NULL,wt=NULL,orderN=c(1,0,0),orderS=c(0,0,0),sea=12,order1=c(0,1,0),order2=c(0,-1,0)){
   ## Estimation of a transfer function model with TWO exogenous variables
   ### The model is Y_t- c0 -c1*c_t -c2*w_t - w(B)/d(B)X_t  - W(b)/D(B)X_{2t} = theta(B)*Theta(B)/[phi(B)*Phi(B)]a_t.
   ### orderN = c(p,d,q) for the regular ARMA part
   ### orderS = c(P,D,Q) for the seasonal ARMA part
   ### order1 = c(r,s,b) where d(B) = 1 - d_1B - ... - d_r B^r
   ###            and w(B) = w_0+w_1B + ... + w_s B^s and b is the delay.
   ###
   ### order2 = c(r2,s2,b2) for the second exogenous variable
   ### wt: for co-integrated system
   ### ct: a given determinsitic variable such as time trend
   ### par=c(c0,w0,w1,...,ws,d1,...,dr,c1,c2,W0, ...,Ws,D1,...,Dr,phi,theta,Phi,Theta): November 2014
   ###
   dify = orderN[2]; dY=y; dX=x; dX2=x2; dW=wt; dC=ct
   phi=NULL; theta=NULL; Phi=NULL; Theta=NULL; omega=NULL; delta=NULL; Omega=NULL; Delta=NULL
   if(dify > 0){
      dY <- y[(dify+1):length(y)]-y[1:(length(y)-dify)]
      dX <- x[(dify+1):length(x)]-x[1:(length(x)-dify)]
      if(!is.null(x2)){
        dX2 <- x2[(dify+1):length(x2)]-x2[1:(length(x2)-dify)]
        }
      if(!is.null(wt)){
        dW <- wt[(dify+1):length(wt)] - wt[1:(length(wt)-dify)]
        }
      if(!is.null(ct)){
       dC <- ct[(dify+1):length(ct)] - ct[1:(length(ct)-dify)]
       }
    }
### seasonal difference, if any
   difys = orderS[2]; lags=difys*sea
   if(difys > 0){
      dY <- dY[(lags+1):length(dY)]-dY[1:(length(dY)-lags)]
      dX <- dX[(lags+1):length(dX)]-dX[1:(length(dX)-lags)]
      if(!is.null(x2)){
        dX2 <- dX2[(lags+1):length(dX2)]-dX2[1:(length(dX2)-lags)]
        }
      if(!is.null(wt)){
        dW <- dW[(lags+1):length(dW)] - dW[1:(length(dW)-lags)]
        }
      if(!is.null(ct)){
       dC <- dC[(lags+1):length(dC)] - dC[1:(length(dC)-lags)]
        }
   }
#
   N = length(dY); N1=length(dX)
   N=min(N,N1)
   if(length(dX2) > 0)N=min(N,length(dX2))
   if(length(dW) > 0) N=min(N,length(dW))
   if(length(dC) > 0) N=min(N,length(dC))
   phi=NULL; theta=NULL; ome=NULL; del=NULL; ome2=NULL; del2=NULL; Phi=NULL; Theta=NULL
   r=order1[1]; s=order1[2]; b=order1[3]; p=orderN[1]; q=orderN[3]; P=orderS[1]; Q=orderS[3]
   r=max(r,0); s=max(0,s); b=max(0,b); p=max(0,p); q=max(0,q); P=max(0,P); Q=max(0,Q)
   r2=order2[1]; s2=order2[2]; b2=order2[3]
### subroutines used
 Nlike <- function(par,dY=dY,dX=dX,dX2=dX2,dW=dW,dC=dC,orderN=orderN,orderS=orderS,sea=sea,order1=order1,order2=order2){
   resi = Gaulike(par,dY=dY,dX=dX,dX2=dX2,dW=dW,dC=dC,orderN=orderN,orderS=orderS,sea=sea,order1=order1,order2=order2)
   sig=sqrt(var(resi))
   n1=length(resi)
   Nlike=-sum(dnorm(resi,mean=rep(0,n1),sd=sig,log=TRUE))
  }

 Gaulike <- function(par,dY=dY,dX=dX,dX2=dX2,dW=dW,dC=dC,orderN=orderN,orderS=orderS,sea=sea,order1=order1,order2=order2){
   p=orderN[1]; q=orderN[3]; r=order1[1]; s=order1[2]; b=order1[3]; P=orderS[1]; Q=orderS[3]
   r2=order2[1]; s2=order2[2]; b2=order2[3]
   c0=par[1]
   ome=par[2:(2+s)]
   #
   if(r > 0)del=par[(2+s+1):(2+s+r)]
   icnt=2+s+r
   if(!is.null(dC)){c1=par[icnt+1]
                   icnt=icnt+1
                   }
   if(!is.null(dW)){c2=par[icnt+1]
                   icnt=icnt+1
                   }
   if(!is.null(dX2)){
          ome2=par[(icnt+1):(icnt+1+s2)]
          icnt=icnt+1+s2
          if(r2 > 0){del2=par[(icnt+1):(icnt+r2)]
                      icnt=icnt+r2
                    }
          }
   if(p > 0){phi=par[(icnt+1):(icnt+p)]
             icnt=icnt+p
             }
   if(q > 0){theta=par[(icnt+1):(icnt+q)]
             icnt=icnt+q
            }
   if(P > 0){Phi=par[(icnt+1):(icnt+P)]
             icnt=icnt+P
            }
   if(Q > 0)Theta=par[(icnt+1):(icnt+Q)]
#
   N=length(dY)
   N1t=dY-c0
   Nt = dX
   if(r > 0){
     Nt=filter(dX,del,method="r",init=rep(mean(dX),r))
     }
   ##
   ist=max(b+s+1,b2+s2+1)
   N=length(Nt)
   N1t=N1t[ist:N]-ome[1]*Nt[(ist-b):(N-b)]
   if(s > 0){
      for (j in 1:s){
         N1t=N1t-ome[j+1]*Nt[(ist-j-b):(N-j-b)]
       }
    }
   if(!is.null(dC))N1t=N1t-c1*dC[ist:N]
   if(!is.null(dW))N1t=N1t-c2*dW[ist:N]
   if(!is.null(dX2)){
    Zt=dX2
    if(r2 > 0){
     Zt=filter(dX2,del2,method="r",init=rep(mean(dX2),r2))
     }
    N1t=N1t - ome2[1]*Zt[(ist-b2):(N-b2)]
    if(s2 > 0){
       for (j in 1:s2){
        N1t=N1t-ome2[j+1]*Zt[(ist-j-b2):(N-j-b2)]
        }
       }
    }
   N1=length(N1t)
   re=N1t[(p+1):N1]
   if(p > 0){
      for (j in 1:p){
         re=re-phi[j]*N1t[(p+1-j):(N1-j)]
        }
     }
   #
   if(q > 0)re=filter(re,theta,method="r",init=rep(0,q))
   N1=length(re)
   resi=re[(P*sea+1):N1]
   if(P > 0){
     for (j in 1:P){
      resi=resi-Phi[j]*re[(P*sea+1-j*sea):(N1-j*sea)]
      }
     }
    if(Q > 0){
     f1=rep(0,sea*Q)
     for (j in 1:Q){
      f1[j*sea]=Theta[j]
      }
     resi=filter(resi,f1,method="r",init=rep(0,sea*Q))
    }
   Gaulike = resi
 }

### Obtain the N(t) series
 Nts <- function(par,dY=dY,dX=dX,dX2=dX2,dW=dW,dC=dC,order1=order1,order2=order2){
   r=order1[1]; s=order1[2]; b=order1[3]
   r2=order2[1]; s2=order2[2]; b2=order2[3]
   c0=par[1]
   ome=par[2:(2+s)]
   icnt=2+s
   #
   if(r > 0){del=par[(2+s+1):(2+s+r)]
             icnt=2+s+r
            }
   if(!is.null(dC)){c1=par[icnt+1]
                   icnt=icnt+1
                  }
   if(!is.null(dW)){c2=par[icnt+1]
                   icnt=icnt+1
                 }
   if(!is.null(dX2)){
              ome2=par[(icnt+1):(icnt+1+s2)]
              icnt=icnt+1+s2
        if(r2 > 0){
             del2=par[(icnt+1):(icnt+r2)]
             icnt=icnt+r2
             }
        }
   N=length(dY)
   N1t=dY-c0
   Nt=dX
   if(r > 0){
     Nt=filter(dX,del,method="r",init=rep(mean(dX),r))
    }
   ##
   ist=max(b+s+1,b2+s2+1)
   N=length(Nt)
   N1t=N1t[ist:N]-ome[1]*Nt[(ist-b):(N-b)]
   if(s > 0){
      for (j in 1:s){
         N1t=N1t-ome[j+1]*Nt[(ist-j-b):(N-j-b)]
        }
     }
   if(!is.null(dC))N1t=N1t-c1*dC[ist:N]
   if(!is.null(dW)){N1t=N1t-c2*dW[ist:N]}
   if(!is.null(dX2)){
     Zt=dX2
     if(r2 > 0){
       Zt=filter(Zt,del2,method="r",init=rep(mean(dX2),r2))
       }
      N1t=N1t - ome2[1]*Zt[(ist-b2):(N-b2)]
      if(s2 > 0){
        for (j in 1:s2){
         N1t=N1t-ome2[j+1]*Zt[(ist-b2-j):(N-b2-j)]
         }
        }
     }
   Nts=N1t
  }
####
   ## r = 0 && r2=0, the model can be fitted by the regular "arima" command.
   if((r==0) && (r2==0)){
      ist=max(s+b,s2+b2)+1
      nobe=N-ist+1
      Y=dY[ist:N]
      X=dX[(ist-b):(N-b)]
      if(s > 0){
         for (j in 1:s){
            X=cbind(X,dX[(ist-b-j):(N-b-j)])
         }
      }
      if(!is.null(dC)){X=cbind(X,dC[ist:N])}
      if(!is.null(dW)){X=cbind(X,dW[ist:N])}
      if(!is.null(dX2)){
         X=cbind(X,dX2[(ist-b2):(N-b2)])
         if(s2 > 0){
           for (j  in 1:s2){
             X=cbind(X,dX2[(ist-b2-j):(N-b2-j)])
             }
            }
        }
      X=as.matrix(X)
      if(max(P,Q) > 0){
       m1=arima(Y,order=c(p,0,q),seasonal=list(order=c(P,0,Q),period=sea),xreg=X)
       }
       else{
        m1=arima(Y,order=c(p,0,q),xreg=X)
      }
     est=m1$coef; sigma2=m1$sigma2; residuals=m1$residuals; varcoef=m1$var.coef
#### Changing the sign of the MA coefficients, if any.
     if(q > 0){
      for (j in 1:q){
       loc=p+j
       est[loc]=-est[loc]
       }
      }
     if(Q > 0){
       for (j in 1:Q){
        loc=p+q+P+j
        est[loc]=-est[loc]
        }
      }
#### re-ordering the estimate for computing Nt series
     jcnt=p+q+P+Q+1
     est1=c(est[jcnt:(jcnt+ncol(X))],est[1:(jcnt-1)])
###
      nx=dim(X)[2]
      se=sqrt(diag(m1$var.coef))
      coef.arma=NULL
      se.arma=NULL
      pq=p+q
      if(pq > 0){
         coef.arma=est[1:pq]
         se.arma=se[1:pq]
         p1=cbind(coef.arma,se.arma)
         cat("Regular ARMA coefficients & s.e.:","\n")
         print(t(p1),digits=3)
         if(p > 0)phi=coef.arma[1:p]
         if(q > 0)theta=coef.arma[(p+1):pq]
      }
      PQ=P+Q
      if(PQ > 0){
       coef.sea=est[(pq+1):(pq+PQ)]
       se.sea=se[(pq+1):(pq+PQ)]
       psea=cbind(coef.sea,se.sea)
       cat("Seasonal ARMA coefficients & s.e.: ","\n")
       print(t(psea),digits=3)
       if(P > 0)Phi=coef.sea[1:P]
       if(Q > 0)Theta=coef.sea[(P+1):PQ]
      }
      icnt=pq+PQ
      v=est[(icnt+1):(icnt+1+nx)]
      se.v=se[(icnt+1):(icnt+1+nx)]
      pr=cbind(v,se.v)
      cat("Transfer function coefficients & s.e.:","\n")
      print(t(pr),digits=3)
      cat("Sigma-square & sigma: ",c(sigma2,sqrt(sigma2)),"\n")
      omega=v[1:(s+1)]
      kcnt=s+1
      if(!is.null(dC))kcnt=kcnt+1
      if(!is.null(dW))kcnt=kcnt+1
      Omega=v[(kcnt+1):nx]
   est=est1
   }
   else{
      ist=max(r,s)+1+b
      ist1=max(r2,s2)+1+b2
      ist=max(ist,ist1)
      par=c(mean(dY[ist:N]))
      par=c(par,rep(0.1,s+1))
      par=c(par,rep(0.1,r))
      if(!is.null(dC))par=c(par,.01)
      if(!is.null(dW))par=c(par,.1)
      if(!is.null(dX2)){
       par=c(par,rep(0.1,s2+1))
       par=c(par,rep(0.1,r2))
       }
      if(p > 0)par=c(par,rep(0.1,p))
      if(q > 0)par=c(par,rep(0.01,q))
      if(P > 0)par=c(par,rep(0.01,P))
      if(Q > 0)par=c(par,rep(0.01,Q))
      m11=nlm(Nlike,par,hessian=TRUE,dY=dY,dX=dX,dX2=dX2,dW=dW,dC=dC,orderN=orderN,orderS=orderS,sea=sea,order1=order1,order2=order2)
      est=m11$estimate
      varcoef=solve(m11$hessian)
      se=sqrt(diag(varcoef))
      residuals=Gaulike(est,dY=dY,dX=dX,dX2=dX2,dW=dW,dC=dC,orderN=orderN,orderS=orderS,sea=sea,order1=order1,order2=order2)
      sigma2=var(residuals)
      pq=p+q
      PQ=P+Q
      icnt=1+s+1+r
      v=est[1:icnt]
      se.v=se[1:icnt]
      pr=cbind(v,se.v)
      cat("First exogenous variable: ","\n")
      cat("Delay: ",b,"\n")
      cat("Transfer function coefficients & s.e.:","\n")
      cat("in the order: constant, omega, and delta:",c(1,s+1,r),"\n")
      print(t(pr),digits=3)
      cnst=v[1]
      omega=v[2:(s+2)]
      if(r > 0)delta=v[(s+3):icnt]
      if(!is.null(dC)){icnt=icnt+1
       cat("co-integrated coefficient & se: ",c(est[icnt],se[icnt]),"\n")
       }
      if(!is.null(dW)){icnt=icnt+1
        cat("Co-integration coefficient & se: ",c(est[icnt],se[icnt]),"\n")
         }
      if(!is.null(dX2)){
       jcnt=1+s2+r2
       v=est[(icnt+1):(icnt+jcnt)]
       se.v=se[(icnt+1):(icnt+jcnt)]
       pr=cbind(v,se.v)
       cat("Second exogenous variable: ","\n")
       cat("Delay: ",b2,"\n")
       cat("The transfer function coefficients & s.e.:","\n")
       cat("in the order: omega2 and delta2: ",c(s2+1,r2),"\n")
       print(t(pr),digits=3)
       Omega=v[1:(s2+1)]
       if(r2 > 0)Delta=v[(2+s2):jcnt]
       icnt=icnt+jcnt
      }
      if(pq > 0){
         coef.arma=est[(icnt+1):(icnt+pq)]
         se.arma=se[(icnt+1):(icnt+pq)]
         p1=cbind(coef.arma,se.arma)
         cat("Regular ARMA order:","\n")
         print(c(p,dify,q))
         cat("Regular ARMA coefficients & s.e.:","\n")
         print(t(p1),digits=3)
         icnt=icnt+pq
         if(p > 0)phi=coef.arma[1:p]
         if(q > 0)theta=coef.arma[(p+1):pq]
        }
      if(PQ > 0){
        coef.sea=est[(icnt+1):(icnt+PQ)]
        se.sea=se[(icnt+1):(icnt+PQ)]
        ps=cbind(coef.sea,se.sea)
        cat("Seasonal ARMA order: ","\n")
        print(c(P,difys,Q))
        cat("Seasonal ARMA coefficients & s.e.: ","\n")
        print(t(ps),digits=3)
        if(P > 0)Phi=coef.sea[1:P]
        if(Q > 0)Theta=coef.sea[(P+1):PQ]
       }
    cat("Sigma-square & sigma: ",c(sigma2,sqrt(sigma2)),"\n")
   }
#
   Nt <- Nts(est,dY=dY,dX=dX,dX2=dX2,dW=dW,dC=dC,order1=order1,order2=order2)

   tfm2 <- list(estimate=est,sigma2=sigma2,residuals=residuals,varcoef=varcoef,Nt=Nt,rAR=phi,rMA=theta,sAR=Phi,sMA=Theta,
omega=omega,delta=delta,omega2=Omega,delta2=Delta)
}

### Back-testing
"Btfm2" <- function(y,x,x2=NULL,wt=NULL,ct=NULL,orderN=c(1,0,0),orderS=c(0,0,0),sea=12,order1=c(0,1,0),order2=c(0,-1,0),orig=(length(y)-1)){
err=NULL
r=order1[1]; s=order1[2]; b=order1[3]
r2=order2[1]; s2=order2[2]; b2=order2[3]
p = orderN[1]; dify=orderN[2]; q=orderN[3]
P = orderS[1]; difys=orderS[2]; Q=orderS[3]
dY=y; dX=x; dX2=x2; dW=wt; dC=ct
if(dify > 0){
      dY <- y[(dify+1):length(y)]-y[1:(length(y)-dify)]
      dX <- x[(dify+1):length(x)]-x[1:(length(x)-dify)]
      if(!is.null(x2)){
        dX2 <- x2[(dify+1):length(x2)]-x2[1:(length(x2)-dify)]
        }
      if(!is.null(wt)){
        dW <- wt[(dify+1):length(wt)] - wt[1:(length(wt)-dify)]
        }
      if(!is.null(ct)){
        dC <- ct[(dify+1):length(ct)] - ct[1:(length(ct)-dify)]
       }
    }
if(difys > 0){
      lags=difys*sea
      dY <- dY[(lags+1):length(dY)]-dY[1:(length(dY)-lags)]
      dX <- dX[(lags+1):length(x)]-dX[1:(length(dX)-lags)]
      if(!is.null(x2)){
        dX2 <- dX2[(lags+1):length(dX2)]-dX2[1:(length(dX2)-lags)]
        }
      if(!is.null(wt)){
        dW <- dW[(lags+1):length(dW)] - dW[1:(length(dW)-lags)]
        }
      if(!is.null(ct)){
        dC <- dC[(lags+1):length(dC)] - dC[1:(length(dC)-lags)]
       }
    }
   N = length(dY); N1=length(dX)
   N=min(N,N1)
   if(length(dX2) > 0)N=min(N,length(dX2))
   if(length(dW) > 0) N=min(N,length(dW))
   if(length(dC) > 0) N=min(N,length(dC))
   orig=orig-dify-difys*sea
## function to perform prediction: 1-step ahead only
###
fore1 <- function(par,dY=dY,dX=dX,dX2=x2p,dW=wtp,dC=ctp,orderN=orderN,orderS=orderS,sea=sea,order1=order1,order2=order2,resi=resi){
   p=orderN[1]; q=orderN[3]; r=order1[1]; s=order1[2]; b=order1[3]
   r2=order2[1]; s2=order2[2]; b2=order2[3]; P=orderS[1]; Q=orderS[3]
   c0=par[1]
   ome=par[2:(2+s)]
   #
   if(r > 0)del=par[(2+s+1):(2+s+r)]
   icnt=2+s+r
   if(!is.null(dC)){c1=par[icnt+1]
                  icnt=icnt+1
                  }
   if(!is.null(dW)){c2=par[icnt+1]
                   icnt=icnt+1
                   }
   if(!is.null(dX2)){
          ome2=par[(icnt+1):(icnt+1+s2)]
          icnt=icnt+1+s2
          if(r2 > 0){del2=par[(icnt+1):(icnt+r2)]
                      icnt=icnt+r2
                    }
          }
   if(p > 0){phi=par[(icnt+1):(icnt+p)]
             icnt=icnt+p
             }
   if(q > 0){theta=par[(icnt+1):(icnt+q)]
            icnt=icnt+q
            }
   if(P > 0){Phi=par[(icnt+1):(icnt+P)]
             icnt=icnt+P
            }
   if(Q > 0){Theta=par[(icnt+1):(icnt+Q)]
            }
   N=length(dY)
   tmp=dY-c0
   Nt = dX
   if(r > 0){
     Nt=filter(dX,del,method="r",init=rep(mean(dX),r))
     }
   if(b == 0){
     tmp=tmp-ome[1]*Nt
     }else{
     tmp=tmp-ome[1]*c(rep(0,b),Nt[1:(N-b)])
     }
   if(s > 0){
    for (j in 1:s){
     tmp=tmp-ome[j+1]*c(rep(0,b+j),Nt[1:(N-b-j)])
     }
    }
   if(!is.null(dC))tmp=tmp-c1*dC
   if(!is.null(dW))tmp=tmp-c2*dW
   if(!is.null(dX2)){
    Zt=dX2
    if(r2 > 0){
     Zt=filter(dX2,del2,method="r",init=rep(mean(dX2),r2))
     }
    tmp=tmp-ome2[1]*c(rep(0,b2),Zt[1:(N-b2)])
    if(s2 > 0){
       for (j in 1:s2){
        tmp=tmp-ome2[j+1]*c(rep(0,j+b2),Zt[1:(N-j-b2)])
        }
       }
    }
### The next step is for prediction, starting with exogenous variables at time t+1.
   pred=dY[N]-tmp[N]
   if(p > 0){
    for (j in 1:p){
     pred=pred+phi[j]*tmp[N-j]
     }
    }
   if(P > 0){
     for (j in 1:P){
      pred=pred+Phi[j]*tmp[N-j*sea]
      }
     }
   if((p > 0)&&(P > 0)){
     for (j in 1:P){
       j1=j*sea
       for (i in 1:p){
        pred=pred-Phi[j]*phi[i]*tmp[N-j1-i]
        }
       }
     }
   if(q > 0){
     for (j in 1:q){
      pred=pred-theta[j]*resi[length(resi)+1-j]
      }
     }
    if(Q > 0){
     for (j in 1:Q){
       pred=pred-Theta[j]*resi[length(resi)+1-j*sea]
       }
      }
   if((q > 0)&&(Q > 0)){
     for (j in 1:Q){
      j1=j*sea
      for (i in 1:q){
       pred=pred+Theta[j]*theta[i]*resi[length(resi)+1-i-j1]
       }
      }
    }
   err=dY[N]-pred
   err
}
###
nT=length(dY)
if(nT > orig){
### Estimation
for (it in orig:(nT-1)){
  x2p=NULL; wtp=NULL; ctp = NULL
  if(!is.null(x2))x2p=dX2[1:it]
  if(!is.null(wt))wtp=dW[1:it]
  if(!is.null(ct))ctp=dC[1:it]
  m1 = tfm2(dY[1:it],dX[1:it],x2=x2p,wt=wtp,ct=ctp,orderN=orderN,orderS=orderS,sea=sea,order1=order1,order2=order2)
  par=m1$estimate
  Tp1=it+1
  resi=m1$residuals
  nr=length(resi)
  if(nr < it){
   resi=c(rep(0,it-nr),resi)
  }
### prediction via computing the residuals
 x2p=NULL; wtp=NULL; ctp=NULL
 if(!is.null(x2))x2p=dX2[1:Tp1]
 if(!is.null(wt))wtp=dW[1:Tp1]
 if(!is.null(ct))ctp=dC[1:Tp1]
 error = fore1(par,dY=dY[1:Tp1],dX=dX[1:Tp1],dX2=x2p,dW=wtp,dC=ctp,orderN=orderN,orderS=orderS,sea=sea,order1=order1,order2=order2,resi=resi)
##
 err=c(err,error)
 }
}
 bias=mean(err); nf=length(err)
 mse=mean(err^2); mae=mean(abs(err))
 rmse=sqrt(mse)
 cat("Forecast origin & number of forecasts: ",c(orig,nf),"\n")
 cat("bias,  mse, rmse & MAE: ",c(bias, mse,rmse, mae),"\n")
 Btfm2 <- list(ferror=err,mse=mse,rmse=rmse,mae=mae,nobf=nf)
}

####
"VARchi" <- function(x,p=1,include.mean=T,thres=1.645){
   # Fits a vector AR(p) model, then performs
   # a chi-square test to zero out insignificant parameters.
   if(!is.matrix(x))x=as.matrix(x)
   Tn=dim(x)[1]
   k=dim(x)[2]
   if(p < 1)p=1
   ne=Tn-p
   ist=p+1
   y=x[ist:Tn,]
   if(include.mean){
      xmtx=cbind(rep(1,ne),x[p:(Tn-1),])
   }
   else {
      xmtx=x[p:(Tn-1),]
   }
   if(p > 1){
      for (i in 2:p){
         xmtx=cbind(xmtx,x[(ist-i):(Tn-i),])
      }
   }
   #
   #perform estimation
   ndim=dim(xmtx)[2]
   res=NULL
   xm=as.matrix(xmtx)
   xpx=crossprod(xm,xm)
   xpxinv=solve(xpx)
   xpy=t(xm)%*%as.matrix(y)
   beta=xpxinv%*%xpy
   resi=y-xm%*%beta
   sse=t(resi)%*%resi/(Tn-p-ndim)
   C1=kronecker(sse,xpxinv)
   dd=sqrt(diag(C1))
   #
   bhat=c(beta)
   tratio=bhat/dd
   para=cbind(bhat,dd,tratio)
   npar=length(bhat)
   K=NULL
   omega=NULL
   for (i in 1:npar){
      if(abs(tratio[i]) < thres){
         idx=rep(0,npar)
         idx[i]=1
         K=rbind(K,idx)
         omega=c(omega,bhat[i])
      }
   }
   v=dim(K)[1]
   K=as.matrix(K)
   cat("Number of targeted parameters: ",v,"\n")
   #####print(K)
   if(v > 0){
      C2=K%*%C1%*%t(K)
      C2inv=solve(C2)
      tmp=C2inv%*%as.matrix(omega,v,1)
      chi=sum(omega*tmp)
      pvalue=1-pchisq(chi,v)
      cat("Chi-square test and p-value: ",c(chi,pvalue),"\n")
   }
   else{
      print("No contraints needed")
   }
   VARchi<-list(data=x,cnst=include.mean,order=p,coef=beta,constraints=K,omega=omega,covomega=C2)
}

###
"FEVdec" <- function(Phi,Theta,Sig,lag=4){
   # Perform forecast error vcovariance decomposition
   #
   # Phi: k by kp matrix of AR coefficients, i.e. [AR1,AR2,AR3, ..., ARp]
   # Theta: k by kq matrix of MA coefficients, i.e. [MA1,MA2, ..., MAq]
   # Sig: residual covariance matrix
   # Output: (a) Plot and (b) Decomposition
   if(length(Phi) > 0){
      if(!is.matrix(Phi))Phi=as.matrix(Phi)
     }
   if(length(Theta) > 0){
      if(!is.matrix(Theta))Theta=as.matrix(Theta)
     }
   if(!is.matrix(Sig))Sig=as.matrix(Sig)
   if(lag < 1) lag=1
   # Compute MA representions: This gives impulse response function without considering Sigma.
   p = 0
   if(length(Phi) > 0){
      k=nrow(Phi)
      m=ncol(Phi)
      p=floor(m/k)
    }
   q=0
   if(length(Theta) > 0){
      k=dim(Theta)[1]
      m=dim(Theta)[2]
      q=floor(m/k)
    }
   cat("Order of the ARMA mdoel: ","\n")
   print(c(p,q))
   # Consider the MA part to psi-weights
   Si=diag(rep(1,k))
   if(q > 0){
      Si=cbind(Si,-Theta)
    }
   m=(lag+1)*k
   m1=(q+1)*k
   if(m > m1){
      Si=cbind(Si,matrix(0,k,(m-m1)))
    }
   #
   if (p > 0){
      for (i in 1:lag){
         if (i <= p){
            idx=(i-1)*k
            tmp=Phi[,(idx+1):(idx+k)]
         }
         else{
            tmp=matrix(0,k,k)
         }
         #
         jj=i-1
         jp=min(jj,p)
         if(jp > 0){
            for(j in 1:jp){
               jdx=(j-1)*k
               idx=(i-j)*k
               w1=Phi[,(jdx+1):(jdx+k)]
               w2=Si[,(idx+1):(idx+k)]
               tmp=tmp+w1%*%w2
               ##print(tmp,digits=4)
            }
         }
         kdx=i*k
         Si[,(kdx+1):(kdx+k)]=tmp
         ## end of i loop
      }
      ## end of (p > 0)
     }
   # Compute the impulse response of orthogonal innovations
   orSi=NULL
   m1=chol(Sig)
   P=t(m1)
   orSi=P
   for(i in 1:lag){
      idx=i*k
      w1=Si[,(idx+1):(idx+k)]
      w2=w1%*%P
      orSi=cbind(orSi,w2)
   }
   #### Compute the covariance matrix of forecast errors
   orSi2=orSi^2
   ##### compute the partial sum (summing over lags)
   Ome=orSi2[,1:k]
   wk=Ome
   for (i in 1:lag){
      idx=i*k
      wk=wk+orSi2[,(idx+1):(idx+k)]
      Ome=cbind(Ome,wk)
   }
   FeV=NULL
   ##
   OmeRa = Ome[,1:k]
   FeV=cbind(FeV,apply(OmeRa,1,sum))
   OmeRa = OmeRa/FeV[,1]
   for (i in 1:lag){
      idx=i*k
      wk=Ome[,(idx+1):(idx+k)]
      FeV=cbind(FeV,apply(wk,1,sum))
      OmeRa=cbind(OmeRa,wk/FeV[,(i+1)])
     }
   cat("Standard deviation of forecast error: ","\n")
   print(sqrt(FeV))
   #
   cat("Forecast-Error-Variance Decomposition","\n")
   for (i in 1:(lag+1)){
      idx=(i-1)*k
      cat("Forecast horizon: ",i,"\n")
      Ratio=OmeRa[,(idx+1):(idx+k)]
      print(Ratio)
    }
   FEVdec <- list(irf=Si,orthirf=orSi,Omega=Ome,OmegaR=OmeRa)
  }

####
"mFilter" <- function(da,Wgt,init=NULL){
   # Multivariate filtering algorithm: using the nagative pi-weights
   ## (i+pi1 B + pi2 B^2 + ....)z_t = a_t.
   # Created by Ruey S. Tsay in April 2012.
   #
   # Wgt=[Theta1, Theta2,..., Thetaq]
   # Filered data = a_t - Theta1 *a_{t-1} - ... - Thetaq * a_{t-q}.
   #
   if(!is.matrix(da))da=as.matrix(da)
   if(!is.matrix(Wgt))Wgt=as.matrix(Wgt)
   if(length(init) > 0)init=as.matrix(init)
   #
   #### set up the data matrix for filtering
   ### In mFilter
   ##cat("in mFilter: ","\n")
   ##print(Wgt)

   nT=dim(da)[1]
   k=dim(da)[2]
   if(k == 1){
      q=length(Wgt)
      Wgt=matrix(Wgt,1,q)
   }
   else{
      m=dim(Wgt)[2]
      q=floor(m/k)
   }
   if(length(init) < 0){
      nit = 0
      x=da}
   else{
      nit=dim(init)[1]
      x=rbind(init,da)
   }
   if(k == 1) x=matrix(x,length(x),1)
   # obtain the nagative pi-weights
   Npi = diag(rep(1,k))
   Npi = cbind(Wgt[,1:k],Npi)
   TT=dim(x)[1]
   ####
   for (i in 2:(TT-1)){
      kend=min(q,i)
      if(k == 1){
         tmp=0
         for (j in 1:kend){
            jdx=j-1
            w1=Npi[jdx+1]
            w2=Wgt[jdx+1]
            tmp=tmp+w1*w2
         }
         Npi=c(tmp,Npi)
      }
      else{
         tmp=matrix(0,k,k)
         for (j in 1:kend){
            jdx=(j-1)*k
            w1=Npi[,(jdx+1):(jdx+k)]
            w2=Wgt[,(jdx+1):(jdx+k)]
            tmp=tmp+w1%*%w2
         }
         Npi=cbind(tmp,Npi)
      }
      #
   }
   T1=dim(Npi)[2]
   Wrk=c(t(x))
   T2=length(Wrk)
   At=NULL
   for (it in 1:nT){
      mk=(it-1)*k
      wk3=Npi[,(mk+1):T1]%*%Wrk[1:(T2-mk)]
      At=rbind(t(wk3),At)
      ##if(it < 4)print(At)
   }
   At
 }


#### Exact likelihood VMA programs
"VMAe" <- function(da,q=1,include.mean=T,coef0=NULL,secoef0=NULL,fixed=NULL,prelim=F,details=F,thres=2.0){
   # Estimation of a vector MA model using EXACT MLE (Gaussian dist)
   ### coef0 and secoef0 are the initial estimates and their standard errors (mainly from the conditional estimates).
   #
   if(!is.matrix(da))da=as.matrix(da)
   nT=dim(da)[1]
   k=dim(da)[2]
   if(q < 1)q=1
   kq=k*q
   #
 THini <- function(y,x,q,include.mean){
   # use residuals of a long VAR model to obtain initial estimates of
   # VMA coefficients.
   if(!is.matrix(y))y=as.matrix(y)
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(y)[1]
   k=dim(y)[2]
   ist=1+q
   ne=nT-q
   if(include.mean){
      xmtx=matrix(1,ne,1)
   }
   else {
      xmtx=NULL
   }
   ymtx=y[ist:nT,]
   for (j in 1:q){
      xmtx=cbind(xmtx,x[(ist-j):(nT-j),])
   }
   #xtx=t(xmtx)%*%xmtx
   xtx=crossprod(xmtx,xmtx)
   #xty=t(xmtx)%*%ymtx
   xty=crossprod(xmtx,ymtx)
   xtxinv=solve(xtx)
   beta=xtxinv%*%xty
   resi= ymtx - xmtx%*%beta
   sse=crossprod(resi,resi)/ne
   dd=diag(xtxinv)
   sebeta=NULL
   for (j in 1:k){
      se=sqrt(dd*sse[j,j])
      sebeta=cbind(sebeta,se)
   }
    THini <- list(estimates=beta,se=sebeta)
  }
##
   if(length(coef0) < 1){
      # Obtain initial parameter estimates if necessary
      ### Use VAR approximation to obtain initial parameter estimates
      m1=VARorder(da,q+12,output=FALSE)
      porder=m1$aicor
      if(porder < 1)porder=1
      m2=VAR(da,porder,output=FALSE)
      y=da[(porder+1):nT,]
      x=m2$residuals
      m3=THini(y,x,q,include.mean)
      beta=-m3$estimates
      sebeta=m3$se
      nr=dim(beta)[1]
      if(include.mean){
         beta[1,]=-beta[1,]
      }
      ### Preliminary simplification
      if(prelim){
         fixed = matrix(0,nr,k)
         for (j in 1:k){
            tt=beta[,j]/sebeta[,j]
            idx=c(1:nr)[abs(tt) >= thres]
            fixed[idx,j]=1
         }
      }
      ## end initial estimation
   }
   else {
      beta=coef0
      sebeta=secoef0
      nr=dim(beta)[1]
   }
   #
   if(length(fixed)==0){fixed=matrix(1,nr,k)}
   #
   par=NULL
   separ=NULL
   #
   VMAecnt = 0
   ist=0
   if(include.mean){
      jdx=c(1:k)[fixed[1,]==1]
      VMAecnt=length(jdx)
      if(VMAecnt > 0){
         par=beta[1,jdx]
         separ=sebeta[1,jdx]
      }
      TH=beta[2:(kq+1),]
      seTH=sebeta[2:(kq+1),]
      ist=1
   }
   else {
      TH=beta
      seTH=sebeta
   }
   #########
   for (j in 1:k){
      idx=c(1:(nr-ist))[fixed[(ist+1):nr,j]==1]
      if(length(idx) > 0){
         par=c(par,TH[idx,j])
         separ=c(separ,seTH[idx,j])
      }
   }
   ###
   ParE <- par
   cat("Number of parameters: ",length(par),"\n")
   cat("initial estimates: ",par,"\n")
   ### Set up lower and upper bounds
   lowerBounds=par; upperBounds=par
   npar=length(par)
   mult=2.0
   if((npar > 10)||(q > 2))mult=1.5
   if(length(coef0) > 0){
      mult=1.0
   }
   #
   for (j in 1:npar){
      lowerBounds[j] = par[j]-mult*separ[j]
      upperBounds[j] = par[j]+mult*separ[j]
   }
   cat("Par. Lower-bounds: ",lowerBounds,"\n")
   cat("Par. Upper-bounds: ",upperBounds,"\n")
### likelihood function
 EVMAq <- function(par,zt=da,q=q,include.mean=include.mean,fixed=fixed,EstStep=T){
   # The model used is
   ## a_t' = x_t' - mu' + a_{t-1}'theta_1'+a_{t-2}'theta_2' + ....
   k=dim(zt)[2]
   nT=dim(zt)[1]
   #
   mu=rep(0,k)
   icnt=0; VMAecnt <- 0
   ist=0
   if(include.mean){
      ist=1
      jdx=c(1:k)[fixed[1,]==1]
      icnt=length(jdx); VMAecnt <- icnt
      if(icnt > 0)
       mu[jdx]=par[1:icnt]
   }
   ### remove the mean
   for (j in 1:k){
      zt[,j]=zt[,j]-mu[j]
   }
   ## obtain the Theta-matrix
   kq=k*q
   theta=matrix(0,kq,k)
   for (j in 1:k){
      idx=c(1:kq)[fixed[(ist+1):(ist+kq),j]==1]
      jcnt=length(idx)
      if(jcnt > 0){
         theta[idx,j]=par[(icnt+1):(icnt+jcnt)]
         icnt=icnt+jcnt
      }
   }
   # theta = rbind[theta_1',theta_2', ..., theta_q']
   theta=t(theta)
   ### Check for invertibility before applying mFilter
   ### If necessary, set up the expanded VMA(1) model and data.
   k1=dim(theta)[2]
   Theta=theta[,1:k]
   Zt=zt
   est=NULL
   if(q > 1){
      z0=cbind(diag(1,k*(q-1)),matrix(0,k*(q-1),k))
      Theta=rbind(theta,z0)
      Zt=cbind(zt,matrix(0,nT,k*(q-1)))
   }
   m1=eigen(Theta)
   V1=m1$values
   M1=Mod(V1)
   ich=0
   for (i in 1:k1){
      if(M1[i] > 1){
         V1[i]=1/V1[i]
         ich=1
      }}
   if(ich > 0){
      ###cat("Eigenvalue detection occurred","\n")
      P1=m1$vectors
      P1i=solve(P1)
      Theta=Re(P1%*%diag(V1)%*%P1i)
      ##print(Theta)
      ## Replace the re-normalized parameters
      beta=t(Theta[1:k,])
      ist=0; nr=kq;
      if(include.mean){
         ist=1
         nr=kq+1
      }
      #########
      for (j in 1:k){
         idx=c(1:k1)[fixed[(ist+1):nr,j]==1]
         if(length(idx) > 0){
            est=c(est,beta[idx,j])
         }
      }
 ##     par=est
   }
   #### DO not need to repace parameter estimate in evaluating Hessian
   if(EstStep){
      if(VMAecnt > 0){
         par = c(par[1:VMAecnt],est)
       }
      else {
         par = est
       }
    }
   ##
   theta=Theta[1:k,]
   at=mFilter(zt,theta)
   sig=t(at)%*%at/nT
   ## Obtain the square-root matrix of Sigma
   sig=(sig+t(sig))/2
   m1=eigen(sig)
   va=m1$values+10^(-10)
   VA=diag(1/sqrt(va))
   P=m1$vectors
   SigH=P%*%VA%*%t(P)
   if(q > 1)SigH=kronecker(diag(rep(1,q)),SigH)
   ##### k1 is the dimension of the expanded VMA(1) model when q > 1.
   k1= k*q
   #### Obtain the pi-wights (negative) for VMA(1) model
   ##### In the process, also obtain the X-tilde matrix
   Psi=diag(rep(1,k1))
   Psi=cbind(Theta,Psi)
   tmp=Theta
   X=-SigH
   tmp1=-SigH%*%tmp
   X=rbind(X,tmp1)
   if(nT > 2){
      for (i in 2:nT){
         tmp=tmp%*%Theta
         Psi=cbind(tmp,Psi)
         tmp1=-SigH%*%tmp
         X=rbind(X,tmp1)
      }
      # end of the statement if(nT > 2)
   }
   ## Obtain the intial estimate
   vZt=c(t(Zt))
   Y=rep(0,k1)
   nPsi=dim(Psi)[2]
   for (it in 1:nT){
      iend=it*k1
      wk1=vZt[1:iend]
      wk2=Psi[,(nPsi-iend+1):nPsi]
      wk=wk2%*%as.matrix(wk1,iend,1)
      Y=c(Y,SigH%*%wk)
   }
   XpX=crossprod(X,X)
   XpY=crossprod(X,Y)
   a0H=solve(XpX,XpY)
   resi=Y-X%*%a0H
   SSr=sum(resi^2)
   d1=det(XpX)
   d2=det(sig)
   llike=0.5*(SSr + nT*log(2*pi*d2) + log(d2))
   llike
  }

  # Step 5: Estimate Parameters and Compute Numerically Hessian:
   if(details){
      fit = nlminb(start = ParE, objective = EVMAq, zt=da,q=q,include.mean=include.mean,fixed=fixed,
                lower = lowerBounds, upper = upperBounds, control = list(trace=3))}
   else{
      fit = nlminb(start = ParE, objective = EVMAq, zt=da,q=q,include.mean=include.mean,fixed=fixed,
       control=list(step.min=0.4,step.max=0.8), lower = lowerBounds, upper = upperBounds)
     }
   #
   est=fit$par
   ###
   ################### Checking for invertibility of the fitted VMA models.
   zt = da
   ist=0
   mu=rep(0,k)
   icnt=0
   if(include.mean){
      ist=1
      jdx=c(1:k)[fixed[1,]==1]
      icnt=length(jdx)
      if(icnt > 0)
      mu[jdx]=est[1:icnt]
   }
   ### remove the mean
   for (j in 1:k){
      zt[,j]=zt[,j]-mu[j]
   }
   ## obtain the Theta-matrix
   theta=matrix(0,kq,k)
   for (j in 1:k){
      idx=c(1:kq)[fixed[(ist+1):(ist+kq),j]==1]
      jcnt=length(idx)
      if(jcnt > 0){
         theta[idx,j]=est[(icnt+1):(icnt+jcnt)]
         icnt=icnt+jcnt
      }
   }
   # theta = rbind[theta_1',theta_2', ..., theta_q']
   theta=t(theta)
   ### Check for invertibility of the final estimates
   ### If necessary, set up the expanded VMA(1) model and data.
   k1=dim(theta)[2]
   Theta=theta[,1:k]
   Zt=zt
   if(q > 1){
      z0=cbind(diag(1,k*(q-1)),matrix(0,k*(q-1),k))
      Theta=rbind(theta,z0)
      Zt=cbind(zt,matrix(0,nT,k*(q-1)))
   }
   m1=eigen(Theta)
   V1=m1$values
   M1=Mod(V1)
   ich=0
   for (i in 1:k1){
      if(M1[i] > 1){
         V1[i]=1/V1[i]
         ich=1
      }}
   est1=NULL
   if(VMAecnt >0) est1=est[1:VMAecnt]
   if(ich > 0){
      ###cat("Eigenvalue detection occurred","\n")
      P1=m1$vectors
      P1i=solve(P1)
      Theta=Re(P1%*%diag(V1)%*%P1i)
      ##print(Theta)
      ## Replace the re-normalized parameters
      beta=t(Theta[1:k,])
      ist=0; nr=kq
      if(include.mean){
         ist=1
         nr=kq+1
      }
      #########
      for (j in 1:k){
         idx=c(1:k1)[fixed[(ist+1):nr,j]==1]
         if(length(idx) > 0){
            est1=c(est1,beta[idx,j])
         }
      }
      est=est1
   }
   ### The above steps of checking invertibility were added on April 22, 2012.
   cat("Final   Estimates: ",est,"\n")
   epsilon = 0.0001 * est
   npar=length(par)
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] = (EVMAq(x1,zt=da,q=q,include.mean=include.mean,fixed=fixed,EstStep=F)
                         -EVMAq(x2,zt=da,q=q,include.mean=include.mean,fixed=fixed,EstStep=F)
                         -EVMAq(x3,zt=da,q=q,include.mean=include.mean,fixed=fixed,EstStep=F)
                         +EVMAq(x4,zt=da,q=q,include.mean=include.mean,fixed=fixed,EstStep=F))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   # Step 6: Create and Print Summary Report:
   se.coef = sqrt(diag(solve(Hessian)))
   tval = est/se.coef
   matcoef = cbind(est, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)
   #
   ### recover to the format of unconstrained case for printing purpose.
   cat("---","\n")
   cat("Estimates in matrix form:","\n")
   icnt=0
   ist=0
   cnt=NULL
   if(include.mean){
      ist=1
      cnt=rep(0,k)
      secnt=rep(1,k)
      jdx=c(1:k)[fixed[1,]==1]
      icnt=length(jdx)
      if(icnt > 0){
         cnt[jdx]=est[1:icnt]
         secnt[jdx]=se.coef[1:icnt]
         cat("Constant term: ","\n")
         cat("Estimates: ",cnt,"\n")
      }
   }
   cat("MA coefficient matrix","\n")
   TH=matrix(0,kq,k)
   seTH=matrix(1,kq,k)
   for (j in 1:k){
      idx=c(1:kq)[fixed[(ist+1):nr,j]==1]
      jcnt=length(idx)
      if(jcnt > 0){
         TH[idx,j]=est[(icnt+1):(icnt+jcnt)]
         seTH[idx,j]=se.coef[(icnt+1):(icnt+jcnt)]
         icnt=icnt+jcnt
      }
   }
   icnt=0
   for (i in 1:q){
      cat("MA(",i,")-matrix","\n")
      theta=t(TH[(icnt+1):(icnt+k),])
      print(theta,digits=3)
      icnt=icnt+k
   }
   ## Compute the residuals
   zt=da
   if(include.mean){
      for (i in 1:k){
         zt[,i]=zt[,i]-cnt[i]
      }
   }
   Past=matrix(0,1,kq)
   at=NULL
   for (t in 1:nT){
      tmp=zt[t,]+Past%*%TH
      at=rbind(at,tmp)
      if(q==1){
         Past=tmp
      }
      else{
         Past=c(tmp,Past[1:(kq-k)])
      }
   }
   sig=t(at)%*%at/nT
   cat(" ","\n")
   cat("Residuals cov-matrix:","\n")
   print(sig)
   dd=det(sig)
   d1=log(dd)
   aic=d1+2*npar/nT
   bic=d1+log(T)*npar/nT
   cat("----","\n")
   cat("aic= ",aic,"\n")
   cat("bic= ",bic,"\n")
   ### prepare fot output storage
   Theta=t(TH)
   if(include.mean){
      TH=rbind(cnt,TH)
      seTH=rbind(secnt,seTH)
   }

   VMAe <- list(data=da,MAorder=q,cnst=include.mean,coef=TH,secoef=seTH,residuals=at,Sigma=sig,Theta=Theta,mu=cnt,aic=aic,bic=bic)
 }

"refVMAe" <- function(model,thres=1){
   # This program refines the fitted models of VMA output by removing
   # insigificant parameters with abs(t-ratio) < thres.
   # model: output object from VMA
   x = model$data
   q = model$MAorder
   cnst = model$cnst
   coef=as.matrix(model$coef)
   secoef=as.matrix(model$secoef)
   nr=dim(coef)[1]
   nc=dim(coef)[2]
   for (j in 1:nc){
      for (i in 1:nr){
         if(secoef[i,j] < 10^(-8))secoef[i,j]=1.0
      }
    }
   fix=matrix(0,nr,nc)
   for (j in 1:nc){
      tt=coef[,j]/secoef[,j]
      idx=c(1:nr)[abs(tt) >= thres]
      fix[idx,j]=1
     }
   if(cnst){
      tt=coef[1,]/secoef[1,]
      idx=c(1:nc)[abs(tt) > 1.0]
      if(length(idx) > 0)fix[1,idx]=1
      }
     mm=VMAe(x,q=q,include.mean=cnst,fixed=fix,coef0=coef,secoef0=secoef)
    refVMAe <- list(data=x,MAorder=q,cnst=cnst,coef=mm$coef,secoef=mm$secoef,residuals=mm$residuals,Sigma=mm$Sigma,aic=mm$aic,bic=mm$bic,mu=mm$mu,Theta=mm$Theta)
  }

###
"diffM" <- function(zt,d=1){
   ## taking difference of a vector time series
   ## d: (1-B^d)
   if(!is.matrix(zt))zt=as.matrix(zt)
   nT=dim(zt)[1]
   dzt = zt[(d+1):nT,]-zt[1:(nT-d),]
   dzt
}

##### Psi-weight calculation for a VARMA model.
"PSIwgt" <- function(Phi=NULL,Theta=NULL,lag=12,plot=TRUE,output=FALSE){
   ### Compute the psi-weight matrices of a VARMA(p,q) model,
   #### Phi=[phi1, phi2, ..., phip]
   #### Theta=[theta1,theta2,...,thetaq]
   #### Sigma= residual covariance matrix
   q=0; p=0; k=0
   if(length(Theta) > 0){
      k=dim(Theta)[1]
      k1=dim(Theta)[2]
      q=floor(k1/k)
   }
   #
   if(length(Phi) > 0){
      k=dim(Phi)[1]
      k1=dim(Phi)[2]
      p=floor(k1/k)
   }
   #
   if(k < 1) k=1
   PSI=diag(k); WGT=c(PSI)
   #
   for (il in 1:lag){
      ilk=il*k
      tmp=matrix(0,k,k)
      if((q > 0) && (il <= q))tmp=-Theta[,(ilk-k+1):ilk]
      if(p > 0){
         iend=min(il,p)
         for (j in 1:iend){
            jdx=(il-j)
            kdx=j*k
            tmp=tmp+Phi[,(kdx-k+1):kdx]%*%PSI[,(jdx*k+1):(jdx*k+k)]
         }
         ## end  of p > 0.
      }
      PSI=cbind(PSI,tmp)
      WGT=cbind(WGT,c(tmp))
      ### end of il-loop
   }
   ## print the output if needed
   if(output){
      for (i in 1:lag){
         cat("Lag: ",i," psi-matrix","\n")
         ist=i*k
         print(round(PSI[,(ist+1):(ist+k)],5))
      }
      ## end print
   }
   ## plots the psi-weights
   if(plot){
      tdx=c(1:(lag+1))-1
      par(mfcol=c(k,k),mai=c(0.3,0.3,0.3,0.3))
      gmax=max(WGT)
      gmin=min(WGT)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k^2){
         plot(tdx,WGT[j,],type='l',xlab='lag',ylab='Psiwgt',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,WGT[j,],pch='*',cex=0.8)
         title(main="Psi-weights")
      }
     par(mfcol=c(1,1))
    }
    PSIwgt <- list(psi.weight=PSI,irf=WGT)
  }

##### Pi-weight calculation for a VARMA model.
"PIwgt" <- function(Phi=NULL,Theta=NULL,lag=12,plot=TRUE){
   ### Compute the psi-weight matrices of a VARMA(p,q) model,
   #### Phi=[phi1, phi2, ..., phip]
   #### Theta=[theta1,theta2,...,thetaq]
   #### Sigma= residual covariance matrix
   m1=PSIwgt(Phi=Theta,Theta=Phi,lag=lag,plot=FALSE)
   PImtx=m1$psi.weight
   ###print(PImtx)
   k=dim(PImtx)[1]; nc=dim(PImtx)[2]
   PImtx[,(k+1):nc]=-PImtx[,(k+1):nc]
   lag=floor(nc/k)-1
   WGT=c(diag(k))
   for (i in 1:lag){
      cat("Lag: ",i," pi-matrix","\n")
      ist=(i-1)*k
      WGT=cbind(WGT,c(PImtx[,(ist+1):(ist+k)]))
      print(round(PImtx[,(ist+1):(ist+k)],5))
   }
   ## plots the pi-weights
   if(plot){
      tdx=c(1:(lag+1))-1
      par(mfcol=c(k,k),mai=c(0.3,0.3,0.3,0.3))
      gmax=max(WGT)
      gmin=min(WGT)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k^2){
         plot(tdx,WGT[j,],type='l',xlab='lag',ylab='Piwgt',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,WGT[j,],pch='*',cex=0.8)
         title(main="Pi-weights")
       }
     par(mfcol=c(1,1))
     }
   PIwgt <- list(pi.weight=PImtx)
 }

"VARMAirf" <- function(Phi=NULL,Theta=NULL,Sigma=NULL,lag=12,orth=TRUE){
   #### Phi=[phi1, phi2, ..., phip]
   #### Theta=[theta1,theta2,...,thetaq]
    q=0; p=0; k=0
   if(length(Theta) > 0){
      k=dim(Theta)[1]
      k1=dim(Theta)[2]
      q=floor(k1/k)
   }
   #
   if(length(Phi) > 0){
      k=dim(Phi)[1]
      k1=dim(Phi)[2]
      p=floor(k1/k)
   }
   #
   if(is.null(Sigma)){
      Sigma=diag(rep(1,k))
   }
   #
   if(orth){
      m1=eigen(Sigma)
      v1=sqrt(m1$values)
      vv=diag(v1)
      Pmtx=m1$vectors
      Sh=Pmtx%*%vv%*%t(Pmtx)
   }
   #
   if(k < 1) k=1
   PSI=diag(rep(1,k))
   if(orth){
      WGT=c(PSI%*%Sh)
   }
   else{
      WGT=c(PSI)
   }
   #
   for (il in 1:lag){
      ilk=il*k
      tmp=matrix(0,k,k)
      if((q > 0) && (il <= q))tmp=-Theta[,(ilk-k+1):ilk]
      if(p > 0){
         iend=min(il,p)
         for (j in 1:iend){
            jdx=(il-j)
            kdx=j*k
            tmp=tmp+Phi[,(kdx-k+1):kdx]%*%PSI[,(jdx*k+1):(jdx*k+k)]
         }
         ## end  of p > 0.
      }
      PSI=cbind(PSI,tmp)
      if(orth){
         WGT=cbind(WGT,c(tmp%*%Sh))
      }
      else{
         WGT=cbind(WGT,c(tmp))
      }
      ### end of il-loop
   }
   wk1=WGT
   for (i in 1:k^2){
      wk1[i,] = cumsum(WGT[i,])
   }
   ## plots the psi-weights
   tdx=c(1:(lag+1))-1
   par(mfcol=c(k,k),mai=c(0.3,0.3,0.3,0.3))
   if(orth){
      gmax=max(WGT)
      gmin=min(WGT)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for (j in 1:k^2){
         plot(tdx,WGT[j,],type='l',xlab='lag',ylab='IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,WGT[j,],pch='*',cex=0.8)
         title(main='Orth. innovations')
      }
      cat("Press return to continue ","\n")
      readline()
      gmax=max(wk1)
      gmin=min(wk1)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for (j in 1:k^2){
         plot(tdx,wk1[j,],type='l',xlab='lag',ylab="Acu-IRF",ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,wk1[j,],pch="*",cex=0.8)
         title(main='Orth. innovations')
      }
   }
   else{
      gmax=max(WGT)
      gmin=min(WGT)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k^2){
         plot(tdx,WGT[j,],type='l',xlab='lag',ylab='IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,WGT[j,],pch='*',cex=0.8)
         title(main="Orig. innovations")
      }
      cat("Press return to continue ","\n")
      readline()
      gmax=max(wk1)
      gmin=min(wk1)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k^2){
         plot(tdx,wk1[j,],type='l',xlab='lag',ylab='Acu-IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,wk1[j,],pch='*',cex=0.8)
         title(main="Orig. innovations")
      }
   }
   par(mfcol=c(1,1))
   VARMAirf <- list(psi=PSI,irf=WGT)
 }

"VARMAcov" <- function(Phi=NULL,Theta=NULL,Sigma=NULL,lag=12,trun=120){
   ## trun: trunction point for psi-weights used in the calculation.
   ##
   m1=PSIwgt(Phi=Phi,Theta=Theta,lag=trun,plot=FALSE)
   Psi=m1$psi.weight
   nc=dim(Psi)[2]; k=dim(Psi)[1]
   if(is.null(Sigma)){
      wk=Psi
   }
   else{
      wk=NULL
      for (i in 0:trun){
         ist=i*k
         wk=cbind(wk,Psi[,(ist+1):(ist+k)]%*%Sigma)
      }
      #end of else
   }
   Gam0=wk%*%t(Psi)
   SE=diag(1/sqrt(diag(Gam0)))
   covmtx=Gam0; cormtx=SE%*%Gam0%*%SE
   for (i  in 1:lag){
      ist=i*k
      Gami=wk[,(ist+1):nc]%*%t(Psi[,1:(nc-ist)])
      covmtx=cbind(covmtx,Gami)
      cormtx=cbind(cormtx,SE%*%Gami%*%SE)
   }
   for (i in 0:lag){
      ist=i*k
      cat("Auto-Covariance matrix of lag: ",i,"\n")
      print(round(covmtx[,(ist+1):(ist+k)],5))
   }
   for (i in 0:lag){
      ist=i*k
      cat("cross correlation matrix of lag: ",i,"\n")
      print(round(cormtx[,(ist+1):(ist+k)],4))
   }

   VARMAcov <- list(autocov=covmtx,ccm=cormtx)
}

"Eccm" <- function(zt,maxp=5,maxq=6,include.mean=FALSE,rev=TRUE){
   ### Compute extended cross-correlation matrices using iterated regression
   ### fitting instead of the recursive method.
   #### rev: a switch to compute Q(m) statistics from q to maxq.
   if(!is.matrix(zt))zt=as.matrix(zt)
   x=zt
   nT=dim(x)[1]
   k=dim(x)[2]
   if(include.mean){
      av=apply(x,2,mean)
      for (i in 1:k){
         x[,i]=x[,i]-av[i]
      }
   }
   ksq=k*k
   if(rev){
      maxq1=maxq+1
      m1=revmq(x,maxq1,output=F)
      vEccm=m1$ccm[,1:maxq1]
      pEccm=m1$pvalue
      ARcoef=NULL
      for (p in 1:maxp){
         Phi=NULL
         m1=VAR(x,p,include.mean=F,output=F)
         Phi=rbind(Phi,m1$Phi)
         resi=m1$residuals
         m2=revmq(resi,maxq1,output=F)
         pv1=m2$pvalue[1]
         Eccmit=m2$ccm[,1]
         y=x[(p+1):nT,]
         xreg=NULL
         for (j in 1:p){
            xreg=cbind(xreg,x[(p+1-j):(nT-j),])
            }
         kx=dim(xreg)[2]
         for (it in 1:maxq){
            y=y[-1,]
            yT=dim(y)[1]
            if(it == 1){
               xreg=xreg[-1,]
            }
            else{
               nx=dim(xreg)[2]
               xT=dim(xreg)[1]
               xreg=cbind(xreg[-1,1:kx],xreg[-xT,(kx+1):nx])
            }
            TT=dim(resi)[1]
            xreg=cbind(xreg,resi[-TT,])
            xpx=crossprod(xreg,xreg)/nT
            xpy=crossprod(xreg,y)/nT
            xpxinv=solve(xpx)
            beta=xpxinv%*%xpy
            ##cat("beta","\n")
            ##print(beta)
            wt=y-xreg[,1:kx]%*%beta[1:kx,]
            resi=y-xreg%*%beta
            Phi=rbind(Phi,t(beta[1:kx,]))
            m3=revmq(wt,maxq1,output=F)
            Eccmit=cbind(Eccmit,m3$ccm[,(it+1)])
            pv1=c(pv1,m3$pvalue[it+1])
            ##end of it-loop
         }
         ARcoef=cbind(ARcoef,Phi)
         vEccm=rbind(vEccm,Eccmit)
         pEccm=rbind(pEccm,pv1)
       }
    }
   else {
       m1=ccm(x,(maxq+1),output=F)
      vEccm=m1$ccm[,2:(maxq+2)]
      pEccm=m1$pvalue
       ARcoef=NULL
      for (p in 1:maxp){
         Phi=NULL
         m1=VAR(x,p,include.mean=F,output=F)
         Phi=rbind(Phi,m1$Phi)
         resi=m1$residuals
         m2=ccm(resi,1,output=F)
         pv1=m2$pvalue
         Eccmit=matrix(m2$ccm[,2],ksq,1)
         y=x[(p+1):nT,]
         xreg=NULL
         for (j in 1:p){
            xreg=cbind(xreg,x[(p+1-j):(nT-j),])
         }
          kx=dim(xreg)[2]
         for (it in 1:maxq){
            y=y[-1,]
            yT=dim(y)[1]
            if(it == 1){
               xreg=xreg[-1,]
            }
            else{
               nx=dim(xreg)[2]
               xT=dim(xreg)[1]
               xreg=cbind(xreg[-1,1:kx],xreg[-xT,(kx+1):nx])
            }
            TT=dim(resi)[1]
            xreg=cbind(xreg,resi[-TT,])
            xpx=crossprod(xreg,xreg)/nT
            xpy=crossprod(xreg,y)/nT
            xpxinv=solve(xpx)
            beta=xpxinv%*%xpy
             wt=y-xreg[,1:kx]%*%beta[1:kx,]
            resi=y-xreg%*%beta
            Phi=rbind(Phi,t(beta[1:kx,]))
            m3=ccm(wt,it+1,output=F)
            Eccmit=cbind(Eccmit,m3$ccm[,(it+2)])
            pv1=c(pv1,m3$pvalue[it+1])
            ##end of it-loop
         }
          ARcoef=cbind(ARcoef,Phi)
         vEccm=rbind(vEccm,Eccmit)
         pEccm=rbind(pEccm,pv1)
       }
    }
   cat("p-values table of Extended Cross-correlation Matrices:","\n")
   cat("Column: MA order","\n")
   cat("Row   : AR order","\n")
   colnames(pEccm) <- c(c(0:maxq))
   rownames(pEccm) <- c(c(0:maxp))
   tmp=round(pEccm,4)
   printCoefmat(tmp)
    Eccm <- list(pEccm=pEccm,vEccm=vEccm,ARcoef=ARcoef)
  }


"revmq" <- function(x,lag=12,output=FALSE){
   # Compute multivariate Ljung-Box test statistics
   ## Show the results based on the following reversed test:
   ## H_0: rho_{i} = rho_{i+1} = ... = rho_{maxq} = 0.
   ## for i = 1, 2, ...., maxq.
   if(!is.matrix(x))x=as.matrix(x)
   nr=dim(x)[1]
   nc=dim(x)[2]
   nr1=nr-1
   nrsq=nr*nr
   ksq=nc*nc
   x1=scale(x,center=TRUE,scale=FALSE)
   g0=crossprod(x1,x1)/nr1
   S1=sqrt(diag(g0))
   D=diag(1/S1)
   ginv=solve(g0)
   Qm=NULL
   ccm = NULL
   qm=0.0
   for (i in 1:lag){
      x1a=x1[(i+1):nr,]
      x2a=x1[1:(nr-i),]
      g = crossprod(x1a,x2a)/nr1
      rho=D%*%g%*%D
      ccm=cbind(ccm,matrix(c(rho),ksq,1))
      h=t(g)%*%ginv%*%g%*%ginv
      qm=qm+nrsq*sum(diag(h))/(nr-i)
      Qm=c(Qm,qm)
   }
   df=ksq*lag
   rqm=Qm[lag]
   pvs=1-pchisq(Qm[lag],df)
   if(lag > 1){
      for (i in 1:(lag-1)){
         tst=Qm[lag]-Qm[i]
         df=df-ksq
         rqm=c(rqm,tst)
         pvs=c(pvs,1-pchisq(tst,df))
      }
   }
   if(output){
      cat("Qm:","\n")
      print(Qm)
      cat("reversed-qm","\n")
      print(rqm)
      cat("p-values of rqm: ","\n")
      print(pvs)
   }
   revmq <- list(ccm=ccm,rqm=rqm,pvalue=pvs)
 }

"Kronid" <- function(x,plag=5,crit=0.05){
   # Identifies the Kronecker indexes for a vector time series
   # plag is the number of lags used to represent the PAST vector
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(x)[1]
   k=dim(x)[2]
   y=as.matrix(x)
   if(plag < 1){
      plag=floor(log(nT))+1
   }
   # Construct the PAST-vector
   iend=nT-plag
   past=y[1:iend,]
   if (plag > 1){
      for (i in 2:plag){
         past=cbind(y[i:(iend+i-1),],past)
      }
   }
   # initialize the Kronecker indexes and control variable.
   kdx=rep(0,k)
   found=rep(0,k)
   h=0
   ist=plag+1
   futu1=as.matrix(y[ist:nT,])
   cat("h = ",h,"\n")
   #print(h)
   for (i in 1:k){
      cat("Component = ",i,"\n")
      s1=c(i)
      if(i > 1){
         fnd=found[1:(i-1)]
         jdx=c(1:(i-1))[fnd==0]
         s1=c(jdx,i)
      }
      futu=as.matrix(futu1[,s1])
      m1=cancor(past,futu)
      df=dim(futu)[2]
      dp=dim(past)[2]
      deg=dp-df+1
      seig=m1$cor[df]^2
      cat("square of the smallest can. corr. = ",seig,"\n")
      tst=-(nT-1-0.5*(dp+df-1))*log(1-seig)
      pv=1-pchisq(tst,deg)
      stat=c(tst,deg,pv)
      cat("    test,   df, &  p-value:","\n")
      print(round(stat,3))
      if(i>1){
         cstar=cbind(cstar,stat)
      }
      else{
         cstar=stat
      }
      if(pv > crit){
         found[i]=1
         kdx[i]=h
         cat("A Kronecker index found","\n")
      }
   }
   cat("=============","\n")
   while(sum(found) < k){
      idim=dim(past)[1]
      h=h+1
      cat("h = ",h,"\n")
      past=past[1:(idim-1),]
      futu=futu[1:(idim-1),]
      futu1=y[(ist+h):nT,]
      for (ii in 1:k){
         if(found[ii]==0){
            cat("Component = ",ii,"\n")
            #print(ii)
            futu=cbind(futu,futu1[,ii])
            m1=cancor(past,futu)
            df=dim(futu)[2]
            dp=dim(past)[2]
            deg=dp-df+1
            seig=m1$cor[df]^2
            cat("Square of the smallest can. corr. = ",seig,"\n")
            y1=futu%*%(m1$ycoef[,df])
            x1=past%*%(m1$xcoef[,df])
            m2=acf(y1,lag.max=h,plot=F)
            acfy=m2$acf[2:(h+1)]
            m3=acf(x1,lag.max=h,plot=F)
            acfx=m3$acf[2:(h+1)]
            dsq=1+2*sum(acfx*acfy)
            seig=seig/dsq
            tst=-(nT-1-0.5*(dp+df-1))*log(1-seig)
            pv=1-pchisq(tst,deg)
            stat=c(tst,deg,pv,dsq)
            cat("    test,     df, p-value & d-hat:","\n")
            print(round(stat,3))
            stat=stat[1:3]
            cstar=cbind(cstar,stat)
            if(pv > crit){
               found[ii]=1
               kdx[ii]=h
               futu=futu[,1:(df-1)]
               cat("A Kronecker found","\n")
            }
         }
      }
      cat("============","\n")
   }
   cat("   ","\n")
   cat("Kronecker indexes identified:","\n")
   print(kdx)
   Kronid<-list(index=kdx,tests=cstar)
 }

"Kronspec" <- function(kdx,output=TRUE){
   # Specify a VARMA model for a given set of Kronecker indices
   #
   # Output: 1 = No estimation (the coefficient of Z_{it}
   #         2 = estimation
   #         0 = fixed to zero.
   k=length(kdx)
   if(output){
      cat("Kronecker indices: ",kdx,"\n")
      cat("Dimension: ",k,"\n")
   }
   KK=sort(kdx,index.return=T)
   idx=KK$ix
   p=KK$x[k]
   q=p
   mx=(p+1)*k
   Theta=matrix(2,k,k*(q+1))
   for (i in 1:k){
      Theta[i,i]=1
      if(kdx[i] < q){
         jj=(kdx[i]+1)*k
         Theta[i,(jj+1):mx]=0
      }
   }
   if(k > 1){
      for (i in 1:(k-1)){
         Theta[i,(i+1):k]=0
      }
   }
   # Indicator matrix of AR polynomial: 1 = estimation, 0 denotes zero.
   Phi=Theta
   # specify the Phi(0) lower triangular part
   if (k > 1){
      for (i in 2:k){
         for (j in 1:(i-1)){
            if(kdx[j] <= kdx[i]) Phi[i,j]=0
            # j-loop
         }
         # i-loop
      }
      # for the case of k > 1
   }
   Theta[1:k,1:k]=Phi[1:k,1:k]
   ## specify redundant parameters
   for (i in 1:k){
      for (j in 1:k){
         if(kdx[i] > kdx[j]){
            for (ii in 1:(kdx[i]-kdx[j]))
            Phi[i,ii*k+j]=0
         }
      }
   }
   if(output){
      cat("Notation: ","\n")
      cat(" 0: fixed to 0","\n")
      cat(" 1: fixed to 1","\n")
      cat(" 2: estimation","\n")
      cat("AR coefficient matrices: ","\n")
      print(Phi)
      cat("MA coefficient matrices: ","\n")
      print(Theta)
   }
   Kronspec <- list(PhiID=Phi,ThetaID=Theta)
 }

"Kronfit" <- function(da,kidx,include.mean=T,fixed=NULL,Kpar=NULL,seKpar=NULL,prelim=F,details=F,thres=1.0){
   # Estimation of a vector ARMA model using conditional MLE (Gaussian dist)
   #  The model is specified via Kronecker indices.
   # When prelim=TRUE, fixed is assigned based on the results of AR approximation.
   if(!is.matrix(da))da=as.matrix(da)
   nT=dim(da)[1]; k=dim(da)[2]
    k1=length(kidx)
      if(k1 <= 0){
         k1=k; kidx=rep(1,k)
       }
      maxk=max(kidx)
      m0=Kronspec(kidx,output=F)
      ARid=m0$PhiID; MAid=m0$ThetaID
      #
      print(ARid)
      print(MAid)

 iniKro <- function(da,at,ARid,MAid,include.mean){
   #### z(t) = xi0 z(t) + SUM[xii *z(t-i)] + SUM[Omegai*a(t-i)] + a(t).
   if(!is.matrix(da))da=as.matrix(da)
   if(!is.matrix(at))at=as.matrix(at)
   nT=dim(da)[1];   k=dim(da)[2]
   ## obtain the maximum index value.
   p=floor(dim(ARid)[2]/k)-1
### Minimum order is 1.
   if(p <= 0)p=1
   ist = p + 1
   ## est: stores the estimates (equation 1, equation 2, etc.)
   est=NULL
   estse=NULL
   for (i in 1:k){
      X=NULL
      Y=da[ist:nT,i]
      if(include.mean)X=rep(1,(nT-p))
      ### This is for i > 1 Only.
      if(i > 1){
         for (j in 1:(i-1)){
            if(ARid[i,j] > 1){
               tmp=at[ist:nT,j]-da[ist:nT,j]
               X=cbind(X,tmp)
            }
         }
       }
      ### setup the lagged AR variables
      for(lag in 1:p){
         jst=lag*k
         for (j in 1:k){
            if(ARid[i,jst+j] > 1){
               tmp=da[(ist-lag):(nT-lag),j]
               X=cbind(X,tmp)
             }
          }
        }
       for(lag in 1:p){
         jst=lag*k
         for (j in 1:k){
            if(MAid[i,jst+j] > 1){
               tmp=at[(ist-lag):(nT-lag),j]
               X=cbind(X,tmp)
             }
          }
       }
      XPX=crossprod(X,X)/nT
      XPXinv=solve(XPX)
      XPY=crossprod(X,Y)/nT
      beta=XPXinv%*%XPY
      l1=dim(XPX)[1]
      resi=Y-X%*%matrix(beta,l1,1)
      evar=c(crossprod(resi,resi)/(nT-p))
      est=c(est,beta)
      estse=c(estse,sqrt(c(diag(XPXinv)*evar)/nT))
     }
   iniKro <- list(par=est,se=estse)
  }
##
  if(length(Kpar) < 1){
      m1=VARorder(da,maxk+9,output=FALSE)
      porder=m1$aicor
      if(porder < 1)porder=1
      m2=VAR(da,porder,output=FALSE)
      y=da[(porder+1):nT,]
      x=m2$residuals
      m3=iniKro(y,x,ARid,MAid,include.mean)
      ### Kpar is the vector of ALL estimable parameters.
      Kpar <- m3$par; seKpar=m3$se
      ### Kpar is a vector; which stores parameters equation-by-equation.
      nr=length(Kpar)
      ### Preliminary simplification
      if(prelim){
         fixed = rep(0,nr)
         for (j in 1:nr){
            tt=Kpar[j]/seKpar[j]
            if(abs(tt) >= thres){
               fixed[j]=1
            }
            else{
               Kpar[j]=0
            }
          }
        }
      }
     else{
      nr=length(Kpar)
     }
   if(length(fixed) < 1){fixed=rep(1,nr)}
   # Identify parameters to be estimated.
   nr=length(Kpar)
   JJdx=c(1:nr)[fixed==1]
   par=Kpar[JJdx]
   separ= seKpar[JJdx]
   #########
   cat("Number of parameters: ",length(par),"\n")
   cat("initial estimates: ",round(par,4),"\n")
   ### Set up lower and upper bounds
   lowerBounds=par; upperBounds=par
   for (j in 1:length(par)){
      lowerBounds[j] = par[j]-2*separ[j]
      upperBounds[j] = par[j]+2*separ[j]
   }
   cat("Upper-bound: ",round(upperBounds,4),"\n")
   cat("Lower-bound: ",round(lowerBounds,4),"\n")
### likelihood function
 LLKron <- function(par,zt=da,JJdx=JJdx,kidx=kidx,ARid=ARid,MAid=MAid,Kpar=Kpar,include.mean=include.mean){
   k=dim(zt)[2]
   nT=dim(zt)[1]
   maxk = max(kidx)
   Kpar[JJdx]=par
   ###  Assign parameters to their proper locations in the program.
   Cnt=rep(0,k)
   Ph0=diag(rep(1,k))
   kp1= dim(ARid)[2]; kp=kp1-k
   PH=matrix(0,k,kp)
   TH=matrix(0,k,kp)
   icnt=0
   for (i in 1:k){
      idx=c(1:kp1)[ARid[i,] > 1]; jdx=c(1:kp1)[MAid[i,] > 1]
      # kdx denotes the locations of non-zero elements in lag-0.
      kdx=c(1:k)[ARid[i,1:k] > 1]
      if(length(kdx) > 0){
         nlag0 <- length(kdx)
         idx=idx[-c(1:nlag0)]; jdx=jdx[-c(1:nlag0)]
      }
      iend=length(idx); jend=length(jdx); kend=length(kdx)
      #### icnt: parameter count
      if(include.mean){
         icnt=icnt+1
         Cnt[i]=Kpar[icnt]
      }
      if(kend > 0){
         Ph0[i,kdx]=Kpar[(icnt+1):(icnt+kend)]
         icnt=icnt+kend
      }
      if(iend > 0){
         PH[i,idx-k]=Kpar[(icnt+1):(icnt+iend)]
         icnt=icnt+iend
      }
      if(jend > 0){
         TH[i,jdx-k]=Kpar[(icnt+1):(icnt+jend)]
         icnt=icnt+jend
      }
   }
   Ph0i=solve(Ph0)
   ARc=Ph0i%*%PH
   MAc=Ph0i%*%TH
   Cntc=Ph0i%*%as.matrix(Cnt,k,1)
   ist=maxk+1
   at=matrix((zt[1,]-Cntc),1,k)
   if(maxk > 1){
      for (t in 2:maxk){
         tmp=matrix((zt[t,]-Cntc),1,k)
         for (j in 1:maxk){
            if((t-j) > 0){
               jdx=(j-1)*k
               tmp1=matrix(zt[(t-j),],1,k)%*%t(as.matrix(ARc[,(jdx+1):(jdx+k)]))
               tmp=tmp-tmp1
            }
         }
         for (j in 1:maxk){
            jdx=(j-1)*k
            if((t-j)>0){
               tmp2=matrix(at[(t-j),],1,k)%*%t(as.matrix(MAc[,(jdx+1):(jdx+k)]))
               tmp=tmp-tmp2
            }
           }
         at=rbind(at,tmp)
        }
     }
   ### for t from ist on
   ist=maxk+1
   Pcnt = NULL; beta=NULL
   if(include.mean)beta=matrix(Cntc,1,k)
   beta=rbind(beta,t(ARc),t(MAc))
   idim=k*maxk*2
   if(include.mean){
      Pcnt=c(1)
      idim=idim+1
   }
   #
   for (t in (maxk+1):nT){
      Past=NULL
      for (j in 1:maxk){
         Past=c(Past,zt[(t-j),])
      }
      for (j in 1:maxk){
         Past=c(Past,at[(t-j),])
      }
      tmp = matrix(c(Pcnt,Past),1,idim)%*%beta
      tmp3=zt[t,]-tmp
      at=rbind(at,tmp3)
   }
   at=at[(ist:nT),]
   sig=crossprod(at,at)/(nT-maxk)
   ll=dmvnorm(at,rep(0,k),sig)
   LLKron=-sum(log(ll))
   LLKron
  }
   # Step 5: Estimate Parameters and Compute Numerically Hessian:
   if(details){
      fit = nlminb(start = par, objective = LLKron,zt=da,include.mean=include.mean,JJdx=JJdx,kidx=kidx,
      Kpar=Kpar,ARid=ARid,MAid=MAid,lower = lowerBounds, upper = upperBounds, control = list(trace=3))
   }
   else {
      fit = nlminb(start = par, objective = LLKron, zt=da,include.mean=include.mean,JJdx=JJdx,kidx=kidx,
       Kpar=Kpar,ARid=ARid,MAid=MAid,lower = lowerBounds, upper = upperBounds)
   }
   epsilon = 0.0001 * fit$par
   npar=length(par)
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] = (LLKron(x1,zt=da,include.mean=include.mean,JJdx=JJdx,kidx=kidx,Kpar=Kpar,ARid=ARid,MAid=MAid)
                         -LLKron(x2,zt=da,include.mean=include.mean,JJdx=JJdx,kidx=kidx,Kpar=Kpar,ARid=ARid,MAid=MAid)
                         -LLKron(x3,zt=da,include.mean=include.mean,JJdx=JJdx,kidx=kidx,Kpar=Kpar,ARid=ARid,MAid=MAid)
                         +LLKron(x4,zt=da,include.mean=include.mean,JJdx=JJdx,kidx=kidx,Kpar=Kpar,ARid=ARid,MAid=MAid))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   # Step 6: Create and Print Summary Report:
   d1=det(Hessian)
   if(d1 < 1.0e-10){
      se.coef=rep(1,npar)
   }
   else{
      se.coef = sqrt(diag(solve(Hessian)))
   }
   tval = fit$par/se.coef
   matcoef = cbind(fit$par, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)
   Kpar[JJdx]=fit$par
   seKpar[JJdx]=se.coef
   # Restore estimates to the format of unconstrained case for printing.
   Cnt=rep(0,k); seCnt=rep(0,k)
   Ph0=diag(rep(1,k)); sePh0=diag(rep(1,k))
   kp1= dim(ARid)[2]; kp=kp1-k
   PH=matrix(0,k,kp); sePH=matrix(0,k,kp)
   TH=matrix(0,k,kp); seTH=matrix(0,k,kp)
   icnt=0
   for (i in 1:k){
      idx=c(1:kp1)[ARid[i,] > 1]; jdx=c(1:kp1)[MAid[i,] > 1]
      # kdx denotes the locations of the non-zero elements in lag-0.
      kdx=c(1:k)[ARid[i,1:k] > 1]
      if(length(kdx) > 0){
         nlag0 <- length(kdx)
         idx=idx[-c(1:nlag0)]; jdx=jdx[-c(1:nlag0)]
      }
      iend=length(idx); jend=length(jdx); kend=length(kdx)
      if(include.mean){
         icnt=icnt+1
##         Cnt[i]=Kpar[icnt]
##         seCnt[i]=seKpar[icnt]
          Cnt[i] <- fit$par[icnt]
          seCnt[i] <- se.coef[icnt]
      }
      if(kend > 0){
##         Ph0[i,kdx]=Kpar[(icnt+1):(icnt+kend)]
##         sePh0[i,kdx]=seKpar[(icnt+1):(icnt+kend)]
         Ph0[i,kdx]=fit$par[(icnt+1):(icnt+kend)]
         sePh0[i,kdx]=se.coef[(icnt+1):(icnt+kend)]
         icnt=icnt+kend
      }
      if(iend > 0){
         ##cat("idx-k: ",idx-k,"\n")
#         PH[i,idx-k]=Kpar[(icnt+1):(icnt+iend)]
#         sePH[i,idx-k]=seKpar[(icnt+1):(icnt+iend)]
         PH[i,idx-k]=fit$par[(icnt+1):(icnt+iend)]
         sePH[i,idx-k]=se.coef[(icnt+1):(icnt+iend)]
         icnt=icnt+iend
      }
      if(jend > 0){
##         TH[i,jdx-k]=Kpar[(icnt+1):(icnt+jend)]
##         seTH[i,jdx-k]=seKpar[(icnt+1):(icnt+jend)]
         TH[i,jdx-k]=fit$par[(icnt+1):(icnt+jend)]
         seTH[i,jdx-k]=se.coef[(icnt+1):(icnt+jend)]
         icnt=icnt+jend
      }
   }
   cat("---","\n")
   cat("Estimates in matrix form:","\n")
   if(include.mean){
      cat("Constant term: ","\n")
      cat("Estimates: ",round(Cnt,3),"\n")
   }
   cat("AR and MA lag-0 coefficient matrix","\n")
   print(round(Ph0,3))
   cat("AR coefficient matrix","\n")
   jcnt=0
   for (i in 1:maxk){
      cat("AR(",i,")-matrix","\n")
      ph=PH[,(jcnt+1):(jcnt+k)]
      print(round(ph,3))
      jcnt=jcnt+k
   }
   cat("MA coefficient matrix","\n")
   icnt=0
   for (i in 1:maxk){
      cat("MA(",i,")-matrix","\n")
      theta=-TH[,(icnt+1):(icnt+k)]
      print(round(theta,3))
      icnt=icnt+k
   }
   ##### Compute the residuals
   Ph0i=solve(Ph0)
   ARc=Ph0i%*%PH
   MAc=Ph0i%*%TH
   Cntc=Ph0i%*%as.matrix(Cnt,k,1)
   zt=da
   ist=maxk+1
   #### consider the case t from 1 to maxk+1
   at=matrix((zt[1,]-Cntc),1,k)
   if(maxk > 1){
      for (t in 2:maxk){
         tmp=matrix((zt[t,]-Cntc),1,k)
         for (j in 1:maxk){
            if((t-j) > 0){
               jdx=(j-1)*k
               tmp1=matrix(zt[(t-j),],1,k)%*%t(as.matrix(ARc[,(jdx+1):(jdx+k)]))
               tmp=tmp-tmp1
            }
          }
          for (j in 1:maxk){
            jdx=(j-1)*k
            if((t-j)>0){
               tmp2=matrix(at[(t-j),],1,k)%*%t(as.matrix(MAc[,(jdx+1):(jdx+k)]))
               tmp=tmp-tmp2
            }
          }
         at=rbind(at,tmp)
       }
    }
    ### for t from ist on
   ist=maxk+1
   Pcnt=NULL
   beta=NULL
   if(include.mean){
      beta=matrix(Cntc,1,k)
      Pcnt=c(1)
   }
   beta=rbind(beta,t(ARc),t(MAc))
   idim=k*maxk*2
   if(include.mean){
      Pcnt=c(1)
      idim=idim+1
   }
   #
   for (t in (maxk+1):nT){
      Past=NULL
      for (j in 1:maxk){
         Past=c(Past,zt[(t-j),])
      }
      for (j in 1:maxk){
         Past=c(Past,at[(t-j),])
      }
      tmp = matrix(c(Pcnt,Past),1,idim)%*%beta
      tmp3=zt[t,]-tmp
      at=rbind(at,tmp3)
   }
    at=at[(ist:nT),]
   sig=crossprod(at,at)/(nT-maxk)
   cat(" ","\n")
   cat("Residuals cov-matrix:","\n")
   print(sig)
   dd=det(sig)
   d1=log(dd)
   aic=d1+2*npar/nT
   bic=d1+log(nT)*npar/nT
   cat("----","\n")
   cat("aic= ",aic,"\n")
   cat("bic= ",bic,"\n")

   Kronfit <- list(data=da,Kindex=kidx,ARid=ARid,MAid=MAid,cnst=include.mean,coef=Kpar,secoef=seKpar,residuals=at,Sigma=sig,aic=aic,bic=bic, Ph0=Ph0,Phi=PH,Theta=-TH,const=Cnt)
}

"refKronfit" <- function(model,thres=1.0){
   zt=model$data
   inc.mean=model$cnst
   kidx=model$Kindex
   Kpar= model$coef
   seKpar= model$secoef
   maxk=max(kidx)
   nr=length(Kpar)
   fix=rep(0,nr)
   for (j in 1:nr){
      tt = 0
      iav=is.na(seKpar[j])
      if(iav)seKpar[j]=0.01
      tt=Kpar[j]/seKpar[j]
      if(abs(tt) > thres){
         fix[j]=1
      }
      else{
         Kpar[j]=0
      }
     }
   m1=Kronfit(zt,kidx,include.mean=inc.mean,fixed=fix,Kpar=Kpar,seKpar=seKpar)
   ARid=m1$ARid; MAid=m1$MAid
   Kpar=m1$coef; seKpar=m1$secoef
   sig=m1$Sigma; aic=m1$aic; bic=m1$bic
   Ph0=m1$Ph0
   PH=m1$Phi
   TH=-m1$Theta
   at=m1$residuals
   Cnt=m1$const

   refKronfit <- list(data=zt,Kindex=kidx,ARid=ARid,MAid=MAid,cnst=inc.mean,coef=Kpar,secoef=seKpar,residuals=at,Sigma=sig,aic=aic,bic=bic, Ph0=Ph0,Phi=PH,Theta=-TH,const=Cnt)
}

"sVARMA" <- function(da,order=c(0,0,0),sorder=c(0,0,0),s=12,include.mean=T,fixed=NULL,details=F,switch=F){
   # Estimation of a multiplicative vector ARMA model using conditional MLE (Gaussian dist)
   if(!is.matrix(da))da=as.matrix(da)
   p=order[1];d=order[2];q=order[3];P=sorder[1];D=sorder[2];Q=sorder[3]
   nT=dim(da)[1]; k=dim(da)[2]
   # basic setup.
   if(p < 0)p=0; if(q < 0)q=0; if(P < 0) P = 0; if(Q < 0) Q = 0; if(s < 0) s=-s
   if(d > 1){
      cat("Regular difference is adjusted to d=1","\n")
      d=1
   }
   if(D > 1){
      cat("Seasonal difference is adjusted to D=1","\n")
      D=1
   }
   kp=k*p
   kq=k*q
   kP=k*P
   kQ=k*Q
   # Take care of the difference
   if(d==1){
      X=NULL
      MEAN=rep(0,k)
      for (j in 1:k){
         X=cbind(X,diff(da[,j]))
         t1=t.test(X[,j])
         if(t1$p.value < 0.05)MEAN[j]=1
      }
      if(sum(MEAN) < 1)include.mean=FALSE
   }
   else{
      X=da
   }
   if(D==1){
      DX=NULL
      Smean=rep(0,k)
      for (j in 1:k){
         DX=cbind(DX,diff(X[,j],s))
         t1=t.test(DX[,j])
         if(t1$p.value < 0.05)Smean[j]=1
      }
      if(sum(Smean) < 1)include.mean=FALSE
   }
   else{
      DX=X
   }
   nT=dim(DX)[1]
   arlags=NULL
   if(p > 0){
      arlags=c(1:p)
      if(P > 0)arlags=c(arlags,c(1:P)*s,c(1:P)*s+c(1:p))
   }
   else{
      if(P > 0)arlags=c(1:P)*s
   }
   malags=NULL
   if(q > 0){
      malags=c(1:q)
      if(Q > 0)malags=c(malags,c(1:Q)*s,c(1:Q)*s+c(1:q))
   }
   else{
      if(Q > 0)malags=c(1:Q)*s
   }
   # number of AR and MA lags of the model
   nar=length(arlags)
   nma=length(malags)
   idim=k*(nar+nma)
   if(include.mean)idim=idim+1
   if(length(fixed)==0){fixed=matrix(1,idim,k)}
   Order <- c(order,sorder)
   ARlags <- arlags; MAlags <- malags
   ####
   phi=NULL; sphi=NULL; sephi=NULL; sesphi=NULL
   if(p > 0)phi=matrix(0,k,k*p); sephi=phi
   if(P > 0)sphi=matrix(0,k,k*P);sesphi=sphi
   theta=NULL; stheta=NULL;setheta=NULL; sestheta=NULL
   if(q > 0)theta=matrix(0,k,k*q);setheta=theta
   if(Q > 0)stheta=matrix(0,k,k*Q);sestheta=stheta
   ## Obtain initial estimates of the component parameters using univariate models.
   ### For cross-series initial estimates, we use linear models with univariate at-series
   resi=NULL
   for (j in 1:k){
      m1=arima(DX[,j],order=c(p,0,q),seasonal=list(order=c(P,0,Q),period=s))
      resi=cbind(resi,m1$residuals)
      seest=sqrt(diag(m1$var.coef))
      icnt=0
      if(p > 0){
         for (i in 1:p){
            icnt=icnt+1
            ii=(i-1)*k
            phi[j,(ii+j)]=m1$coef[icnt]
            sephi[j,(ii+j)]=seest[icnt]
         }
      }
      if(q > 0){
         for (i in 1:q){
            ii=(i-1)*k
            icnt=icnt+1
            theta[j,(ii+j)]=-m1$coef[icnt]
            setheta[j,(ii+j)]=seest[icnt]
         }
      }
      if(P > 0){
         for (i in 1:P){
            icnt=icnt+1
            ii=(i-1)*k
            sphi[j,(ii+j)]=m1$coef[icnt]
            sesphi[j,(ii+j)]=seest[icnt]
         }
      }
      if(Q > 0){
         for (i in 1:Q){
            ii=(i-1)*k
            icnt=icnt+1
            stheta[j,(ii+j)]=-m1$coef[icnt]
            sestheta[j,(ii+j)]=seest[icnt]
         }
      }
    }

siniEST <- function(y,x,arlags,malags,include.mean){
   if(!is.matrix(y))y=as.matrix(y)
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(y)[1]
   k=dim(y)[2]
   nar=length(arlags)
   nma=length(malags)
   p=0; if(nar > 0)p=arlags[nar]
   q=0; if(nma > 0)q=malags[nma]
   pq=max(p,q)
   ist=1+pq
   ne=nT-pq
   if(include.mean){
      xmtx=matrix(1,ne,1)
   }
   else {
      xmtx=NULL
   }
   ymtx=as.matrix(y[ist:nT,])
   if(nar > 0){
      for (j in 1:nar){
         jj=arlags[j]
         xmtx=cbind(xmtx,y[(ist-jj):(nT-jj),])
      }
   }
   if(nma > 0){
      for (j in 1:nma){
         jj=malags[j]
         xmtx=cbind(xmtx,x[(ist-jj):(nT-jj),])
      }
   }
   xmtx=as.matrix(xmtx)
   xtx=crossprod(xmtx,xmtx)
   xty=crossprod(xmtx,ymtx)
   xtxinv=solve(xtx)
   beta=xtxinv%*%xty
   resi= ymtx - xmtx%*%beta
   sse=crossprod(resi,resi)/ne
   dd=diag(xtxinv)
   sebeta=NULL
   for (j in 1:k){
      se=sqrt(dd*sse[j,j])
      sebeta=cbind(sebeta,se)
   }
   siniEST <- list(estimates=beta,se=sebeta)
 }
   #### Obtain estimates of cross-series parameters, using Least-Squares approximation.
   m2=siniEST(DX,resi,arlags,malags,include.mean)
   #### Fill in the coefficient matrices
   beta=t(m2$estimates)
   sebeta=t(m2$se)
   ##
   icnst=0
   if(include.mean)icnst=1
   if(nar > 0){
      if(p > 0){
         for (i in 1:p){
            idx=(i-1)*k
            for (ii in 1:k){
               jdx=c(1:k)[-ii]
               phi[jdx,(idx+ii)]=beta[jdx,(icnst+idx+ii)]
               sephi[jdx,(idx+ii)]=sebeta[jdx,(icnst+idx+ii)]
            }
         }
       }
      if(P > 0){
         for (i in 1:P){
            kdx=(i-1)*k
            idx=k*p+kdx
            for (ii in 1:k){
               jdx=c(1:k)[-ii]
               sphi[jdx,(kdx+ii)]=beta[jdx,(icnst+idx+ii)]
               sesphi[jdx,(kdx+ii)]=sebeta[jdx,(icnst+idx+ii)]
            }
         }
      }
    }
   if(nma > 0){
      if(q > 0){
         for (i in 1:q){
            kdx=(i-1)*k
            idx=nar*k+kdx
            for (ii in 1:k){
               jdx=c(1:k)[-ii]
               theta[jdx,(kdx+ii)]=-beta[jdx,(icnst+idx+ii)]
               setheta[jdx,(kdx+ii)]=sebeta[jdx,(icnst+idx+ii)]
            }
         }
      }
      if(Q > 0){
         for (i in 1:Q){
            kdx=(i-1)*k
            idx=(nar+q)*k+kdx
            for (ii in 1:k){
               jdx=c(1:k)[-ii]
               stheta[jdx,(kdx+ii)]=-beta[jdx,(icnst+idx+ii)]
               sestheta[jdx,(kdx+ii)]=sebeta[jdx,(icnst+idx+ii)]
            }
         }
      }
    }
   # Identify parameters to be estimated.
   par=NULL
   separ=NULL
   ist=0
   ## We took the transpose of beta and sebeta after siniEST program.
   if(include.mean){
      jdx=c(1:k)[fixed[1,]==1]
      if(length(jdx) > 0){
         par=beta[jdx,1]
         separ=sebeta[jdx,1]
      }
      ist=1
    }
   if(nar > 0){
      if(p > 0){
         for (j in 1:k){
            idx=c(1:kp)[fixed[(ist+1):(ist+kp),j]==1]
            if(length(idx) > 0){
               par=c(par,phi[j,idx])
               separ=c(separ,sephi[j,idx])
            }
          }
         ist=ist+kp
      }
     if(P > 0){
         for (j in 1:k){
            idx=c(1:kP)[fixed[(ist+1):(ist+kP),j]==1]
            if(length(idx) > 0){
               par=c(par,sphi[j,idx])
               separ=c(separ,sesphi[j,idx])
            }
         }
         ist=ist+kP
      }
    }
   if(nma > 0){
      if(q > 0){
         for (j in 1:k){
            idx=c(1:kq)[fixed[(ist+1):(ist+kq),j]==1]
            if(length(idx) > 0){
               par=c(par,theta[j,idx])
               separ=c(separ,setheta[j,idx])
            }
         }
         ist=ist+kq
      }
      if(Q > 0){
         for (j in 1:k){
            idx=c(1:kQ)[fixed[(ist+1):(ist+kQ),j]==1]
            if(length(idx) > 0){
               par=c(par,stheta[j,idx])
               separ=c(separ,sestheta[j,idx])
            }
         }
      }
    }
   #### keep the first few residuals to be used in likelihood evaluation to compute "at".
   jst=max(arlags,malags)
   Sresi <- resi[1:jst,]
   cat("Number of parameters: ",length(par),"\n")
   cat("initial estimates: ",par,"\n")
   lowerBounds=par; upperBounds=par
   for (j in 1:length(par)){
      lowerBounds[j] = par[j]-2*separ[j]
      upperBounds[j] = par[j]+2*separ[j]
   }

LLKsvarma <- function(par,zt=DX,Order=Order,ARlags=arlags,MAlags=malags,include.mean=include.mean,fixed=fixed,swi=switch,Sresi=Sresi){
   ## recall the relevant information.
   k <- dim(zt)[2];   nT <- dim(zt)[1]
   p=Order[1];q=Order[3];P=Order[4];Q=Order[6]
   kp=k*p;kP=k*P;kq=k*q;kQ=k*Q
   nar=length(ARlags); nma=length(MAlags)
   istart=max(ARlags,MAlags)+1
   ###  Assign parameters to their proper locations in the program.
   beta=NULL
   ist=0
   icnt=0
   Ph0=rep(0,k)
   if(include.mean){
      idx=c(1:k)[fixed[1,]==1]
      icnt=length(idx)
      if(icnt > 0){
         Ph0[idx]=par[1:icnt]
      }
      ist=1
      beta=rbind(beta,Ph0)
   }
   PH=NULL;sPH=NULL
   if(nar > 0){
      if(p > 0){
         PH = matrix(0,k,kp)
         for (j in 1:k){
            idx=c(1:kp)[fixed[(ist+1):(ist+kp),j]==1]
            jdx=length(idx)
            if(jdx > 0){
               PH[j,idx]=par[(icnt+1):(icnt+jdx)]
               icnt=icnt+jdx
            }
            # end of j-loop
         }
         ist=ist+kp
         #end of if (p > 0)
      }
      #### Seasonal AR part
      if(P > 0){
         sPH=matrix(0,k,kP)
         for (j in 1:k){
            idx=c(1:kP)[fixed[(ist+1):(ist+kP),j]==1]
            jdx=length(idx)
            if(jdx > 0){
               sPH[j,idx]=par[(icnt+1):(icnt+jdx)]
               icnt=icnt+jdx
            }
         }
         ist=ist+kP
       }
    }
   TH=NULL;sTH=NULL
   if(nma > 0){
      if(q > 0){
         TH=matrix(0,k,kq)
         for (j in 1:k){
            idx=c(1:kq)[fixed[(ist+1):(ist+kq),j]==1]
            jdx=length(idx)
            if(jdx > 0){
               TH[j,idx]=par[(icnt+1):(icnt+jdx)]
               icnt=icnt+jdx
            }
          }
         ist=ist+kq
       }
      if(Q > 0){
         sTH=matrix(0,k,kQ)
         for (j in 1:k){
            idx=c(1:kQ)[fixed[(ist+1):(ist+kQ),j]==1]
            jdx=length(idx)
            if(jdx > 0){
               sTH[j,idx]=par[(icnt+1):(icnt+jdx)]
               icnt=icnt+jdx
            }
         }
        }
     }
   # Obtain the product of matrix polynomials if necessary
   if((p > 0)&&(P > 0)){
      if(swi){
         Phi=Mtxprod1(PH,sPH,p,P)
      }
      else{
         Phi=Mtxprod(PH,sPH,p,P)
      }
      beta=rbind(beta,t(Phi))
   }
   if((p > 0)&&(P==0))beta=rbind(beta,t(PH))
   if((p==0)&&(P > 0))beta=rbind(beta,t(sPH))
   #
   if((q > 0)&&(Q > 0)){
      if(swi){
         Theta=Mtxprod1(TH,sTH,q,Q)
      }
      else{
         Theta=Mtxprod(TH,sTH,q,Q)
      }
      beta=rbind(beta,-t(Theta))
   }
   if((q > 0)&&(Q==0))beta=rbind(beta,-t(TH))
   if((q==0)&&(Q > 0))beta=rbind(beta,-t(sTH))
   #
    #### consider the case t from 1 to pqmatx
   at=Sresi
   ### for t from istart to T
   Pcnt = NULL
   idim=k*(nar+nma)
   if(include.mean){
      Pcnt=c(1)
      idim=idim+1
   }
   for (t in istart:nT){
      Past=NULL
      if(nar > 0){
         for (j in 1:nar){
            jj=ARlags[j]
            Past=c(Past,zt[(t-jj),])
         }
      }
      if(nma > 0){
         for (j in 1:nma){
            jj=MAlags[j]
            Past=c(Past,at[(t-jj),])
         }
      }
      tmp = matrix(c(Pcnt,Past),1,idim)%*%beta
      tmp3=zt[t,]-tmp
      at=rbind(at,tmp3)
   }
   at=at[istart:nT,]
   sig=t(at)%*%at/(nT-istart+1)
   ll=dmvnorm(at,rep(0,k),sig)
   LLKsvarma=-sum(log(ll))
####   cat("test: ",LLKsvarma,"\n")
   LLKsvarma
  }
 ## estimation
   if(details){
      fit = nlminb(start = par, objective = LLKsvarma,zt=DX,Order=Order,ARlags=ARlags,MAlags=MAlags,include.mean=include.mean,
       fixed=fixed,swi=switch,Sresi=Sresi,lower = lowerBounds, upper = upperBounds, control = list(trace=3))
   }
   else {
      fit = nlminb(start = par, objective = LLKsvarma,zt=DX,Order=Order,ARlags=ARlags,MAlags=MAlags,include.mean=include.mean,
          fixed=fixed,swi=switch,Sresi=Sresi,lower = lowerBounds, upper = upperBounds)
   }
   epsilon = 0.0001 * fit$par
   npar=length(par)
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] =
          (LLKsvarma(x1,zt=DX,Order=Order,ARlags=ARlags,MAlags=MAlags,include.mean=include.mean,fixed=fixed,swi=switch,Sresi=Sresi)
          -LLKsvarma(x2,zt=DX,Order=Order,ARlags=ARlags,MAlags=MAlags,include.mean=include.mean,fixed=fixed,swi=switch,Sresi=Sresi)
          -LLKsvarma(x3,zt=DX,Order=Order,ARlags=ARlags,MAlags=MAlags,include.mean=include.mean,fixed=fixed,swi=switch,Sresi=Sresi)
          +LLKsvarma(x4,zt=DX,Order=Order,ARlags=ARlags,MAlags=MAlags,include.mean=include.mean,fixed=fixed,swi=switch,Sresi=Sresi))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   # Step 6: Create and Print Summary Report:
   se.coef = sqrt(diag(solve(Hessian)))
   tval = fit$par/se.coef
   matcoef = cbind(fit$par, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)
   est=fit$par
   ### restore estimates to the format of unconstrained case for printing purpose.
   ist=0
   icnt = 0
   Ph0=rep(0,k)
   sePh0=rep(0,k)
   beta=NULL
   sebeta=NULL
   if(include.mean){
      idx=c(1:k)[fixed[1,]==1]
      icnt=length(idx)
      if(icnt > 0){
         Ph0[idx]=est[1:icnt]
         sePh0[idx]=se.coef[1:icnt]
      }
      ist=1
      beta=rbind(beta,Ph0)
      sebeta=rbind(sebeta,sePh0)
   }
   PH=NULL; sePH=NULL; sPH=NULL; sesPH=NULL
   if(p > 0){
      PH=matrix(0,kp,k)
      sePH=matrix(0,kp,k)
      for (j in 1:k){
         idx=c(1:kp)[fixed[(ist+1):(ist+kp),j]==1]
         jdx=length(idx)
         if(jdx > 0){
            PH[idx,j]=est[(icnt+1):(icnt+jdx)]
            sePH[idx,j]=se.coef[(icnt+1):(icnt+jdx)]
            icnt=icnt+jdx
         }
         # end of j-loop
      }
      #end of if (p > 0)
      ist=ist+kp
      beta=rbind(beta,PH)
      sebeta=rbind(sebeta,sePH)
   }
   if(P > 0){
      sPH=matrix(0,kP,k)
      sesPH=matrix(0,kP,k)
      for (j in 1:k){
         idx=c(1:kP)[fixed[(ist+1):(ist+kP),j]==1]
         jdx=length(idx)
         if(jdx > 0){
            sPH[idx,j]=est[(icnt+1):(icnt+jdx)]
            sesPH[idx,j]=se.coef[(icnt+1):(icnt+jdx)]
            icnt=icnt+jdx
         }
      }
       ist=ist+kP
      beta=rbind(beta,sPH)
      sebeta=rbind(sebeta,sesPH)
   }
   TH=NULL;seTH=NULL; sTH=NULL; sesTH=NULL
   if(q > 0){
      TH=matrix(0,kq,k)
      seTH=matrix(0,kq,k)
      for (j in 1:k){
         idx=c(1:kq)[fixed[(ist+1):(ist+kq),j]==1]
         jdx=length(idx)
         if(jdx > 0){
            TH[idx,j]=est[(icnt+1):(icnt+jdx)]
            seTH[idx,j]=se.coef[(icnt+1):(icnt+jdx)]
            icnt=icnt+jdx
         }
       }
      ist=ist+kq
      beta=rbind(beta,-TH)
      sebeta=rbind(sebeta,seTH)
   }
   if(Q > 0){
      sTH=matrix(0,kQ,k)
      sesTH=matrix(0,kQ,k)
      for (j in 1:k){
         idx=c(1:kQ)[fixed[(ist+1):(ist+kQ),j]==1]
         jdx=length(idx)
         if(jdx > 0){
            sTH[idx,j]=est[(icnt+1):(icnt+jdx)]
            sesTH[idx,j]=se.coef[(icnt+1):(icnt+jdx)]
            icnt=icnt+jdx
         }
      }
      beta=rbind(beta,-sTH)
      sebeta=rbind(sebeta,sesTH)
   }
   cat("---","\n")
   cat("Estimates in matrix form:","\n")
   if(include.mean){
      cat("Constant term: ","\n")
      cat("Estimates: ",Ph0,"\n")
   }
   if(p > 0){
      cat("Regular AR coefficient matrix","\n")
      jcnt=0
      for (i in 1:p){
         cat("AR(",i,")-matrix","\n")
         ph=t(PH[(jcnt+1):(jcnt+k),])
         print(ph,digits=3)
         jcnt=jcnt+k
      }
    }
    if(P > 0){
      cat("Seasonal AR coefficient matrix","\n")
      jcnt=0
      for (i in 1:P){
         cat("AR(",i*s,")-matrix","\n")
         ph=t(sPH[(jcnt+1):(jcnt+k),])
         print(ph,digits=3)
         jcnt=jcnt+k
      }
    }
   if(q > 0){
      cat("Regular MA coefficient matrix","\n")
      icnt=0
      for (i in 1:q){
         cat("MA(",i,")-matrix","\n")
         the=t(TH[(icnt+1):(icnt+k),])
         print(the,digits=3)
         icnt=icnt+k
      }
    }
   if(Q > 0){
      cat("Seasonal MA coefficient matrix","\n")
      icnt=0
      for (i in 1:Q){
         cat("MA(",i*s,")-matrix","\n")
         the=t(sTH[(icnt+1):(icnt+k),])
         print(the,digists=3)
         icnt=icnt+k
      }
    }
   ######### Obtain product coefficient matrices
   if((p > 0)&&(P > 0)){
      if(switch){
         Phi=t(Mtxprod1(t(PH),t(sPH),p,P))
      }
      else{
         Phi=t(Mtxprod(t(PH),t(sPH),p,P))
      }
   }
   if((p > 0)&&(P==0))Phi=PH
   if((p==0)&&(P > 0))Phi=sPH
   if((q > 0)&&(Q > 0)){
      if(switch){
         Theta=t(Mtxprod1(t(TH),t(sTH),q,Q))
      }
      else{
         Theta=t(Mtxprod(t(TH),t(sTH),q,Q))
      }
   }
   #
   if((q > 0)&&(Q==0))Theta=TH
   if((q==0)&&(Q > 0))Theta=sTH
   ##### Compute the residuals
   zt=DX
   pqmax=max(ARlags,MAlags)
   ist=pqmax+1
   #### consider the case t from ist to T
   at=Sresi[1:pqmax,]
   for (t in ist:nT){
      tmp=zt[t,]-Ph0
      if(nar > 0){
         for (j in 1:nar){
            jj=ARlags[j]
            jdx=(j-1)*k
            ph=Phi[(jdx+1):(jdx+k),]
            tmp=tmp-matrix(zt[(t-jj),],1,k)%*%ph
         }
      }
      if(nma > 0){
         for (j in 1:nma){
            jj=MAlags[j]
            jdx=(j-1)*k
            th=Theta[(jdx+1):(jdx+k),]
            tmp=tmp+matrix(at[(t-jj),],1,k)%*%th
         }
      }
      at=rbind(at,tmp)
   }
   at=at[(ist:nT),]
   c1 = rep("resi",k)
   colnames(at) <- c1
   sig=t(at)%*%at/(nT-pqmax)
   cat(" ","\n")
   cat("Residuals cov-matrix:","\n")
   print(sig)
   dd=det(sig)
   d1=log(dd)
   aic=d1+2*npar/nT
   bic=d1+log(nT)*npar/nT
   cat("----","\n")
   cat("aic= ",round(aic,4),"\n")
   cat("bic= ",round(bic,4),"\n")
   if(length(PH) > 0)PH=t(PH)
   if(length(sPH) > 0)sPH=t(sPH)
   if(length(TH) > 0)TH=t(TH)
   if(length(sTH) > 0)sTH=t(sTH)

   sVARMA <- list(data=da,order=order,sorder=sorder,period=s,cnst=include.mean,coef=beta,secoef=sebeta,residuals=at,Sigma=sig,aic=aic,bic=bic,regPhi=PH,seaPhi=sPH, regTheta=TH, seaTheta=sTH, Ph0=Ph0,switch=switch)
}

"Mtxprod" <- function(Mtx,sMtx,p,P){
   # obtain the coefficient matrices of product of two matrix polynomials
   if(!is.matrix(Mtx))Mtx=as.matrix(Mtx)
   if(!is.matrix(sMtx))sMtx=as.matrix(sMtx)
   k=dim(Mtx)[1]
   kp=dim(Mtx)[2]
   kP=dim(sMtx)[2]
   #
   pMtx=Mtx
   for (i in 1:P){
      ii=(i-1)*k
      m2=sMtx[,(ii+1):(ii+k)]
      pMtx=cbind(pMtx,m2)
      for (j in 1:p){
         jdx=(j-1)*k
         m1=Mtx[,(jdx+1):(jdx+k)]
         pMtx=cbind(pMtx,-m1%*%m2)
      }
   }
   pMtx
 }

"Mtxprod1" <- function(Mtx,sMtx,p,P){
   # obtain the coefficient matrices of product of two matrix polynomials
   if(!is.matrix(Mtx))Mtx=as.matrix(Mtx)
   if(!is.matrix(sMtx))sMtx=as.matrix(sMtx)
   k=dim(Mtx)[1]
   kp=dim(Mtx)[2]
   kP=dim(sMtx)[2]
   #
   pMtx=Mtx
   for (i in 1:P){
      ii=(i-1)*k
      m2=sMtx[,(ii+1):(ii+k)]
      pMtx=cbind(pMtx,m2)
      for (j in 1:p){
         jdx=(j-1)*k
         m1=Mtx[,(jdx+1):(jdx+k)]
         pMtx=cbind(pMtx,-m2%*%m1)
      }
   }
   pMtx
}

"refsVARMA" <- function(model,thres=0.8){
   # This program refines the fitted models of sVARMA output by removing
   # insigificant parameters with abs(t-ratio) < thres.
   # model: output object from sVARMA
   # thres: threshold value
   #
   x = model$data
   order=model$order
   sorder=model$sorder
   s=model$period
   cnst = model$cnst
   swi = model$switch
   coef=as.matrix(model$coef)
   secoef=as.matrix(model$secoef)
   nr=dim(coef)[1]
   nc=dim(coef)[2]
   for (j in 1:nc){
      idx=is.na(secoef[,j])
      jdx=c(1:nr)[idx==T]
      secoef[jdx,j]=0.01
   }
   fix=matrix(0,nr,nc)
   for (j in 1:nc){
      tt=coef[,j]/secoef[,j]
      idx=c(1:nr)[abs(tt) >= thres]
      fix[idx,j]=1
   }
   ### Try to keep the constant if the t-ratio is greater then 1.
   if(cnst){
      tt=coef[1,]/secoef[1,]
      idx=c(1:nc)[abs(tt) > 1.0]
      if(length(idx) > 0)fix[1,idx]=1
   }

   mm=sVARMA(x,order,sorder,s,include.mean=cnst,fixed=fix,switch=swi)

   refsVARMA <- list(data=x,coef=mm$coef,secoef=mm$secoef,order=mm$order,sorder=mm$sorder,period=mm$period,cnst=cnst,residuals=mm$residuals,regPhi=mm$regPhi,seaPhi=mm$seaPhi,regTheta=mm$regTheta,seaTheta=mm$seaTheta,Ph0=mm$Pho,Sigma=mm$Sigma,aic=mm$aic,bic=mm$bic,switch=mm$switch)

}

"VARX" <- function(zt,p,xt=NULL,m=0,include.mean=T,fixed=NULL,output=T){
   #This command fits the model
   ## z(t) = c0 + sum_{i=1}^p phi_i * z(t-i) + \sum_{j=0}^m xt(t-j) + a(t).
   ##
   zt=as.matrix(zt)
   if(length(xt) < 1){
      m = -1; kx=0}
   else{
      xt=as.matrix(xt); kx=dim(xt)[2]
    }
   if(p < 0)p=0
   ist=max(p,m)+1
   nT=dim(zt)[1]
   k=dim(zt)[2]
   yt=zt[ist:nT,]
   xmtx=NULL
   if(include.mean)xmtx=rep(1,(nT-ist+1))
   #
   if(p > 0){
      for (i in 1:p){
         xmtx=cbind(xmtx,zt[(ist-i):(nT-i),])
      }
   }
   #
   if( m > -1){
      for (j in 0:m){
         xmtx=cbind(xmtx,xt[(ist-j):(nT-j),])
      }
   }
   #
   p1=dim(xmtx)[2]
   nobe=dim(xmtx)[1]
   ##cat("dim of xmtx",c(nobe,p1),"\n")
   #
   if(length(fixed) < 1){
      ## no constriants
      xpx=t(xmtx)%*%xmtx
      xpy=t(xmtx)%*%yt
      xpxi=solve(xpx)
      beta=xpxi%*%xpy
      resi=as.matrix(yt-xmtx%*%beta)
      sig=crossprod(resi,resi)/nobe
      co=kronecker(sig,xpxi)
      se=sqrt(diag(co))
      se.beta=matrix(se,nrow(beta),k)
      npar=nrow(beta)*k
      d1=log(det(sig))
      aic=d1+2*npar/nobe
      bic=d1+(npar*log(nobe))/nobe
   }
   else{
      # with zero-parameter constriants
      beta=matrix(0,p1,k)
      se.beta=matrix(1,p1,k)
      resi=yt
      npar=0
      for (i in 1:k){
         idx=c(1:p1)[fixed[,i] > 0]
         npar=npar+length(idx)
         if(length(idx) > 0){
            xm=as.matrix(xmtx[,idx])
            y1=matrix(yt[,i],nobe,1)
            xpx=t(xm)%*%xm
            xpy=t(xm)%*%y1
            xpxi=solve(xpx)
            beta1=xpxi%*%xpy
            res = y1 - xm%*%beta1
            sig1=sum(res^2)/nobe
            se=sqrt(diag(xpxi)*sig1)
            beta[idx,i]=beta1
            se.beta[idx,i]=se
            resi[,i]=res
         }
         # end of for (i in 1:k)
      }
      #
      sig=crossprod(resi,resi)/nobe
      d1=log(det(sig))
      aic=d1+2*npar/nobe
      bic=d1+log(nobe)*npar/nobe
      # end of else
   }
   ### print
   Ph0=NULL
   icnt=0
   if(include.mean){
      Ph0=beta[1,]; icnt=icnt+1
      cat("constant term: ","\n")
      cat("est: ",round(Ph0,4),"\n")
      cat(" se: ",round(se.beta[1,],4),"\n")
   }
   Phi=NULL
   if(p > 0){
      Phi=t(beta[(icnt+1):(icnt+k*p),])
      sePhi=t(se.beta[(icnt+1):(icnt+k*p),])
      for (j in 1:p){
         cat("AR(",j,") matrix","\n")
         jcnt=(j-1)*k
         print(round(Phi[,(jcnt+1):(jcnt+k)],3))
         cat("standard errors","\n")
         print(round(sePhi[,(jcnt+1):(jcnt+k)],3))
      }
      icnt=icnt+k*p
      ## end of if(p > 0)
   }
   if(m > -1){
      cat("Coefficients of exogenous","\n")
      Beta=t(beta[(icnt+1):(icnt+(m+1)*kx),])
      seBeta=t(se.beta[(icnt+1):(icnt+(m+1)*kx),])
      if(kx == 1){
       Beta=t(Beta)
       seBeta=t(seBeta)
       }
      for (i in 0:m){
         jdx=i*kx
         cat("lag-",i," coefficient matrix","\n")
         print(round(Beta[,(jdx+1):(jdx+kx)],3))
         cat("standard errors","\n")
         print(round(seBeta[,(jdx+1):(jdx+kx)],3))
      }
      ## end of if(m > -1)
   }
   ##
   cat("Residual Covariance Matrix","\n")
   print(round(sig,5))
   cat("===========","\n")
   cat("Information criteria: ","\n")
   cat("AIC: ",aic,"\n")
   cat("BIC: ",bic,"\n")

   VARX <- list(data=zt,xt=xt,aror=p,m=m,Ph0=Ph0,Phi=Phi,beta=Beta,residuals=resi,Sigma=sig,
   coef=beta,se.coef=se.beta,include.mean=include.mean)
}

##### Refine VARX model
"refVARX" <- function(m1,thres=1.0){
   zt=m1$data; xt=m1$xt
   p=m1$aror; m=m1$m; include.m=m1$include.mean
   beta=m1$coef; se.beta=m1$se.coef
   fix=matrix(0,nrow(beta),ncol(beta))
   for (i in 1:ncol(beta)){
      tt=beta[,i]/se.beta[,i]
      idx=c(1:nrow(beta))[abs(tt) > thres]
      if(length(idx) > 0){
         fix[idx,i]=1}
   }

   mm=VARX(zt,p,xt,m,include.mean=include.m,fixed=fix)
   Ph0=mm$Ph0; Phi=mm$Phi; Beta=mm$beta; resi=mm$residuals
   sig=mm$Sigma; coef=mm$beta; se.coef=mm$se.coef

   refVARX <- list(data=zt,aror=p,xt=xt,m=m,Ph0=Ph0,Phi=Phi,beta=Beta,residuals=resi,Sigma=sig,
   coef=coef,se.coef=se.coef,include.mean=include.m)
}

##### Prediction of VARX models.
#####
"VARXpred" <- function(m1,newxt=NULL,hstep=1,orig=0){
   #This program predicts the VARX model.
   ## z(t) = c0 + sum_{i=1}^p phi_i * z(t-i) + \sum_{j=0}^m xt(t-j) + a(t).
   ##
   zt=as.matrix(m1$data); xt=as.matrix(m1$xt); p=m1$aror; m=m1$m
   Ph0=as.matrix(m1$Ph0); Phi=as.matrix(m1$Phi); Sig=as.matrix(m1$Sigma); beta=as.matrix(m1$beta)
   include.m=m1$include.mean
   nT=dim(zt)[1]; k=dim(zt)[2]; dx=dim(xt)[2]
   se=NULL
   if(length(Ph0) < 1)Ph0=matrix(rep(0,k),k,1)
   if(hstep < 1)hstep=1
   if(orig < 1) orig=nT
   #
   if(length(newxt) > 0){
      if(!is.matrix(newxt))newxt=as.matrix(newxt)
      ### calculate predictions
      h1=dim(newxt)[1]
      hstep=min(h1,hstep)
      nzt=as.matrix(zt[1:orig,])
# xt=rbind(as.matrix(xt[1:orig,]),newxt)
### changed made on 7/30/2014
### changed made on 3/5/2015
      if(dx > 1){
        xt=rbind(xt[1:orig,,drop=FALSE],newxt)
	}
	else{
	 xt=as.matrix(c(c(xt[1:orig,]),c(newxt)))
	 }
      for (i in 1:hstep){
         tmp=Ph0
         ti=orig+i
         ## VAR part
         for (i in 1:p){
            idx=(i-1)*k
            tmp=tmp+Phi[,(idx+1):(idx+k)]%*%matrix(nzt[ti-i,],k,1)
         }
         if(m > -1){
            for (j in 0:m){
               jdx=j*dx
               tmp=tmp+beta[,(jdx+1):(jdx+dx)]%*%matrix(xt[ti-j,],dx,1)
            }
         }
         nzt=rbind(nzt,c(tmp))
      }
      ### compute standard errors of predictions
      mm=VARpsi(Phi,lag=hstep)
      Si=Sig
      se=matrix(sqrt(diag(Si)),1,k)
      if(hstep > 1){
         for (i in 2:hstep){
            idx=(i-1)*k
            wk=as.matrix(mm$psi[,(idx+1):(idx+k)])
            Si=Si+wk%*%Sig%*%t(wk)
            se1=sqrt(diag(Si))
            se=rbind(se,se1)
         }
      }
      ### Print forecasts
      cat("Prediction at origin: ",orig,"\n")
      cat("Point forecasts (starting with step 1): ","\n")
      print(round(nzt[(orig+1):(orig+hstep),],5))
      cat("Corresponding standard errors: ","\n")
      print(round(se[1:hstep,],5))

   }
   else{
      cat("Need new data for input variables!","\n")
   }
   #
return <- list(pred=nzt[(orig+1):(orig+hstep),],se=se[1:hstep,],orig=orig,h=hstep)
}
############################
"VARXorder" <- function(x,exog,maxp=13,maxm=3,output=T){
   # Compute the AIC, BIC, HQ values and M-stat
   ##### This is a modified version of the old program in "VARorderE",
   ##### which uses the same number of data points.
   #####
   x1=as.matrix(x)
   exog=as.matrix(exog)
   nT=dim(x1)[1]
   k=dim(x1)[2]
   ksq=k*k
   if(maxp < 1)maxp=1
   nT1=dim(exog)[1]; m=dim(exog)[2]
   #
   if(nT1 > nT){
      cat("Adjustment made for different nobs:",c(nT,nT1), "\n")
   }
   if(nT > nT1){
      cat("Adjustment made for different nobs:",c(nT,nT1),"\n")
      nT=nT1
   }
   ###
   aic=matrix(0,maxp+1,maxm+1)
   bic=aic; hq=aic
   for (mm in 0:maxm){
      ### start with VAR(0) model, which uses just the sample means.
      isto=mm+1
      y=x1[isto:nT,]
      xm=rep(1,rep(nT-mm))
      for (i in 0:mm){
         xm=cbind(xm,exog[(isto-i):(nT-i),])
      }
      xm=as.matrix(xm)
      xpx=crossprod(xm,xm)
      xpxi=solve(xpx)
      xpy=t(xm)%*%y
      beta=xpxi%*%xpy
      y=y-xm%*%beta
      #
      s=t(y)%*%y/(nT-mm)
      enob=nT-mm
      c1=log(det(s))
      aic[1,mm+1]=c1+2*k*mm/enob
      bic[1,mm+1]=c1+log(enob)*k*m/enob
      hq[1,mm+1]=c1+2*log(log(enob))*k*m/enob
      #
      for (p in 1:maxp){
         ist=max(mm+1,p+1)
         enob=nT-ist+1
         y=as.matrix(x1[ist:nT,])
         xmtx=rep(1,enob)
         for (i in 0:mm){
            xmtx=cbind(xmtx,exog[(ist-i):(nT-i),])
          }
         for (j in 1:p){
            xmtx=cbind(xmtx,x1[(ist-j):(nT-j),])
          }
         xm1=as.matrix(xmtx)
         xpx = t(xm1)%*%xm1
         xpxinv=solve(xpx)
         xpy=t(xm1)%*%y
         beta=xpxinv%*%xpy
         resi=y-xm1%*%beta
         sse=(t(resi)%*%resi)/enob
         #print(paste("For p = ",p,"residual variance is", sse))
         d1=log(det(sse))
         npar=p*ksq+k*(mm+1)
         aic[p+1,mm+1]=d1+(2*npar)/enob
         bic[p+1,mm+1]=d1+(log(enob)*npar)/enob
         hq[p+1,mm+1]=d1+(2*log(log(enob))*npar)/enob
      }
      #end of for (mm in 0:maxm)
   }

 ind.min <- function(x){
   if(!is.matrix(x))x=as.matrix(x)
   r=dim(x)[1]
   c=dim(x)[2]
   xm=min(x)
   COntin=TRUE
   while(COntin){
      for(j in 1:c){
         idx=c(1:r)[x[,j]==xm]
         jj=j
         if(length(idx) > 0){
            ii=c(1:r)[x[,jj]==xm][1]
            kdx=c(ii,jj)
            ##print(kdx)
            COntin=FALSE
         }
      }
    }
    kdx
  }
   ## selection
   aicor=ind.min(aic)-1; bicor=ind.min(bic)-1;hqor=ind.min(hq)-1
   if(output){
      cat("selected order(p,s): aic = ",aicor,"\n")
      cat("selected order(p,s): bic = ",bicor,"\n")
      cat("selected order(p,s): hq = ",hqor,"\n")
   }

   VARXorder<-list(aic=aic,aicor=aicor,bic=bic,bicor=bicor,hq=hq,hqor=hqor)
 }

#### Regression model with time series errors (Multivariate case)
"REGts" <- function(zt,p,xt,include.mean=T,fixed=NULL,par=NULL,se.par=NULL,details=F){
   ## Fit a multivariate regression model with time series errors
   ### VAR model only.
   ### obtain preliminary estimation if needed.
   if(!is.matrix(zt))zt=as.matrix(zt)
   if(!is.matrix(xt))xt=as.matrix(xt)
   nT=dim(zt)[1];  k <- dim(zt)[2]
   kx=dim(xt)[2]
   if(p < 0)p=0
   if(length(par) < 1){
      m1=Mlm(zt,xt,constant=include.mean,output=F)
      par=c(m1$beta)
      r1=dim(m1$beta)[1]
      se.par=c(m1$se.beta)
      res=m1$residuals
      if(p > 0){
         m2=VAR(res,p,include.mean=F,output=F)
         par1=c(m2$coef); par=c(par,par1)
         se1=c(m2$secoef); se.par=c(se.par,se1)
         r2=dim(m2$coef)[1]
      }
      if(length(fixed) < 1){
         fixed=matrix(1,(r1+r2),k)
      }
    }
   r1=kx
   if(include.mean){r1=r1+1; kx=kx+1}
   r2=p*k
   cat("Number of parameters: ",length(par),"\n")
   cat("initial estimates: ",par,"\n")
   ### Set up lower and upper bounds
   lowerBounds=par; upperBounds=par
   npar=length(par)
   mult=1.5
   if(npar > 10)mult=1.3
   for (j in 1:npar){
      lowerBounds[j] = par[j]-mult*se.par[j]
      upperBounds[j] = par[j]+mult*se.par[j]
   }
   cat("Par. Lower-bounds: ",lowerBounds,"\n")
   cat("Par. Upper-bounds: ",upperBounds,"\n")

 RegXmtx <- function(zt,xt,p,par,include.mean,fixed){
  nT <- dim(zt)[1]; k <- dim(zt)[2]; kx <- dim(xt)[2]
   xmtx=xt; ist=p+1
   if(include.mean){
      xmtx=cbind(rep(1,nT),xmtx)
      kx=kx+1
    }
   ## setup parameter matrix for regressors
   beta=matrix(0,kx,k)
   icnt=0
   for(i in 1:k){
      idx=c(1:kx)[fixed[1:kx,i] > 0]
      if(length(idx) > 0){
         ii=length(idx)
         beta[idx,i]=par[(icnt+1):(icnt+ii)]
         icnt=icnt+ii
       }
     }
   res=zt-as.matrix(xmtx)%*%beta
   resi=res; tsxm=NULL
   if(p > 0){
      tsxm=res[(ist-1):(nT-1),]
      if(p > 1){
         for (j in 2:p){
            tsxm=cbind(tsxm,res[(ist-j):(nT-j),])
          }
       }
      #setup time-series parameter
      kp=p*k
      Phi=matrix(0,kp,k)
      fix1=fixed[(kx+1):(kx+kp),]
      for (i in 1:k){
         idx=c(1:kp)[fix1[,i] > 0]
         jj=length(idx)
         if(jj > 0){
            Phi[idx,i]=par[(icnt+1):(icnt+jj)]
            icnt=icnt+jj
         }
       }
      resi=res[ist:nT,]-as.matrix(tsxm)%*%Phi
     }
   RegXmtx <- list(xmtx=xmtx,residuals=resi)
  }

lRegts <- function(par,zt=zt,xt=xt,p=p,include.mean=include.mean,fixed=fixed){
   # compute the log-likelihood function of a REGts model
   nT <- dim(zt)[1];    k <- dim(zt)[2]
   nobe=nT-p
   m1=RegXmtx(zt,xt,p,par,include.mean,fixed)
   resi=m1$residuals
   ##
   ## evaluate log-likelihood function
   resi=as.matrix(resi)
   sig=t(resi)%*%resi/nobe
   ll=dmvnorm(resi,rep(0,k),sig)
   lRegts=-sum(log(ll))
  }

   # Estimate Parameters and Compute Numerically Hessian:
   if(details){
      fit = nlminb(start = par, objective = lRegts, zt=zt,xt=xt,p=p,include.mean=include.mean,fixed=fixed,
              lower = lowerBounds, upper = upperBounds, control = list(trace=3))}
   else{
      fit = nlminb(start = par, objective = lRegts, zt=zt,xt=xt,p=p,include.mean=include.mean,fixed=fixed,
          control=list(step.min=0.2,step.max=0.5), lower = lowerBounds, upper = upperBounds)
      #fit=optim(par,lRegts,method=c("L-BFGS-B"),lower=lowerBounds,upper=upperBounds,hessian=TRUE)
   }
   epsilon = 0.0001 * fit$par
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] = (lRegts(x1,zt=zt,xt=xt,p=p,include.mean=include.mean,fixed=fixed)
                         -lRegts(x2,zt=zt,xt=xt,p=p,include.mean=include.mean,fixed=fixed)
                         -lRegts(x3,zt=zt,xt=xt,p=p,include.mean=include.mean,fixed=fixed)
                         +lRegts(x4,zt=zt,xt=xt,p=p,include.mean=include.mean,fixed=fixed))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   est=fit$par
   cat("Final   Estimates: ",est,"\n")
   # Step 6: Create and Print Summary Report:
   se.coef = sqrt(diag(solve(Hessian)))
   tval = fit$par/se.coef
   matcoef = cbind(fit$par, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)
   #
   ### Prepare parameters for printing
   beta=NULL; se.beta=NULL; Phi=NULL; se.Phi=NULL; icnt=0
   ### Regressor parameters
   if(r1 > 0){
      beta=matrix(0,r1,k)
      se.beta=matrix(1,r1,k)
      for (i in 1:k){
         idx=c(1:r1)[fixed[1:r1,i] > 0]
         ii=length(idx)
         if(ii > 0){
            beta[idx,i]=est[(icnt+1):(icnt+ii)]
            se.beta[idx,i]=se.coef[(icnt+1):(icnt+ii)]
            icnt=icnt+ii
          }
       }
      cat("======= ","\n")
      cat("Coefficient matrix for constant + exogenous variable","\n")
      cat("Estimates: ","\n")
      print(round(t(beta),3))
      cat("Standard errors: ","\n")
      print(round(t(se.beta),3))
     }
   ### VAR parameters
   if(r2 > 0){
      Phi=matrix(0,r2,k)
      se.Phi=matrix(1,r2,k)
      fix1=fixed[(r1+1):(r1+r2),]
      for (i in 1:k){
         idx=c(1:r2)[fix1[1:r2,i] > 0]
         ii=length(idx)
         if(ii > 0){
            Phi[idx,i]=est[(icnt+1):(icnt+ii)]
            se.Phi[idx,i]=se.coef[(icnt+1):(icnt+ii)]
            icnt=icnt+ii
          }
       }
      cat("VAR coefficient matrices: ","\n")
      for (i in 1:p){
         kdx=(i-1)*k
         cat("AR(",i,") coefficient: ","\n")
         phi=t(Phi[(kdx+1):(kdx+k),])
         print(round(phi,3))
         cat("standard errors:","\n")
         sephi=t(se.Phi[(kdx+1):(kdx+k),])
         print(round(sephi,3))
       }
    }
   ### compute the residuals
   m1=RegXmtx(zt,xt,p,est,include.mean,fixed)
   resi=m1$residuals
   sig=t(resi)%*%resi/(nT-p)
   cat("Residual Covariance matrix: ","\n")
   print(sig,digits=4)
   d1=log(det(sig))
   aic=d1+2*npar/(nT-p)
   bic=d1+log(nT-p)*npar/(nT-p)
   cat("============","\n")
   cat("Information criteria: ","\n")
   cat("AIC: ",aic,"\n")
   cat("BIC: ",bic,"\n")
   #
   coef=rbind(beta,Phi)
   se.coef=rbind(se.beta,se.Phi)

   REGts <- list(data=zt,xt=xt,aror=p,include.mean=include.mean,Phi=t(Phi),se.Phi=t(se.Phi),
   beta=t(beta),se.beta=t(se.beta),residuals=resi,Sigma=sig,coef=coef,se.coef=se.coef)
}


#### Refinement
"refREGts" <- function(m1,thres=1.0){
   zt=m1$data; xt=m1$xt; p=m1$aror; include.m=m1$include.mean
   coef=m1$coef; se.coef=m1$se.coef
   k=dim(zt)[2]
   n1=dim(coef)[1]
   kx=dim(xt)[2]
   if(include.m)kx=kx+1
   icnt=0
   par=NULL; separ=NULL
   ### locate significant beta-parameters
   fix1=matrix(0,kx,k)
   for (i in 1:k){
      tt=coef[1:kx,i]/se.coef[1:kx,i]
      idx=c(1:kx)[abs(tt) > thres]
      ii=length(idx)
      if(ii > 0){
         par=c(par,coef[idx,i])
         separ=c(separ,se.coef[idx,i])
         fix1[idx,i]=1
         icnt=icnt+ii
      }
   }
   ## locate the significant VAR parameters
   r2=n1-kx
   Phi=coef[(kx+1):n1,]
   sePhi=se.coef[(kx+1):n1,]
   fix2=matrix(0,r2,k)
   for (i in 1:k){
      tt=Phi[,i]/sePhi[,i]
      jdx=c(1:r2)[abs(tt) > thres]
      jj=length(jdx)
      if(jj > 0){
         par=c(par,Phi[jdx,i])
         separ=c(separ,sePhi[jdx,i])
         icnt=icnt+jj
         fix2[jdx,i]=1
      }
   }
   fix=rbind(fix1,fix2)
   ####print(fix)

   mm = REGts(zt,p,xt,include.mean=include.m,fixed=fix,par=par,se.par=separ)
   coef=mm$coef;se.coef=mm$se.coef;Phi=t(mm$Phi);se.Phi=t(mm$se.Phi)
   beta=t(mm$beta);se.beta=t(mm$se.beta);resi=mm$residuals;sig=mm$Sigma

   refREGts <- list(data=zt,xt=xt,aror=p,include.mean=include.m,Phi=t(Phi),se.Phi=t(se.Phi),
   beta=t(beta),se.beta=t(se.beta),residuals=resi,Sigma=sig,coef=coef,se.coef=se.coef)
}


"Mlm" <- function(y,z,constant=TRUE,output=TRUE){
   # This program performs multivariate linear regression analysis.
   # z: design matrix
   # constant: switch for the constant term of the regression model
   # y: dependent variables
   ## Model is y = z%*%beta+error
   z=as.matrix(z)
   n=nrow(z)
   nx=ncol(z)
   zc=z
   if (constant) zc=cbind(rep(1,n),z)
   p=ncol(zc)
   y=as.matrix(y)
   ztz=t(zc)%*%zc
   zty=t(zc)%*%y
   ztzinv=solve(ztz)
   beta=ztzinv%*%zty
   res=y-zc%*%beta
   sig=t(res)%*%res/(n-p)
   co=kronecker(sig,ztzinv)
   sd=sqrt(diag(co))
   se.beta=matrix(sd,nrow(beta),ncol(beta))
   #
   if(output){
      print("LSE of parameters")
      print("  est   s.d.   t-ratio    prob")
      par=c(beta)
      deg=n-p
      iend=nrow(beta)*ncol(beta)
      tmp=matrix(0,iend,4)
      for (i in 1:iend){
         tt=par[i]/sd[i]
         pr=2*(1-pt(abs(tt),deg))
         tmp[i,]=c(par[i],sd[i],tt,pr)
       }
      print(tmp,digits=3)
    }
   Mlm <- list(beta=beta,se.beta=se.beta,residuals=res,sigma=sig)
 }

#### Missing value programs
####
"Vmiss" <- function(zt,piwgt,sigma,tmiss,cnst=NULL,output=T){
   ## Estimate the missing values of a vector time series.
   ## zt: T-by-k time series
   ## piwgt: pi-weight matrices of the model: k-by-N matrix
   ### [pi1,pi2,pi3, ...]. The number of columns determines the loop used in
   ### estimating the missing value.
   ## tmiss: time index of missing values
   ## sigma: k-by-k matrix of the innovations
   ##
   ### cnst: k-by-1 vector of constant.
   ###      cnst is Ph0 for VAR model and [theta(1)]^{-1}*Ph0 for VARMA models.
   ###
   if(!is.matrix(zt))zt=as.matrix(zt)
   if(!is.matrix(piwgt))piwgt=as.matrix(piwgt)
   if(!is.matrix(sigma))sigma=as.matrix(sigma)
   m1=eigen(sigma)
   va=sqrt(m1$values); P=m1$vectors; di=diag(1/va)
   Sroot=P%*%di%*%t(P)  # square root matrix of sigma
   k=dim(zt)[2]; nT=dim(zt)[1]
   if(length(cnst) < 0){
      cnst=matrix(0,1,k)}
   else{
      cnst=matrix(cnst,1,k)
   }
   #
   lpi=dim(piwgt)[2]
   lags=floor(lpi/k)
   ## setup the multivariate linear regression
   Y=NULL; X=NULL; Tpiwgt=t(piwgt)
   zt1=zt; zt1[tmiss,]=rep(0,k)
   iend=min(nT,(tmiss+lags))
   if((tmiss > 1) && (tmiss < nT)){
      # estimate the missing values
      wk=matrix(0,1,lpi)
      icnt=0
      jend=min(tmiss-1,lags)
      for (j in 1:jend){
         wk[1,(icnt+1):(icnt+k)]=zt1[tmiss-j,]
         icnt=icnt+k
      }
      yt=wk%*%Tpiwgt+cnst
      xt=diag(rep(1,k))
      Y=Sroot%*%t(yt)
      X=Sroot%*%xt
      #
      Tmax=min(nT,tmiss+lags)
      iend=min(lags,Tmax-tmiss)
      for (i in 1:iend){
         wk[1,]=c(zt1[tmiss+i-1,],wk[1,1:(lpi-k)])
         yt=zt1[(tmiss+i),]-wk%*%Tpiwgt-cnst
         kst=(i-1)*k
         xt=piwgt[,(kst+1):(kst+k)]
         Y=rbind(Y,Sroot%*%t(yt))
         X=rbind(X,Sroot%*%xt)
      }
      xpx=t(X)%*%X
      xpy=t(X)%*%Y
      xpxi=solve(xpx)
      est=xpxi%*%xpy
      if(output){
         cat("Estimate of missing value at time index",tmiss,"\n")
         print(round(est,5))
       }
   }
   return(est)
 }

"Vpmiss" <- function(zt,piwgt,sigma,tmiss,mdx,cnst=NULL,output=T){
   ## Estimate a PARTIALLY missing observation of a vector time series.
   ## See Vmiss for variable descriptions
   ### mdx: a k-dimensional vector to locating missing components.
   ### mdx[i] = 0 if the i-th component is missing;
   ### mdx[i] = 1 if the -th component is observed.
   ###
   if(!is.matrix(zt))zt=as.matrix(zt)
   if(!is.matrix(piwgt))piwgt=as.matrix(piwgt)
   if(!is.matrix(sigma))sigma=as.matrix(sigma)
   k=dim(zt)[2]; nT=dim(zt)[1]
   if(length(mdx) < 1)mdx=rep(0,k)
   miss=c(1:k)[mdx==0]
   nmiss=c(1:k)[mdx==1]
   nm=length(miss)
   arrange=c(miss,nmiss)
   ARR=diag(rep(1,k))
   ARR=ARR[,arrange]
   ARRi=solve(ARR)
   ### re-arrange the Sigma matrix
   sig=ARR%*%sigma%*%t(ARR)
   m1=eigen(sig)
   va=sqrt(m1$values); P=m1$vectors; di=diag(1/va)
   Sroot=P%*%di%*%t(P)  # square root matrix of sigma
   #
   if(length(cnst) < 0){
      cnst=matrix(0,1,k)}
   else{
      cnst=matrix(cnst,1,k)
   }
   #
   ncnst=t(ARR%*%t(cnst))
   lpi=dim(piwgt)[2]
   lags=floor(lpi/k)
   ## compute the transformed pi-weight matrices
   npiwgt=piwgt
   for (i in 1:lags){
      icnt=(i-1)*k
      tmp=piwgt[,(icnt+1):(icnt+k)]
      tmp1=ARR%*%tmp%*%ARRi
      npiwgt[,(icnt+1):(icnt+k)]=tmp1
   }
   ##### Partially missing can occur at any time point
   ##### This part is different from "Vmiss.R". However, estimation of
   ##### missing values at the beginning of a time series may not be efficient.
   ## setup the multivariate linear regression
   Y=NULL; X=NULL; Tpiwgt=t(npiwgt)
   zt1=zt[,arrange]; zt1[tmiss,1:nm]=rep(0,nm)
   yobs=rep(0,k)
   if(k > nm)yobs=matrix(zt1[tmiss,(nm+1):k],(k-nm),1)
   zt1[tmiss,]=rep(0,k)
   iend=min(nT,(tmiss+lags))
   # estimate the missing values
   wk=matrix(0,1,lpi)
   icnt=0
   jend=min(tmiss-1,lags)
   if(jend > 0){
      for (j in 1:jend){
         wk[1,(icnt+1):(icnt+k)]=zt1[tmiss-j,]
         icnt=icnt+k
       }
    }
   yt=wk%*%Tpiwgt+ncnst
   xt=diag(rep(1,k))
   Y1=Sroot%*%t(yt)
   X1=Sroot%*%xt
   if(k > nm){
      Y=Y1-X1[,(nm+1):k]%*%yobs
     }
   else{
      Y=Y1
    }
   X=X1[,1:nm]
   if(nm == 1)X=matrix(X1[,1],k,1)
   Tmax=min(nT,tmiss+lags)
   iend=min(lags,Tmax-tmiss)
   if(iend > 0){
      for (i in 1:iend){
         if(lpi > k){
           wk[1,]=c(zt1[tmiss+i-1,],wk[1,1:(lpi-k)])
           }
           else{
            wk[1,]=zt1[tmiss+i-1,]
            }
         yt=zt1[(tmiss+i),]-wk%*%Tpiwgt-ncnst
         kst=(i-1)*k
         xt=npiwgt[,(kst+1):(kst+k)]
         Y1=Sroot%*%t(yt)
         X1=Sroot%*%as.matrix(xt)
         if(k > nm){
            Y=rbind(Y,Y1-X1[,(nm+1):k]%*%yobs)
          }
         else{
            Y=rbind(Y,Y1)
          }
         if(nm==1){
            X1=matrix(X1[,1],k,1)
            X=rbind(X,X1)
          }
         else{
            X=rbind(X,X1[,1:nm])}
      }
   }
   xpx=t(X)%*%X
   xpy=t(X)%*%Y
   xpxi=solve(xpx)
   est=xpxi%*%xpy
   if(output){
      cat("Estimate of missing value at time index",tmiss,"\n")
      cat("The missing idicator is: ",mdx,"\n")
      print(round(est,5))
    }
   return(est)
 }

"SCMid" <- function(zt,maxp=5,maxq=5,h=0,crit=0.05,output=FALSE){
   ### Identify SCMs for a given k-dimensional time series zt.
   if(!is.matrix(zt))zt=as.matrix(zt)
   nT=dim(zt)[1]
   k=dim(zt)[2]
   nar=maxp+1; nma=maxq+1
   zeroTbl=matrix(0,nar,nma)
   diagDif=matrix(0,nar,nma)
   for (m in 0:maxp){
      for (j in 0:maxq){
         ##h=maxq-1-j
         ist=m+j+h+2
         ### setup the Ymt matrix
         Ymt=zt[ist:nT,]
         if(m > 0){
            for (i in 1:m){
               Ymt=cbind(Ymt,zt[(ist-i):(nT-i),])
            }
         }
         Ymt=as.matrix(Ymt)
         k1=dim(Ymt)[2]
         ### setup the Yht-matrix and denote it by Pt.
         Pt=zt[(ist-j-1):(nT-j-1),]
         if(m > 0){
            for (i in 1:m){
               Pt=cbind(Pt,zt[(ist-1-i-j):(nT-1-i-j),])
            }
         }
         if(h > 0){
            for (i in 1:h){
               Pt=cbind(Pt,zt[(ist-1-j-m-i):(nT-1-j-m-i),])
            }
         }
         Pt=as.matrix(Pt)
         ##print(c(dim(Ymt),dim(Pt)))
         m1=cancor(Ymt,Pt)
         corsq=m1$cor^2
         #
         if(output){
            cat("For (m,j) = ",c(m,j),"\n")
            cat("Squares of canonical correlations: ","\n")
            print(round(sort(corsq),3))
         }
         ### compute the variance of canonical correlations
         dsq=rep(1,k1)
         if(j > 0){
            xM=as.matrix(m1$xcoef)
            yM=as.matrix(m1$ycoef)
            ## Normalization
            for (kk in 1:k1){
               xM[,kk]=xM[,kk]/sqrt(sum(xM[,kk]^2))
               yM[,kk]=yM[,kk]/sqrt(sum(yM[,kk]^2))
            }
            xT=Ymt%*%xM
            yT=Pt%*%yM[,1:k1]
            for (jj in 1:k1){
               d1=1.0
               m1a=acf(xT[,jj],lag.max=j,plot=F)
               m1b=acf(yT[,jj],lag.max=j,plot=F)
               for (ij in 2:(j+1)){
                  d1=d1+2*m1a$acf[ij]*m1b$acf[ij]
               }
               dsq[jj]=d1
               ## end of jj-loop
            }
            ## end of if(j > 0)
         }
         #### Since dsq is only valid for stationary series, we set an upper limit.
         chk=qnorm(1-crit/2)
         chk1=chk^2/nT
         idx=c(1:k1)[corsq > chk1 ]
         dsq[idx]=1
         ###
         if(output){
            cat("Variance of canonical correlations","\n")
            print(round(dsq,3))
            cat("Test results: ","\n")
         }
         ### Perform tests to check the number of SCMs at the (m,j)-position
         icnt=0
         tst=0
         k2=(j+1)*k
         k2=min(k1,k2)
         for (kk in 1:k2){
            tmp=corsq[k1-kk+1]/dsq[k1-kk+1]
            if(tmp >= 1)tmp=0.999
            tmp=log(1-tmp)
            tst=tst-(nT-m-j)*tmp
            deg=kk*(kk+h*k)
            pv=1-pchisq(tst,deg)
            if(output)print(c(tst,deg,pv),digits=3)
            if(pv >= crit)icnt=icnt+1
         }
         zeroTbl[(m+1),(j+1)]=icnt
       }
     }
   #### Print the output tables
   cat("Column: MA order","\n")
   cat("Row   : AR order","\n")
   cat("Number of zero canonical correlations","\n")
   colnames(zeroTbl) <- c(c(0:maxq))
   rownames(zeroTbl) <- c(c(0:maxp))
   printCoefmat(zeroTbl)
   diagDif=zeroTbl
   for (i in 1:maxp){
      for (j in 1:maxq){
         diagDif[(i+1),(j+1)]=min(zeroTbl[(i+1),(j+1)]-zeroTbl[i,j],k)
       }
    }
   cat("Diagonal Differences: ","\n")
   colnames(diagDif) <- c(c(0:maxq))
   rownames(diagDif) <- c(c(0:maxp))
   printCoefmat(diagDif)

   SCMid <- list(Nmtx=zeroTbl,DDmtx=diagDif)
 }


##### Second-stage of specifiction ##################################################
"SCMid2" <- function(zt,maxp=2,maxq=2,h=0,crit=0.05,sseq=NULL){
### Identify details of specified SCMs. This is a second-step specification.
### sseq denotes the sequence of orders (m,j) for searching SCMs.
#### Written by Ruey Tsay in June 2012.
#### Updated by Ruey S. Tsay in October 2013
#### Updated by Ruey S. Tsay in March, 2015
####
if(!is.matrix(zt))zt=as.matrix(zt)
nT=dim(zt)[1]
k=dim(zt)[2]
nar=maxp+1; nma=maxq+1; Order=matrix(0,k,2)
cmax=max((maxp+1)*k*k*k,100)
####
maxpq=maxp+maxq
if(length(sseq) < 1){
## set default sequence to find SCMs
 sseq=c(0,0)
 for (ell in 1:maxpq){
   for (jj in 0:ell){
     m=ell-jj; j=jj
     if( (m <= maxp) && (j <= maxq)){sseq=rbind(sseq,c(m,j))}
     #end of jj-loop
     }
    #end of ell-loop
    }
   #end of if(length(sseq) < 1)
  }
tcases=dim(sseq)[1]  ## The total number of SCM orders to be tested.
## wkspace: storage space to store genuine eigenvectors.
wkspace=matrix(0,tcases,cmax)
Nscm=rep(0,tcases)
## Tmx: Transformation matrix.
Tmx=NULL
## Jcnt: counts of linearly independent SCMs
Jcnt=0
##
for (nc in 1:tcases){
if(Jcnt >= k)break
 m=sseq[nc,1];j=sseq[nc,2]
 ist=m+j+h+2
### setup the Ymt matrix
 Ymt=zt[ist:nT,]
 if(m > 0){
  for (i in 1:m){
   Ymt=cbind(Ymt,zt[(ist-i):(nT-i),])
   }
  }
Ymt=as.matrix(Ymt)
k1=dim(Ymt)[2]
### setup the Yht-matrix and denote it by Pt.
Pt=zt[(ist-j-1):(nT-j-1),]
 if(m > 0){
  for (i in 1:m){
   Pt=cbind(Pt,zt[(ist-1-i-j):(nT-1-i-j),])
   }
  }
 if(h > 0){
  for (i in 1:h){
   Pt=cbind(Pt,zt[(ist-1-j-m-i):(nT-1-j-m-i),])
   }
  }
Pt=as.matrix(Pt)
mcan=cancor(Ymt,Pt)
corsq=mcan$cor^2
#
cat("For (pi,qi) = (",m,",",j,")","\n")

### compute the variance of canonical correlations
dsq=rep(1,k1)
xM=as.matrix(mcan$xcoef)
yM=as.matrix(mcan$ycoef)
## Normalization
for (kk in 1:k1){
  xM[,kk]=xM[,kk]/sqrt(sum(xM[,kk]^2))
  yM[,kk]=yM[,kk]/sqrt(sum(yM[,kk]^2))
  }
xT=Ymt%*%xM
yT=Pt%*%yM[,1:k1]
for (jj in 1:k1){
  d1=1.0
  if(j > 0){
   m1a=acf(xT[,jj],lag.max=j,plot=F)
   m1b=acf(yT[,jj],lag.max=j,plot=F)
   for (ij in 2:(j+1)){
    d1=d1+2*m1a$acf[ij]*m1b$acf[ij]
   }
  # end of if(j > 0)
  }
  dsq[jj]=d1
 ## end of jj-loop
 }

#### Since dsq is only valid for stationary series, we set an upper limit.
chk=qnorm(1-crit/2)
chk1=chk^2/nT
idx=c(1:k1)[corsq > chk1 ]
dsq[idx]=1
###
cat("Tests:","\n")
re=NULL
### Perform tests to check the number of SCMs at the (m,j)-position
icnt=0
tst=0
k2=(j+1)*k
k2=min(k1,k2)
for (kk in 1:k2){
ik=k1-kk+1
tmp=corsq[ik]/dsq[ik]
if(tmp >= 1)tmp=corsq[ik]
tmp=log(1-tmp)
tst=tst-(nT-m-j)*tmp
deg=kk*(kk+h*k)
pv=1-pchisq(tst,deg)
re=rbind(re,c(corsq[ik],dsq[ik],tst,deg,pv))
if(pv >= crit)icnt=icnt+1
}
re1=round(re,3)
colnames(re1) <- c("Eigvalue","St.dev","Test","deg","p-value")
print(re1)
#
cat("Summary:","\n")
cat("Number of SCMs detected: ",icnt,"\n")
Nscm[nc]=icnt; wk1 = NULL; n12=0
###
#####cat("Nscm[nc]", Nscm[nc],"\n")
if(icnt > 0){
 ldx=rev(c((k1-icnt+1):k1))
 wk1=as.matrix(xM[,ldx])
###
if((nc > 1) && (Jcnt > 0)){
  ## checking for newly detected SCM, if any.
  wk2=NULL  ## contains all the implied SCMs
   ### obtain the SCMs found before.
    for (j1 in 1:(nc-1)){
     wk3=NULL
     ndup=min(m-sseq[j1,1],j-sseq[j1,2])
     m1=sseq[j1,1]; wcnt=Nscm[j1]
     if((ndup >= 0) && (wcnt > 0)){
      leng=(m1+1)*k*wcnt
      wvector=matrix(wkspace[j1,1:leng],(m1+1)*k,wcnt)
      cat("wvector","\n")
      print(wvector,digits=3)
      if(ndup == 0){
       if(m1==m){wk3=cbind(wk3,wvector)}
        else{tmp=rbind(wvector,matrix(0,(m-m1)*k,wcnt))
             wk3=cbind(wk3,tmp)
             }
       }
      if(ndup > 0){
       tmp=rbind(wvector,matrix(0,(m-m1)*k,wcnt))
       wk3=cbind(wk3,tmp)
       jdim=dim(wk3)[1]; tmp1=tmp
       for (ell in 1:ndup){
         tmp1=rbind(matrix(0,k,wcnt),tmp1[1:(jdim-k),])
         wk3=cbind(wk3,tmp1)
        }
       }
      }
     wk2=cbind(wk2,wk3)
     }
###
     n12=dim(wk2)[2]
     if(icnt <= n12){
      cat("No new SCM found.","\n")
      ngenu = 0
      }
      else{
       chknew=cancor(wk1,wk2)
       xcoef=as.matrix(chknew$xcoef)
       dd=t(xcoef)%*%xcoef
       dd=sqrt(diag(dd))
       for (ii in 1:icnt){
        xcoef[,ii]=xcoef[,ii]/dd[ii]
        }
      wk=wk1%*%xcoef[,(n12+1):icnt]
      ngenu=icnt-n12
      cat("The number of newly found SCMs: ",ngenu,"\n")
      wk1=wk
      cat("Vectors: ","\n")
      print(wk1,digits=3)
      }
###
##  Checking for possible exchangeable SCM
   if(ngenu > 0){
    iexch = 0
    for (j1 in 1:(nc-1)){
     m1=sseq[j1,1]; j2=sseq[j1,2]
     if((m1+j2)==(m+j)){
       wcnt=Nscm[j1]; leng=(m1+1)*k*wcnt
       wvector = matrix(wkspace[j1,1:leng],(m1+1)*k,wcnt)
#
       if((wcnt > 0) && (j2 > j)){
           wk2 = rbind(wvector,matrix(0,(m-m1)*k,wcnt)); wk3=wk1}
        else{ij=dim(wk1)[1]; wk2 = wvector[1:ij,]; wk3=wk1}
       mchg=cancor(wk3,wk2)
       ich=0
       h11=min(wcnt,icnt)
       for (ij in 1:h11){
        if(mchg$cor[ij] > 0.8){ich=ich+1}
        }
       if(ich > 0){
        cat("Exchangeable SCM found with order: ", c(m1,j2),"\n")
         iexch=iexch+ich
         }
        } # end of (m1+j2) == m+j
      }  ##end of for-loop
     } ## end of if(ngenu > 0)
####
   }### end of (if (nc > 1) && (Jcnt > 0))
    newSCM=icnt-n12
    if(newSCM > 0){
      for (ii in 1:newSCM){
      Order[Jcnt+ii,1]=m; Order[Jcnt+ii,2]=j
      }
     }
  } ## end of if(icnt > 0)
    if(n12 > 0){icnt=icnt-n12}
##### Update the new information found, if any
    Nscm[nc]=icnt
    Jcnt=Jcnt+icnt
    leng=(m+1)*k*icnt
    if(leng > 0){wkspace[nc,1:leng] = c(wk1)} ###
###
###    cat("Nscm: ", Nscm[1:nc],"\n")
    if(icnt > 0){Tmx=cbind(Tmx,wk1[1:k,])}
#####    cat("dim: ",c(ncol(Tmx),ncol(wk1)),"\n")
 } ### end of for-loop
#
   cat("SUMMARY:","\n")
   cat("Overall model: ",apply(Order,2,max),"\n")
   cat("Orders of SCM: ","\n")
   print(Order)
    cat("Transformation Matrix (Column): ","\n")
    print(Tmx,digits=3)

  SCMid2 <- list(Tmatrix = t(Tmx),SCMorder=Order)
}

##############################
"SCMmod" <- function(order,Ivor,output){
   ## Parameter specification for a given set of SCMs and indicator of T-matrix.
   ## order is a k-by-2 matrix of the orders of SCMs.
   ## Ivor is a k-dimensional vector with position of 1.
   if(!is.matrix(order))order=as.matrix(order)
   k=dim(order)[1]
   p=max(order[,1])
   q=max(order[,2])
   kp=k*p; kq=k*q
   if(output) cat("VARMA order (p,q) = (",p,",",q,")","\n")
   phi=NULL; theta=NULL
   if(p > 0)phi=matrix(0,k,kp)
   if(q > 0)theta=matrix(0,k,kq)
   ### 2: estimation; 0: fixed at zero; 1: fixed at 1.
   for (i in 1:k){
      pi=order[i,1]; qi=order[i,2]
      if(pi > 0){
         for (j in 1:pi){
            jst=k*(j-1)
            phi[i,(jst+1):(jst+k)]=2
         }
      }
      if(qi > 0){
         for (j in 1:qi){
            jst=k*(j-1)
            theta[i,(jst+1):(jst+k)]=2
         }
      }
   }
   ## check for redundant parameters
   for (i in 1:k){
      pi=order[i,1];qi=order[i,2]
      for (j in 1:i){
         pj=order[j,1];qj=order[j,2]
         mm=min(pi-pj,qi-qj)
         if(mm > 0){
            for (jj in 1:mm){
               jdx=(jj-1)*k+j
               theta[i,jdx]=0
            }
         }
         ## finish redundant parameters
      }
      # finish the AR and MA parameter sepcification
   }
   if(output){
      cat("VAR matrices: ","\n")
      print(phi)
      cat("VMA matrices: ","\n")
      print(theta)
   }
   #
   Tmtx=matrix(2,k,k)
   ### finding the pivotal positions
   for (i  in 1:k){
      k1=Ivor[i]
      Tmtx[i,k1]=1
   }
   # row-by-row
   for (i in 2:k){
      pi=order[i,1]; qi=order[i,2]
      for (j in 1:(i-1)){
         k1=Ivor[j]
         pj=order[j,1];qj=order[j,2]
         mink=min(pi-pj,qi-qj)
         if(mink > -1)Tmtx[i,k1]=0
       }
    }
   if(output){
      cat("Transformation matrix: ","\n")
      print(Tmtx)
    }
   SCMmod <- list(Tmtx=Tmtx,ARpar=phi,MApar=theta)
 }

#### SCM estimation
"SCMfit" <- function(da,scms,Tdx,include.mean=T,fixed=NULL,prelim=F,details=F,thres=1.0,ref=0,SCMpar=NULL,seSCMpar=NULL){
   # Estimation of a vector ARMA model using conditional MLE (Gaussian dist)
   #  The model is specified via SCMs.
   #
   # The program is modified from Kronfit.R, July 2012.
   #
   # When prelim=TRUE, fixed is assigned based on the results of AR approximation.
   # Here "thres" is used either prelim = TRUE or in refined estimation.
   # ref = 0 denotes not a refined estimation.
   ##
   # use mvtnorm package for multivariate normal density.
   if(!is.matrix(da))da=as.matrix(da)
   nT=dim(da)[1]; k=dim(da)[2]
   p=max(scms[,1]); q=max(scms[,2]); pq=max(p,q); kp=k*p; kq=k*q
   pq=max(p,q)
   cat("Maximum VARMA order: (",p,",",q,")","\n")
      # Obtain the parameter specifications.
      mm1=SCMmod(scms,Tdx,FALSE)
      # Step 1: assign the data and locations of parameters globally
      locTmtx <- mm1$Tmtx; locAR <- mm1$ARpar; locMA <- mm1$MApar
      #
   if(ref < 1){
      cat("Locations of estimable parameters: Transformation Matrix","\n")
      print(locTmtx)
      cat("AR parameters","\n")
      print(locAR)
      cat("MA parameters","\n")
      print(locMA)
    }
 iniSCM <- function(da,at,scms,Tdx,locTmtx,locAR,locMA,inc.mean){
   ### The output parameters are in a vector:
   #### It contains parameters equation-by-equation, including the constant term, if any.
   ##### Format:
   #### z(t) = xi0 z(t) + SUM[xii *z(t-i)] + SUM[Omegai*a(t-i)] + a(t).
   if(!is.matrix(da))da=as.matrix(da)
   if(!is.matrix(at))at=as.matrix(at)
   nT=dim(da)[1]; k=dim(da)[2]; p = 0; q=0
   ## obtain the maximum index value.
   if(length(locAR) > 0)p=floor(dim(locAR)[2]/k)
   if(length(locMA) > 0)q=floor(dim(locMA)[2]/k)
   ##   cat("iniSCM p and q: ",c(p,q),"\n")
   pq=p+q
   if(pq < 1){
      cat("The series is white noise. No estimation is needed","\n")
   }
   ## est: stores the estimates (equation 1, equation 2, etc.)
   est=NULL
   estse=NULL
   ist=pq+1
   ### Perform estimation equation-by-equation.
   for (i in 1:k){
      ## setup the variables of the contemporaneous lag if any.
      X=NULL
      loki=Tdx[i]
      Y=da[ist:nT,loki]
      ##
      if(inc.mean)X=rep(1,(nT-pq))
      ### setup contemporaneous parameters
      for(j in 1:k){
         if(j != loki){
            if(locTmtx[i,j] > 1)X=cbind(X,-da[ist:nT,j])
         }
      }
      ### setup the lagged AR variables
      pi=scms[i,1]; qi=scms[i,2]
      if(pi > 0){
         for(lag in 1:pi){
            jst=(lag-1)*k
            for (j in 1:k){
               if(locAR[i,jst+j] > 1){
                  tmp=da[(ist-lag):(nT-lag),j]
                  X=cbind(X,tmp)
               }
            }
         }
      }
      ### Next come the MA part
      ### setup the lagged MA variables
      if(qi > 0){
         for(lag in 1:qi){
            jst=(lag-1)*k
            for (j in 1:k){
               if(locMA[i,jst+j] > 1){
                  tmp=at[(ist-lag):(nT-lag),j]
                  X=cbind(X,tmp)
               }
            }
         }
       }
      ### Perform estimation
      XPX=crossprod(X,X)/nT
      XPXinv=solve(XPX)
      XPY=crossprod(X,Y)/nT
      beta=XPXinv%*%XPY
      l1=dim(XPX)[1]
      resi=Y-X%*%matrix(beta,l1,1)
      evar=crossprod(resi,resi)/(nT-p)
      est=c(est,beta)
      estse=c(estse,sqrt(diag(XPXinv)*evar/nT))
   }
   iniSCM <- list(par=est,se=estse)
 }
   # The next statement is designed for model refinement.
   if(ref < 1){
       ### Use VAR approximation to obtain approximate innovations
      m1=VARorder(da,pq+9,output=FALSE)
      porder=m1$aicor
      if(porder < 1)porder=1
      m2=VAR(da,porder,output=FALSE)
      y=da[(porder+1):nT,]
      x=m2$residuals
      m3=iniSCM(y,x,scms,Tdx,locTmtx,locAR,locMA,include.mean)
      ### SCMpar is the vector of ALL estimable parameters.
      ####               [Some of which maybe fixed to zero.]
      SCMpar <- m3$par; seSCMpar <- m3$se
      ### SCMpar is a vector; which stores parameters equation-by-equation.
      ##
      nr=length(SCMpar)
      ### Preliminary simplification
      if(prelim){
         fixed = rep(0,nr)
         for (j in 1:nr){
            tt=SCMpar[j]/seSCMpar[j]
            if(abs(tt) >= thres){
               fixed[j]=1
            }
            else{
               SCMpar[j]=0
            }
            # end of j-loop
         }
         # end of if(prelim)
      }
      #### fixed = 1 means "estimation"; = 0 means fixed to zero.
      if(length(fixed) < 1)fixed=rep(1,nr)
    }
   #### JJdx is kept for identification purpose.
   nr=length(SCMpar)
   JJdx=c(1:nr)[fixed==1]
   par=SCMpar[JJdx]
   separ= seSCMpar[JJdx]
   #########
   cat("Number of parameters: ",length(par),"\n")
   cat("initial estimates: ",round(par,4),"\n")
   ### Set up lower and upper bounds
   lowerBounds=par; upperBounds=par
   for (j in 1:length(par)){
      lowerBounds[j] = par[j]-2*separ[j]
      upperBounds[j] = par[j]+2*separ[j]
   }
   cat("Upper-bound: ",round(upperBounds,4),"\n")
   cat("Lower-bound: ",round(lowerBounds,4),"\n")

 LLSCM <- function(par,zt=da,scms=scms,Tdx=Tdx,SCMpar=SCMpar,JJdx=JJdx,include.mean=include.mean,fixed=fixed,locTmtx=locTmtx,locAR=locAR,locMA=locMA){
   k <- dim(zt)[2];  nT <- dim(zt)[1]
   p=max(scms[,1]); q=max(scms[,2]); pq=max(p,q); kp=k*p; kq=k*q
   Tdx <- Tdx
   SCMpar[JJdx] <- par
   ###  Assign parameters to their proper locations in the program.
   Cnt=rep(0,k)
   ### separate lag-0 coefficient matrix.
   Ph0=locTmtx; PH=NULL; TH=NULL
   if(p > 0)PH=matrix(0,k,kp)
   if(q > 0)TH=matrix(0,k,kq)
   icnt=0
   for (i in 1:k){
      idx=NULL; jdx=NULL; kdx=NULL
      if(p > 0)idx=c(1:kp)[locAR[i,] > 1]
      if(q > 0)jdx=c(1:kq)[locMA[i,] > 1]
      # kdx denotes the number of non-zero elements in lag-0.
      kdx=c(1:k)[locTmtx[i,] > 1]
      iend=length(idx); jend=length(jdx); kend=length(kdx)
      #### icnt: parameter count
      if(include.mean){
         icnt=icnt+1
         Cnt[i]=SCMpar[icnt]
       }
      if(kend > 0){
         Ph0[i,kdx]=SCMpar[(icnt+1):(icnt+kend)]
         icnt=icnt+kend
       }
      if(iend > 0){
         PH[i,idx]=SCMpar[(icnt+1):(icnt+iend)]
         icnt=icnt+iend
       }
      if(jend > 0){
         TH[i,jdx]=SCMpar[(icnt+1):(icnt+jend)]
         icnt=icnt+jend
       }
    }
   ##### Compute the residuals
   ###### Compute the AR and MA coefficient matrix
   Ph0i=solve(Ph0); ARc=NULL; MAc=NULL
   if(p > 0)ARc=Ph0i%*%PH
   if(q > 0)MAc=Ph0i%*%TH
   Cntc=Ph0i%*%as.matrix(Cnt,k,1)
   ##
   ist=pq+1
   #### consider the case t from 1 to pq+1
   at=matrix((zt[1,]-Cntc),1,k)
   if(pq > 1){
      for (t in 2:pq){
         tmp=matrix((zt[t,]-Cntc),1,k)
         if(p > 0){
            for (j in 1:p){
               if((t-j) > 0){
                  jdx=(j-1)*k
                  tmp1=matrix(zt[(t-j),],1,k)%*%t(as.matrix(ARc[,(jdx+1):(jdx+k)]))
                  tmp=tmp-tmp1
               }
             }
          }
         if(q > 0){
            for (j in 1:q){
               jdx=(j-1)*k
               if((t-j)>0){
                  tmp2=matrix(at[(t-j),],1,k)%*%t(as.matrix(MAc[,(jdx+1):(jdx+k)]))
                  tmp=tmp-tmp2
               }
            }
          }
         at=rbind(at,tmp)
      }
   }
   ### for t from ist on
   ist=pq+1
   Pcnt = NULL; beta=NULL
   if(q < 1)MAc=NULL; if(p < 1)ARc=NULL
   if(include.mean)beta=matrix(Cntc,1,k)
   if(length(ARc) > 0)beta=rbind(beta,t(ARc))
   if(length(MAc) > 0)beta=rbind(beta,t(MAc))
   #
   idim=k*(p+q)
   if(include.mean){
      Pcnt=c(1)
      idim=idim+1
   }
   #
   for (t in ist:nT){
      Past=NULL
      if(p > 0){
         for (j in 1:p){
            Past=c(Past,zt[(t-j),])
         }
      }
      if(q > 0){
         for (j in 1:q){
            Past=c(Past,at[(t-j),])
         }
      }
      tmp = matrix(c(Pcnt,Past),1,idim)%*%beta
      tmp3=zt[t,]-tmp
      at=rbind(at,tmp3)
   }
   at=as.matrix(at[(ist:nT),])
   sig=crossprod(at,at)/(nT-pq)
   ll=dmvnorm(at,rep(0,k),sig)
   LLSCM=-sum(log(ll))
   LLSCM
 }

  #  Estimate Parameters and Compute Numerically Hessian:
   if(details){
      fit = nlminb(start = par, objective = LLSCM,zt=da,scms=scms,Tdx=Tdx,SCMpar=SCMpar,JJdx=JJdx,include.mean=include.mean,fixed=fixed,
      locTmtx=locTmtx,locAR=locAR,locMA=locMA,lower = lowerBounds, upper = upperBounds, control = list(trace=3))
   }
   else {
      fit = nlminb(start = par, objective = LLSCM,zt=da,scms=scms,Tdx=Tdx,SCMpar=SCMpar,JJdx=JJdx,include.mean=include.mean,fixed=fixed,
       locTmtx=locTmtx,locAR=locAR,locMA=locMA,lower = lowerBounds, upper = upperBounds)
   }
   epsilon = 0.0001 * fit$par
   npar=length(par)
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] = (LLSCM(x1,zt=da,scms=scms,Tdx=Tdx,SCMpar=SCMpar,JJdx=JJdx,include.mean=include.mean,fixed=fixed,locTmtx=locTmtx,locAR=locAR,locMA=locMA)
                         -LLSCM(x2,zt=da,scms=scms,Tdx=Tdx,SCMpar=SCMpar,JJdx=JJdx,include.mean=include.mean,fixed=fixed,locTmtx=locTmtx,locAR=locAR,locMA=locMA)
                         -LLSCM(x3,zt=da,scms=scms,Tdx=Tdx,SCMpar=SCMpar,JJdx=JJdx,include.mean=include.mean,fixed=fixed,locTmtx=locTmtx,locAR=locAR,locMA=locMA)
                         +LLSCM(x4,zt=da,scms=scms,Tdx=Tdx,SCMpar=SCMpar,JJdx=JJdx,include.mean=include.mean,fixed=fixed,locTmtx=locTmtx,locAR=locAR,locMA=locMA))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   # Step 6: Create and Print Summary Report:
   d1=det(Hessian)
   if(d1 < 1.0e-13){
      se.coef=rep(1,npar)
   }
   else{
      se.coef = sqrt(diag(solve(Hessian)))
   }
   tval = fit$par/se.coef
   matcoef = cbind(fit$par, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)
   SCMpar[JJdx]=fit$par
   seSCMpar[JJdx]=se.coef
   ##cat("SCMpar: ",round(SCMpar,3),"\n")
   ######### Use locTmtx, locAR, and locMA and include.mean to identify the parameters.
   # Restore estimates to the format of unconstrained case for printing.
   Cnt=rep(0,k); seCnt=rep(0,k)
   ### separate lag-0 coefficient matrix.
   Ph0=locTmtx; sePh0=matrix(0,k,k); PH=NULL; TH=NULL
   if(p > 0){
      PH=matrix(0,k,kp); sePH=matrix(0,k,kp)
   }
   else {
      PH = NULL; sePH=NULL
   }
   if(q > 0){
      TH=matrix(0,k,kq); seTH=matrix(0,k,kq)
   }
   else{
      TH=NULL; seTH=NULL
   }
   ###
   icnt=0
   for (i in 1:k){
      idx=NULL; jdx=NULL; kdx=NULL
      if(p > 0)idx=c(1:kp)[locAR[i,] > 1]
      if(q > 0)jdx=c(1:kq)[locMA[i,] > 1]
      kdx=c(1:k)[locTmtx[i,] > 1]
      iend=length(idx); jend=length(jdx); kend=length(kdx)
      #### icnt: parameter count
      if(include.mean){
         icnt=icnt+1
         Cnt[i]=SCMpar[icnt]
         seCnt[i]=seSCMpar[icnt]
      }
      if(kend > 0){
         Ph0[i,kdx]=SCMpar[(icnt+1):(icnt+kend)]
         sePh0[i,kdx]=seSCMpar[(icnt+1):(icnt+kend)]
         icnt=icnt+kend
      }
      if(iend > 0){
         ##cat("idx: ",idx,"\n")
         PH[i,idx]=SCMpar[(icnt+1):(icnt+iend)]
         sePH[i,idx]=seSCMpar[(icnt+1):(icnt+iend)]
         icnt=icnt+iend
      }
      if(jend > 0){
         TH[i,jdx]=SCMpar[(icnt+1):(icnt+jend)]
         seTH[i,jdx]=seSCMpar[(icnt+1):(icnt+jend)]
         icnt=icnt+jend
      }
      ### end of the i-loop
   }
   #########
   cat("---","\n")
   cat("Estimates in matrix form:","\n")
   if(include.mean){
      cat("Constant term: ","\n")
      cat("Estimates: ",round(Cnt,3),"\n")
   }
   cat("AR and MA lag-0 coefficient matrix","\n")
   print(round(Ph0,3))
   jcnt=0
   if(p > 0){
      cat("AR coefficient matrix","\n")
      for (i in 1:p){
         cat("AR(",i,")-matrix","\n")
         ph=PH[,(jcnt+1):(jcnt+k)]
         print(round(ph,3))
         jcnt=jcnt+k
      }
   }
   if(q > 0){
      cat("MA coefficient matrix","\n")
      icnt=0
      for (i in 1:q){
         cat("MA(",i,")-matrix","\n")
         theta=-TH[,(icnt+1):(icnt+k)]
         print(round(theta,3))
         icnt=icnt+k
      }
   }
   ##### Compute the residuals
   ###### Compute the AR and MA coefficient matrix
   Ph0i=solve(Ph0); ARc = NULL; MAc=NULL
   if(p > 0)ARc=Ph0i%*%PH
   if(q > 0)MAc=Ph0i%*%TH
   Cntc=Ph0i%*%as.matrix(Cnt,k,1)
   zt=da
   #### consider the case t from 1 to pq
   at=matrix((zt[1,]-Cntc),1,k)
   if(pq > 1){
      for (t in 2:pq){
         tmp=matrix((zt[t,]-Cntc),1,k)
         if(p > 0){
            for (j in 1:p){
               if((t-j) > 0){
                  jdx=(j-1)*k
                  tmp1=matrix(zt[(t-j),],1,k)%*%t(as.matrix(ARc[,(jdx+1):(jdx+k)]))
                  tmp=tmp-tmp1
               }
               # end of j-loop
            }
            # end of if(p > 0).
         }
         if(q > 0){
            for (j in 1:q){
               jdx=(j-1)*k
               if((t-j)>0){
                  tmp2=matrix(at[(t-j),],1,k)%*%t(as.matrix(MAc[,(jdx+1):(jdx+k)]))
                  tmp=tmp-tmp2
               }
               #end of j-loop
            }
            #end of if(q > 0)
         }
         at=rbind(at,tmp)
         # end of for(t in 2:pq)
      }
      # end of if(pq > 1) statement
   }

   ### for t from ist on
   ist=pq+1
   Pcnt=NULL
   beta=NULL
   if(include.mean){
      beta=matrix(Cntc,1,k)
      Pcnt=c(1)
   }
   if(length(ARc) > 0)beta=rbind(beta,t(ARc))
   if(length(MAc) > 0)beta=rbind(beta,t(MAc))
   idim=k*(p+q)
   if(include.mean){
      Pcnt=c(1)
      idim=idim+1
   }
   #
   for (t in ist:nT){
      Past=NULL
      if(p > 0){
         for (j in 1:p){
            Past=c(Past,zt[(t-j),])
         }
      }
      if( q > 0){
         for (j in 1:q){
            Past=c(Past,at[(t-j),])
         }
      }
      tmp = matrix(c(Pcnt,Past),1,idim)%*%beta
      tmp3=zt[t,]-tmp
      at=rbind(at,tmp3)
   }
   #### skip the first max(p,q) residuals.
   at=as.matrix(at[(ist:nT),])
   sig=crossprod(at,at)/(nT-pq)
   ##
   cat(" ","\n")
   cat("Residuals cov-matrix:","\n")
   print(sig)
   dd=det(sig)
   d1=log(dd)
   ### adjusting for the number of parameters in T-matrix
   jj=0
   for (i in 1:k){
      kdx=c(1:k)[locTmtx[i,] > 1]
      jj=jj+length(kdx)
   }
   aic=d1+2*(npar-jj)/nT
   bic=d1+log(nT)*(npar-jj)/nT
   cat("----","\n")
   cat("aic= ",aic,"\n")
   cat("bic= ",bic,"\n")
   TH1=NULL
   if(length(TH) > 0)TH1=-TH

   SCMfit <- list(data=da,SCMs=scms,Tdx=Tdx,locTmtx=locTmtx,locAR=locAR,locMA=locMA,cnst=include.mean,coef=SCMpar,secoef=seSCMpar,residuals=at,Sigma=sig,aic=aic,bic=bic, Ph0=Ph0,Phi=PH,Theta=TH1)
}

"refSCMfit" <- function(model,thres=1.0){
   zt=model$data
   inc.mean=model$cnst
   scms=model$SCMs
   Tdx=model$Tdx
   SCMpar= model$coef
   seSCMpar= model$secoef
   p=max(scms[,1]);q=max(scms[,2])
   #
   nr=length(SCMpar)
   fix=rep(0,nr)
   for (j in 1:nr){
      tt = 0
      if(seSCMpar[j] > 0.000001)tt=SCMpar[j]/seSCMpar[j]
      if(abs(tt) > thres){
         fix[j]=1
      }
      else{
         SCMpar[j]=0
      }
      ### end of "for(j in 1:nr)"
   }
   m1=SCMfit(zt,scms,Tdx,include.mean=inc.mean,fixed=fix,ref=1,SCMpar=SCMpar,seSCMpar=seSCMpar)
   locAR=m1$locAR; locMA=m1$locMA; Tdx=m1$Tdx; locTmtx=m1$locTmtx
   SCMpar=m1$coef; seSCMpar=m1$secoef; scms=m1$SCMs
   sig=m1$Sigma; aic=m1$aic; bic=m1$bic
   Ph0=m1$Ph0; PH=m1$Phi; TH=m1$Theta; if(length(TH)>0)TH=-TH
   at=m1$residuals

   refSCMfit <- list(data=zt,SCMs=scms,Tdx=Tdx,locTmtx=locTmtx,locAR=locAR,locMA=locMA,cnst=inc.mean,coef=SCMpar,secoef=seSCMpar,residuals=at,Sigma=sig,aic=aic,bic=bic, Ph0=Ph0,Phi=PH,Theta=TH)
}


################### Co-integration part
"ECMvar1" <- function(x,p,wt,include.const=FALSE,fixed=NULL,output=TRUE){
   # Fits an error-correction VAR model.
   ### This program assumes the co-integrating process w(t) is known.
   ###
   if(!is.matrix(x))x=as.matrix(x)
   if(p < 1)p=1
   nT=dim(x)[1]
   k=dim(x)[2]
   dx=x[2:nT,]-x[1:(nT-1),]
   dx=rbind(rep(0,k),dx)
   wt=as.matrix(wt)
   m=dim(wt)[2]
   wtadj=wt
   ### number of parameters in each equation
   idm=k*(p-1)+m
   if(include.const){
      idm=idm+1
   }
   else{
      wtadj=wt-matrix(1,nT,1)%*%matrix(apply(wt,2,mean),1,m)
   }
   # effective sample size
   ist=max(1,p)
   ne=nT-ist+1
   y=dx[ist:nT,]
   xmtx=wtadj[(ist-1):(nT-1),]
   if(include.const)xmtx=cbind(xmtx,rep(1,(nT-ist+1)))
   if(p > 1){
      for (i in 2:p){
         ii=i-1
         xmtx=cbind(xmtx,dx[(ist-ii):(nT-ii),])
      }
   }
   y=as.matrix(y)
   xmtx=as.matrix(xmtx)
   sdbeta=matrix(1,idm,k)
   #### beta denotes the paramaters in the multiple linear regression format
   #### and is of dimension idm * k
   if(length(fixed) < 1){
      xpx = t(xmtx)%*%xmtx
      xpxinv=solve(xpx)
      xpy=t(xmtx)%*%y
      beta=xpxinv%*%xpy
      yhat=xmtx%*%beta
      resi=y-yhat
      sse=(t(resi)%*%resi)/ne
      dd=diag(xpxinv)
      sdbeta=matrix(1,idm,k)
      for (i in 1:k){
         sdbeta[,i]=sqrt(sse[i,i]*dd)
      }
      npar=idm*k
      ##
   }
   else{
      ## perform estimation equation-by-equation
      resi=NULL
      beta=matrix(0,idm,k)
      sdbeta=matrix(1,idm,k)
      npar=0
      for (i in 1:k){
         idx=c(1:idm)[fixed[,i]==1]
         npi=length(idx)
         cat("Equation: ",i," npar = ",npi,"\n")
         npar=npar+npi
         if(npi > 0){
            xm=xmtx[,idx]
            xpx=t(xm)%*%xm
            xpxinv=solve(xpx)
            dd=diag(xpxinv)
            xpy=t(xm)%*%y[,i]
            betai=xpxinv%*%xpy
            beta[idx,i]=betai
            res=y[,i]-xm%*%betai
            resi=cbind(resi,res)
            se2=sum(res^2)/ne
            sdbeta[idx,i]=sqrt(dd*se2)
            ## end of if(npi > 0)
         }
         # end of for(i in 1:k)
      }
      ##
   }
   sse=(t(resi)%*%resi)/ne
   ### print parameter estimates
   aic=0; bic=0
   if(output){
      alpha=beta[1:m,]
      icnt=m
      if(include.const){
         icnt=m+1
         c=beta[icnt,]
      }
      se=sdbeta[1:m,]
      cat("alpha: ","\n")
      print(t(alpha),digits=3)
      cat("standard error","\n")
      print(t(se),digits=3)
      if(include.const){
         cat("constant term:","\n")
         print(c,digits=3)
         se=sdbeta[icnt,]
         cat("standard error","\n")
         print(se,digits=3)
      }
      ## AR coefficients if any
      if(p > 1){
         cat("AR coefficient matrix","\n")
         jst=icnt
         for (i in 1:(p-1)){
            cat("AR(",i,")-matrix","\n")
            phi=t(beta[(jst+1):(jst+k),])
            se=t(sdbeta[(jst+1):(jst+k),])
            print(phi,digits=3)
            cat("standard error","\n")
            print(se,digits=3)
            jst=jst+k
            ###cat("      ","\n")
         }
         # end of printing AR coefficients
      }
      cat("-----","\n")
      cat("Residuals cov-mtx:","\n")
      print(sse)
      #sse=sse*ne/nT
      cat("      ","\n")
      dd=det(sse)
      cat("det(sse) = ",dd,"\n")
      d1=log(dd)
      aic=d1+(2*npar)/nT
      bic=d1+log(nT)*npar/nT
      cat("AIC = ",aic,"\n")
      cat("BIC = ",bic,"\n")
      ## end of if(output)
   }

   ECMvar1 <-list(data=x,wt=wt,arorder=p,include.const=include.const,coef=beta,aic=aic,bic=bic,residuals=resi,secoef=sdbeta,Sigma=sse)
}

###
"refECMvar1" <- function(m1,thres=1.0){
   ### m1 is a fitted model from ECMvar1 or refECMvar1.
   x=m1$data; wt=m1$wt; p=m1$arorder; include.con=m1$include.const
   coef=m1$coef
   secoef=m1$secoef
   idm=dim(coef)[1]
   k=dim(coef)[2]
   fix=matrix(0,idm,k)
   #
   for (i in 1:k){
      tra=coef[,i]/secoef[,i]
      idx=c(1:idm)[abs(tra) > thres]
      fix[idx,i]=1
   }
   #
   mm=ECMvar1(x,p,wt,include.const=include.con,fixed=fix)
   beta=mm$coef; sdbeta=mm$secoef
   aic=mm$aic; bic=mm$bic; resi=mm$residuals; sse=mm$Sigma

   refECMvar1 <- list(data=x,wt=wt,arorder=p,include.const=include.con,coef=beta,aic=aic,bic=bic,residuals=resi,secoef=sdbeta,Sigma=sse)
}

#####
"ECMvar" <- function(x,p,ibeta,include.const=FALSE,fixed=NULL,alpha=NULL,se.alpha=NULL,se.beta=NULL,phip=NULL,se.phip=NULL){
   # Fits an error-correction VAR model.
   ### This program assumes the co-integrating process w(t) is unknown.
   ### It is a refined version of ECMvar1.
   ### ibeta: initial estimates of beta-matrix. (k by m matrix).
   ###   Typically, it is available from the co-integration test.
   if(!is.matrix(x))x=as.matrix(x)
   if(!is.matrix(ibeta))ibeta=as.matrix(ibeta)
   if(p < 1)p=1; m=dim(ibeta)[2]
   cat("Order p: ",p," Co-integrating rank: ",m,"\n")
   nT <- dim(x)[1]; k <- dim(x)[2]
   dx=x[2:nT,]-x[1:(nT-1),]
   dx=rbind(rep(0,k),dx)
   if(length(fixed) < 1){
    #### Obtain initial parameter estimates via ECMvar1, if necessary
    wt=x%*%ibeta
    m1=ECMvar1(x,p,wt,include.const=include.const,output=FALSE)
    est=m1$coef
    se.est=m1$secoef
    alpha=t(est[1:m,])
    se.alpha=t(se.est[1:m,])
    icnt=m
    idm=dim(est)[1]
    ## phip inlcudes the constant term, if any.
    if(idm > icnt){
      phip=est[(icnt+1):idm,]
      se.phip=se.est[(icnt+1):idm,]
      }
    par=c(alpha)
    separ=c(se.alpha)
    par=c(par,c(ibeta[(m+1):k,]))
    separ=c(separ,rep(1/sqrt(nT),(k-m)*m))
    par=c(par,c(phip))
    separ=c(separ,c(se.phip))
    }
   else{
    par=c(alpha); separ=c(se.alpha)
    par=c(par,c(ibeta[(m+1):k,])); separ=c(separ,rep(1/sqrt(nT),(k-m)*m))
    idm=dim(phip)[1]
    for (j in 1:k){
     idx=c(1:idm)[fixed[,j]==1]
     if(length(idx) > 0){
       par=c(par,phip[idx,j]); separ=c(separ,se.phip[idx,j])
       }
      }
    }
   npar=length(par)
##Setup the X-matrix for ECMvar estimation.
 ECMxmtx <- function(x,p,m,include.const){
   nT <- dim(x)[1]; k <- dim(x)[2]
   dx=x[2:nT,]-x[1:(nT-1),]
   dx=rbind(rep(0,k),dx)
   ist=p
   if(ist < 2)ist=2
   xm=x[(ist-1):(nT-1),]
   ne=nT-ist+1
   if(include.const)xm=cbind(xm,rep(1,ne))
   if(p > 1){
      for (ii in 1:(p-1)){
         xm=cbind(xm,dx[(ist-ii):(nT-ii),])
      }
   }
   ECMxmtx <- list(xm = xm, y=dx[ist:nT,])
  }
   m2=ECMxmtx(x,p,m,include.const)
   ECMy <- m2$y; ECMxm <- m2$xm
   ##
   cat("Number of parameters: ",length(par),"\n")
   cat("initial estimates: ",par,"\n")
   ### Set up lower and upper bounds
   lowerBounds=par; upperBounds=par
   mult=1.5
   for (j in 1:npar){
      lowerBounds[j] = par[j]-mult*separ[j]
      upperBounds[j] = par[j]+mult*separ[j]
   }
   cat("Par. Lower-bounds: ",lowerBounds,"\n")
   cat("Par. Upper-bounds: ",upperBounds,"\n")

 LECMvar <- function(par,x=x,p=p,m=m,include.const=include.const,fixed=fixed,ECMy=ECMy,ECMxm=ECMxm){
   nT <- dim(x)[1]; k <- dim(x)[2]
   dx=x[2:nT,]-x[1:(nT-1),]
   dx=rbind(rep(0,k),dx)
   #
   km = k*m; kmm = k-m
   npar=length(par)
   if(length(fixed) < 1){
      alpha <- matrix(par[1:km],k,m)
      Im = diag(rep(1,m))
      icnt=(k-m)*m
      beta1=  matrix(par[(km+1):(km+icnt)],kmm,m)
      beta=rbind(Im,beta1)
      Pi=alpha%*%t(beta)
      icnt=icnt+km
      idm=(p-1)*k
      if(include.const)idm=idm+1
      if(npar > icnt){
         ome=matrix(par[(icnt+1):npar],idm,k)
       }
      else{
         ome=NULL
       }
      Ome=rbind(t(Pi),ome)
      resi=ECMy-as.matrix(ECMxm)%*%as.matrix(Ome)
      # end of if(length(fix) < 1)
    }
   else{
      alpha <- matrix(par[1:km],k,m)
      Im <- diag(rep(1,m))
      icnt=(k-m)*m
      beta1 <- matrix(par[(km+1):(km+icnt)],kmm,m)
      beta <- rbind(Im,beta1)
      Pi = alpha%*%t(beta)
      icnt=icnt+km
      idm=(p-1)*k
      if(include.const)idm=idm+1
      if(npar > icnt){
       ome=matrix(0,idm,k)
       for (j in 1:k){
         idx=c(1:idm)[fixed[,j]==1]
         if(length(idx) > 0){
           jj=length(idx)
           ome[idx,j]=par[(icnt+1):(icnt+jj)]
            icnt=icnt+jj
          }
         }
        }
       else{
        ome=NULL
        }
      Ome=rbind(t(Pi),ome)
      resi=ECMy - as.matrix(ECMxm)%*%as.matrix(Ome)
    }
   ## evaluate the log likelihood
   sig=t(resi)%*%resi/nT
   ll=dmvnorm(resi,rep(0,k),sig)
   LECMvar=-sum(log(ll))
   LECMvar
  }
   ###mm=optim(par,LECMvar,method=c("L-BFGS-B"),lower=lowerBounds,upper=upperBounds,hessian=TRUE)
   ###mm=optim(par,LECMvar,method=c("BFGS"),hessian=TRUE)
   ##est=mm$par
   ##H=mm$hessian
   details=FALSE
   # Step 5: Estimate Parameters and Compute Numerically Hessian:
   if(details){
      fit = nlminb(start = par, objective = LECMvar,x=x,p=p,m=m,include.const=include.const,fixed=fixed,ECMy=ECMy,ECMxm=ECMxm,
      lower = lowerBounds, upper = upperBounds, control = list(trace=3))
   }
   else {
      fit = nlminb(start = par, objective = LECMvar,x=x,p=p,m=m,include.const=include.const,fixed=fixed,ECMy=ECMy,ECMxm=ECMxm,
       lower = lowerBounds, upper = upperBounds)
   }
   epsilon = 0.0001 * fit$par
   ##npar=length(par)
   Hessian = matrix(0, ncol = npar, nrow = npar)
   for (i in 1:npar) {
      for (j in 1:npar) {
         x1 = x2 = x3 = x4  = fit$par
         x1[i] = x1[i] + epsilon[i]; x1[j] = x1[j] + epsilon[j]
         x2[i] = x2[i] + epsilon[i]; x2[j] = x2[j] - epsilon[j]
         x3[i] = x3[i] - epsilon[i]; x3[j] = x3[j] + epsilon[j]
         x4[i] = x4[i] - epsilon[i]; x4[j] = x4[j] - epsilon[j]
         Hessian[i, j] = (LECMvar(x1,x=x,p=p,m=m,include.const=include.const,fixed=fixed,ECMy=ECMy,ECMxm=ECMxm)
                         -LECMvar(x2,x=x,p=p,m=m,include.const=include.const,fixed=fixed,ECMy=ECMy,ECMxm=ECMxm)
                         -LECMvar(x3,x=x,p=p,m=m,include.const=include.const,fixed=fixed,ECMy=ECMy,ECMxm=ECMxm)
                         +LECMvar(x4,x=x,p=p,m=m,include.const=include.const,fixed=fixed,ECMy=ECMy,ECMxm=ECMxm))/
         (4*epsilon[i]*epsilon[j])
      }
   }
   est=fit$par
   cat("Final   Estimates: ",est,"\n")
   # Step 6: Create and Print Summary Report:
   se.coef = sqrt(diag(solve(Hessian)))
   tval = fit$par/se.coef
   matcoef = cbind(fit$par, se.coef, tval, 2*(1-pnorm(abs(tval))))
   dimnames(matcoef) = list(names(tval), c(" Estimate",
   " Std. Error", " t value", "Pr(>|t|)"))
   cat("\nCoefficient(s):\n")
   printCoefmat(matcoef, digits = 4, signif.stars = TRUE)
   ### print parameter estimates in the ECM model
   km=k*m
   kmm = (k-m)*m
   alpha=matrix(est[1:km],k,m)
   se.alpha=matrix(se.coef[1:km],k,m)
   beta1=matrix(est[(km+1):(km+kmm)],(k-m),m)
   se.beta1=matrix(se.coef[(km+1):(km+kmm)],(k-m),m)
   Im=diag(rep(1,m))
   beta=rbind(Im,beta1); se.beta=rbind(Im,se.beta1)
   icnt=km+kmm
   idm=k*(p-1)
   if(include.const)idm=idm+1
   ### Again, phip includes the constant
   if(icnt < npar){
     if(length(fixed) < 1){
       phip=matrix(est[(icnt+1):npar],idm,k)
       se.phip=matrix(se.coef[(icnt+1):npar],idm,k)
       }
      else{
       phip=matrix(0,idm,k); se.phip=matrix(1,idm,k)
       for (j in 1:k){
        idx=c(1:idm)[fixed[,j]==1]
        jj = length(idx)
        if(jj > 0){
          phip[idx,j]=est[(icnt+1):(icnt+jj)]
          se.phip[idx,j]=se.coef[(icnt+1):(icnt+jj)]
          icnt=icnt+jj
         }
        }
      }
   }
   cat("alpha: ","\n")
   print(alpha,digits=3)
   cat("standard error","\n")
   print(se.alpha,digits=3)
   cat("beta: ","\n")
   print(beta,digits=3)
   cat("standard error","\n")
   print(se.beta,digits=3)
   #
   icnt=0
   if(include.const){
      cat("constant term:","\n")
      print(phip[1,],digits=3)
      se=se.phip[1,]
      cat("standard error","\n")
      print(se,digits=3)
      icnt=1
   }
   ## AR coefficients if any
   if(p > 1){
      cat("AR coefficient matrix","\n")
      jst=icnt
      for (i in 1:(p-1)){
         cat("AR(",i,")-matrix","\n")
         phi=t(phip[(jst+1):(jst+k),])
         se=t(se.phip[(jst+1):(jst+k),])
         print(phi,digits=3)
         cat("standard error","\n")
         print(se,digits=3)
         jst=jst+k
         ###cat("      ","\n")
      }
      # end of printing AR coefficients
   }
   ## compute the residual covariance matrix
   Pi=alpha%*%t(beta)
   Ome=rbind(t(Pi),phip)
   resi=ECMy-as.matrix(ECMxm)%*%Ome
   sse=t(resi)%*%resi/nT
   #
   cat("-----","\n")
   cat("Residuals cov-mtx:","\n")
   print(sse)
   #sse=sse*ne/nT
   cat("      ","\n")
   dd=det(sse)
   cat("det(sse) = ",dd,"\n")
   d1=log(dd)
   aic=d1+(2*npar)/nT
   bic=d1+log(nT)*npar/nT
   cat("AIC = ",aic,"\n")
   cat("BIC = ",bic,"\n")

   ECMvar <-list(data=x,ncoint=m,arorder=p,include.const=include.const,alpha=alpha,se.alpha=se.alpha,beta=beta,se.beta=se.beta,aic=aic,bic=bic,residuals=resi,Phip=phip,se.Phip=se.phip,Sigma=sse)
}



#### refinemeant of ECMvar
"refECMvar" <- function(m1,thres=1.0){
   ### m1 is a fitted model from ECMvar or refECMvar.
   x=m1$data; m=m1$ncoint; p=m1$arorder; include.const=m1$include.const
   alpha=m1$alpha; se.alpha=m1$se.alpha; beta=m1$beta; se.beta=m1$se.beta
   Phip=m1$Phip; se.Phip=m1$se.Phip; aic=m1$aic; bic=m1$bic; resi=m1$residuals; sse=m1$Sigma
   if(p < 2){
    cat("refinement only applies to the case of p > 1","\n")
    }
   else {
    k <- ncol(x)
    idm=(p-1)*k
    if(include.const){idm=idm+1}
    fixed=matrix(0,idm,k)
    for (j in 1:k){
     tra=Phip[,j]/se.Phip[,j]
     idx=c(1:idm)[abs(tra) > thres]
     fixed[idx,j]=1
     }
    mm=ECMvar(x,p,beta,include.const=include.const,fixed=fixed,alpha=alpha,se.alpha=se.alpha,se.beta=se.beta,phip=Phip,se.phip=se.Phip)
    alpha=mm$alpha; se.alpha=mm$se.alpha; beta=mm$beta; se.beta=mm$se.beta
    Phip=mm$Phip; se.Phip=mm$se.Phip; aic=mm$aic; bic=mm$bic
    resi=mm$residuals; sse=mm$Sigma; include.const=mm$include.const
    }
   refECMvar <-list(data=x,ncoint=m,arorder=p,include.const=include.const,alpha=alpha,se.alpha=se.alpha,beta=beta,se.beta=se.beta,aic=aic,bic=bic,residuals=resi,Phip=Phip,se.Phip=se.Phip,Sigma=sse)

}

"SWfore" <- function(y,x,orig,m){
   ### Performs Stock and Watson's diffusion index prediction
   ### y: dependent variable
   ### x: observed regressors
   ### orig: forecast origin
   ### m: selected number of PCs
   ###
   ### Output: Forecasts and MSE of forecasts (if data available)
   if(!is.matrix(x))x=as.matrix(x)
   nT=dim(x)[1]
   k=dim(x)[2]
   if(orig > nT)orig=nT
   if(m > k)m=k; if(m < 1)m=1
   # standardize the predictors
   x1=x[1:orig,]
   me=apply(x1,2,mean)
   se=sqrt(apply(x1,2,var))
   x1=x
   for (i in 1:k){
      x1[,i]=(x1[,i]-me[i])/se[i]
   }
   #
   V1=cov(x1[1:orig,])
   m1=eigen(V1)
   sdev=m1$values
   M=m1$vectors
   M1=M[,1:m]
   Dindex=x1%*%M1
   y1=y[1:orig]; DF=Dindex[1:orig,]
   mm=lm(y1~DF)
   coef=matrix(mm$coefficients,(m+1),1)
   #cat("coefficients: ","\n")
   #print(round(coef,4))
   yhat=NULL; MSE=NULL
   if(orig < nT){
      newx=cbind(rep(1,(nT-orig)),Dindex[(orig+1):nT,])
      yhat=newx%*%coef
      err=y[(orig+1):nT]-yhat
      MSE=mean(err^2)
      cat("MSE of out-of-sample forecasts: ",MSE,"\n")
   }

   SWfore <- list(coef=coef,yhat=yhat,MSE=MSE,loadings=M1,DFindex=Dindex)
}

####
"apca" <- function(da,m){
   ### Perform asymptotic PCA when the number of observations is smaller than
   ### the number of variables.
   if(!is.matrix(da))da=as.matrix(da)
   if(m < 1)m=1
   nT=dim(da)[1]
   k=dim(da)[2]
   ### check the validity for performing asymptotic pca.
   if(k <= nT){
      da=t(da)
      nT=dim(da)[1]
      k=dim(da)[2]
   }
   m1=princomp(t(da),cor=F,rotation="none")
   print(summary(m1))
   factors=matrix(m1$loadings,nT,nT)
   factors=factors[,1:m]
   loadings=m1$scores[,1:m]
   sdev=m1$sdev

   apca <- list(sdev=sdev,factors=factors,loadings=loadings)
}


#### Constrained factor models of Tsai and Tsay (2011)
####
"hfactor" <- function(X,H,r){
   # Performs estimation of a constrained factor model. The data matrix is "X".
   # The column constraint matrix is H.
   # r: The number of common factor.
   # The program uses a two-step procedure to implement weighted LS estimates.
   # The standardized X follows the following factor model:
   #  SX_t = H * Omega * F_t + epsilon_t
   #
   # This program was written in 2009.
   if(!is.matrix(X))X=as.matrix(X)
   if(!is.matrix(H))H=as.matrix(H)
   N=ncol(X)
   nT=nrow(X)
   m=ncol(H)
   x=X
   print("Data are individually standardized")
   if(r < 1)r=1
   # standardized the data
   x=scale(X,center=TRUE,scale=TRUE)
   V1=cov(x)
   mpca=eigen(V1)
   cat("First r eigenvalues of the correlation matrix: ","\n")
   print(mpca$values[1:r])
   ratio=sum(mpca$values[1:r])/N
   cat("Variability explained: ","\n")
   print(ratio)
   cat("Loadings: ","\n")
   print(mpca$vectors[,1:r],digits=3)

   ## New version use square-root of (H'H)^{-1} and
   ## [(H'H)^{-1/2}H'X'][XH(H'H)^{-1/2}] to perform eigenvalues analysis
   Y=as.matrix(x%*%H)
   HPH=t(H)%*%H
   mh=msqrt(HPH)
   Mhinv=mh$invsqrt
   YH=Y%*%Mhinv
   D=t(YH)%*%YH/nT
   m1=eigen(D)
   cat("eigenvalues of constrained part: ","\n")
   print(m1$values,digits=3)
   d=m1$vectors[,1:r]
   Fhat=YH%*%d
   HPHi=Mhinv%*%Mhinv

   # standardize the eigen vectors so that cov(f_t) = I_r.
   V2=apply(Fhat,2,var)
   s1=sqrt(V2)
   for (i in 1:r){
      Fhat[,i]=Fhat[,i]*(1/s1[i])
   }

   Omehat=HPHi%*%t(Y)%*%Fhat/nT
   print("Omega-Hat")
   print(Omehat,digits=3)

   HO=H%*%Omehat
   pro=sum(diag(t(HO)%*%HO))/N
   cat("Variation explained by the constrained factors: ","\n")
   print(pro)
   cat("H*Omega: constrained loadings ","\n")
   HOOH=HO%*%t(HO)
   Cload=HO
   dd=diag(t(HO)%*%HO)
   for (i in 1:r){
      Cload[,i]=HO[,i]/sqrt(dd[i])
   }
   print(Cload,digits=3)
   Psi=V1-HOOH
   print("Psi:")
   print(Psi,digits=3)
   mpsi=eigen(Psi)
   cat("Diagonal elements of Psi:","\n")
   print(diag(Psi),digits=3)
   cat("eigenvalues of Psi:","\n")
   print(mpsi$values,digits=3)

   list(Omega=Omehat,F=Fhat,Psi=Psi)
}

"msqrt" <- function(M){
   # computes the square-root of a positive definite matrix
   if(!is.matrix(M))M=as.matrix(M)
   n1=nrow(M)
   if(n1 == 1){
      Mh=sqrt(M)
      Mhinv=1/Mh
   }
   if(n1 > 1){
      M=(M+t(M))/2
      m1=eigen(M)
      V=m1$vectors
      eiv=sqrt(m1$values)
      L=diag(eiv)
      Linv=diag(1/eiv)
      Mh=V%*%L%*%t(V)
      Mhinv=V%*%Linv%*%t(V)
   }
  msqrt <- list(mtxsqrt=Mh,invsqrt=Mhinv)
}

"BVAR" <- function(z,p=1,C,V0,n0=5,Phi0=NULL,include.mean=T){
## Perform Bayesian estimation of a VAR(p) model
##
## z: time series (T-by-k)
## p: AR order
## phi0: prior mean for coefficient matrix [k-by-(kp+1)]
## C: precision matrix of coefficient matrix. [(kp+1)-by-(kp+1)]
## (V0,n0): prior input for Sigma_a (inverted Wishart parameters)
##
if(!is.matrix(z))z=as.matrix(z)
if(p < 1) p=1
if(!is.matrix(C))C=as.matrix(C)
if(!is.matrix(V0))V0=as.matrix(V0)
if(n0 < 1)n0=1
##
nT=dim(z)[1]
k=dim(z)[2]
idim=k*p+1
if(length(Phi0) <= 0)Phi0=matrix(0,idim,k)
X=NULL
ne=nT-p
if(include.mean)X=rep(1,ne)
for (i in 1:p){
X=cbind(X,z[(p+1-i):(nT-i),])
}
Z=as.matrix(z[(p+1):nT,])
X=as.matrix(X)
###
XpX=crossprod(X,X)
XpY=crossprod(X,Z)
## Bayesian Estimate
WpW=XpX+C
WpWinv=solve(WpW)
WpY=XpY+C%*%Phi0
Bbhat=WpWinv%*%WpY
bAhat=Z-X%*%Bbhat
bB=Bbhat-Phi0
S=t(bAhat)%*%bAhat +t(bB)%*%C%*%bB
BSig=(V0+S)/(n0+ne-k-1)
SD=kronecker(BSig,WpWinv)
phi=c(Bbhat)
se=sqrt(diag(SD))
Est=cbind(phi,se,phi/se)
colnames(Est) <- c("Est","s.e.","t-ratio")
cat("Bayesian estimate:","\n")
print(Est)
cat("Covariance matrix: ","\n")
print(BSig)
cnst=NULL; Bphi=NULL
if(include.mean){
   cnst=Bbhat[1,]
   Bphi=t(Bbhat[2:idim,])
   }else{
    Bphi=t(Bbhat)
   }
BVAR <- list(phi0=cnst,Phi=Bphi,residuals=bAhat,Sigma=BSig,p=p,priorm=Phi0,precision=C)
}


"comVol" <- function(rtn,m=10,p=1,stand=FALSE){
# checking for common volatility components
if(!is.matrix(rtn))rtn=as.matrix(rtn)
# Fit a VAR(p) model to remove any serial correlations in the data.
if(p < 1){x=scale(rtn,center=T,scale=F)}
 else{
  m1=VAR(rtn,p=p,output=FALSE)
  x=as.matrix(m1$residuals)
 }
#
nT=dim(x)[1]
k=dim(x)[2]
#
if(m < 1)m=1
# standardize the returns
# mean of x is zero because VARfit employs a constant term.
V1=cov(x)
##print(V1,digits=3)
m1=eigen(V1)
D1=diag(1/sqrt(m1$values))
P1=m1$vectors
Shalf=P1%*%D1%*%t(P1)
x1=x%*%Shalf
#
A=matrix(0,k,k)
for (h in 1:m){
ist=h+1
for (i in 1:k){
for (j in i:k){
Cmtx=matrix(0,k,k)
y2=x1[(ist-h):(nT-h),i]*x1[(ist-h):(nT-h),j]
for (ii in 1:k){
for (jj in ii:k){
y1=x1[ist:nT,ii]*x1[ist:nT,jj]
Cmtx[ii,jj]=cov(y1,y2)*(nT-h)/nT
Cmtx[jj,ii]=Cmtx[ii,jj]
}
}
Cmtx=Cmtx*((nT-h)/nT)
A= A+Cmtx%*%Cmtx
#end of j
}
#end of i
}
#end of h
}
#print(Cmtx)
if(stand){
dd=diag(A)
D=diag(1/sqrt(dd))
A=D%*%A%*%D
}
else{
A=A/(k*(k+1)/2)
}
m2=eigen(A)
Valu=m2$values
Prop=Valu/sum(Valu)
cat("eigen-values: ",Valu,"\n")
cat("proportion:   ",Prop,"\n")
Vec=m2$vectors
Mmtx=Shalf%*%Vec
# normalize each column of Mmtx
for (j in 1:k){
Mmtx[,j]=Mmtx[,j]/sqrt(sum(Mmtx[,j]^2))
}

archTstC <- function(x,m){
# perform F-test for ARCH effect using x^2 series
# m*Fratio is asymptotically chi-square with m degrees of freedom.
#
if(m < 1)m=1
nT=length(x)
ist=m+1
EffN = nT-m
Xmtx=matrix(1,EffN,1)
Y=matrix(x[ist:nT]^2,EffN,1)
for (j in 1:m){
Xmtx=cbind(Xmtx,x[(ist-j):(nT-j)]^2)
}
XtX=crossprod(Xmtx,Xmtx)
XtY=crossprod(Xmtx,Y)
beta=solve(XtX,XtY)
Resi=Y-Xmtx%*%beta
Ywm=scale(Y,center=T,scale=F)
SSR=sum(Resi^2)
deg=EffN-m-1
Fratio=((sum(Ywm^2)-SSR)/m)/(SSR/deg)
pv=1-pf(Fratio,m,deg)
result=c(Fratio,pv)
result
}

# Perform ARCH tests for each transformed series
Tst=NULL
Tx = x%*%Mmtx
for (i in 1:k){
TT=NULL
mtst10=archTstC(Tx[,i],10)
TT=c(TT,mtst10)
mtst20=archTstC(Tx[,i],20)
TT=c(TT,mtst20)
mtst30=archTstC(Tx[,i],30)
TT=c(TT,mtst30)
Tst=rbind(Tst,c(i,TT))
}
cat("Checking: ","\n")
cat("Results of individual F-test for ARCH effect","\n")
cat("Numbers of lags used: 10, 20, 30","\n")
cat("Component,(F-ratio P-val) (F-ratio P-val) (F-ratio P-Val)","\n")
print(Tst,digits=3)

comVol <- list(residuals=x,values=m2$values,vectors=m2$vectors,M=Mmtx)
}


"GrangerTest" <- function (X, p = 1, include.mean = T, locInput=c(1))
{
    if (!is.matrix(X))X = as.matrix(X)
    Tn = dim(X)[1]
    k = dim(X)[2]
## Re-ordering the components so that the input variables are in front.
    idx=c(1:k)
    if(is.null(locInput))locInput=c(1)
    endog=idx[-locInput]
    jdx=c(locInput,endog)
    x=X[,jdx]
    k1 = length(locInput)
    k2=k-k1
#
    if (p < 1)p = 1
    ne = Tn - p
    ist = p + 1
    y = x[ist:Tn, ]
    if (include.mean) {
        xmtx = cbind(rep(1, ne), x[p:(Tn - 1), ])
    }
    else {
        xmtx = x[p:(Tn - 1), ]
    }
    if (p > 1) {
        for (i in 2:p) {
            xmtx = cbind(xmtx, x[(ist - i):(Tn - i), ])
        }
    }
    ndim = dim(xmtx)[2]
    res = NULL
    xm = as.matrix(xmtx)
    xpx = crossprod(xm, xm)
    xpxinv = solve(xpx)
    xpy = t(xm) %*% as.matrix(y)
    beta = xpxinv %*% xpy
    resi = y - xm %*% beta
    sse = t(resi) %*% resi/(Tn - p - ndim)
    C1 = kronecker(sse, xpxinv)
    bhat = c(beta)
    npar = length(bhat)
    K = NULL
    omega = NULL
##### Locating the zero parameters based on Granger's causality
    for (i in 1:k1) {
      icnt=0
      if(include.mean)icnt=icnt+1
       for (ii in 1:p){
        icnt=icnt+k1
         for (j in 1:k2){
            icnt=icnt+1
            idx=rep(0,npar)
            idx[icnt] = 1
            K = rbind(K, idx)
            omega = c(omega, bhat[icnt])
            }
          }
       }
    K = as.matrix(K)
    v = dim(K)[1]
    cat("Number of targeted zero parameters: ", v, "\n")
    if (v > 0) {
        C2 = K %*% C1 %*% t(K)
        C2inv = solve(C2)
        tmp = C2inv %*% as.matrix(omega, v, 1)
        chi = sum(omega * tmp)
        pvalue = 1 - pchisq(chi, v)
        cat("Chi-square test for Granger Causality and p-value: ", c(chi, pvalue),
            "\n")
    }
### If p-value is large, perform the estimation of constrained model
 if(pvalue >= 0.05){
  ndim=p*k
  fixed=matrix(1,ndim,k)
  for (i in 1:k1){
    for (ii in 1:p){
      icnt=(ii-1)*k
      icnt=icnt+k1
      fixed[(icnt+1):(icnt+k2),i]=0
      }
    }
   if(include.mean){fixed=rbind(rep(1,k),fixed)}
   m1=VAR(X,p=p,include.mean=include.mean,fixed=fixed)
   coef=m1$coef
   secoef=m1$secoef
   aic=m1$aic
   bic=m1$bic
   hq=m1$hq
   resi=m1$residuals
   Sigma=m1$Sigma
   Phi=m1$Phi
   Ph0=m1$Ph0
 }
 else{
   coef=beta
   secoef=NULL
   aic=NULL
   bic=NULL
   hq=NULL
   Sigma=sse
   Phi=NULL
   Ph0=NULL
   }
#
    GrangerTest <- list(data = X, cnst = include.mean, order = p,
        coef = coef, constraints = K, aic=aic, bic=bic, hq=hq,
        residuals=resi, secoef=secoef, Sigma=Sigma,
        Phi=Phi, Ph0=Ph0, omega = omega, covomega = C2, locInput=locInput)
}

#####
"VARXirf" <- function(model,lag=12,orth=TRUE){
   # Computes impulse response function of a given VARX(p,m) model.
   # The model must be an object from the VARX command
   #
   Phi <- model$Phi
   beta <- model$beta
   p <- model$aror
   xorder <- model$m
   Sig <- model$Sigma
   xt <- model$xt
###
   if(!is.matrix(Phi))Phi=as.matrix(Phi)
   if(!is.matrix(Sig))Sig=as.matrix(Sig)
   if(!is.matrix(beta))beta <- as.matrix(beta)
   kx <- ncol(beta)/(1+xorder)
#### The impulse response function of the pure VAR-part
   # Compute MA representions: This gives impulse response function without considering Sigma.
   k=nrow(Phi)
###
   Si=diag(rep(1,k))
   wk=c(Si)
   ## acuwk: accumulated response
   awk=c(wk)
   acuwk=c(awk)
   if(p < 1) p =1
   if(lag < 1) lag=1
   #
   for (i in 1:lag){
      if (i <= p){
         idx=(i-1)*k
         tmp=Phi[,(idx+1):(idx+k)]
      }
      else{
         tmp=matrix(0,k,k)
      }
      #
      jj=i-1
      jp=min(jj,p)
      if(jp > 0){
         for(j in 1:jp){
            jdx=(j-1)*k
            idx=(i-j)*k
            w1=Phi[,(jdx+1):(jdx+k)]
            w2=Si[,(idx+1):(idx+k)]
            tmp=tmp+w1%*%w2
            ##print(tmp,digits=4)
         }
      }
      Si=cbind(Si,tmp)
      wk=cbind(wk,c(tmp))
      awk=awk+c(tmp)
      acuwk=cbind(acuwk,awk)
      ##print(Si,digits=3)
   }
   # Compute the impulse response of orthogonal innovations
   orSi=NULL
   wk1=NULL
   awk1=NULL
   acuwk1=NULL
   if(orth){
      m1=chol(Sig)
      P=t(m1)
      wk1=cbind(wk1,c(P))
      awk1=wk1
      acuwk1=wk1
      orSi=cbind(orSi,P)
      for(i in 1:lag){
         idx=i*k
         w1=Si[,(idx+1):(idx+k)]
         w2=w1%*%P
         orSi=cbind(orSi,w2)
         wk1=cbind(wk1,c(w2))
         awk1=awk1+c(w2)
         acuwk1=cbind(acuwk1,awk1)
      }
   }

   tdx=c(1:(lag+1))-1
   par(mfcol=c(k,k),mai=c(0.3,0.3,0.3,0.3))
   if(orth){
      gmax=max(wk1)
      gmin=min(wk1)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for (j in 1:k^2){
         plot(tdx,wk1[j,],type='l',xlab='lag',ylab='IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,wk1[j,],pch='*',cex=0.8)
         title(main='IRF, Orth. innovations')
      }
      cat("Press return to continue ","\n")
      readline()
      gmax=max(acuwk1)
      gmin=min(acuwk1)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for (j in 1:k^2){
         plot(tdx,acuwk1[j,],type='l',xlab='lag',ylab="Acu-IRF",ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,acuwk1[j,],pch="*",cex=0.8)
         title(main='Cumulative IRF, Orth. innovations')
      }
   }
   else{
      gmax=max(wk)
      gmin=min(wk)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k^2){
         plot(tdx,wk[j,],type='l',xlab='lag',ylab='IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,wk[j,],pch='*',cex=0.8)
         title(main="IRF, Orig. innovations")
      }
      cat("Press return to continue ","\n")
      readline()
      gmax=max(acuwk)
      gmin=min(acuwk)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k^2){
         plot(tdx,acuwk[j,],type='l',xlab='lag',ylab='Acu-IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,acuwk[j,],pch='*',cex=0.8)
         title(main="Cumulative IRF, Orig. innovations")
      }
   }
##### Compute the impulse response function of the exogenous variables
  PsiX <- beta[,1:kx]
  wk <- c(PsiX)
  awk <- wk
  acuwk <- wk
###
   for (i in 1:lag){
      if (i <= xorder){
         idx=i*kx
         tmp=beta[,(idx+1):(idx+kx)]
      }
      else{
         tmp=matrix(0,k,kx)
      }
      #
      jj=i-1
      jp=min(jj,p)
      if(jp > 0){
         for(j in 1:jp){
            jdx=(j-1)*k
            idx=(i-j)*kx
            w1=Phi[,(jdx+1):(jdx+k)]
            w2=Si[,(idx+1):(idx+kx)]
            tmp=tmp+w1%*%w2
            ##print(tmp,digits=4)
         }
      }
      PsiX=cbind(PsiX,tmp)
      wk=cbind(wk,c(tmp))
      awk=awk+c(tmp)
      acuwk=cbind(acuwk,awk)
      ##print(PsiX,digits=3)
   }
### Plotting
 cat("Press return for impulse response of exogenous variables: ","\n")
 readline()
   par(mfcol=c(k,kx),mai=c(0.3,0.3,0.3,0.3))
      gmax=max(wk)
      gmin=min(wk)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:(k*kx)){
         plot(tdx,wk[j,],type='l',xlab='lag',ylab='IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,wk[j,],pch='*',cex=0.8)
         title(main="IRF of Exogenous Var.")
      }
      cat("Press return to continue ","\n")
      readline()
      gmax=max(acuwk)
      gmin=min(acuwk)
      cx=(gmax-gmin)/10
      gmax=gmax+cx
      gmin=gmin-cx
      for(j in 1:k*kx){
         plot(tdx,acuwk[j,],type='l',xlab='lag',ylab='Acu-IRF',ylim=c(gmin,gmax),cex.axis=0.8)
         points(tdx,acuwk[j,],pch='*',cex=0.8)
         title(main="Cumulative IRF of X-variables")
      }
###

   VARXirf <- list(irf=Si,orthirf=orSi,irfX=PsiX)
}

#####
"backtest" <- function(m1,rt,orig,h=1,xre=NULL,fixed=NULL,inc.mean=TRUE, 
    reest=1,method=c("CSS-ML")){
    regor = c(m1$arma[1], m1$arma[6], m1$arma[2])
    seaor = list(order = c(m1$arma[3], m1$arma[7], m1$arma[4]), 
        period = m1$arma[5])
    if((regor[2]>0) || (seaor[2] > 0))inc.mean=FALSE
#
### Attaching sub-routines used.
#### 
forehstep=function(m1,rt,at,orig,h,xreg,include.mean){
####
 p <- m1$arma[1]; d=m1$arma[6]; q=m1$arma[2]
 P <- m1$arma[3]; D=m1$arma[7]; Q=m1$arma[4]
 s <- m1$arma[5]; coef=m1$coef  
 nx <- 0
 if(!is.null(xreg)){xreg=as.matrix(xreg); nx <- ncol(xreg)}
 rar <- NULL
 if(p > 0)rar=c(1,-coef[1:p])
 rma <- NULL
 if(q > 0)rma=c(1,coef[(p+1):(p+q)])
 ist=p+q
 sar <- NULL
 if(P > 0){
      sar=c(1,-coef[(ist+1):(ist+P)])
      ist=ist+P
      }
 sma <- NULL
 if(Q > 0){
  sma=c(1,coef[(ist+1):(ist+Q)])
  ist=ist+Q
  }
 mu=0
 if(include.mean){mu=coef[ist+1]
    ist=ist+1
   }
beta <- NULL
 if(nx > 0)beta=coef[(ist+1):(ist+nx)]
### AR and MA polynomials with difference
phi <- multiplicate(rar,sar,s)$poly
if(D==1)phi=multiplicate(phi,c(1,-1),s)$poly
if(D==2)phi=multiplicate(phi,c(1,-1),s)$poly
if(d==1)phi=c(phi,0)-c(0,phi)
if(d==2)phi=c(phi,0)-c(0,phi)
arorder=length(phi)-1
###
theta <- multiplicate(rma,sma,s)$poly
maorder=length(theta)-1
###
###
 xt <- rt[1:orig]
### removing exogenous effects
 xt <- xt-mu
 if(nx > 0){
   for (j in 1:nx){
    xt=xt-beta[j]*xreg[1:orig,j]
    }
  }
##
### Prediction of mean-adjusted series
pred <- NULL
for (i in 1:h){
 it=orig+i
 w <- 0
 if(arorder > 0){
  for (j in 1:arorder){
   w = w-phi[j+1]*xt[it-j]
   }
 }

 if(maorder > 0){
   for (j in 1:maorder){
    w = w +theta[j+1]*at[it-j]
    }
  }
if(0){
 cat("after ma-- w: ",w,"\n")
}
## update xt 
  xt=c(xt,w)
### compute actual prediction
  w=w+mu
  if(nx > 0){
    for (j in 1:nx){
     w = w+beta[j]*xreg[it,j]
     }
   }

  at=c(at,0)
  pred=c(pred,w)
 }

forehsetp <- list(pred=pred)
}

multiplicate=function(p1,p2,s=1){
### p1: coefficient vector of regular part
### p2: coefficient vector of the seasonal part
### s: period
###
if(!is.null(p1)){
   d1 <- length(p1)-1
   }else{
   d1 = 0; p1=c(1)}
if(!is.null(p2)){
  d2 <- length(p2)-1
  }else{d2=0; p2=c(1)}
##
### p3: product vector with degrees d3.
d3 <- 0; p3=c(1)
if((d1==0) && (d2 > 0)){d3=d2
    p3 <- c(1)
    for (i in 1:d2){
     p3 <- c(p1,rep(0,s-1),p2[i+1])
     }
   }
if((d2==0) && (d1 > 0)){d3=d1; p3=p1}
if((d1 > 0) && (d2 > 0)){
d3 <- d1+s*d2
p3 <- c(1,rep(0,d3))
p3[2:(d1+1)]=p1[2:(d1+1)]
for (i in 1:d2){
 ist = i*s+1
 p3[ist:(ist+d1)]=p3[ist:(ist+d1)]+p1*p2[i+1]
 }
}
multiplicative <- list(degree=d3,poly=p3)
}
### end of subroutines used.
###
### Resume the backtest program.
    nT = length(rt)
    if (orig > nT) orig = nT-1
    if (h < 1) h = 1
    rmse = rep(0, h)
    mabso = rep(0, h)
    nori = nT - orig
    err = matrix(0, nori, h)
    fcst = matrix(0, nori, h)
    jlast = nT - 1
    ireest <- reest
    for (n in orig:jlast) {
        jcnt = n - orig + 1
        x = rt[1:n]
        if (is.null(xre)){ 
            pretor = NULL
        }else{ pretor = xre[1:n,]}
        if (ireest == reest) {
           mm=arima(x,order=regor,seasonal=seaor,xreg=pretor,fixed=fixed,include.mean=inc.mean,method=method)
            ireest <- 1
            at <- mm$residuals
           if (is.null(xre)) {
            nx = NULL
           }else {
            nx = xre[(n + 1):(n + h),]
         }
         fore =predict(mm,h,newxreg=nx)
         at=c(at,rt[n+1]-fore$pred[1])
        }
        else{
         ireest <- ireest + 1
         fore = forehstep(mm,rt,at,orig=n,h=h,xreg=xre,include.mean=inc.mean)
          at <- c(at,rt[n+1]-fore$pred[1])
        }
        kk = min(nT, (n + h))
        nof = kk - n
        pred = fore$pred[1:nof]
        obsd = rt[(n + 1):kk]
        err[jcnt, 1:nof] = obsd - pred
        fcst[jcnt, 1:nof] = pred
    }
    for (i in 1:h) {
        iend = nori - i + 1
        tmp = err[1:iend, i]
        mabso[i] = sum(abs(tmp))/iend
        rmse[i] = sqrt(sum(tmp^2)/iend)
    }
    print("RMSE of out-of-sample forecasts")
    print(rmse)
    print("Mean absolute error of out-of-sample forecasts")
    print(mabso)

### end of backtest
backtest <- list(origin = orig, error = err, forecasts = fcst, 
        rmse = rmse, mabso = mabso, reest = reest)
}

####
"REGtspred" <- function(model,newxt,h=1,orig=0){
### Compute the forecats of a fitted REGts model
### newxt: data matrix for the regressors in the forecasting period
### h: number of forecasts to be produced
### orig: forecast origin. Set to end of the data in the default.
###
zt <- model$data
xt <- model$xt
p <- model$aror
include.mean <- model$include.mean
Phi <- model$Phi
beta <- as.matrix(model$beta)
Sigma <- model$Sigma
nT <- nrow(zt)
if(orig <= 0){orig=nT}
k <- ncol(zt)
kx <- ncol(xt)
Xmtx = xt
nxt <- as.matrix(newxt)
if(include.mean){nxt <- cbind(rep(1,h),nxt)
                 Xmtx <- cbind(rep(1,orig),xt[1:orig,])
                 }
wzt <- zt[1:orig,]-Xmtx[1:orig,]%*%t(beta)
wzt <- as.matrix(wzt)
m1 <- list(data = wzt,cnst=FALSE,order=p,Ph0=rep(0,k),Phi=Phi,Sigma=Sigma)
pm1 <- VARpred(m1,h=h,orig=orig,output=FALSE)  ### Compute s.e. and rmse of forecasts
se.err <- pm1$se.err
rmse <- pm1$rmse
### compute the point forecasts
for (t in (orig+1):(orig+h)){
 wk <- NULL
 for (j in 1:p){
  wk <- c(wk,wzt[t-j,])
  }
  pred <- matrix(wk,1,p*k)%*%t(Phi)
  wzt <- rbind(wzt,pred)
 }
fcst <- wzt[(orig+1):(orig+h),]
pred <- fcst + nxt%*%t(beta)
##
cat("### Predictions of REGts Model ###","\n")
cat("Predictions at forecast origin: ",orig,"\n")
cat("Point forecasts: 1-step to",h,"-step","\n")
print(round(pred,5))
cat("Standard errors of predictions: ","\n")
print(round(se.err,5))
cat("RMSE of predictions: ","\n")
print(round(rmse,5))

REGtspred <- list(pred=pred,se.err=se.err,rmse=rmse,orig=orig)

}

#####
"sVARMApred" <- function(model,orig,h=1){
# Prediction of a multiplicative vector ARMA model
# where "model" is a sVARMA output.
x <- as.matrix(model$data)
order <- model$order
sorder <- model$sorder
s <- model$period
resi <- as.matrix(model$residuals)
Sigma <- model$Sigma
phi <- model$regPhi
PHI <- model$seaPhi
theta <- model$regTheta
THETA <- model$seaTheta
Ph0 = model$Ph0
inc.mean <- model$cnst
switch <- model$switch
p <- order[1]; d <- order[2]; q <- order[3]
P <- sorder[1]; D <- sorder[2]; Q <- sorder[3]
arP <- p+P*s
maQ <- q+Q*s
### Data handling
k <- ncol(x)
nT <- nrow(x)
if(orig > nT)orig = nT
if(orig < (arP+D*s+d))orig = arP+D*s+d
#### definition matrix polynomial multiplication
mtxpoly <- function(aa,AA,v,V,s,k,switch){
coef = NULL
if(v > 0)aa=as.matrix(aa)
if(V > 0)AA=as.matrix(AA)
gap <- s-1-v
if((v == 0) && (V > 0)){
  for (i in 1:V){
   idx = (i-1)*k
   if(gap > 0)coef=cbind(coef,matrix(0,k,gap*k))
   coef=cbind(coef,AA[,(idx+1):(idx+k)])
   }
}
if((v > 0) && (V == 0))coef=aa
if((v > 0) && (V > 0)){
 coef <- aa
 for (i in 1:V){
   idx = (i-1)*k
   SS <- AA[,(idx+1):(idx+k)]
   if(gap > 0)coef=cbind(coef,matrix(0,k,gap*k))
   coef=cbind(coef,SS)
   for (j in 1:v){
     if(switch){
      coef=cbind(coef,SS%*%aa[,((j-1)*k+1):(j*k)])
      }
    else{
      coef=cbind(coef,aa[,((j-1)*k+1):(j*k)]%*%SS)
      }
    }
  }
 }
coef
}
### obtain the AR and MA matrix polynomials
arcoef <- mtxpoly(phi,PHI,p,P,s,k,switch)
### Take care of differencing, if any.
Ik=diag(rep(1,k))
gap = s-1-p
if(d > 0){
  for (i in 1:d){
   if(length(arcoef) < 1){arcoef=Ik
            arP=1
            }
	    else{
	      arP=arP+1
	      arcoef1 <- cbind(arcoef,Ik)
	      arcoef2 <- cbind(Ik,-arcoef)
	      arcoef <- arcoef1+arcoef2
	      }
            }
  }
#### seasonal difference, if any
if(D > 0){
    for (i in 1:D){
      if(length(arcoef) < 1){arcoef=cbind(matrix(0,k,gap*k),Ik)
                             arP=arP+s
                     }
		     else{
		     arP = arP+s
		     arcoef1 = cbind(arcoef,matrix(0,k,s*k))
		     arcoef2 = cbind(matrix(0,k,(s-1)*k),Ik,-arcoef)
		     arcoef=arcoef1+arcoef2
		     }
                   }
            }
macoef <- mtxpoly(theta,THETA,q,Q,s,k,switch)
###
mm <- list(data=x,ARorder=arP, MAorder=maQ,cnst=inc.mean,residuals=resi,Phi=arcoef,Theta=macoef,Ph0=Ph0,coef=t(cbind(cbind(arcoef,macoef))),Sigma=Sigma)

m1 = VARMApred(mm,h=h,orig=orig)
pred=m1$pred
fse=m1$se.err

sVARMApred <- list(data=x, orig=orig, pred=pred, se.err=fse)
}

"Kronpred" <- function(model,orig=0,h=1){
### Compute forecasts of a fitted model via the command "Kronfit".
zt <- as.matrix(model$data)
Kdx <- model$Kindex
ARid <- model$ARid
MAid <- model$MAid
include.mean <- model$cnst
Kpar <- model$coef
resi <- model$residuals
Sig <- model$Sigma
Ph0 <- model$Ph0
Phi <- as.matrix(model$Phi)
Theta <- as.matrix(model$Theta)
const <- model$const
##
nT <- nrow(zt)
k <- ncol(zt)
nT1 <- nrow(resi)
if (nT1 < nT){
  resi=rbind(matrix(0,(nT-nT1),k),resi)
  }
if(orig <= 0)orig=nT
if(orig > nT)orig=nT
p <- floor(ncol(Phi)/k)
Ph0i <- solve(Ph0)
const=Ph0i%*%matrix(c(const),k,1)
if(p > 0){
 Phi <- Ph0i%*%Phi
 Theta <- Ph0i%*%Theta
}
###
### Use the VARMApred command to compute the forecasts
mod <- list(data=zt,residuals=resi,cnst=include.mean,ARorder=p,MAorder=p,Ph0=t(const),
 Phi=Phi,Theta=Theta,Sigma=Sig)
mm <- VARMApred(mod,h=h,orig=orig)

Kronpred <- list(pred=mm$pred,se.err=mm$se.err,orig=orig)
}

"Corner" <- function(y,x,Nrow=11,Ncol=7){
### compute the "corner-table" for output "y" and input "x".
### y: filtered dependent variable
### x: filtered input variable AND is supposed to be a white noise series
if(is.matrix(y))y=y[,1]
if(is.matrix(x))x=x[,1]
nT <- min(length(y),length(x))
lag <- Nrow+Ncol+1
y1 <- y[1:nT]
x1 <- x[1:nT]
Sy <- sqrt(var(y1))
Sx <- sqrt(var(x1))
Y <- y1[lag:nT]
X <- x1[lag:nT]
for (i in 1:(lag-1)){
X <- cbind(X,x1[(lag-i):(nT-i)])
}
vi <- cor(Y,X)
vi <- vi*Sy/Sx
vmax <- max(abs(vi))
vi <- vi/vmax
##cat("Corr: ",vi,"\n")
tbl <- matrix(0,Nrow, Ncol)
tbl[,1] <- vi[1:Nrow]
for (j in 2:Ncol){
for (i in 1:Nrow){
 cmx = diag(rep(vi[i],j))
 for (ii in 2:j){
  for (jj in 1:(ii-1)){
   idx = i+jj
   cmx[ii,jj] = vi[idx]
   }
  }
 for (jj in 2:j){
  for (ii in 1:(jj-1)){
   idx = i-jj+1
   if(idx > 0)cmx[ii,jj]=vi[idx]
   }
  }
#  cat("cmx: ",cmx,"\n")
tbl[i,j]=det(cmx)
 }
 }
stbl <- tbl
crit=2/sqrt(nT)
tbl=cbind(c(1:Nrow)-1,tbl)
colnames(tbl) <- c("r->",paste(c(1:Ncol)))
cat("Corner Table: ","\n")
print(round(tbl,3))
for (i in 1:Nrow){
 for (j in 1:Ncol){
  if(abs(tbl[i,j+1]) <= crit){
      stbl[i,j] = "O"
      }
      else{
      stbl[i,j] = "X"
      }
   }
 }
cat("\n")
cat("Simplified Table: 2/sqrt(T): ","\n")
J=paste(c(1:Nrow)-1)
stbl=cbind(J,stbl)
colnames(stbl) <- c("r->",paste(c(1:Ncol)))
print(stbl)

Corner <- list(cornor = tbl)
}

Try the MTS package in your browser

Any scripts or data that you put into this service are public.

MTS documentation built on April 11, 2022, 5:07 p.m.