
Convert ODE-based linear compartment models to analytical linCmt() form
Source:R/odeToLin.R
odeToLin.RdDetects whether a model's ODE equations form a standard 1-3 compartment
pharmacokinetic system and, if so, replaces them with a linCmt()
analytical solution. The conversion removes all d/dt() equations
and the central-compartment output assignment (e.g. cp <- central/v),
adding cp <- linCmt() in their place. All other model lines
(parameter assignments, error model, etc.) are preserved unchanged.
Value
An rxUi model with ODE equations replaced by linCmt(), or
(with a message) the original model unchanged if conversion is not possible.
Details
Detection succeeds when:
Every ODE right-hand side is linear in the state variables.
There are 1-4 compartments total (depot + 1-3 pharmacokinetic compartments).
The compartment topology matches a standard PK model (optional depot feeding a central compartment, with 0-2 peripheral compartments exchanging bidirectionally with central).
There is exactly one output line of the form
var <- central_cmt / v_expr.
The converted model retains all named parameter assignments
(cl, v, ka, q, vp, etc.) so that
linCmt() can infer the parameterization automatically. For models
that already use canonical PK parameter names, no additional assignments
are added.
See also
linToOde for the inverse transformation.
Examples
oneCmtOde <- function() {
ini({
tka <- 0.45
tcl <- log(2.7)
tv <- 3.45
add.sd <- 0.7
})
model({
ka <- exp(tka)
cl <- exp(tcl)
v <- exp(tv)
d/dt(depot) <- -ka * depot
d/dt(central) <- ka * depot - cl/v * central
cp <- central / v
cp ~ add(add.sd)
})
}
linCmtModel <- odeToLin(oneCmtOde)
#>
#>
#> ℹ parameter labels from comments are typically ignored in non-interactive mode
#> ℹ Need to run with the source intact to parse comments
twoCmtOde <- function() {
ini({
tcl <- 1
tv <- 3
tq <- 0.5
tvp <- 6
add.sd <- 0.7
})
model({
cl <- exp(tcl)
v <- exp(tv)
q <- exp(tq)
vp <- exp(tvp)
d/dt(central) <- -(cl+q)/v * central + q/vp * peripheral
d/dt(peripheral) <- q/v * central - q/vp * peripheral
cp <- central / v
cp ~ add(add.sd)
})
}
linCmtModel2 <- odeToLin(twoCmtOde)
#>
#>
#> ℹ parameter labels from comments are typically ignored in non-interactive mode
#> ℹ Need to run with the source intact to parse comments