## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = (4/6)*7 ) ## ----setup-------------------------------------------------------------------- library(QAEnsemble) ## ----eval=TRUE---------------------------------------------------------------- library(svMisc) library(coda) library(expm) library(diagram) ## ----eval=TRUE---------------------------------------------------------------- set.seed(10) ## ----eval=TRUE---------------------------------------------------------------- names_diagram = c("W", "S", "D") #Note: byrow = true is not used in the matrix functions in order to have the #direction of the arrows correctin the diagram diagram_matrix = matrix(c("q_WW", "q_WS", "q_WD", "q_SW", "q_SS", "q_SD", 0, 0, "q_DD"), nrow = 3, ncol = 3) curve_matrix = matrix(c(0.1, 0.1, 0, 0.1, 0.1, 0, 0, 0, 0.1), nrow = 3, ncol = 3) diagram::plotmat(diagram_matrix, pos = c(2, 1), curve = curve_matrix, name = names_diagram, lwd = 2, box.lwd = 2, cex.txt = 0.8, self.lwd = 2, self.cex = 0.5, self.shiftx = c(-0.1, 0.1, -0.1), box.type = "circle", box.prop = 0.5, arr.type = "triangle") ## ----eval=TRUE---------------------------------------------------------------- num_cycles = 20 ## ----eval=TRUE---------------------------------------------------------------- #well people that become sick per day q_WS = 5e-2 #sick people that become well per day q_SW = 1e-3 #well people that die per day q_WD = 1e-7 #sick people that die per day q_SD = 5e-4 q_WW = -1*(q_WS + q_WD) q_SS = -1*(q_SW + q_SD) q_DD = 0 ## ----eval=TRUE---------------------------------------------------------------- MarkovModel_sol <- function(param) { q_WS_use = param[1] q_SW_use = param[2] q_WD_use = param[3] q_SD_use = param[4] q_WW_use = -1*(q_WS_use + q_WD_use) q_SS_use = -1*(q_SW_use + q_SD_use) q_DD_use = 0 Q_transition_matrix_use = matrix(c(q_WW_use, q_WS_use, q_WD_use, q_SW_use, q_SS_use, q_SD_use, 0, 0, q_DD_use), nrow = 3, ncol = 3, byrow = TRUE) num_cycles = 20 num_states = 3 name_states = c("W", "S", "D") #People over time begin day 0 cohort_over_time = matrix(NA, nrow = (num_cycles+1), ncol = num_states, dimnames = list(0:num_cycles, name_states)) cohort_0day = c(W = 3995, S = 5, D = 0) cohort_over_time[1,] = cohort_0day rownames(cohort_over_time) = paste("Day", c(0:(num_cycles)), sep = "_") for(t in 1:num_cycles) { cohort_over_time[t+1, ] = cohort_over_time[t, ] %*% expm::expm(Q_transition_matrix_use*(1)) } return(cohort_over_time) } ## ----eval=TRUE---------------------------------------------------------------- time_use = c(1:num_cycles) cohort_over_time = MarkovModel_sol(c(q_WS, q_SW, q_WD, q_SD)) plot(time_use, diff(cohort_over_time[,2]), xlab="Days (t)", ylab="New daily sick people", type = "l", col = "red") plot(time_use, diff(cohort_over_time[,3]), xlab="Days (t)", ylab="New daily deaths", type = "l", col = "red") ## ----eval=TRUE---------------------------------------------------------------- p1 = 0.1 p2 = 0.3 data_nbin_new_S = matrix(NA, nrow = 1, ncol = num_cycles) data_nbin_new_D = matrix(NA, nrow = 1, ncol = num_cycles) new_S_true = diff(cohort_over_time[,2]) new_D_true = diff(cohort_over_time[,3]) for(t in 1:num_cycles) { data_nbin_new_S[t] = rnbinom(1, size = (new_S_true[t]*p1)/(1 - p1), prob = p1) if(new_D_true[t] == 0) { data_nbin_new_D[t] = 0 } else { data_nbin_new_D[t] = rnbinom(1, size = (new_D_true[t]*p2)/(1 - p2), prob = p2) } } plot(time_use, data_nbin_new_S, xlab="Days (t)", ylab="New daily sick people") plot(time_use, data_nbin_new_D, xlab="Days (t)", ylab="New daily deaths") ## ----eval=TRUE---------------------------------------------------------------- logp <- function(param) { q_WS_use = param[1] q_SW_use = param[2] q_SD_use = param[3] p1_use = param[4] p2_use = param[5] logp_val = dunif(q_WS_use, min = 1e-4, max = 10, log = TRUE) + dunif(q_SW_use, min = 1e-7, max = 1e-1, log = TRUE) + dunif(q_SD_use, min = 1e-6, max = 1e-2, log = TRUE) + dunif(p1_use, min = 1e-4, max = 1, log = TRUE) + dunif(p2_use, min = 1e-4, max = 1, log = TRUE) return(logp_val) } logl <- function(param) { cohort_over_time_use = MarkovModel_sol(c(param[1], param[2], q_WD, param[3])) new_S_sol = diff(cohort_over_time_use[,2]) new_D_sol = diff(cohort_over_time_use[,3]) issue_flag = 0 for(t in 1:num_cycles) { if(new_S_sol[t] < 0 || new_D_sol[t] < 0) { issue_flag = 1 } if(issue_flag == 1) { break } if(new_S_sol[t] == 0) { new_S_sol[t] = 1e-4; } if(new_D_sol[t] == 0) { new_D_sol[t] = 1e-4; } } if(issue_flag == 0) { logl_val = sum(dnbinom(data_nbin_new_S, size = ((new_S_sol)*param[4])/(1 - param[4]), prob = param[4], log = TRUE)) + sum(dnbinom(data_nbin_new_D, size = ((new_D_sol)*param[5])/(1 - param[5]), prob = param[5], log = TRUE)) } else { logl_val = -Inf } return(logl_val) } logfuns = list(logp = logp, logl = logl) ## ----eval=TRUE---------------------------------------------------------------- num_par = 5 num_chains = 2*num_par theta0 = matrix(0, nrow = num_par, ncol = num_chains) temp_val = 0 j = 0 while(j < num_chains) { initial = c(runif(1, 1e-4, 10), runif(1, 1e-7, 1e-1), runif(1, 1e-6, 1e-2), runif(1, 1e-4, 1), runif(1, 1e-4, 1)) temp_val = logl(initial) + logp(initial) while(is.na(temp_val) || is.infinite(temp_val)) { initial = c(runif(1, 1e-4, 10), runif(1, 1e-7, 1e-1), runif(1, 1e-6, 1e-2), runif(1, 1e-4, 1), runif(1, 1e-4, 1)) temp_val = logl(initial) + logp(initial) } j = j + 1 message(paste('j:', j)) theta0[1,j] = initial[1] theta0[2,j] = initial[2] theta0[3,j] = initial[3] theta0[4,j] = initial[4] theta0[5,j] = initial[5] } ## ----eval=TRUE---------------------------------------------------------------- num_chain_iterations = 1.5e4 thin_val_par = 10 floor(num_chain_iterations/thin_val_par)*num_chains ## ----eval=TRUE---------------------------------------------------------------- Dis_Model_Quad_result = ensemblealg(theta0, logfuns, T_iter = num_chain_iterations, Thin_val = thin_val_par, ShowProgress = TRUE, ReturnCODA = TRUE) ## ----eval=TRUE---------------------------------------------------------------- my_samples = Dis_Model_Quad_result$theta_sample my_log_prior = Dis_Model_Quad_result$log_prior_sample my_log_like = Dis_Model_Quad_result$log_like_sample my_mcmc_list_coda = Dis_Model_Quad_result$mcmc_list_coda ## ----eval=TRUE---------------------------------------------------------------- varnames(my_mcmc_list_coda) = c("q_WS", "q_SW", "q_SD", "p1", "p2") plot(my_mcmc_list_coda) ## ----eval=TRUE---------------------------------------------------------------- my_samples_burn_in = my_samples[,,-c(1:floor((num_chain_iterations/thin_val_par)*0.25))] my_log_prior_burn_in = my_log_prior[,-c(1:floor((num_chain_iterations/thin_val_par)*0.25))] my_log_like_burn_in = my_log_like[,-c(1:floor((num_chain_iterations/thin_val_par)*0.25))] ## ----eval=TRUE---------------------------------------------------------------- diagnostic_result = psrfdiagnostic(my_samples_burn_in, 0.05) diagnostic_result$p_s_r_f_vec ## ----eval=TRUE---------------------------------------------------------------- log_un_post_vec = as.vector(my_log_prior_burn_in + my_log_like_burn_in) k1 = as.vector(my_samples_burn_in[1,,]) k2 = as.vector(my_samples_burn_in[2,,]) k3 = as.vector(my_samples_burn_in[3,,]) k4 = as.vector(my_samples_burn_in[4,,]) k5 = as.vector(my_samples_burn_in[5,,]) ## ----eval=TRUE---------------------------------------------------------------- #q_WS posterior median and 95% credible interval median(k1) hpdparameter(k1, 0.05) #(The 95% CI is narrower than the prior distribution and it contains the true #value of q_WS, 5e-2) #q_SW posterior median and 95% credible interval median(k2) hpdparameter(k2, 0.05) #(The 95% CI is narrower than the prior distribution and it contains the true #value of q_SW, 1e-3) #q_SD posterior median and 95% credible interval median(k3) hpdparameter(k3, 0.05) #(The 95% CI is narrower than the prior distribution and it contains the true #value of q_SD, 5e-4) #p1 posterior median and 95% credible interval median(k4) hpdparameter(k4, 0.05) #(The 95% CI is narrower than the prior distribution and it contains the true #value of p1, 0.1) #p2 posterior median and 95% credible interval median(k5) hpdparameter(k5, 0.05) #(The 95% CI is narrower than the prior distribution and it contains the true #value of p2, 0.3) #q_WS, q_SW, q_SD, p1, and p2 maximum posterior k1[which.max(log_un_post_vec)] k2[which.max(log_un_post_vec)] k3[which.max(log_un_post_vec)] k4[which.max(log_un_post_vec)] k5[which.max(log_un_post_vec)] ## ----eval=TRUE---------------------------------------------------------------- plot(k1, exp(log_un_post_vec), xlab="q_WS", ylab="unnormalized posterior density") ## ----eval=TRUE---------------------------------------------------------------- plot(k2, exp(log_un_post_vec), xlab="q_SW", ylab="unnormalized posterior density") ## ----eval=TRUE---------------------------------------------------------------- plot(k3, exp(log_un_post_vec), xlab="q_SD", ylab="unnormalized posterior density") ## ----eval=TRUE---------------------------------------------------------------- plot(k4, exp(log_un_post_vec), xlab="p1", ylab="unnormalized posterior density") ## ----eval=TRUE---------------------------------------------------------------- plot(k5, exp(log_un_post_vec), xlab="p2", ylab="unnormalized posterior density") ## ----eval=TRUE---------------------------------------------------------------- num_samples = 10000 new_S_predict = matrix(NA, nrow = num_samples, ncol = length(time_use)) new_D_predict = matrix(NA, nrow = num_samples, ncol = length(time_use)) discrepancy_new_S = matrix(NA, nrow = num_samples, ncol = 1) discrepancy_new_S_pred = matrix(NA, nrow = num_samples, ncol = 1) ind_pred_exceeds_new_S = matrix(NA, nrow = num_samples, ncol = 1) discrepancy_new_D = matrix(NA, nrow = num_samples, ncol = 1) discrepancy_new_D_pred = matrix(NA, nrow = num_samples, ncol = 1) ind_pred_exceeds_new_D = matrix(NA, nrow = num_samples, ncol = 1) for (i in (length(log_un_post_vec) - num_samples + 1):length(log_un_post_vec)) { l = i - (length(log_un_post_vec) - num_samples) my_sol = MarkovModel_sol(c(k1[i], k2[i], 1e-7, k3[i])) my_new_S_mean = diff(my_sol[,2]) my_new_D_mean = diff(my_sol[,3]) for(j in 1:length(time_use)) { new_S_predict[l,j] = rnbinom(1, size = ((my_new_S_mean[j])*k4[i])/(1 - k4[i]), prob = k4[i]) new_D_predict[l,j] = rnbinom(1, size = ((my_new_D_mean[j])*k5[i])/(1 - k5[i]), prob = k5[i]) } discrepancy_new_S[l,1] = sum((data_nbin_new_S - my_new_S_mean)^2) discrepancy_new_S_pred[l,1] = sum((new_S_predict[l,] - my_new_S_mean)^2) discrepancy_new_D[l,1] = sum((data_nbin_new_D - my_new_D_mean)^2) discrepancy_new_D_pred[l,1] = sum((new_D_predict[l,] - my_new_D_mean)^2) if(discrepancy_new_S_pred[l,1] > discrepancy_new_S[l,1]) { ind_pred_exceeds_new_S[l,1] = 1 } else { ind_pred_exceeds_new_S[l,1] = 0 } if(discrepancy_new_D_pred[l,1] > discrepancy_new_D[l,1]) { ind_pred_exceeds_new_D[l,1] = 1 } else { ind_pred_exceeds_new_D[l,1] = 0 } svMisc::progress(l, num_samples, progress.bar = TRUE, init = (l == 1)) } ## ----eval=TRUE---------------------------------------------------------------- Bayes_p_value = sum(c(ind_pred_exceeds_new_S, ind_pred_exceeds_new_D))/length(c(ind_pred_exceeds_new_S, ind_pred_exceeds_new_D)) Bayes_p_value ## ----eval=TRUE---------------------------------------------------------------- new_S_predict_lower = matrix(NA, nrow = 1, ncol = length(time_use)) new_S_predict_upper = matrix(NA, nrow = 1, ncol = length(time_use)) new_D_predict_lower = matrix(NA, nrow = 1, ncol = length(time_use)) new_D_predict_upper = matrix(NA, nrow = 1, ncol = length(time_use)) for(j in 1:length(time_use)) { new_S_predict_lower[j] = quantile(new_S_predict[,j], probs = 0.025) new_S_predict_upper[j] = quantile(new_S_predict[,j], probs = 0.975) new_D_predict_lower[j] = quantile(new_D_predict[,j], probs = 0.025) new_D_predict_upper[j] = quantile(new_D_predict[,j], probs = 0.975) } ## ----eval=TRUE---------------------------------------------------------------- plot(time_use, data_nbin_new_S, main="New daily sicknesses (Disease Markov Model Example)", cex.main = 1, xlab="Days (t)", ylab="New daily sick people", type = "p", lty = 0, ylim = c(0, 500)) lines(time_use, diff(cohort_over_time[,2]), type = "l", lty = 1, col = "red") lines(time_use, colMeans(new_S_predict), type = "l", lty = 1, col = "blue") lines(time_use, new_S_predict_lower, type = "l", lty = 2, col = "blue") lines(time_use, new_S_predict_upper, type = "l", lty = 2, col = "blue") legend("topleft", legend = c("Data", "True model", "Posterior predictive mean", "95% prediction interval"), lty=c(0,1,1,2), col = c("black", "red", "blue", "blue"), pch=c(1,NA,NA,NA)) ## ----eval=TRUE---------------------------------------------------------------- plot(time_use, data_nbin_new_D, main="New daily deaths (Disease Markov Model Example)", cex.main = 1, xlab="Days (t)", ylab="New daily deaths", type = "p", lty = 0, ylim = c(0, 20)) lines(time_use, diff(cohort_over_time[,3]), type = "l", lty = 1, col = "red") lines(time_use, colMeans(new_D_predict), type = "l", lty = 1, col = "blue") lines(time_use, new_D_predict_lower, type = "l", lty = 2, col = "blue") lines(time_use, new_D_predict_upper, type = "l", lty = 2, col = "blue") legend("topleft", legend = c("Data", "True model", "Posterior predictive mean", "95% prediction interval"), lty=c(0,1,1,2), col = c("black", "red", "blue", "blue"), pch=c(1,NA,NA,NA))