The simulation backend in
PKPDsim
uses an ODE solver written in C++
(Boost::odeint
) to make sure simulations are fast.
Therefore, for most simulation problems computational speed will not be
an issue. Even simulating thousands (or millions) of patients for
complex models will rarely take more than a few minutes. Simpler
simulation problems will commonly take seconds to complete.
However, in some special cases speed could become an issue, and for
that it is important to understand the structure of PKPDsim’s main
function (sim()
) because. The sim()
function
is composed of three parts:
From this structure it is easy to understand that when you would request simulation of 1,000 patients:
dat <- sim(ode = mod, ...., n = 1000)
the pre- and post-processing parts will take relatively minor
computational time, since the main part will be the loop simulating the
PK for the subjects. However, if instead you would write a loop yourself
to simulate 1,000 patients, and would call sim()
repeatedly:
dat <- c()
for(i in 1:1000) {
dat <- rbindlist(dat, sim(ode = mod, ...., n = 1))
}
now in each iteration also the pre- and post-processing functionality
would be invoked, and the overall simulation will take much longer than
before, probably by an order of magnitude. The same concept applies if
you would use sim()
in the context of population (NLME) or
individual (MAP) estimation, or in optimal design in evaluation of the
FIM.
There is a different way to solve ODEs with PKPDsim
though, which uses only the core ODE solver function and does not
perform pre-/post-processing. If you need to use PKPDsim in an iterative
context as described above, you should therefore use the
sim_core()
function instead, and perform the pre- and
post-processing outside of the main loop, e.g.:
design <- sim(mod = mod, ...., return_design=TRUE)
dat <- c()
for(i in 1:1000) {
dat <- rbindlist(dat, sim_core(design = design, ode = mod))
}
# potentially any post-processing here
Several other open source R packages provide similar features as
PKPDsim, the main ones being RxODE
(now renamed to
rxode2
) and mrgsolve
.
In the rxode2
package, the overhead from pre- and
post-processing is separated from the main simulation function by
default, while mrgsolve
is more similar to
PKPDsim
with the overhead being included within the main
simulation function. Therefore, especially when used in an iterative
context, RxODE
will seem much faster than
PKDPsim
and mrgsolve
, while
PKPDsim
and mrgsolve
will seem broadly
similar. However, when using the sim_core()
function as
outlined above, our benchmarks indicate that simulation speed for
PKDDsim
is highly similar to that obtained with the
RxODE
package.