qcond_pcond_vine-original/hjcondvine.R

#' # Assume vine array with 1:d on diagonal.
#' # Vine functions for mapping of (u[1],...,u[d])  to
#' # p[1]=u[1], p[2]=C_{2|1}(u[2]|u[1]) , ...
#' #         p[d]=C_{d|1:(d-1)}(u[d]}u[1:(d-1)])
#' # and inverse.
#' # Byproducts :
#' #  (a) conditional cdf F_{d|1:(d-1)}(x_d| x_1,...,x_{d-1}) after converting
#' #   x_j to u_j=F_j(x_j) for j=1,...,d
#' #  (b) conditional quantile F^{-1}_{d|1:(d-1)}(p|x_1,...,x_{d-1})
#' #  after converting x_j to u_jF_j(x_j) for j=1,...,d-1 and
#' #  applying F_d^{-1}(u_d) to the output u_d
#'
#' # Note that if pair-copula families are permutation asymmetric,
#' # the code below needs to replace pcond (pcondnames)
#' # with pcond21 (pcond21names) and pcond12 (pcond12names),
#' # with small changes to the code, replacing pcond by either pcond21 or pcond12
#'
#' # so below is not valid for pcondgumv pcondgumu etc where
#' # one of the U(0,1) variables has been reflected to ger negative depc.
#'
#' #============================================================
#'
#' # Versions of pcond vectors for R-vine
#' #   with different pair-copula family for each edge of the vine
#' # for each row u[1:d] of hypercube data,
#' # return
#' # u1, C_{2|1}(u2|u1), C_{3|12}(u3|u1,u2), ...  C_{d|1..d-1}(u_d|u[1:(d-1)])
#'
#' #' Copula Conditional Distributions
#' #'
#' #' These functions compute the conditional distributions of the
#' #' last variable, given the other variables in the vine.
#' #'
#' #' parvec = vector of parameters of pair-copulas
#' #' udat = nxd matrix with uniform scores
#' #' A = dxd vine array with 1:d on diagonal
#' #' ntrunc = truncated level, assume >=1
#' #' pcondmat = matrix of names of conditional cdfs for trees 1,...,ntrunc
#' #'  (assuming only one needed for permutation symmetric pair-copulas)
#' #'   pcondmat is empty for diagonal and lower triangle,
#' #'    and could have ntrunc rows or be empty for rows ntrunc+1 to d-1
#' #' np = dxd where np[ell,j] is size for parameter th[ell,j]
#' #'   for pair-copula in tree ell, variables j and A[ell,j]
#' #'   np=0 on and below diagonal
#' #' Output:
#' #' return C_{2|1}(u2|u1), C_{3|12}(u3|u1,u2), ...  C_{d|1..d-1}(ud|u1,...u[d-1])
#' #' [This function is modification of rvinellkv.trunc2 in CopulaModel]
#' #' @author Harry Joe
#' #' @import CopulaModel
#' #' @export
#' #rvinellkv.trunc2=function(parvec,udat,A,ntrunc,logdcopmat,pcondmat,np)
#' rvinepcond=function(parvec,udat,A,ntrunc,pcondmat,np)
#' { d=ncol(A)  # or ncol(udat)
#'   npmax=max(np); th=array(0,c(npmax,d,d)) # format of parameter for vine
#'   ii=0;
#'   for(ell in 1:ntrunc)
#'   { for(j in (ell+1):d)
#'     { ipp=1:np[ell,j]
#'       th[ipp,ell,j]=parvec[ii+ipp]
#'       ii=ii+np[ell,j]
#'     }
#'   }
#'   out=varray2M(A)
#'   M=out$mxarray
#'   icomp=out$icomp
#'   n=nrow(udat)
#'   #llkv=rep(0,n)
#'   vinepcond=matrix(0,n,d)
#'   vinepcond[,1]=udat[,1]
#'   v=matrix(0,n,d); vp=matrix(0,n,d); s=matrix(0,n,d);
#'   nllk=0
#'   # tree 1
#'   #for(j in 2:d)
#'   #{ ipp=1:np[1,j]
#'     #logdcop=match.fun(logdcopmat[1,j])
#'     #llkv=llkv+logdcop(udat[,A[1,j]],udat[,j],th[ipp,1,j])
#'   #}
#'   # tree 2
#'   if(ntrunc>=2)
#'   { for(j in 2:d)
#'     { ipp=1:np[1,j]
#'       pcond=match.fun(pcondmat[1,j])
#'       if(icomp[1,j]==1) vp[,j]=pcond(udat[,A[1,j]],udat[,j],th[ipp,1,j])
#'       v[,j]=pcond(udat[,j],udat[,A[1,j]],th[ipp,1,j])
#'     }
#'     vinepcond[,2]=v[,2]
#'     for(j in 3:d)
#'     { if(A[2,j]<M[2,j]) s[,j]=vp[,M[2,j]] else s[,j]=v[,A[2,j]] }
#'     #for(j in 3:d)
#'     #{ ipp=1:np[2,j]
#'       #logdcop=match.fun(logdcopmat[2,j])
#'       #llkv=llkv+logdcop(s[,j],v[,j],th[ipp,2,j])
#'     #}
#'     w=v; wp=vp
#'   }
#'   # remaining trees
#'   if(ntrunc>=3)
#'   { for(ell in 3:ntrunc)
#'     { for(j in ell:d)
#'       { ipp=1:np[ell-1,j]
#'         pcond=match.fun(pcondmat[ell-1,j])
#'         if(icomp[ell-1,j]==1) vp[,j]=pcond(s[,j],w[,j],th[ipp,ell-1,j])
#'         v[,j]=pcond(w[,j],s[,j],th[ipp,ell-1,j])
#'       }
#'       vinepcond[,ell]=v[,ell]
#'       for(j in (ell+1):d)
#'       { if(A[ell,j]<M[ell,j]) s[,j]=vp[,M[ell,j]] else s[,j]=v[,A[ell,j]] }
#'       #for(j in (ell+1):d)
#'       #{ ipp=1:np[ell,j]
#'         #logdcop=match.fun(logdcopmat[ell,j])
#'         #llkv=llkv+logdcop(s[,j],v[,j],th[ipp,ell,j])
#'       #}
#'       w=v; # wp=vp  # wp is not used
#'     }
#'   }
#'   if(ntrunc>1 & ntrunc<d)
#'   { ell=ntrunc+1
#'     for(j in ell:d)
#'     { ipp=1:np[ell-1,j]
#'       pcond=match.fun(pcondmat[ell-1,j])
#'       if(icomp[ell-1,j]==1) vp[,j]=pcond(s[,j],w[,j],th[ipp,ell-1,j])
#'       v[,j]=pcond(w[,j],s[,j],th[ipp,ell-1,j])
#'       vinepcond[,j]=v[,j]
#'     }
#'   }
#'   if(ntrunc==1)
#'   { ell=2
#'     for(j in ell:d)
#'     { ipp=1:np[ell-1,j]
#'       pcond=match.fun(pcondmat[ell-1,j])
#'       v[,j]=pcond(udat[,j],udat[,A[1,j]],th[ipp,ell-1,j])
#'       vinepcond[,j]=v[,j]
#'     }
#'   }
#'   #llkv
#'   vinepcond
#' }
#'
#' #============================================================
#'
#' # modification of previous R-vine simualtion code to get quantile function
#' # this code is not efficient but should be OK for case of
#' #  pair-copulas all permutation symmetric
#'
#' #' n = #replications or sample size
#' #' pmat = nxd matrix of levels of u1, C_{2|1}(u_2|u_1),...,
#' #'                          C_{d|1..d-1}(u_d|u[1:(d-1)])
#' #' parvec = vector of parameters to be optimized in nllk
#' #' A = dxd vine array with 1:d on diagonal
#' #' ntrunc = truncated level, assume >=1
#' #' pcondmat = matrix of names of conditional cdfs for trees 1,...,ntrunc
#' #'  (assuming only one needed for permutation symmetric pair-copulas)
#' #' qcondmat = matrix of names of conditional quantile functions for
#' #'        trees 1,...,ntrunc
#' #'   qcondmat and pcondmat are empty for diagonal and lower triangle,
#' #'    and could have ntrunc rows or be empty for rows ntrunc+1 to d-1
#' #' np = dxd where np[ell,j] is #parameters for parameter th[ell,j]
#' #'   for pair-copula in tree ell, variables j and A[ell,j]
#' #'   np=0 on and below diagonal
#' #' iinv=T to check that this is inverse of rvinepcond()
#' #'    in this case, columns of pmat come from rvinepcond()
#' #' iinv=F, get quantiles C_{d|1:(d-1)}(p|u[1:(d-1)]) based on last column of
#' #'       pmat[,d] where u[1],..,u[d-1] have been previously converted to
#' #'       u[1], C_{2|1}(u[2]|u[1]), ... C_{d-1|1:(d-2)}(u[d-1]|u[1:(d-2)])
#' #'       via rvinepcond()
#' #' @return n x d matrix with values in (0,1) or
#' #'       quantile C_{d|1...d-1}(p| u[1:(d-1)])
#' #' [This function is modification of rvinesimvec2 in CopulaModel]
#' #' @author Harry Joe
#' #' @import CopulaModel
#' #' @export
#' #rvinesimvec2=function(nsim,A,ntrunc,parvec,np,qcondmat,pcondmat,iprint=F)
#' rvineqcond=function(pmat,A,ntrunc,parvec,np,qcondmat,pcondmat,iinv=F)
#' { d=ncol(A)
#'   # get matrix ip1,ip2 of indices
#'   ii=0
#'   ip1=matrix(0,d,d); ip2=matrix(0,d,d)
#'   for(ell in 1:ntrunc)
#'   { for(j in (ell+1):d)
#'     { ip1[ell,j]=ii+1; ip2[ell,j]=ii+np[ell,j]
#'       ii=ii+np[ell,j]
#'     }
#'   }
#'   #if(iprint) { print(ip1); print(ip2) }
#'   out=varray2M(A)
#'   M=out$mxarray
#'   icomp=out$icomp
#'   #p=matrix(runif(nsim*d),nsim,d)
#'   p=pmat
#'   n=nrow(p)
#'   qq=array(0,c(n,d,d)); v=array(0,c(n,d,d))
#'   u=matrix(0,n,d)
#'   u[,1]=p[,1]; qq[,1,1]=p[,1]; qq[,2,2]=p[,2];
#'   qcond=match.fun(qcondmat[1,2])
#'   u[,2]=qcond(p[,2],p[,1],parvec[ip1[1,2]:ip2[1,2]])
#'   qq[,1,2]=u[,2]
#'   if(icomp[1,2]==1)
#'   { #pcond=match.fun(pcondnames[1])
#'     pcond=match.fun(pcondmat[1,2])
#'     v[,1,2]=pcond(u[,1],u[,2],parvec[ip1[1,2]:ip2[1,2]])
#'   }
#'   # the main loop
#'   for(j in 3:d)  # variable
#'   { tt=min(ntrunc,j-1)
#'     qq[,tt+1,j]=p[,j]
#'     if(tt>1)
#'     { for(ell in seq(tt,2)) # tree
#'       { if(A[ell,j]==M[ell,j]) { s= qq[,ell,A[ell,j]] }
#'         else { s=v[,ell-1,M[ell,j]] }
#'         #qcond=match.fun(qcondnames[ell])
#'         qcond=match.fun(qcondmat[ell,j])
#'         qq[,ell,j]=qcond(qq[,ell+1,j], s, parvec[ip1[ell,j]:ip2[ell,j]]);
#'       }
#'     }
#'     #qcond=match.fun(qcondnames[1])
#'     qcond=match.fun(qcondmat[1,j])
#'     qq[,1,j]=qcond(qq[,2,j],u[,A[1,j]], parvec[ip1[1,j]:ip2[1,j]])
#'     u[,j]=qq[,1,j]
#'     # set up for next iteration (not needed for last j=d)
#'     #pcond=match.fun(pcondnames[1])
#'     pcond=match.fun(pcondmat[1,j])
#'     v[,1,j]=pcond(u[,A[1,j]],u[,j],parvec[ip1[1,j]:ip2[1,j]])
#'     if(tt>1)
#'     { for(ell in 2:tt)
#'       { if(A[ell,j]==M[ell,j]) { s=qq[,ell,A[ell,j]] }
#'         else { s=v[,ell-1,M[ell,j]] }
#'         if(icomp[ell,j]==1)
#'         { #pcond=match.fun(pcondnames[ell])
#'           pcond=match.fun(pcondmat[ell,j])
#'           v[,ell,j]=pcond(s, qq[,ell,j], parvec[ip1[ell,j]:ip2[ell,j]]);
#'         }
#'       }
#'     }
#'   }
#'   if(iinv) u=u[,d]  # last column as quantiles
#'   u  # nxd matrix to check that this funciton is inverse of rvinepcond
#' }
#'
vincenzocoia/copsupp documentation built on Aug. 23, 2020, 7:37 a.m.