Skip to contents

Detects 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.

Usage

odeToLin(ui)

Arguments

ui

rxUi-like model object (function, rxUi, or anything accepted by as.rxUi).

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:

  1. Every ODE right-hand side is linear in the state variables.

  2. There are 1-4 compartments total (depot + 1-3 pharmacokinetic compartments).

  3. The compartment topology matches a standard PK model (optional depot feeding a central compartment, with 0-2 peripheral compartments exchanging bidirectionally with central).

  4. 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.

Author

Matthew Fidler

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