rxTest({ test_that("Parallel solve vs single vs for; Issue RxODE#450", { TV_CLr <- 6.54 # L/h, (CLr/F) TV_CLnr <- 2.39 # L/h, (CLnr/F) TV_Vc <- 95.1 # L, (V/F) TV_alag <- 0.145 # h, TV_D <- 0.512 # h, TV_Q <- 2.1 #L/h, (Q/F) TV_Vp <- 23.3 #L, (Vp/F) OM_D_normal <- log((128/100)^2+1) D_trans <- 0.0819 OM_CLr <- log((36.2/100)^2+1) OM_CLnr <- log((43.6/100)^2+1) OM_Vc <- log((14.4/100)^2+1) OM_Q <- log((15.1/100)^2+1) OM_Vp <- log((37.6/100)^2+1) OM_CLr_CLnr <- 0.101 OM_CLr_Vc <- 0.0066 rwishart <- function(df, p = nrow(SqrtSigma), Sigma, SqrtSigma = diag(p)) { if (!missing(Sigma)) { tmp <- svd(Sigma) SqrtSigma <- sqrt(tmp$d) * t(tmp$u) } if ((Ident <- missing(SqrtSigma)) && missing(p)) stop("either p, Sigma or SqrtSigma must be specified") Z <- matrix(0, p, p) diag(Z) <- sqrt(rchisq(p, df:(df - p + 1))) if (p > 1) { pseq <- 1:(p - 1) Z[rep(p * pseq, pseq) + unlist(lapply(pseq, seq))] <- rnorm(p * (p - 1)/2) } if (Ident) crossprod(Z) else crossprod(Z %*% SqrtSigma) } sample.etas <- function(df, R, n) { R.inv = solve(df*R) R0 = chol(.5*(R.inv+t(R.inv))) ## R0 is an upper-diag matrix R1 = solve(rwishart(df, SqrtSigma=R0)) eta = rxRmvn(n = n, mu= rep(0, nrow(R)), sigma= .5*(R1+t(R1))) eta } rxWithSeed(100, { nsubj <- 200 n.pts.pk <- 300 # number of subjects in PK model fitting eta_CLr_CLnr_Vc <- as.data.frame(sample.etas(df = n.pts.pk, R = lotri({eta_CLr + eta_CLnr + eta_Vc ~ c(OM_CLr, OM_CLr_CLnr, OM_CLnr, OM_CLr_Vc, 0, OM_Vc) }), n = nsubj)) eta_D_trans <- data.frame(eta_D_normal = rnorm(mean=0,sd=sqrt(OM_D_normal),n=nsubj)) %>% dplyr::mutate(eta_D = ((exp(eta_D_normal))^D_trans-1)/D_trans) par.pk <- data.frame(sim.id = seq(nsubj), D = TV_D * exp(eta_D_trans$eta_D), CLr = TV_CLr * exp(eta_CLr_CLnr_Vc$eta_CLr), CLnr = TV_CLnr * exp(eta_CLr_CLnr_Vc$eta_CLnr), Vc = TV_Vc * exp(eta_CLr_CLnr_Vc$eta_Vc), Vp = TV_Vp * exp(rnorm(nsubj, 0, sqrt(OM_Vp))), Q = TV_Q * exp(rnorm(nsubj, 0, sqrt(OM_Q))), alag = TV_alag) # zero-order absorption with lag time 2-compartment mod <- rxode2({ CL <- CLr+CLnr C2 <- central/Vc*1000 all<- central+periph+output d/dt(central) <- - CL/Vc*central - Q/Vc*central + Q/Vp*periph d/dt(periph) <- Q/Vc*central - Q/Vp*periph d/dt(output) <- CL/Vc*central alag(central) <- alag dur(central) <- D }) ev <- et(amt=2,cmt="central",rate=-2,ii=24,addl=4) %>% et(seq(0,120,0.1)) bar2x <- rxSolve(mod, ev, params=par.pk, cores=2L, returnType="data.frame") bar1x <- rxSolve(mod, ev, params=par.pk, cores=1L, returnType="data.frame") expect_equal(bar1x, bar2x) bar3x <- rxSolve(mod, ev, params=par.pk) # add for loop for testing against res.all = NULL for (id in seq(nsubj)) { # now combine ev.new <- eventTable() %>% add.dosing(dose = 2, nbr.doses = 5, dosing.interval = 24, dur = par.pk$D[par.pk$sim.id == id]) %>% add.sampling(seq(0,120,0.1)) theta <- c(CLr = par.pk$CLr[par.pk$sim.id == id], CLnr = par.pk$CLnr[par.pk$sim.id == id], Vc = par.pk$Vc[par.pk$sim.id == id], Q = par.pk$Q[par.pk$sim.id == id], Vp = par.pk$Vp[par.pk$sim.id == id], alag = par.pk$alag[par.pk$sim.id == id], D = par.pk$D[par.pk$sim.id == id]) res.id = data.frame(sim.id=id, rxSolve(mod, theta, ev.new, returnType="data.frame")) expect_equal(theta, unlist(bar3x$params[bar3x$params$sim.id == id, -1])) ## tmp <- rbind(data.frame(res.id, type="for"), data.frame(bar3x[bar3x$sim.id == id,], type="single")) ## ggplot(tmp, aes(time, C2, col=type)) + geom_line() row.names(res.id) <- NULL res2 <- as.data.frame(bar3x[bar3x$sim.id == id,]) row.names(res2) <- NULL expect_equal(res.id, res2, tolerance=1e-4) res.all = rbind(res.all, res.id) } expect_equal(bar2x, res.all) }) }) })