#############################################################################
#############################################################################
#### Functions in Univariate Autoregressive Cokriging Models
#############################################################################
#############################################################################
margin.posterior= function(param, input, output, level, H, dist, cov.model="matern_5_2",
prior="JR", hyperparam=NULL){
Dim = dim(dist)[3]
p.x = Dim
S = length(output)
if(is.null(hyperparam)){
al = 0.5-p.x
bl = 1 * dim(dist)[1]^(-1/p.x) * (al + p.x)
nugget.UB = 1
}else{
al = hyperparam$a
bl = hyperparam$b * dim(dist)[1]^(-1/p.x) * (al + p.x)
nugget.UB = hyperparam$nugget.UB
}
# param contains phi and nugget (maybe)
if(length(param)==Dim){ #no nugget
phi = exp(-param)
is.nugget=FALSE
}else{
phi = exp(-param[1:Dim])
nugget = nugget.UB*exp(param[Dim+1]) / (1 + exp(param[Dim+1]))
is.nugget = TRUE
phi = c(phi, nugget)
}
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
}
n = sapply(output, length)
# input.max = apply(input[[level]], 2, max)
# input.min = apply(input[[level]], 2, min)
# Cl = abs(input.max-input.min)
Cl = hyperparam$Cl
t = level
if(level==1){
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
X.aug = H[[t]]
y.aug = output[[t]]
HRH = t(X.aug)%*%RInv%*%X.aug #+ diag(1e-6,dim(X.aug)[2])
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
betahat = HRHInv%*%(t(X.aug)%*%(RInv%*%y.aug))
res = y.aug - X.aug%*%betahat
SSE = c(t(res)%*%RInv%*%res)
logdetG = -sum(log(diag(U)))
g = logdetG - sum(log(diag(HRHchol))) + (-0.5)*(n[t]-q[t])*log(SSE)
if(prior=="Ind_Jeffreys"){
g = g + 0.5*(q[t])*log(SSE)
}
}else{
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
IB = match.input(input[[t]], input[[t-1]])$IB
y_t1 = as.matrix(output[[t-1]][IB])
X.aug = cbind(H[[t]], y_t1)
y.aug = output[[t]]
HRH = t(X.aug)%*%RInv%*%X.aug #+ diag(1e-6,dim(X.aug)[2])
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
betahat = HRHInv%*%(t(X.aug)%*%(RInv%*%y.aug))
res = y.aug - X.aug%*%betahat
SSE = c(t(res)%*%RInv%*%res)
logdetG = -sum(log(diag(U)))
g = logdetG - sum(log(diag(HRHchol))) + (-0.5)*(n[t]-q[t]-1)*log(SSE)
if(prior=="Ind_Jeffreys"){
g = g + 0.5*(q[t]+1)*log(SSE)
}
}
X = X.aug
## compute priors
if(is.nugget){
lnJacobian = sum(param[1:Dim]) + log(nugget) + log(nugget.UB - nugget) -
log(abs(nugget.UB+(nugget.UB-1)*nugget)) # - sum(log(phi)) + log(nugget)
if(prior=="JR"){
temp = sum(1/phi[1:Dim] * Cl) + nugget
ln_prior = lnJacobian + al*log(temp) - bl*temp
}else{
lnIJ_prior = log_objective_prior(c(1/phi, nugget), dist, RInv, X, cov.model, is.nugget, prior)
ln_prior = lnIJ_prior + lnJacobian
}
}else{
lnJacobian = sum(param)
if(prior=="JR"){
temp = sum(1/phi * Cl)
ln_prior = lnJacobian + al*log(temp) - bl*temp
}else{
lnIJ_prior = log_objective_prior(c(1/phi), dist, RInv, X, cov.model, is.nugget, prior)
ln_prior = lnIJ_prior + lnJacobian
}
}
g = ln_prior + g
return(g)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
condsim.ND.univariate = function(formula, output, input, input.new, phi, cov.model="matern_5_2",
nsample){
Dim = dim(input[[1]])[2]
p.x = Dim
if(dim(phi)[1]==Dim){
is.nugget=FALSE
}else{
is.nugget=TRUE
}
S = length(output)
n = sapply(output, length)
np = dim(input.new)[1]
y = output
## add new inputs to missing inputs
# input.miss = list()
# input.union = list()
# for(t in 1:S){
# input.miss[[t]] = input.new
# input.union[[t]] = rbind(input.new, input[[t]])
# }
input.miss = list()
input.union = list()
pred.ID = list()
ID.orig = list()
index.full = 1:np
indB = list()
for(t in 1:(S)){
ind.list = match.input(input[[t]], input.new)
# indlist = ismember(input.new, input[[t]])
if(!is.null(ind.list$IA)){
indA = ind.list$IA
indB[[t]] = ind.list$IB
pred.ID.exist = indA
input.exist = input[[t]][indA, ,drop=FALSE] # common inputs
input.added = input.new[-indB[[t]], ,drop=FALSE] # inputs in input.new but not in input[[t]]
n.added = dim(input.added)[1]
pred.ID.added = seq(1, n.added, by=1)
ID.orig[[t]] = c(index.full[-indB[[t]]], indB[[t]])
pred.ID[[t]] = c(pred.ID.added, pred.ID.exist+n.added)
input.miss[[t]] = input.added
input.union[[t]] = rbind(input.added, input[[t]])
}else{
ID.orig[[t]] = 1:np
pred.ID[[t]] = 1:np
input.miss[[t]] = input.new
input.union[[t]] = rbind(input.new, input[[t]])
}
}
n.m = rep(NA, S)
for(t in 1:S){
n.m[t] = dim(input.miss[[t]])[1]
}
###################################################################
#### create covariates
###################################################################
H = list()
Hm = list()
for(t in 1:S){
colnames(input[[t]]) = paste0("x", 1:p.x)
df = data.frame(input[[t]])
H[[t]] = model.matrix(formula[[t]], df)
colnames(input.miss[[t]]) = paste0("x", 1:p.x)
df = data.frame(input.miss[[t]])
Hm[[t]] = model.matrix(formula[[t]], df)
}
###################################################################
#### compute intermediate quantities
###################################################################
dist.o = list()
dist.m = list()
dist.mo = list()
distlist = list()
for(t in 1:S){
dist.o[[t]] = compute_distance(input[[t]], input[[t]])
#if(t<S){
dist.m[[t]] = compute_distance(input.miss[[t]], input.miss[[t]])
dist.mo[[t]] = compute_distance(input.miss[[t]], input[[t]])
#}
distlist[[t]] = compute_distance(input.union[[t]], input.union[[t]])
}
ym.hat = list()
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
ym.hat[[t]] = matrix(NA, nsample, n.m[[t]])
}
#################################################################################
#### Sampling from predictive distribution
#################################################################################
t = 1
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
#UH = backsolve(U, H[[t]], transpose=TRUE)
#HRHInv = solve(crossprod(UH))
HRHInv = solve(t(H[[t]])%*%RInv%*%H[[t]])
betahat = HRHInv%*%t(H[[t]])%*%(RInv%*%y[[t]])
res = y[[t]] - H[[t]]%*%betahat
SSE = c(t(res)%*%RInv%*%res)
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
RmoU = t(backsolve(U, t(Rmo), transpose=TRUE))
RmoRInv = Rmo%*%RInv
# XXRR = t(Hm[[t]]) - t(H[[t]])%*%RInv%*%t(Rmo)
XXRR = Hm[[t]] - RmoRInv%*%H[[t]]
# Sig_ymymy = Rm - Rmo%*%RInv%*%t(Rmo) + (XXRR)%*%HRHInv%*%t(XXRR)
Sig_ymymy = Rm - tcrossprod(RmoU) + (XXRR)%*%HRHInv%*%t(XXRR)
Sig = Sig_ymymy * SSE/(n[t] - q[t])
#Sig = Sig_ymymy * SSE/(n[t])
mu_ymy = Hm[[t]]%*%betahat + RmoRInv%*%res
#ym.hat[[t]] = c(mu_ymy)
#krige[[t]] = ym.hat[[t]][pred.ID[[t]]]
ym.hat[[t]] = mvtnorm::rmvt(nsample, sigma=Sig, df=n[t]-q[t], delta=mu_ymy, type="shifted")
#Sig[Sig<0] = 0
#krigeSE[[t]] = sqrt(diag(Sig)[pred.ID[[t]]])
# for(k in 1:nsample){
for(t in 2:(S)){
############################################################################
#### estimate missing data ym
############################################################################
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
IB = match.input(input[[t]], input[[t-1]])$IB
y_t1 = y[[t-1]][IB]
X = cbind(H[[t]], y_t1)
XRXInv = solve(t(X)%*%RInv%*%X)
betahat = XRXInv%*%t(X)%*%(RInv%*%y[[t]])
res = y[[t]] - X%*%betahat
SSE = c(t(res)%*%RInv%*%res)
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
# IB = match.input(input.miss[[t]], input.miss[[t-1]])$IB
# ym_t1 = ym.hat[[t-1]][ ,IB]
ym_t1 = matrix(NA, nsample, n.m[t])
for(k in 1:nsample){
ym_t1[k, ] = create.w.new(t=t, input=input[[t-1]], input.miss=input.miss,
y=y[[t-1]], ym=as.matrix(ym.hat[[t-1]][k,]))
Xm = cbind(Hm[[t]], as.matrix(ym_t1[k, ]))
XXRR = t(Xm) - t(X)%*%RInv%*%t(Rmo)
Sig_ymymy = Rm - Rmo%*%RInv%*%t(Rmo) + t(XXRR)%*%XRXInv%*%XXRR
Sig = Sig_ymymy * SSE/(n[t]-q[t]-1)
mu_ymy = Xm%*%betahat + Rmo%*%(RInv%*%res)
ym.hat[[t]][k, ] = c(mvtnorm::rmvt(1, sigma=Sig, df=n[t]-q[t]-1, delta=mu_ymy, type="shifted"))
}
}
# }
## get summary statistics
krige = list()
krigeSE = list()
krige.lower95 = list()
krige.upper95 = list()
for(t in 1:S){
# yhat[[t]] = ym.hat[[t]][ ,pred.ID[[t]], ]
krige[[t]] = apply(ym.hat[[t]], 2, mean)
krigeSE[[t]] = apply(ym.hat[[t]], 2, sd)
krige.lower95[[t]] = apply(ym.hat[[t]], 2, quantile, 0.025)
krige.upper95[[t]] = apply(ym.hat[[t]], 2, quantile, 0.975)
}
pred.mu = list()
pred.SE = list()
pred.lower95 = list()
pred.upper95 = list()
for(t in 1:S){
pred.mu[[t]] = rep(NA, np)
pred.SE[[t]] = rep(0, np)
pred.lower95[[t]] = rep(NA, np)
pred.upper95[[t]] = rep(NA, np)
ind.list = ismember(input.new, input.miss[[t]])
pred.mu[[t]][ind.list$IIA] = krige[[t]][ind.list$IA]
pred.SE[[t]][ind.list$IIA] = krigeSE[[t]][ind.list$IA]
pred.lower95[[t]][ind.list$IIA] = krige.lower95[[t]][ind.list$IA]
pred.upper95[[t]][ind.list$IIA] = krige.upper95[[t]][ind.list$IA]
if(length(ind.list$IIA)<np){
ind.input = ismember(input.new, input[[t]])
pred.mu[[t]][ind.input$IIA] = y[[t]][ind.input$IA]
pred.lower95[[t]][ind.input$IIA] = y[[t]][ind.input$IA]
pred.upper95[[t]][ind.input$IIA] = y[[t]][ind.input$IA]
}
}
names(pred.mu) = paste0("Level", seq(1:S), "")
names(pred.SE) = paste0("Level", seq(1:S), "")
names(pred.lower95) = paste0("Level", seq(1:S), "")
names(pred.upper95) = paste0("Level", seq(1:S), "")
pred = list(mu=pred.mu, SE=pred.SE,
lower95=pred.lower95,upper95=pred.upper95)
return(pred)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
compute.g.univ = function(param, input.list, level, y, H, ym, Hm, dist, hyper, cov.model){
## compute g function at fidelity level t
##
# param is a vector
Dim = dim(dist)[3]
p.x = Dim
N = ncol(y[[1]])
nsample = dim(ym[[1]])[1]
if(is.null(hyper)){
al = 0.5-p.x
bl = dim(dist)[1]^(-1/p.x) * (al + p.x)
nugget.UB = 1
}else{
al = hyper$a
bl = hyper$b * dim(dist)[1]^(-1/p.x) * (al + p.x)
nugget.UB = hyper$nugget.UB
}
# param contains phi and nugget (maybe)
if(length(param)==Dim){ #no nugget
phi = exp(-param)
# phi = 1/param
is.nugget=FALSE
}else{
phi = exp(-param[1:Dim])
nugget = nugget.UB*exp(param[Dim+1]) / (1 + exp(param[Dim+1]))
is.nugget = TRUE
phi = c(phi, nugget)
}
# inputlist = augment.input(input)
# input.miss = inputlist$miss
# input.union = inputlist$union
input = input.list$input
input.miss = input.list$input.miss
S = length(y)
n = rep(NA, S)
n.aug = rep(NA, S)
for(t in 1:S){
n[t] = dim(y[[t]])[1]
if(t<S){
n.aug[t] = n[t] + dim(Hm[[t]])[1]
}else{
n.aug[t] = n[t]
}
}
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
}
# input.max = apply(input[[level]], 2, max)
# input.min = apply(input[[level]], 2, min)
# Cl = abs(input.max-input.min)
Cl = hyper$Cl
if(is.nugget){
lnJacobian = sum(param[1:Dim]) + log(nugget) + log(nugget.UB - nugget) -
log(abs(nugget.UB+(nugget.UB-1)*nugget))
temp = sum(1/phi[1:Dim] * Cl) + nugget
}else{
lnJacobian = sum(param)
temp = sum(1/phi * Cl)
}
# if(is.nugget){
# lnJacobian = sum(log(param[1:Dim])) + log(nugget) + log(nugget.UB - nugget) -
# log(abs(nugget.UB+(nugget.UB-1)*nugget))
# temp = sum(1/phi[1:Dim] * Cl) + nugget
# }else{
# lnJacobian = sum(log(param))
# temp = sum(1/phi * Cl)
# }
lnJacobian = lnJacobian + al*log(temp) - bl*temp
#print(phi)
t = level
if(level==1){
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
X = H[[t]]
Xm = Hm[[t]]
X.aug = rbind(X, Xm)
RInvX = RInv%*%X.aug
HRH = t(X.aug)%*%RInvX
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
# compute Q
Q = RInv - RInvX%*%HRHInv%*%t(RInvX)
S_2_log = 0
for(k in 1:nsample){
y.aug = rbind(y[[t]], as.matrix(ym[[t]][k, , ]))
S_2_log = S_2_log + compute_S(y.aug, Q)
}
S_2_log = S_2_log / nsample
# S_2_log = compute_S3D(y[[t]], ym[[t]], Q) # too slow
g = -N*sum(log(diag(U))) - N*sum(log(diag(HRHchol))) - 0.5*(n.aug[t]-q[t])*S_2_log
}else if(level>1 & level<S){
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
## compute QH
H.aug = rbind(H[[t]], Hm[[t]])
RInvH = RInv%*%H.aug
HRH = t(H.aug)%*%RInvH
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
K = RInvH%*%HRHInv%*%t(RInvH)
#QH = RInv - K
y_t1 = array(NA, dim=c(nsample, n[t], N))
ym_t1 = array(NA, dim=c(nsample, nrow(Hm[[t]]), N))
S_2_log_sum = 0
for(k in 1:nsample){
# IB = match.input(input[[t]], input.miss[[t-1]])$IB
# y_t1 = as.matrix(ym[[t-1]][IB])
y_t1[k, , ] = create.w(t=t, input=input, input.miss=input.miss[[t-1]],
y=y[[t-1]], ym=as.matrix(ym[[t-1]][k, , ]))
# IB = match.input(input.miss[[t]], input.miss[[t-1]])$IB
# ym_t1 = as.matrix(ym[[t-1]][IB])
ym_t1[k, , ] = create.w(t=t, input=input.miss, input.miss=input.miss[[t-1]],
y=as.matrix(ym[[t-1]][k, , ]), ym=as.matrix(ym[[t-1]][k, , ]))
y.aug = rbind(y[[t]], as.matrix(ym[[t]][k, , ]))
y_t1.aug = rbind(as.matrix(y_t1[k, , ]), as.matrix(ym_t1[k, , ]))
S_2_log_sum = S_2_log_sum + compute_S_sum(y.aug, H.aug, y_t1.aug, RInv, K)
}
S_2_log_sum = S_2_log_sum / nsample
g = - N*sum(log(diag(U))) - 0.5*S_2_log_sum
}else{
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
RInvH = RInv%*%H[[t]]
HRH = t(H[[t]])%*%RInvH
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
K = RInvH%*%HRHInv%*%t(RInvH)
#QH = RInv - K
y_t1 = array(NA, dim=c(nsample, n[t], N))
logdetX = matrix(0, nsample, N)
S_2_log = matrix(0, nsample, N)
S_2_log_sum = 0
for(k in 1:nsample){
y_t1[k, , ] = create.w(t=t, input=input, input.miss=input.miss[[t-1]],
y=y[[t-1]], ym=as.matrix(ym[[t-1]][k, , ]))
S_2_log_sum = S_2_log_sum + compute_S_sum(y[[t]], H[[t]], as.matrix(y_t1[k, ,]), RInv, K)
# out = compute_S_sum2(y[[t]], H[[t]], y_t1[k, ,], RInv)
}
S_2_log_sum = S_2_log_sum / nsample
g = -N*sum(log(diag(U))) - 0.5*S_2_log_sum
}
g = lnJacobian + g
return(g)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
condsim.NN.univariate <- function(formula,output,input,input.new,phi,cov.model,
nsample){
Dim = dim(input[[1]])[2]
p.x = Dim
if(dim(phi)[1]==Dim){
is.nugget=FALSE
}else{
is.nugget=TRUE
}
###################################################################
#### augment input
###################################################################
S = length(output) # number of code
out = augment.input(input)
input.union = out$union
input.miss = out$miss
np = dim(input.new)[1]
n = sapply(output, length)
n.aug = rep(NA, S)
y = output
## add new inputs to missing inputs
# for(t in 1:(S-1)){
# input.miss[[t]] = rbind(input.new, input.miss[[t]])
# }
pred.ID = list()
ID.org = list()
index.full = 1:np
for(t in 1:(S-1)){
ind.list = match.input(input.union[[t]], input.new)
if(!is.null(ind.list$IA)){
indA = ind.list$IA
indB = ind.list$IB
pred.ID.exist = indA
input.exist = input.union[[t]][indA, ,drop=FALSE]
input.added = input.new[-indB, ,drop=FALSE]
n.added = dim(input.added)[1]
pred.ID.added = seq(1,n.added,by=1)
ID.org[[t]] = c(index.full[-indB], indB)
pred.ID[[t]] = c(pred.ID.added, pred.ID.exist+n.added)
input.miss[[t]] = rbind(input.added, input.miss[[t]])
input.union[[t]] = rbind(input.miss[[t]], input[[t]])
}else{
ID.org[[t]] = 1:np
pred.ID[[t]] = 1:np
input.miss[[t]] = rbind(input.new, input.miss[[t]])
input.union[[t]] = rbind(input.new, input.union[[t]])
}
}
t = S
ind.list = match.input(input[[t]], input.new)
if(!is.null(ind.list$IA)){
indA = ind.list$IA
indB = ind.list$IB
pred.ID.exist = indA
input.exist = input.union[[t]][indA, , drop=FALSE]
input.added = input.new[-indB, , drop=FALSE]
n.added = dim(input.added)[1]
pred.ID.added = seq(1, n.added, by=1)
ID.org[[t]] = c(index.full[-indB], indB)
pred.ID[[t]] = c(pred.ID.added, pred.ID.exist+n.added)
input.miss[[t]] = input.added
}else{
input.miss[[t]] = input.new
ID.org[[t]] = 1:np
pred.ID[[t]] = 1:np
}
input.union[[S]] = rbind(input.new, input.union[[S]])
## add new inputs to union of inputs
# for(t in 1:S){
# input.union[[t]] = rbind(input.new, input.union[[t]])
# }
###################################################################
#### create covariates
###################################################################
H = list()
Hm = list()
for(t in 1:S){
colnames(input[[t]]) = paste0("x", 1:p.x)
df = data.frame(input[[t]])
H[[t]] = model.matrix(formula[[t]], df)
colnames(input.miss[[t]]) = paste0("x", 1:p.x)
df = data.frame(input.miss[[t]])
Hm[[t]] = model.matrix(formula[[t]], df)
}
n.m = rep(NA, S)
for(t in 1:S){
n.m[t] = dim(input.miss[[t]])[1]
}
###################################################################
#### compute intermediate quantities
###################################################################
dist.o = list()
dist.m = list()
dist.mo = list()
distlist = list()
for(t in 1:S){
dist.o[[t]] = compute_distance(input[[t]], input[[t]])
#if(t<S){
dist.m[[t]] = compute_distance(input.miss[[t]], input.miss[[t]])
dist.mo[[t]] = compute_distance(input.miss[[t]], input[[t]])
#}
distlist[[t]] = compute_distance(input.union[[t]], input.union[[t]])
}
##
ym.hat = list()
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
ym.hat[[t]] = matrix(NA, nsample, dim(Hm[[t]])[1])
}
#################################################################################
#### Sampling from predictive distribution
#################################################################################
t = 1
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
#UH = backsolve(U, H[[t]], transpose=TRUE)
#HRHInv = solve(crossprod(UH))
HRHInv = solve(t(H[[t]])%*%RInv%*%H[[t]])
betahat = HRHInv%*%t(H[[t]])%*%(RInv%*%y[[t]])
res = y[[t]] - H[[t]]%*%betahat
SSE = c(t(res)%*%RInv%*%res)
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
#RmoU = t(backsolve(U, t(Rmo), transpose=TRUE))
XXRR = t(Hm[[t]]) - t(H[[t]])%*%RInv%*%t(Rmo)
#XXRR = t(Hm[[t]]) - t(RmoU%*%UH)
Sig_ymymy = Rm - Rmo%*%RInv%*%t(Rmo) + t(XXRR)%*%HRHInv%*%XXRR
#Sig_ymymy = Rm - tcrossprod(RmoU) + t(XXRR)%*%HRHInv%*%XXRR
Sig = Sig_ymymy * SSE/(n[t] - q[t])
#Sig = Sig_ymymy * SSE/(n[t])
mu_ymy = Hm[[t]]%*%betahat + Rmo%*%(RInv%*%res)
ym.hat[[t]] = mvtnorm::rmvt(nsample, sigma=Sig, df=n[t]-q[t], delta=mu_ymy, type="shifted")
for(t in 2:(S)){
############################################################################
#### estimate missing data ym
############################################################################
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
R_sk = Rm - Rmo%*%RInv%*%t(Rmo)
for(k in 1:nsample){
y_t1 = create.w.univ(t=t, input=input, input.miss=input.miss[[t-1]],
y=y[[t-1]], ym=(ym.hat[[t-1]][k, ]))
ym_t1 = create.w.new(t=t, input=input[[t-1]], input.miss=input.miss,
y=y[[t-1]], ym=(ym.hat[[t-1]][k, ]))
# ym.hat[[t]][k, ] = conditional_simulation(y[[t]], H[[t]], as.matrix(y_t1),
# RInv, Hm[[t]], as.matrix(ym_t1), Rmo, R_sk)
X = cbind(H[[t]], y_t1)
XRXInv = solve(t(X)%*%RInv%*%X)
betahat = XRXInv%*%t(X)%*%(RInv%*%y[[t]])
res = y[[t]] - X%*%betahat
SSE = c(t(res)%*%RInv%*%res)
Xm = cbind(Hm[[t]], ym_t1)
XXRR = t(Xm) - t(X)%*%RInv%*%t(Rmo)
Sig_ymymy = R_sk + t(XXRR)%*%XRXInv%*%XXRR
Sig = Sig_ymymy * SSE/(n[t]-q[t]-1)
mu_ymy = Xm%*%betahat + Rmo%*%(RInv%*%res)
ym.hat[[t]][k, ] = c(mvtnorm::rmvt(1, sigma=Sig, df=n[t]-q[t]-1,
delta=mu_ymy, type="shifted"))
}
}
################################################################################
## get summary statistics
krige = list()
krigeSE = list()
krige.lower95 = list()
krige.upper95 = list()
for(t in 1:S){
# yhat[[t]] = ym.hat[[t]][ ,pred.ID[[t]], ]
krige[[t]] = apply(ym.hat[[t]], 2, mean)
krigeSE[[t]] = apply(ym.hat[[t]], 2, sd)
krige.lower95[[t]] = apply(ym.hat[[t]], 2, quantile, 0.025)
krige.upper95[[t]] = apply(ym.hat[[t]], 2, quantile, 0.975)
}
pred.mu = list()
pred.SE = list()
pred.lower95 = list()
pred.upper95 = list()
for(t in 1:S){
pred.mu[[t]] = rep(NA, np)
pred.SE[[t]] = rep(0, np)
pred.lower95[[t]] = rep(NA, np)
pred.upper95[[t]] = rep(NA, np)
ind.list = ismember(input.new, input.miss[[t]])
pred.mu[[t]][ind.list$IIA] = krige[[t]][ind.list$IA]
pred.SE[[t]][ind.list$IIA] = krigeSE[[t]][ind.list$IA]
pred.lower95[[t]][ind.list$IIA] = krige.lower95[[t]][ind.list$IA]
pred.upper95[[t]][ind.list$IIA] = krige.upper95[[t]][ind.list$IA]
if(length(ind.list$IIA)<np){
ind.input = ismember(input.new, input[[t]])
pred.mu[[t]][ind.input$IIA] = y[[t]][ind.input$IA]
pred.lower95[[t]][ind.input$IIA] = y[[t]][ind.input$IA]
pred.upper95[[t]][ind.input$IIA] = y[[t]][ind.input$IA]
}
}
names(pred.mu) = paste0("Level", seq(1:S), "")
names(pred.SE) = paste0("Level", seq(1:S), "")
names(pred.lower95) = paste0("Level", seq(1:S), "")
names(pred.upper95) = paste0("Level", seq(1:S), "")
pred = list(mu=pred.mu, SE=pred.SE,
lower95=pred.lower95,upper95=pred.upper95)
return(pred)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
#### Functions in Multivariate Autoregressive Cokriging Models
#############################################################################
#############################################################################
margin.posterior.mv = function(param, input, output, level, H, dist, cov.model="matern_5_2",
hyper=NULL){
Dim = dim(dist)[3]
p.x = Dim
t = level
n = dim(output[[t]])[1] # number of model runs
N = dim(output[[t]])[2] # number of spatial lomessageions
if(is.null(hyper)){
al = 0.5-p.x
bl = 1 * dim(dist)[1]^(-1/p.x) * (al + p.x)
nugget.UB = 1
}else{
al = hyper$a
bl = hyper$b * dim(dist)[1]^(-1/p.x) * (al + p.x)
nugget.UB = hyper$nugget.UB
}
# param contains phi and nugget (maybe)
if(length(param)==Dim){ #no nugget
phi = exp(-param)
is.nugget=FALSE
}else{
phi = exp(-param[1:Dim])
nugget = nugget.UB*exp(param[Dim+1]) / (1 + exp(param[Dim+1]))
is.nugget = TRUE
phi = c(phi, nugget)
}
q = dim(H)[2]
#Cl = dim(dist)[1]^(-1/p.x)
# input.max = apply(input[[level]], 2, max)
# input.min = apply(input[[level]], 2, min)
# Cl = abs(input.max-input.min)
Cl = hyper$Cl
if(is.nugget){
lnJacobian = sum(param[1:Dim]) + log(nugget) + log(nugget.UB - nugget) -
log(abs(nugget.UB+(nugget.UB-1)*nugget))
temp = sum(1/phi[1:Dim] * Cl) + nugget
}else{
lnJacobian = sum(param)
temp = sum(1/phi * Cl)
}
lnJacobian = lnJacobian + al*log(temp) - bl*temp
if(level==1){
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
X.aug = H
HRH = t(X.aug)%*%RInv%*%X.aug #+ diag(1e-6,dim(X.aug)[2])
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
# compute Q
Q = RInv%*%(diag(n)-X.aug%*%HRHInv%*%t(X.aug)%*%RInv)
S_2_log = compute_S(output[[t]], Q)
g = -N*sum(log(diag(U))) - N*sum(log(diag(HRHchol))) - 0.5*(n-q)*S_2_log
}else{
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
RInvH = RInv%*%H
HRH = t(H)%*%RInvH
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
K = RInvH%*%HRHInv%*%t(RInvH)
#QH = RInv - K
IB = match.input(input[[t]], input[[t-1]])$IB
y_t1 = output[[t-1]][IB, ]
S_2_log_sum = compute_S_sum(output[[t]], H, y_t1, RInv, K)
g = -N*sum(log(diag(U))) - 0.5*S_2_log_sum
}
g = lnJacobian + g
return(g)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
compute.g = function(param, input.list, level, y, H, ym, Hm, dist, hyper, cov.model="matern_5_2"){
## compute g function at fidelity level t
##
# param is a vector
Dim = dim(dist)[3]
p.x = Dim
N = ncol(y[[1]])
nsample = dim(ym[[1]])[1]
if(is.null(hyper)){
al = 0.5-p.x
bl = dim(dist)[1]^(-1/p.x) * (al + p.x)
nugget.UB = 1
}else{
al = hyper$a
bl = hyper$b * dim(dist)[1]^(-1/p.x) * (al + p.x)
nugget.UB = hyper$nugget.UB
}
# param contains phi and nugget (maybe)
if(length(param)==Dim){ #no nugget
phi = exp(-param)
# phi = 1/param
is.nugget=FALSE
}else{
phi = exp(-param[1:Dim])
nugget = nugget.UB*exp(param[Dim+1]) / (1 + exp(param[Dim+1]))
is.nugget = TRUE
phi = c(phi, nugget)
}
# inputlist = augment.input(input)
# input.miss = inputlist$miss
# input.union = inputlist$union
input = input.list$input
input.miss = input.list$input.miss
S = length(y)
n = rep(NA, S)
n.aug = rep(NA, S)
for(t in 1:S){
n[t] = dim(y[[t]])[1]
if(t<S){
n.aug[t] = n[t] + dim(Hm[[t]])[1]
}else{
n.aug[t] = n[t]
}
}
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
}
# input.max = apply(input[[level]], 2, max)
# input.min = apply(input[[level]], 2, min)
# Cl = abs(input.max-input.min)
Cl = hyper$Cl
if(is.nugget){
lnJacobian = sum(param[1:Dim]) + log(nugget) + log(nugget.UB - nugget) -
log(abs(nugget.UB+(nugget.UB-1)*nugget))
temp = sum(1/phi[1:Dim] * Cl) + nugget
}else{
lnJacobian = sum(param)
temp = sum(1/phi * Cl)
}
# if(is.nugget){
# lnJacobian = sum(log(param[1:Dim])) + log(nugget) + log(nugget.UB - nugget) -
# log(abs(nugget.UB+(nugget.UB-1)*nugget))
# temp = sum(1/phi[1:Dim] * Cl) + nugget
# }else{
# lnJacobian = sum(log(param))
# temp = sum(1/phi * Cl)
# }
lnJacobian = lnJacobian + al*log(temp) - bl*temp
#print(phi)
t = level
if(level==1){
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
X = H[[t]]
Xm = Hm[[t]]
X.aug = rbind(X, Xm)
RInvX = RInv%*%X.aug
HRH = t(X.aug)%*%RInvX
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
# compute Q
Q = RInv - RInvX%*%HRHInv%*%t(RInvX)
S_2_log = 0
for(k in 1:nsample){
y.aug = rbind(y[[t]], as.matrix(ym[[t]][k, , ]))
S_2_log = S_2_log + compute_S(y.aug, Q)
}
S_2_log = S_2_log / nsample
# S_2_log = compute_S3D(y[[t]], ym[[t]], Q) # too slow
g = -N*sum(log(diag(U))) - N*sum(log(diag(HRHchol))) - 0.5*(n.aug[t]-q[t])*S_2_log
}else if(level>1 & level<S){
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
## compute QH
H.aug = rbind(H[[t]], Hm[[t]])
RInvH = RInv%*%H.aug
HRH = t(H.aug)%*%RInvH
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
K = RInvH%*%HRHInv%*%t(RInvH)
#QH = RInv - K
y_t1 = array(NA, dim=c(nsample, n[t], N))
ym_t1 = array(NA, dim=c(nsample, nrow(Hm[[t]]), N))
S_2_log_sum = 0
for(k in 1:nsample){
# IB = match.input(input[[t]], input.miss[[t-1]])$IB
# y_t1 = as.matrix(ym[[t-1]][IB])
y_t1[k, , ] = create.w(t=t, input=input, input.miss=input.miss[[t-1]],
y=y[[t-1]], ym=as.matrix(ym[[t-1]][k, , ]))
# IB = match.input(input.miss[[t]], input.miss[[t-1]])$IB
# ym_t1 = as.matrix(ym[[t-1]][IB])
ym_t1[k, , ] = create.w(t=t, input=input.miss, input.miss=input.miss[[t-1]],
y=as.matrix(ym[[t-1]][k, , ]), ym=as.matrix(ym[[t-1]][k, , ]))
y.aug = rbind(y[[t]], as.matrix(ym[[t]][k, , ]))
y_t1.aug = rbind(as.matrix(y_t1[k, , ]), as.matrix(ym_t1[k, , ]))
S_2_log_sum = S_2_log_sum + compute_S_sum(y.aug, H.aug, y_t1.aug, RInv, K)
}
S_2_log_sum = S_2_log_sum / nsample
g = - N*sum(log(diag(U))) - 0.5*S_2_log_sum
}else{
R = buildcov(phi, dist, covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
RInvH = RInv%*%H[[t]]
HRH = t(H[[t]])%*%RInvH
HRHchol = chol(HRH)
HRHInv = chol2inv(HRHchol)
K = RInvH%*%HRHInv%*%t(RInvH)
#QH = RInv - K
y_t1 = array(NA, dim=c(nsample, n[t], N))
logdetX = matrix(0, nsample, N)
S_2_log = matrix(0, nsample, N)
S_2_log_sum = 0
for(k in 1:nsample){
y_t1[k, , ] = create.w(t=t, input=input, input.miss=input.miss[[t-1]],
y=y[[t-1]], ym=as.matrix(ym[[t-1]][k, , ]))
S_2_log_sum = S_2_log_sum + compute_S_sum(y[[t]], H[[t]], y_t1[k, ,], RInv, K)
# out = compute_S_sum2(y[[t]], H[[t]], y_t1[k, ,], RInv)
}
S_2_log_sum = S_2_log_sum / nsample
g = -N*sum(log(diag(U))) - 0.5*S_2_log_sum
}
g = lnJacobian + g
return(g)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
fit.ND=function(formula, output, input, phi, cov.model,
prior, opt){
hyperparam = prior$hyper
Dim = dim(input[[1]])[2]
p.x = Dim
if(dim(phi)[1]==Dim){
is.nugget=FALSE
}else{
is.nugget=TRUE
}
S = length(output)
###################################################################
#### create covariates
###################################################################
H = list()
Hm = list()
for(t in 1:S){
colnames(input[[t]]) = paste0("x", 1:p.x)
df = data.frame(input[[t]])
H[[t]] = model.matrix(formula[[t]], df)
}
###################################################################
#### compute intermediate quantities
###################################################################
distlist = list()
for(t in 1:S){
distlist[[t]] = compute_distance(input[[t]], input[[t]])
}
Cl = list()
for(t in 1:S){
input.max = apply(input[[t]], 2, max)
input.min = apply(input[[t]], 2, min)
Cl[[t]] = abs(input.max-input.min)
}
for(t in 1:S){
hyperparam[[t]]$Cl = Cl[[t]]
}
###################################################################
#### begin optimization algorithm
###################################################################
phi.new = phi
for(t in 1:S){
if(is.nugget){
nu = log(phi[p.x+1, t]) - log(hyperparam[[t]]$nugget.UB-phi[p.x+1, t]) # logit of nugget
init.val = c(-log(phi[1:p.x, t]), nu)
}else{
init.val = -log(phi[ ,t])
}
fit = try(optim(init.val, margin.posterior.mv, input=input, output=output, level=t,
H=H[[t]], dist=distlist[[t]], cov.model=cov.model,
hyper=hyperparam[[t]],
control=list(fnscale=-1, maxit=opt$maxit),
method=opt$method, lower=opt$lower, upper=opt$upper),
silent=T)
if(inherits(fit, "try-error")){
phi.new[ ,t] = phi[ ,t]
message("\n optimization error, skip t=", t, "\n")
print(fit)
}else{
if(is.nugget){
nugget = hyperparam[[t]]$nugget.UB*exp(fit$par[p.x+1]) / (1+exp(fit$par[p.x+1]))
phi.new[ ,t] = c(exp(-fit$par[1:p.x]), nugget)
}else{
phi.new[ ,t] = exp(-fit$par)
}
}
}
colnames(phi.new) = paste0("Level", seq(1:S), "")
return(list(par=phi.new))
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
fit.NN <- function(formula,output,input,phi,cov.model,prior,
opt, MCEM){
hyperparam = prior$hyperparam
maxit = MCEM$maxit
tol = MCEM$tol
n.sample = MCEM$n.sample
verbose = MCEM$verbose
Dim = dim(input[[1]])[2]
p.x = Dim
if(dim(phi)[1]==Dim){
is.nugget=FALSE
}else{
is.nugget=TRUE
}
###################################################################
#### augment input
###################################################################
S = length(output) # number of code
out = augment.input(input)
input.union = out$union
input.miss = out$miss
input.list = list(input=input, input.miss=input.miss)
Cl = list()
for(t in 1:S){
input.max = apply(input.list$input[[t]], 2, max)
input.min = apply(input.list$input[[t]], 2, min)
Cl[[t]] = abs(input.max-input.min)
}
for(t in 1:S){
hyperparam[[t]]$Cl = Cl[[t]]
}
###################################################################
#### create covariates
###################################################################
H = list()
Hm = list()
for(t in 1:S){
colnames(input[[t]]) = paste0("x", 1:p.x)
df = data.frame(input[[t]])
H[[t]] = model.matrix(formula[[t]], df)
if(t<S){
colnames(input.miss[[t]]) = paste0("x", 1:p.x)
df = data.frame(input.miss[[t]])
Hm[[t]] = model.matrix(formula[[t]], df)
}
}
###################################################################
#### compute intermediate quantities
###################################################################
dist.o = list()
dist.m = list()
dist.mo = list()
distlist = list()
for(t in 1:S){
dist.o[[t]] = compute_distance(input[[t]], input[[t]])
if(t<S){
dist.m[[t]] = compute_distance(input.miss[[t]], input.miss[[t]])
dist.mo[[t]] = compute_distance(input.miss[[t]], input[[t]])
}
distlist[[t]] = compute_distance(input.union[[t]], input.union[[t]])
}
###################################################################
#### begin MCEM algorithm
###################################################################
phi.new = phi
conv = FALSE
iter = 1
while(!conv){
###############################################################
#### generate M Monte Carlo samples for missing data
###############################################################
# y.m = list()
#system.time(
# for(k in 1:n.sample){
# y.m[[k]] = sample.ym(y=output,input=input,param=phi,Ho=H,Hm=Hm,dist.o=dist.o,
# dist.m=dist.m,dist.mo=dist.mo,cov.model=cov.model)
# }
y.m = sample.ym(y=output,input=input,param=phi,Ho=H,Hm=Hm,dist.o=dist.o,
dist.m=dist.m,dist.mo=dist.mo,cov.model=cov.model,
nsample=n.sample)
#)
###############################################################
#### compute and maximize the Q function at each fidelity
###############################################################
for(t in 1:S){
if(is.nugget){
nu = log(phi[p.x+1, t]) - log(hyperparam[[t]]$nugget.UB-phi[p.x+1, t]) # logit of nugget
init.val = c(-log(phi[1:p.x, t]), nu)
}else{
init.val = -log(phi[ ,t])
}
fit = try(optim(init.val, compute.g, input.list=input.list, level=t, y=output, H=H, ym=y.m, Hm=Hm,
dist=distlist[[t]], hyper=hyperparam[[t]], cov.model=cov.model,
control=list(fnscale=-1, maxit=opt$maxit),
method=opt$method, lower=opt$lower, upper=opt$upper),
silent=T)
# fit = try(optimr(init.val, compute.Q.default, input=input, level=t, y=output, H=H, y.m=y.m, Hm=Hm,
# distlist=distlist, cov.model=cov.model,
# control=list(fnscale=-1, maxit=opt$maxit),
# method=opt$method, lower=opt$lower, upper=opt$upper),
# silent=T)
if(inherits(fit, "try-error")){
phi.new[ ,t] = phi[ ,t]
message("\n optimization error, skip t=", t, "\n")
print(fit)
}else{
if(is.nugget){
nugget = hyperparam[[t]]$nugget.UB*exp(fit$par[p.x+1]) / (1+exp(fit$par[p.x+1]))
phi.new[ ,t] = c(exp(-fit$par[1:p.x]), nugget)
}else{
phi.new[ ,t] = exp(-fit$par)
}
}
}
###############################################################
#### check convergence
if(inherits(fit, "try-error")){
diff = tol + 1
}else{
diff = mean((phi.new - phi)^2)
}
if(verbose){
message("iter=", iter, "\n")
}
if(iter>maxit){
conv = TRUE
}else{
if(diff<tol){
conv = TRUE
}
}
phi = phi.new
iter = iter + 1
}
colnames(phi) = paste0("Level", seq(1:S), "")
return(list(par=phi, eps=diff, iter=iter))
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
predict.ND = function(formula, output, input, input.new, phi, cov.model){
Dim = dim(input[[1]])[2]
p.x = Dim
if(dim(phi)[1]==Dim){
is.nugget=FALSE
}else{
is.nugget=TRUE
}
S = length(output)
n = rep(NA, S)
for(t in 1:S){
n[t] = dim(output[[t]])[1]
}
np = dim(input.new)[1]
y = output
## add new inputs to missing inputs
input.miss = list()
input.union = list()
for(t in 1:S){
input.miss[[t]] = input.new
input.union[[t]] = rbind(input.new, input[[t]])
}
###################################################################
#### create covariates
###################################################################
H = list()
Hm = list()
for(t in 1:S){
colnames(input[[t]]) = paste0("x", 1:p.x)
df = data.frame(input[[t]])
H[[t]] = model.matrix(formula[[t]], df)
colnames(input.miss[[t]]) = paste0("x", 1:p.x)
df = data.frame(input.miss[[t]])
Hm[[t]] = model.matrix(formula[[t]], df)
}
###################################################################
#### compute intermediate quantities
###################################################################
dist.o = list()
dist.m = list()
dist.mo = list()
distlist = list()
for(t in 1:S){
dist.o[[t]] = compute_distance(input[[t]], input[[t]])
#if(t<S){
dist.m[[t]] = compute_distance(input.miss[[t]], input.miss[[t]])
dist.mo[[t]] = compute_distance(input.miss[[t]], input[[t]])
#}
distlist[[t]] = compute_distance(input.union[[t]], input.union[[t]])
}
ym.hat = list()
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
}
krige = list()
krige.var = list()
#################################################################################
#### Get predictive mean and predictive variance
#################################################################################
t = 1
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
#UH = backsolve(U, H[[t]], transpose=TRUE)
#HRHInv = solve(crossprod(UH))
HRHInv = solve(t(H[[t]])%*%RInv%*%H[[t]])
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
# compute predictive mean
RmoRInv = Rmo%*%RInv
KW = (Hm[[t]] - RmoRInv%*%H[[t]])%*%HRHInv%*%t(H[[t]])%*%RInv + RmoRInv
krige[[t]] = KW%*%y[[t]]
# compute predictive variance
XXRR = t(Hm[[t]]) - t(H[[t]])%*%RInv%*%t(Rmo)
c_star = diag(Rm - Rmo%*%RInv%*%t(Rmo) + t(XXRR)%*%HRHInv%*%XXRR)
c_star[c_star<0] = 0 # avoid numerical problems
Q = RInv - (RInv%*%H[[t]])%*%HRHInv%*%t(RInv%*%H[[t]])
sigma2.hat = compute_Svec(y[[t]], Q) / (n[t]-q[t])
constant = (n[t]-q[t])/(n[t]-q[t]-2)
krige.var[[t]] = constant*c_star %*% t(sigma2.hat) # m-by-N matrix
for(t in 2:S){
############################################################################
#### estimate missing data ym
############################################################################
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
# RInvH = RInv%*%H[[t]]
# HRH = t(H[[t]])%*%RInvH
# HRHchol = chol(HRH)
# HRHInv = chol2inv(HRHchol)
# K = RInvH%*%HRHInv%*%t(RInvH)
# QH = RInv - K
IB = match.input(input[[t]], input[[t-1]])$IB
y_t1 = y[[t-1]][IB, ]
IB = match.input(input.miss[[t]], input.miss[[t-1]])$IB
ym_t1 = krige[[t-1]][IB, ]
# Xm = cbind(Hm[[t]], ym_t1)
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
R_sk_diag = diag(Rm - Rmo%*%RInv%*%t(Rmo))
R_sk_diag[R_sk_diag<0] = 0
pred.list = compute_prediction(y[[t]], H[[t]], y_t1, krige[[t-1]],krige.var[[t-1]],
RInv, Hm[[t]], ym_t1, Rmo, R_sk_diag)
krige[[t]] = pred.list$krige
krige.var[[t]] = pred.list$krige.var
}
################################################################################
# for(t in 1:(S-1)){
# ind = sort(ID.org[[t]], index.return=TRUE)$ix
# krige[[t]][ind] = krige[[t]]
# krigeSE[[t]][ind] = krigeSE[[t]]
# }
krigeSE = list()
lower95 = list()
upper95 = list()
for(t in 1:S){
krige.var[[t]][krige.var[[t]]<0] = 0
krigeSE[[t]] = sqrt(krige.var[[t]])
# degree = ifelse(t==1, n[t]-q[t], n[t]-q[t]-1)
lower95[[t]] = krige[[t]] - 2*krigeSE[[t]]
upper95[[t]] = krige[[t]] + 2*krigeSE[[t]]
}
names(krige) = paste0("Level", seq(1:S), "")
names(krigeSE) = paste0("Level", seq(1:S), "")
names(lower95) = paste0("Level", seq(1:S), "")
names(upper95) = paste0("Level", seq(1:S), "")
out = list(mu=krige, SE=krigeSE, lower95=lower95, upper95=upper95)
return(out)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
predict.NN <- function(formula,output,input,input.new,phi,cov.model="matern_5_2",
nsample=30){
Dim = dim(input[[1]])[2]
N = dim(output[[1]])[2]
p.x = Dim
if(dim(phi)[1]==Dim){
is.nugget=FALSE
}else{
is.nugget=TRUE
}
###################################################################
#### augment input
###################################################################
S = length(output) # number of code
out = augment.input(input)
input.union = out$union
input.miss = out$miss
np = dim(input.new)[1]
n = rep(NA, S)
for(t in 1:S){
n[t] = dim(input[[t]])[1]
}
y = output
## add new inputs to missing inputs
# for(t in 1:(S-1)){
# input.miss[[t]] = rbind(input.new, input.miss[[t]])
# }
pred.ID = list()
ID.org = list()
index.full = 1:np
for(t in 1:(S-1)){
ind.list = match.input(input.union[[t]], input.new)
if(!is.null(ind.list$IA)){
indA = ind.list$IA
indB = ind.list$IB
pred.ID.exist = indA
input.exist = input.union[[t]][indA, ,drop=FALSE]
input.added = input.new[-indB, ,drop=FALSE]
n.added = dim(input.added)[1]
pred.ID.added = seq(1,n.added,by=1)
ID.org[[t]] = c(index.full[-indB], indB)
pred.ID[[t]] = c(pred.ID.added, pred.ID.exist+n.added)
input.miss[[t]] = rbind(input.added, input.miss[[t]])
input.union[[t]] = rbind(input.miss[[t]], input[[t]])
}else{
ID.org[[t]] = 1:np
pred.ID[[t]] = 1:np
input.miss[[t]] = rbind(input.new, input.miss[[t]])
input.union[[t]] = rbind(input.new, input.union[[t]])
}
}
t = S
ind.list = match.input(input[[t]], input.new)
if(!is.null(ind.list$IA)){
indA = ind.list$IA
indB = ind.list$IB
pred.ID.exist = indA
input.exist = input.union[[t]][indA, , drop=FALSE]
input.added = input.new[-indB, , drop=FALSE]
n.added = dim(input.added)[1]
pred.ID.added = seq(1, n.added, by=1)
ID.org[[t]] = c(index.full[-indB], indB)
pred.ID[[t]] = c(pred.ID.added, pred.ID.exist+n.added)
input.miss[[t]] = input.added
}else{
input.miss[[t]] = input.new
ID.org[[t]] = 1:np
pred.ID[[t]] = 1:np
}
input.union[[S]] = rbind(input.new, input.union[[S]])
###################################################################
#### create covariates
###################################################################
H = list()
Hm = list()
for(t in 1:S){
colnames(input[[t]]) = paste0("x", 1:p.x)
df = data.frame(input[[t]])
H[[t]] = model.matrix(formula[[t]], df)
colnames(input.miss[[t]]) = paste0("x", 1:p.x)
df = data.frame(input.miss[[t]])
Hm[[t]] = model.matrix(formula[[t]], df)
}
n.m = rep(NA, S)
for(t in 1:S){
n.m[t] = dim(input.miss[[t]])[1]
}
###################################################################
#### compute intermediate quantities
###################################################################
dist.o = list()
dist.m = list()
dist.mo = list()
distlist = list()
for(t in 1:S){
dist.o[[t]] = compute_distance(input[[t]], input[[t]])
#if(t<S){
dist.m[[t]] = compute_distance(input.miss[[t]], input.miss[[t]])
dist.mo[[t]] = compute_distance(input.miss[[t]], input[[t]])
#}
distlist[[t]] = compute_distance(input.union[[t]], input.union[[t]])
}
##
krige = list()
krigeSE = list()
ym.hat = list()
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
ym.hat[[t]] = array(NA, dim=c(nsample, dim(Hm[[t]])[1], N))
}
#################################################################################
#### get predictive mean and predictive variance
#################################################################################
t = 1
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
HRHInv = solve(t(H[[t]])%*%RInv%*%H[[t]])
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
# compute conditional mean
RmoRInv = Rmo%*%RInv
KW = (Hm[[t]]-RmoRInv%*%H[[t]]) %*% HRHInv %*% t(H[[t]]) %*% RInv + RmoRInv
mu_ymy = KW %*% y[[t]] # n.m-by-N matrix
# compute predictive variance
XXRR = t(Hm[[t]]) - t(H[[t]])%*%RInv%*%t(Rmo)
c_star = Rm - Rmo%*%RInv%*%t(Rmo) + t(XXRR)%*%HRHInv%*%XXRR
## c_star is not positive definite!!! So, there is no cholesky decomposition available
# compute S2
Q = RInv - RInv%*%H[[t]]%*%HRHInv%*%t(H[[t]])%*%t(RInv)
sigma2.hat = compute_Svec(y[[t]], Q) / (n[t]-q[t])
L = t(chol(c_star))
ym.hat[[t]] = sample_mvt(mu_ymy, L=L, sigma=sigma2.hat, df=n[t]-q[t], nsample)
#for(k in 1:nsample){
for(t in 2:(S)){
############################################################################
#### simulating missing data ym
############################################################################
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
R_sk = Rm - Rmo%*%RInv%*%t(Rmo)
# RmoRInv = Rmo%*%RInv
y_t1 = array(NA, dim=c(nsample, n[t], N))
ym_t1 = array(NA, dim=c(nsample, n.m[t], N))
# IB = match.input(input[[t]], input.miss[[t-1]])$IB
# y_t1 = ym.hat[[t-1]][IB]
# b = matrix(NA, q[t]+1, N)
# mu_y = matrix(NA, n.m[t], N)
for(k in 1:nsample){
y_t1[k, , ] = create.w(t=t, input=input, input.miss=input.miss[[t-1]],
y=y[[t-1]], ym=as.matrix(ym.hat[[t-1]][k, , ]))
ym_t1[k, , ] = create.w.pred(t=t, input=input[[t-1]], input.miss=input.miss,
y=y[[t-1]], ym=as.matrix(ym.hat[[t-1]][k, ,]))
ym.hat[[t]][k, , ] = conditional_simulation(y[[t]], H[[t]], y_t1[k, , ],
RInv, Hm[[t]], ym_t1[k, , ], Rmo, R_sk)
}
}
#}
################################################################################
krige = list()
krigeSE = list()
krige.lower95 = list()
krige.upper95 = list()
for(t in 1:S){
# yhat[[t]] = ym.hat[[t]][ ,pred.ID[[t]], ]
krige[[t]] = apply(ym.hat[[t]], c(2,3), mean)
krigeSE[[t]] = apply(ym.hat[[t]], c(2,3), sd)
krige.lower95[[t]] = apply(ym.hat[[t]], c(2,3), quantile, 0.025)
krige.upper95[[t]] = apply(ym.hat[[t]], c(2,3), quantile, 0.975)
}
pred.mu = list()
pred.SE = list()
pred.lower95 = list()
pred.upper95 = list()
for(t in 1:S){
pred.mu[[t]] = matrix(NA, np, N)
pred.SE[[t]] = matrix(0, np, N)
pred.lower95[[t]] = matrix(NA, np, N)
pred.upper95[[t]] = matrix(NA, np, N)
ind.list = ismember(input.new, input.miss[[t]])
pred.mu[[t]][ind.list$IIA, ] = krige[[t]][ind.list$IA, ]
pred.SE[[t]][ind.list$IIA, ] = krigeSE[[t]][ind.list$IA, ]
pred.lower95[[t]][ind.list$IIA, ] = krige.lower95[[t]][ind.list$IA, ]
pred.upper95[[t]][ind.list$IIA, ] = krige.upper95[[t]][ind.list$IA, ]
if(length(ind.list$IIA)<np){
ind.input = ismember(input.new, input[[t]])
pred.mu[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
pred.lower95[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
pred.upper95[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
}
}
names(pred.mu) = paste0("Level", seq(1:S), "")
names(pred.SE) = paste0("Level", seq(1:S), "")
names(pred.lower95) = paste0("Level", seq(1:S), "")
names(pred.upper95) = paste0("Level", seq(1:S), "")
pred = list(mu=pred.mu, SE=pred.SE,
lower95=pred.lower95,upper95=pred.upper95)
return(pred)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
condsim.ND = function(formula, output, input, input.new, phi, cov.model="matern_5_2",
nsample=30){
Dim = dim(input[[1]])[2]
N = dim(output[[1]])[2]
p.x = Dim
if(dim(phi)[1]==Dim){
is.nugget=FALSE
}else{
is.nugget=TRUE
}
S = length(output)
np = dim(input.new)[1]
n = rep(NA, S)
for(t in 1:S){
n[t] = dim(input[[t]])[1]
}
y = output
## add new inputs to missing inputs
# input.miss = list()
# input.union = list()
# for(t in 1:S){
# input.miss[[t]] = input.new
# input.union[[t]] = rbind(input.new, input[[t]])
# }
# input.miss = list()
# for(t in 1:S){
# input.miss[[t]] = input.new
# }
input.miss = list()
input.union = list()
pred.ID = list()
ID.orig = list()
index.full = 1:np
indB = list()
for(t in 1:(S)){
ind.list = match.input(input[[t]], input.new)
# indlist = ismember(input.new, input[[t]])
if(!is.null(ind.list$IA)){
indA = ind.list$IA
indB[[t]] = ind.list$IB
pred.ID.exist = indA
input.exist = input[[t]][indA, ,drop=FALSE] # common inputs
input.added = input.new[-indB[[t]], ,drop=FALSE] # inputs in input.new but not in input[[t]]
n.added = dim(input.added)[1]
pred.ID.added = seq(1, n.added, by=1)
ID.orig[[t]] = c(index.full[-indB[[t]]], indB[[t]])
pred.ID[[t]] = c(pred.ID.added, pred.ID.exist+n.added)
input.miss[[t]] = input.added
input.union[[t]] = rbind(input.added, input[[t]])
}else{
ID.orig[[t]] = 1:np
pred.ID[[t]] = 1:np
input.miss[[t]] = input.new
input.union[[t]] = rbind(input.new, input[[t]])
}
}
#
n.m = rep(NA, S)
for(t in 1:S){
n.m[t] = dim(input.miss[[t]])[1]
}
###################################################################
#### create covariates
###################################################################
H = list()
Hm = list()
for(t in 1:S){
colnames(input[[t]]) = paste0("x", 1:p.x)
df = data.frame(input[[t]])
H[[t]] = model.matrix(formula[[t]], df)
colnames(input.miss[[t]]) = paste0("x", 1:p.x)
df = data.frame(input.miss[[t]])
Hm[[t]] = model.matrix(formula[[t]], df)
}
###################################################################
#### compute intermediate quantities
###################################################################
dist.o = list()
dist.m = list()
dist.mo = list()
distlist = list()
for(t in 1:S){
dist.o[[t]] = compute_distance(input[[t]], input[[t]])
#if(t<S){
dist.m[[t]] = compute_distance(input.miss[[t]], input.miss[[t]])
dist.mo[[t]] = compute_distance(input.miss[[t]], input[[t]])
#}
distlist[[t]] = compute_distance(input.union[[t]], input.union[[t]])
}
ym.hat = list()
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
ym.hat[[t]] = array(NA, dim=c(nsample, dim(Hm[[t]])[1], N))
}
#################################################################################
#### Sampling from predictive distribution
#################################################################################
t = 1
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
HRHInv = solve(t(H[[t]])%*%RInv%*%H[[t]])
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
# compute conditional mean
RmoRInv = Rmo%*%RInv
KW = (Hm[[t]]-RmoRInv%*%H[[t]]) %*% HRHInv %*% t(H[[t]]) %*% RInv + RmoRInv
mu_ymy = KW %*% y[[t]]
RmoU = t(backsolve(U, t(Rmo), transpose=TRUE))
# compute predictive variance
XXRR = t(Hm[[t]]) - t(H[[t]])%*%RInv%*%t(Rmo)
c_star = Rm - Rmo%*%RInv%*%t(Rmo) + t(XXRR)%*%HRHInv%*%XXRR
## c_star is not positive definite!!! So, there is no cholesky decomposition available
# compute S2
Q = RInv - RInv%*%H[[t]]%*%HRHInv%*%t(H[[t]])%*%t(RInv)
sigma2.hat = compute_Svec(y[[t]], Q) / (n[t]-q[t])
# for(j in 1:N){
# Sig = c_star * sigma2.hat[j]
# ym.hat[[t]][ , ,j] = mvtnorm::rmvt(nsample, sigma=Sig, df=n[t]-q[t], delta=mu_ymy[ ,j], type="shifted")
# }
L = t(chol(c_star))
ym.hat[[t]] = sample_mvt(mu_ymy, L=L, sigma=sigma2.hat, df=n[t]-q[t], nsample)
# ym.hatC = array(NA, dim=c(nsample, dim(Hm[[t]])[1], N))
for(t in 2:(S)){
############################################################################
#### estimate missing data ym
############################################################################
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
IB = match.input(input[[t]], input[[t-1]])$IB
y_t1 = y[[t-1]][IB, ]
# for(k in 1:nsample){
# ym_t1[k, ,] = create.w.pred(t=t, input=input[[t-1]], input.miss=input.miss,
# y=y[[t-1]], ym=ym.hat[k, , ])
# }
ym_t1 = array(NA, dim=c(nsample, n.m[t], N))
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
R_sk = Rm - Rmo%*%RInv%*%t(Rmo)
RmoRInv = Rmo%*%RInv
# b = matrix(NA, q[t]+1, N)
# mu_y = matrix(NA, nrow(Hm[[t]]), N)
# ts = proc.time()
for(k in 1:nsample){
ym_t1[k, ,] = create.w.pred(t=t, input=input[[t-1]], input.miss=input.miss,
y=y[[t-1]], ym=as.matrix(ym.hat[[t-1]][k, , ]))
# ym.hatC = array(NA, dim=c(nsample, dim(Hm[[t]])[1], N))
ym.hat[[t]][k, , ] = conditional_simulation(y[[t]], H[[t]], y_t1,
RInv, Hm[[t]], ym_t1[k, , ], Rmo, R_sk)
# ym.hatC[[t]][k, , ] = pred.list$ym
# sigma = pred.list$sigma
# for(j in 1:N){
# X = cbind(H[[t]], y_t1[ ,j])
# XRXInv = solve(t(X)%*%RInv%*%X)
# b[ ,j] = XRXInv%*%t(X)%*%RInv%*%y[[t]][ ,j]
# Xp = cbind(Hm[[t]], ym_t1[k, ,j])
# mu_y[ ,j] = Xp%*%b[ ,j] + RmoRInv%*%(y[[t]][ ,j]-X%*%b[ ,j])
# temp = Xp - RmoRInv%*%X
# c_star = R_sk + temp%*%XRXInv%*%t(temp)
# ym.hat[[t]][k, ,j] = mvtnorm::rmvt(1, sigma=sigma[j]*c_star, df=n[t]-q[t]-1,
# delta=mu_y[ ,j], type="shifted")
# }
}
# te = proc.time() - ts
}
## get summary statistics
krige = list()
krigeSE = list()
krige.lower95 = list()
krige.upper95 = list()
for(t in 1:S){
# yhat[[t]] = ym.hat[[t]][ ,pred.ID[[t]], ]
krige[[t]] = apply(ym.hat[[t]], c(2,3), mean)
krigeSE[[t]] = apply(ym.hat[[t]], c(2,3), sd)
krige.lower95[[t]] = apply(ym.hat[[t]], c(2,3), quantile, 0.025)
krige.upper95[[t]] = apply(ym.hat[[t]], c(2,3), quantile, 0.975)
}
pred.mu = list()
pred.SE = list()
pred.lower95 = list()
pred.upper95 = list()
for(t in 1:S){
pred.mu[[t]] = matrix(NA, np, N)
pred.SE[[t]] = matrix(0, np, N)
pred.lower95[[t]] = matrix(NA, np, N)
pred.upper95[[t]] = matrix(NA, np, N)
ind.list = ismember(input.new, input.miss[[t]])
pred.mu[[t]][ind.list$IIA, ] = krige[[t]][ind.list$IA, ]
pred.SE[[t]][ind.list$IIA, ] = krigeSE[[t]][ind.list$IA, ]
pred.lower95[[t]][ind.list$IIA, ] = krige.lower95[[t]][ind.list$IA, ]
pred.upper95[[t]][ind.list$IIA, ] = krige.upper95[[t]][ind.list$IA, ]
if(length(ind.list$IIA)<np){
ind.input = ismember(input.new, input[[t]])
pred.mu[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
pred.lower95[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
pred.upper95[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
}
}
names(pred.mu) = paste0("Level", seq(1:S), "")
names(pred.SE) = paste0("Level", seq(1:S), "")
names(pred.lower95) = paste0("Level", seq(1:S), "")
names(pred.upper95) = paste0("Level", seq(1:S), "")
pred = list(mu=pred.mu, SE=pred.SE,
lower95=pred.lower95,upper95=pred.upper95)
return(pred)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
condsim.NN <- function(formula,output,input,input.new,phi,cov.model="matern_5_2",
nsample=30){
Dim = dim(input[[1]])[2]
N = dim(output[[1]])[2]
p.x = Dim
if(dim(phi)[1]==Dim){
is.nugget=FALSE
}else{
is.nugget=TRUE
}
###################################################################
#### augment input
###################################################################
S = length(output) # number of code
out = augment.input(input)
input.union = out$union
input.miss = out$miss
np = dim(input.new)[1]
n = rep(NA, S)
for(t in 1:S){
n[t] = dim(input[[t]])[1]
}
y = output
## add new inputs to missing inputs
# for(t in 1:(S-1)){
# input.miss[[t]] = rbind(input.new, input.miss[[t]])
# }
pred.ID = list()
ID.org = list()
index.full = 1:np
for(t in 1:(S-1)){
ind.list = match.input(input.union[[t]], input.new)
if(!is.null(ind.list$IA)){
indA = ind.list$IA
indB = ind.list$IB
pred.ID.exist = indA
input.exist = input.union[[t]][indA, ,drop=FALSE]
input.added = input.new[-indB, ,drop=FALSE]
n.added = dim(input.added)[1]
pred.ID.added = seq(1,n.added,by=1)
ID.org[[t]] = c(index.full[-indB], indB)
pred.ID[[t]] = c(pred.ID.added, pred.ID.exist+n.added)
input.miss[[t]] = rbind(input.added, input.miss[[t]])
input.union[[t]] = rbind(input.miss[[t]], input[[t]])
}else{
ID.org[[t]] = 1:np
pred.ID[[t]] = 1:np
input.miss[[t]] = rbind(input.new, input.miss[[t]])
input.union[[t]] = rbind(input.new, input.union[[t]])
}
}
t = S
ind.list = match.input(input[[t]], input.new)
if(!is.null(ind.list$IA)){
indA = ind.list$IA
indB = ind.list$IB
pred.ID.exist = indA
input.exist = input.union[[t]][indA, , drop=FALSE]
input.added = input.new[-indB, , drop=FALSE]
n.added = dim(input.added)[1]
pred.ID.added = seq(1, n.added, by=1)
ID.org[[t]] = c(index.full[-indB], indB)
pred.ID[[t]] = c(pred.ID.added, pred.ID.exist+n.added)
input.miss[[t]] = input.added
}else{
input.miss[[t]] = input.new
ID.org[[t]] = 1:np
pred.ID[[t]] = 1:np
}
input.union[[S]] = rbind(input.new, input.union[[S]])
###################################################################
#### create covariates
###################################################################
H = list()
Hm = list()
for(t in 1:S){
colnames(input[[t]]) = paste0("x", 1:p.x)
df = data.frame(input[[t]])
H[[t]] = model.matrix(formula[[t]], df)
colnames(input.miss[[t]]) = paste0("x", 1:p.x)
df = data.frame(input.miss[[t]])
Hm[[t]] = model.matrix(formula[[t]], df)
}
n.m = rep(NA, S)
for(t in 1:S){
n.m[t] = dim(input.miss[[t]])[1]
}
###################################################################
#### compute intermediate quantities
###################################################################
dist.o = list()
dist.m = list()
dist.mo = list()
distlist = list()
for(t in 1:S){
dist.o[[t]] = compute_distance(input[[t]], input[[t]])
#if(t<S){
dist.m[[t]] = compute_distance(input.miss[[t]], input.miss[[t]])
dist.mo[[t]] = compute_distance(input.miss[[t]], input[[t]])
#}
distlist[[t]] = compute_distance(input.union[[t]], input.union[[t]])
}
##
krige = list()
krigeSE = list()
ym.hat = list()
q = rep(NA, S)
for(t in 1:S){
q[t] = dim(H[[t]])[2]
ym.hat[[t]] = array(NA, dim=c(nsample, dim(Hm[[t]])[1], N))
}
#################################################################################
#### get predictive mean and predictive variance
#################################################################################
t = 1
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
HRHInv = solve(t(H[[t]])%*%RInv%*%H[[t]])
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
# compute conditional mean
RmoRInv = Rmo%*%RInv
KW = (Hm[[t]]-RmoRInv%*%H[[t]]) %*% HRHInv %*% t(H[[t]]) %*% RInv + RmoRInv
mu_ymy = KW %*% y[[t]] # n.m-by-N matrix
# compute predictive variance
XXRR = t(Hm[[t]]) - t(H[[t]])%*%RInv%*%t(Rmo)
c_star = Rm - Rmo%*%RInv%*%t(Rmo) + t(XXRR)%*%HRHInv%*%XXRR
## c_star is not positive definite!!! So, there is no cholesky decomposition available
# compute S2
Q = RInv - RInv%*%H[[t]]%*%HRHInv%*%t(H[[t]])%*%t(RInv)
sigma2.hat = compute_Svec(y[[t]], Q) / (n[t]-q[t])
L = t(chol(c_star))
ym.hat[[t]] = sample_mvt(mu_ymy, L=L, sigma=sigma2.hat, df=n[t]-q[t], nsample)
#for(k in 1:nsample){
for(t in 2:(S)){
############################################################################
#### simulating missing data ym
############################################################################
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=FALSE)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=is.nugget)
R_sk = Rm - Rmo%*%RInv%*%t(Rmo)
# RmoRInv = Rmo%*%RInv
y_t1 = array(NA, dim=c(nsample, n[t], N))
ym_t1 = array(NA, dim=c(nsample, n.m[t], N))
# IB = match.input(input[[t]], input.miss[[t-1]])$IB
# y_t1 = ym.hat[[t-1]][IB]
# b = matrix(NA, q[t]+1, N)
# mu_y = matrix(NA, n.m[t], N)
for(k in 1:nsample){
y_t1[k, , ] = create.w(t=t, input=input, input.miss=input.miss[[t-1]],
y=y[[t-1]], ym=as.matrix(ym.hat[[t-1]][k, , ]))
ym_t1[k, , ] = create.w.pred(t=t, input=input[[t-1]], input.miss=input.miss,
y=y[[t-1]], ym=as.matrix(ym.hat[[t-1]][k, ,]))
ym.hat[[t]][k, , ] = conditional_simulation(y[[t]], H[[t]], y_t1[k, , ],
RInv, Hm[[t]], ym_t1[k, , ], Rmo, R_sk)
}
}
#}
################################################################################
krige = list()
krigeSE = list()
krige.lower95 = list()
krige.upper95 = list()
for(t in 1:S){
# yhat[[t]] = ym.hat[[t]][ ,pred.ID[[t]], ]
krige[[t]] = apply(ym.hat[[t]], c(2,3), mean)
krigeSE[[t]] = apply(ym.hat[[t]], c(2,3), sd)
krige.lower95[[t]] = apply(ym.hat[[t]], c(2,3), quantile, 0.025)
krige.upper95[[t]] = apply(ym.hat[[t]], c(2,3), quantile, 0.975)
}
pred.mu = list()
pred.SE = list()
pred.lower95 = list()
pred.upper95 = list()
for(t in 1:S){
pred.mu[[t]] = matrix(NA, np, N)
pred.SE[[t]] = matrix(0, np, N)
pred.lower95[[t]] = matrix(NA, np, N)
pred.upper95[[t]] = matrix(NA, np, N)
ind.list = ismember(input.new, input.miss[[t]])
pred.mu[[t]][ind.list$IIA, ] = krige[[t]][ind.list$IA, ]
pred.SE[[t]][ind.list$IIA, ] = krigeSE[[t]][ind.list$IA, ]
pred.lower95[[t]][ind.list$IIA, ] = krige.lower95[[t]][ind.list$IA, ]
pred.upper95[[t]][ind.list$IIA, ] = krige.upper95[[t]][ind.list$IA, ]
if(length(ind.list$IIA)<np){
ind.input = ismember(input.new, input[[t]])
pred.mu[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
pred.lower95[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
pred.upper95[[t]][ind.input$IIA, ] = y[[t]][ind.input$IA, ]
}
}
names(pred.mu) = paste0("Level", seq(1:S), "")
names(pred.SE) = paste0("Level", seq(1:S), "")
names(pred.lower95) = paste0("Level", seq(1:S), "")
names(pred.upper95) = paste0("Level", seq(1:S), "")
pred = list(mu=pred.mu, SE=pred.SE,
lower95=pred.lower95,upper95=pred.upper95)
return(pred)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
sample.ym <- function(y, input, param, Ho, Hm, dist.o, dist.m, dist.mo, cov.model="matern_5_2", nsample=30){
S = length(y)
Dim = dim(dist.o[[1]])[3]
N = dim(y[[1]])[2]
# param contains phi and nugget (maybe)
if(length(param[ ,1])==Dim){ #no nugget
#phi = exp(-param)
is.nugget=FALSE
}else{
#phi = exp(-param[1:Dim, ,drop=FALSE])
#nugget = exp(param[Dim+1, ,drop=FALSE]) / (1 + exp(param[Dim+1, ,drop=FALSE]))
is.nugget = TRUE
#phi = rbind(phi, nugget)
}
phi = param
inputlist = augment.input(input)
input.miss = inputlist$miss
nm = rep(NA, S-1)
for(t in 1:(S-1)){
nm[t] = dim(dist.m[[t]])[1]
}
n = rep(NA, S)
q = rep(NA, S)
for(t in 1:S){
n[t] = dim(y[[t]])[1]
q[t] = dim(Ho[[t]])[2]
}
ym = list()
for(t in 1:(S-1)){
ym[[t]] = array(NA, dim=c(nsample, nm[t], N))
}
names(ym) = paste0("Level", seq(1:(S-1)), "")
t=1
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
HRHInv = solve(t(Ho[[t]])%*%RInv%*%Ho[[t]])
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=is.nugget)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=FALSE)
# compute conditional mean
RmoRInv = Rmo%*%RInv
KW = (Hm[[t]]-RmoRInv%*%Ho[[t]]) %*% HRHInv %*% t(Ho[[t]]) %*% RInv + RmoRInv
mu_ymy = KW %*% y[[t]] # n.m-by-N matrix
RmoU = t(backsolve(U, t(Rmo), transpose=TRUE))
# compute predictive variance
XXRR = t(Hm[[t]]) - t(Ho[[t]])%*%RInv%*%t(Rmo)
c_star = Rm - Rmo%*%RInv%*%t(Rmo) + t(XXRR)%*%HRHInv%*%XXRR
# compute S2
Q = RInv - RInv%*%Ho[[t]]%*%HRHInv%*%t(Ho[[t]])%*%t(RInv)
sigma2.hat = compute_Svec(y[[t]], Q) / (n[t]-q[t])
# for(j in 1:N){
# Sig = c_star * sigma2.hat[j]
# ym[[t]][ ,j] = c(mvtnorm::rmvt(1, sigma=Sig, df=n[t]-q[t], delta=mu_ymy[ ,j], type="shifted"))
# }
L = t(chol(c_star))
ym[[t]] = sample_mvt(mu=mu_ymy, L=L, sigma=sigma2.hat, df=n[t]-q[t], nsample)
if(S>2){
for(t in 2:(S-1)){
R = buildcov(phi[ ,t], dist.o[[t]], covmodel=cov.model, nugget=is.nugget)
U = chol(R)
RInv = chol2inv(U)
# IB = match.input(input[[t]], input.miss[[t-1]])$IB
# y_t1 = ym[[t-1]][IB]
y_t1 = create.w(t=t, input=input, input.miss=input.miss[[t-1]],
y=y[[t-1]], ym=ym[[t-1]])
# IB = match.input(input.miss[[t]], input.miss[[t-1]])$IB
# ym_t1 = ym[[t-1]][IB]
ym_t1 = create.w(t=t, input=input.miss, input.miss=input.miss[[t-1]],
y=ym[[t-1]], ym=ym[[t-1]])
Rm = buildcov(phi[ ,t], dist.m[[t]], covmodel=cov.model, nugget=is.nugget)
Rmo = buildcov(phi[ ,t], dist.mo[[t]], covmodel=cov.model, nugget=FALSE)
R_sk = Rm - Rmo%*%RInv%*%t(Rmo)
pred.list = conditional_simulation(y[[t]], Ho[[t]], y_t1,
RInv, Hm[[t]], ym_t1, Rmo, R_sk)
# sample ym at t
#ym[[t]] = c(mvtnorm::rmvt(1, sigma=Sig, df=n[t]-q[t]-1, delta=mu_ymy, type="shifted"))
}
}
return(ym)
}
#############################################################################
#############################################################################
#############################################################################
#############################################################################
#############################################################################
#############################################################################
#############################################################################
#############################################################################
#############################################################################
#############################################################################
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.