Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the tlast handling to be based on tlast per cmt #819

Merged
merged 7 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

- Rework the `tad()` and related functions so they use the same
interface as compartments (this way they do not depend on the order
of compartments); See #815. Also allow dummy variables to ignore
state requirements (for parsing mu-referenced equations).
of compartments); See #815. For mu-referencing, Also allow dummy
variables to ignore state requirements (ie `podo(depot)` in a single
line will not error when parsing mu-referenced equations).

- Add `getRxNpars` to api. This allows the development version of
`babelmixr2` to better check what model is loaded and unload/reload
Expand All @@ -12,6 +13,12 @@
- Add `rxUdfUiControl()` to rxode2 user function to get control
information from something like `nlmixr2`

- Bug fix for tracking time after dose when dosing to 2 compartments
occur at the exact same time (#804, #819)

- Change `transit()` model so that it uses `tad0()`, `podo0()` and
related functions for a bit more stable simulation and estimation

# rxode2 3.0.2

- Bug fix for `api`, the censoring function pointer has been updated
Expand Down
6 changes: 6 additions & 0 deletions R/d.R
Original file line number Diff line number Diff line change
Expand Up @@ -546,13 +546,19 @@
.rxD$podo <- list(function(a) {
return("0")
})
.rxD$podo0 <- .rxD$podo
.rxD$dose0 <- .rxD$dose

.rxD$tlast <- list(function(a) {
return("0")
})
.rxD$tfirst <- list(function(a) {
return("0")
})

.rxD$tlast0 <- .rxD$tlast
.rxD$tfirst0 <- .rxD$tfirst

.rxD$first <- list(function(a) {
return("0")
})
Expand Down
102 changes: 52 additions & 50 deletions R/parseFuns.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,35 @@
"fprec", "fround", "ftrunc", "transit", "gammaq", "gammapDer",
"gammapInv", "gammapInva", "gammaqInv", "gammaqInva", "lowergamma",
"uppergamma", "max", "min", "logit", "expit", "probit", "probitInv",
"tlast", "tfirst", "lag", "lead", "dose", "podo", "dabs", "dabs2",
"abs1", "dabs1", "erfinv", "abs0", "dosenum", "first", "last",
"diff", "is.nan", "is.na", "is.finite", "is.infinite", "llikPois",
"llikPoisDlambda", "llikBinom", "llikBinomDprob", "llikNbinom",
"llikNbinomDprob", "llikNbinomMu", "llikNbinomMuDmu", "llikBeta",
"llikBetaDshape1", "llikBetaDshape2", "llikT", "llikTDdf", "llikTDmean",
"llikTDsd", "llikChisq", "llikChisqDdf", "llikExp", "llikExpDrate",
"llikF", "llikFDdf1", "llikFDdf2", "llikGeom", "llikGeomDprob",
"llikUnif", "llikUnifDalpha", "llikUnifDbeta", "llikWeibull",
"llikWeibullDshape", "llikWeibullDscale", "llikGamma", "llikGammaDshape",
"llikGammaDrate", "llikCauchy", "llikCauchyDlocation", "llikCauchyDscale",
"llikNorm", "llikNormDmean", "llikNormDsd", "llikXPois", "llikXPoisDlambda",
"llikXBinom", "llikXBinomDprob", "llikXNbinomMu", "llikXNbinomMuDmu",
"llikXNbinom", "llikXNbinomDprob", "llikXBeta", "llikXBetaDshape1",
"llikXBetaDshape2", "llikXT", "llikXTDdf", "llikXTDmean", "llikXTDsd",
"llikXChisq", "llikXChisqDdf", "llikXExp", "llikXExpDrate", "llikXF",
"llikXFDdf1", "llikXFDdf2", "llikXGeom", "llikXGeomDprob", "llikXUnif",
"llikXUnifDalpha", "llikXUnifDbeta", "llikXWeibull", "llikXWeibullDshape",
"llikXWeibullDscale", "llikXGamma", "llikXGammaDshape", "llikXGammaDrate",
"llikXCauchy", "llikXCauchyDlocation", "llikXCauchyDscale", "llikXNorm",
"llikXNormDmean", "llikXNormDsd", "ReLU", "dReLU", "GELU", "dGELU",
"d2GELU", "d3GELU", "d4GELU", "ELU", "dELU", "d2ELU", "d2aELU",
"dELUa", "d2ELUa", "softplus", "dsoftplus", "d2softplus", "d3softplus",
"d4softplus", "SELU", "dSELU", "lReLU", "dlReLU", "PReLU", "dPReLU",
"d2PReLU", "dPReLUa", "dPReLUa1", "Swish", "dSwish", "linCmt",
"rnorm", "rxnorm", "rxbinom", "rbinom", "rxcauchy", "rcauchy",
"rchisq", "rxchisq", "rexp", "rxexp", "rbeta", "rxbeta", "rgeom",
"rxgeom", "rxpois", "rpois", "rxt", "rt")
"tlast", "tlast0", "tfirst", "tfirst0", "lag", "lead", "dose",
"podo", "dose0", "podo0", "dabs", "dabs2", "abs1", "dabs1", "erfinv",
"abs0", "dosenum", "first", "last", "diff", "is.nan", "is.na",
"is.finite", "is.infinite", "llikPois", "llikPoisDlambda", "llikBinom",
"llikBinomDprob", "llikNbinom", "llikNbinomDprob", "llikNbinomMu",
"llikNbinomMuDmu", "llikBeta", "llikBetaDshape1", "llikBetaDshape2",
"llikT", "llikTDdf", "llikTDmean", "llikTDsd", "llikChisq", "llikChisqDdf",
"llikExp", "llikExpDrate", "llikF", "llikFDdf1", "llikFDdf2",
"llikGeom", "llikGeomDprob", "llikUnif", "llikUnifDalpha", "llikUnifDbeta",
"llikWeibull", "llikWeibullDshape", "llikWeibullDscale", "llikGamma",
"llikGammaDshape", "llikGammaDrate", "llikCauchy", "llikCauchyDlocation",
"llikCauchyDscale", "llikNorm", "llikNormDmean", "llikNormDsd",
"llikXPois", "llikXPoisDlambda", "llikXBinom", "llikXBinomDprob",
"llikXNbinomMu", "llikXNbinomMuDmu", "llikXNbinom", "llikXNbinomDprob",
"llikXBeta", "llikXBetaDshape1", "llikXBetaDshape2", "llikXT",
"llikXTDdf", "llikXTDmean", "llikXTDsd", "llikXChisq", "llikXChisqDdf",
"llikXExp", "llikXExpDrate", "llikXF", "llikXFDdf1", "llikXFDdf2",
"llikXGeom", "llikXGeomDprob", "llikXUnif", "llikXUnifDalpha",
"llikXUnifDbeta", "llikXWeibull", "llikXWeibullDshape", "llikXWeibullDscale",
"llikXGamma", "llikXGammaDshape", "llikXGammaDrate", "llikXCauchy",
"llikXCauchyDlocation", "llikXCauchyDscale", "llikXNorm", "llikXNormDmean",
"llikXNormDsd", "ReLU", "dReLU", "GELU", "dGELU", "d2GELU", "d3GELU",
"d4GELU", "ELU", "dELU", "d2ELU", "d2aELU", "dELUa", "d2ELUa",
"softplus", "dsoftplus", "d2softplus", "d3softplus", "d4softplus",
"SELU", "dSELU", "lReLU", "dlReLU", "PReLU", "dPReLU", "d2PReLU",
"dPReLUa", "dPReLUa1", "Swish", "dSwish", "linCmt", "rnorm",
"rxnorm", "rxbinom", "rbinom", "rxcauchy", "rcauchy", "rchisq",
"rxchisq", "rexp", "rxexp", "rbeta", "rxbeta", "rgeom", "rxgeom",
"rxpois", "rpois", "rxt", "rt")
.parseEnv$.parseNum <- c(lgamma = 1, abs = 1, acos = 1, acosh = 1, asin = 1, asinh = 1,
atan = 1, atan2 = 2, atanh = 1, beta = 2, cos = 1, cosh = 1,
erf = 1, erfc = 1, exp = 1, gamma = 1, linCmtA = 20, linCmtC = 20,
Expand All @@ -52,28 +53,29 @@ fprec = 2, fround = 2, ftrunc = 2, transit = NA, gammaq = 2,
gammapDer = 2, gammapInv = 2, gammapInva = 2, gammaqInv = 2,
gammaqInva = 2, lowergamma = 2, uppergamma = 2, max = NA, min = NA,
logit = NA, expit = NA, probit = NA, probitInv = NA, tlast = NA,
tfirst = NA, lag = NA, lead = NA, dose = NA, podo = NA, dabs = 1,
dabs2 = 1, abs1 = 1, dabs1 = 1, erfinv = 1, abs0 = 1, dosenum = 0,
first = 1, last = 1, diff = 1, is.nan = 1, is.na = 1, is.finite = 1,
is.infinite = 1, llikPois = 2, llikPoisDlambda = 2, llikBinom = 3,
llikBinomDprob = 3, llikNbinom = 3, llikNbinomDprob = 3, llikNbinomMu = 3,
llikNbinomMuDmu = 3, llikBeta = 3, llikBetaDshape1 = 3, llikBetaDshape2 = 3,
llikT = 4, llikTDdf = 4, llikTDmean = 4, llikTDsd = 4, llikChisq = 2,
llikChisqDdf = 2, llikExp = 2, llikExpDrate = 2, llikF = 3, llikFDdf1 = 3,
llikFDdf2 = 3, llikGeom = 2, llikGeomDprob = 2, llikUnif = 3,
llikUnifDalpha = 3, llikUnifDbeta = 3, llikWeibull = 3, llikWeibullDshape = 3,
llikWeibullDscale = 3, llikGamma = 3, llikGammaDshape = 3, llikGammaDrate = 3,
llikCauchy = 3, llikCauchyDlocation = 3, llikCauchyDscale = 3,
llikNorm = 3, llikNormDmean = 3, llikNormDsd = 3, llikXPois = 3,
llikXPoisDlambda = 3, llikXBinom = 4, llikXBinomDprob = 4, llikXNbinomMu = 4,
llikXNbinomMuDmu = 4, llikXNbinom = 4, llikXNbinomDprob = 4,
llikXBeta = 4, llikXBetaDshape1 = 4, llikXBetaDshape2 = 4, llikXT = 5,
llikXTDdf = 5, llikXTDmean = 5, llikXTDsd = 5, llikXChisq = 3,
llikXChisqDdf = 3, llikXExp = 3, llikXExpDrate = 3, llikXF = 4,
llikXFDdf1 = 4, llikXFDdf2 = 4, llikXGeom = 3, llikXGeomDprob = 3,
llikXUnif = 4, llikXUnifDalpha = 4, llikXUnifDbeta = 4, llikXWeibull = 4,
llikXWeibullDshape = 4, llikXWeibullDscale = 4, llikXGamma = 4,
llikXGammaDshape = 4, llikXGammaDrate = 4, llikXCauchy = 4, llikXCauchyDlocation = 4,
tlast0 = NA, tfirst = NA, tfirst0 = NA, lag = NA, lead = NA,
dose = NA, podo = NA, dose0 = NA, podo0 = NA, dabs = 1, dabs2 = 1,
abs1 = 1, dabs1 = 1, erfinv = 1, abs0 = 1, dosenum = 0, first = 1,
last = 1, diff = 1, is.nan = 1, is.na = 1, is.finite = 1, is.infinite = 1,
llikPois = 2, llikPoisDlambda = 2, llikBinom = 3, llikBinomDprob = 3,
llikNbinom = 3, llikNbinomDprob = 3, llikNbinomMu = 3, llikNbinomMuDmu = 3,
llikBeta = 3, llikBetaDshape1 = 3, llikBetaDshape2 = 3, llikT = 4,
llikTDdf = 4, llikTDmean = 4, llikTDsd = 4, llikChisq = 2, llikChisqDdf = 2,
llikExp = 2, llikExpDrate = 2, llikF = 3, llikFDdf1 = 3, llikFDdf2 = 3,
llikGeom = 2, llikGeomDprob = 2, llikUnif = 3, llikUnifDalpha = 3,
llikUnifDbeta = 3, llikWeibull = 3, llikWeibullDshape = 3, llikWeibullDscale = 3,
llikGamma = 3, llikGammaDshape = 3, llikGammaDrate = 3, llikCauchy = 3,
llikCauchyDlocation = 3, llikCauchyDscale = 3, llikNorm = 3,
llikNormDmean = 3, llikNormDsd = 3, llikXPois = 3, llikXPoisDlambda = 3,
llikXBinom = 4, llikXBinomDprob = 4, llikXNbinomMu = 4, llikXNbinomMuDmu = 4,
llikXNbinom = 4, llikXNbinomDprob = 4, llikXBeta = 4, llikXBetaDshape1 = 4,
llikXBetaDshape2 = 4, llikXT = 5, llikXTDdf = 5, llikXTDmean = 5,
llikXTDsd = 5, llikXChisq = 3, llikXChisqDdf = 3, llikXExp = 3,
llikXExpDrate = 3, llikXF = 4, llikXFDdf1 = 4, llikXFDdf2 = 4,
llikXGeom = 3, llikXGeomDprob = 3, llikXUnif = 4, llikXUnifDalpha = 4,
llikXUnifDbeta = 4, llikXWeibull = 4, llikXWeibullDshape = 4,
llikXWeibullDscale = 4, llikXGamma = 4, llikXGammaDshape = 4,
llikXGammaDrate = 4, llikXCauchy = 4, llikXCauchyDlocation = 4,
llikXCauchyDscale = 4, llikXNorm = 4, llikXNormDmean = 4, llikXNormDsd = 4,
ReLU = 1, dReLU = 1, GELU = 1, dGELU = 1, d2GELU = 1, d3GELU = 1,
d4GELU = 1, ELU = 2, dELU = 2, d2ELU = 2, d2aELU = 2, dELUa = 2,
Expand Down
30 changes: 20 additions & 10 deletions R/symengine.R
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,15 @@ regIfOrElse <- rex::rex(or(regIf, regElse))
"probit" = NA,
"probitInv" = NA,
"tlast" = NA,
"tlast0" = NA,
"tfirst" = NA,
"tfirst0" = NA,
"lag" = NA,
"lead" = NA,
"dose" =NA,
"podo" =NA,
"dose0" =NA,
"podo0" =NA,
"dabs" = 1,
"dabs2" = 1,
"abs1" = 1,
Expand Down Expand Up @@ -662,7 +666,7 @@ rxToSE <- function(x, envir = NULL, progress = FALSE,
}

.rxToSEDualVarFunction <- c("tlast", "tlast0", "tad", "tad0", "tafd", "tafd0",
"dose", "podo")
"dose", "podo", "dose0", "podo0")

#' Change rxode2 syntax to symengine syntax for symbols and numbers
#'
Expand Down Expand Up @@ -1090,6 +1094,9 @@ rxToSE <- function(x, envir = NULL, progress = FALSE,
if (identical(x[[1]], quote(`podo`))) {
return(paste0("podo(", .rxLastAssignedDdt, ")"))
}
if (identical(x[[1]], quote(`podo0`))) {
return(paste0("podo0(", .rxLastAssignedDdt, ")"))
}
} else if (.len == 2L) {
if (length(x[[2]]) != 1) {
stop(as.character(x[[1]]), "() must be used with a state", call. = FALSE)
Expand Down Expand Up @@ -1284,11 +1291,11 @@ rxToSE <- function(x, envir = NULL, progress = FALSE,
.bio <- .rxToSE(x[[4]], envir = envir)
if (isEnv) envir$..curCall <- .lastCall
return(paste0(
"exp(log((", .bio, ")*(podo(", .rxLastAssignedDdt, ")))+log(",
"exp(log((", .bio, ")*(podo0(", .rxLastAssignedDdt, ")))+log(",
.n, " + 1)-log(", .mtt, ")+(", .n,
")*((log(", .n, "+1)-log(", .mtt,
"))+log(t-tlast(", .rxLastAssignedDdt, ")))-((", .n, "+1)/(", .mtt,
"))*(t-tlast(", .rxLastAssignedDdt, "))-lgamma(1+", .n, "))"
"))+log(t-tlast0(", .rxLastAssignedDdt, ")))-((", .n, "+1)/(", .mtt,
"))*(t-tlast0(", .rxLastAssignedDdt, "))-lgamma(1+", .n, "))"
))
} else if (length(x) == 3) {
if (isEnv) {
Expand All @@ -1298,7 +1305,7 @@ rxToSE <- function(x, envir = NULL, progress = FALSE,
.n <- .rxToSE(x[[2]], envir = envir)
.mtt <- .rxToSE(x[[3]], envir = envir)
if (isEnv) envir$..curCall <- .lastCall
return(paste0("exp(log(podo(", .rxLastAssignedDdt, "))+(log(", .n, "+1)-log(", .mtt, "))+(", .n, ")*((log(", .n, "+1)-log(", .mtt, "))+ log(t-tlast(", .rxLastAssignedDdt, ")))-((", .n, " + 1)/(", .mtt, "))*(t-tlast(",.rxLastAssignedDdt, "))-lgamma(1+", .n, "))"))
return(paste0("exp(log(podo0(", .rxLastAssignedDdt, "))+(log(", .n, "+1)-log(", .mtt, "))+(", .n, ")*((log(", .n, "+1)-log(", .mtt, "))+ log(t-tlast0(", .rxLastAssignedDdt, ")))-((", .n, " + 1)/(", .mtt, "))*(t-tlast0(",.rxLastAssignedDdt, "))-lgamma(1+", .n, "))"))
} else {
stop("'transit' can only take 2-3 arguments", call. = FALSE)
}
Expand Down Expand Up @@ -1351,7 +1358,7 @@ rxToSE <- function(x, envir = NULL, progress = FALSE,
} else if (identical(x[[1]], quote(`tad`))) {
return(.rxToSETad(x, envir = envir, progress = progress, isEnv=isEnv))
} else if (identical(x[[1]], quote(`tad0`))) {
return(.rxToSETad(x, envir = envir, progress = progress, isEnv=isEnv))
return(.rxToSETad0(x, envir = envir, progress = progress, isEnv=isEnv))
} else if (identical(x[[1]], quote(`lag`)) ||
identical(x[[1]], quote(`lead`))) {
return(.rxToSELagOrLead(x, envir = envir, progress = progress, isEnv=isEnv))
Expand All @@ -1361,10 +1368,12 @@ rxToSE <- function(x, envir = NULL, progress = FALSE,
return(.rxToSETlastOrTafd0(x, envir = envir, progress = progress, isEnv=isEnv))
} else if (identical(x[[1]], quote(`tlast`)) ||
identical(x[[1]], quote(`tfirst`)) ||
identical(x[[1]], quote(`last0`)) ||
identical(x[[1]], quote(`first0`)) ||
identical(x[[1]], quote(`tlast0`)) ||
identical(x[[1]], quote(`tfirst0`)) ||
identical(x[[1]], quote(`dose`)) ||
identical(x[[1]], quote(`podo`))) {
identical(x[[1]], quote(`podo`)) ||
identical(x[[1]], quote(`dose0`)) ||
identical(x[[1]], quote(`podo0`))) {
return(.rxToSETlastOrTfirst(x, envir = envir, progress = progress, isEnv=isEnv))
} else if (identical(x[[1]], quote(`psigamma`))) {
return(.rxToSEPsigamma(x, envir = envir, progress = progress, isEnv=isEnv))
Expand Down Expand Up @@ -2375,7 +2384,8 @@ rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"),
")"
)
return(.ret)
} else if (any(paste(.ret0[[1]]) == c("tlast", "tfirst", "dose", "podo"))) {
} else if (any(paste(.ret0[[1]]) == c("tlast", "tfirst", "dose", "podo",
"tlast0", "first0", "dose0", "podo0"))) {
if (length(.ret0) == 1L) {
return(paste0(.ret0[[1]], "()"))
} else if (length(.ret0) == 2L) {
Expand Down
Binary file modified data/rxReservedKeywords.rda
Binary file not shown.
Binary file modified data/rxResidualError.rda
Binary file not shown.
Binary file modified data/rxSyntaxFunctions.rda
Binary file not shown.
5 changes: 5 additions & 0 deletions inst/include/rxode2_model_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,14 @@ static inline double Rx_pow_di_(double a, double b, rx_solve *rx) {
#define _logitInv1(x) expit(x, 0.0, 1.0)
#define _logitInv2(x, y) expit(x, y, 1.0)
#define _podo0() (_solveData->subjects[_cSub].curDose)
#define _podo00() (ISNA(_solveData->subjects[_cSub].curDose) ? 0 : _solveData->subjects[_cSub].curDose)
#define _podo1(x) (_solveData->subjects[_cSub].curDoseS[x])
#define _podo01(x) (ISNA(_solveData->subjects[_cSub].curDoseS[x]) ? 0 : _solveData->subjects[_cSub].curDoseS[x])

#define _dose0() (_solveData->subjects[_cSub].curDose)
#define _dose1(x) (_solveData->subjects[_cSub].curDoseS[x])
#define _dose00() (ISNA(_solveData->subjects[_cSub].curDose) ? 0 : _solveData->subjects[_cSub].curDose)
#define _dose01(x) (ISNA(_solveData->subjects[_cSub].curDoseS[x]) ? 0 : _solveData->subjects[_cSub].curDoseS[x])
#define _tad0() (t-_solveData->subjects[_cSub].tlast)
#define _tad1(x) (t-_solveData->subjects[_cSub].tlastS[x])
#define _tad00() (ISNA(_solveData->subjects[_cSub].tlast)? 0 : (t- _solveData->subjects[_cSub].tlast))
Expand Down
5 changes: 3 additions & 2 deletions inst/include/rxode2parseHandleEvid.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,10 @@ static inline void handleTlastInline(double *time, rx_solving_options_ind *ind)
} else {
evid = getEvid(ind, ind->ix[ind->idx]);
}
if (op->neq + op->extraCmt != 0 && ind->tlast != _time &&
if (op->neq + op->extraCmt != 0 &&
isDose(evid) &&
ind->cmt < op->neq + op->extraCmt) {
ind->cmt < op->neq + op->extraCmt &&
ind->tlastS[ind->cmt] != _time) {
double curDose = getDoseIndex(ind, ind->idx), tinf = NA_REAL;
if (handleTlastInlineUpateDosingInformation(ind, &curDose, &tinf) == 0) return;
ind->dosenum++;
Expand Down
6 changes: 6 additions & 0 deletions src/genModelVars.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ static inline int sortStateVectorsErrHandle(int prop, int pass, int i) {
if ((prop & propDose) != 0) {
sAppend(&sbt, "'dose(%s)', ", buf);
}
if ((prop & propPodo0) != 0) {
sAppend(&sbt, "'podo0(%s)', ", buf);
}
if ((prop & propDose0) != 0) {
sAppend(&sbt, "'dose0(%s)', ", buf);
}
// Take off trailing "',
sbt.o -= 2;
sbt.s[sbt.o] = 0;
Expand Down
7 changes: 7 additions & 0 deletions src/parseFuns.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ typedef struct transFunctions {
int isDose;
int isPodo;

int isDose0;
int isPodo0;

int isTfirst;
int isTfirst0;

Expand Down Expand Up @@ -140,6 +143,10 @@ static inline void transFunctionsIni(transFunctions *tf) {
tf->isDose = 0;
tf->isPodo = 0;

tf->isDose0 = 0;
tf->isPodo0 = 0;


tf->isTfirst = 0;
tf->isTfirst0 = 0;

Expand Down
9 changes: 8 additions & 1 deletion src/parseFunsDosing.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ static inline int isFunctionTadType(transFunctions *tf) {
(tf->isTfirst0 = !strcmp("tfirst0", tf->v)) ||

(tf->isDose = !strcmp("dose", tf->v)) ||
(tf->isPodo = !strcmp("podo", tf->v));
(tf->isPodo = !strcmp("podo", tf->v)) ||

(tf->isPodo0 = !strcmp("podo0", tf->v)) ||
(tf->isDose0 = !strcmp("dose0", tf->v));
}
static inline int handleFunctionTadEmptyCcode(transFunctions *tf,char *v2) {
if (allSpaces(v2)){
Expand Down Expand Up @@ -101,6 +104,10 @@ static inline int handleFunctionTadSingleStateCcode(transFunctions *tf,char *v2)
tb.dprop[tb.id] += propDose;
} else if (tf->isPodo && (tb.dprop[tb.id] & propPodo) == 0) {
tb.dprop[tb.id] += propPodo;
} else if (tf->isPodo0 && (tb.dprop[tb.id] & propPodo0) == 0) {
tb.dprop[tb.id] += propPodo0;
} else if (tf->isDose0 && (tb.dprop[tb.id] & propDose0) == 0) {
tb.dprop[tb.id] += propDose0;
}
return 1;
}
Expand Down
3 changes: 3 additions & 0 deletions src/tran.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,4 +389,7 @@ char *getLine (char *src, int line, int *lloc);
#define propPodo 8192
#define propDose 16384

#define propPodo0 32768
#define propDose0 65536

#endif // __TRAN_H__
16 changes: 12 additions & 4 deletions tests/testthat/test-dsl.R
Original file line number Diff line number Diff line change
Expand Up @@ -210,21 +210,22 @@ rxTest({

expect_equal(
rxToSE(transit(n, mtt, bio)),
"exp(log((bio)*(podo()))+log(n + 1)-log(mtt)+(n)*((log(n+1)-log(mtt))+log(t-tlast()))-((n+1)/(mtt))*(t-tlast())-lgamma(1+n))")
"exp(log((bio)*(podo0()))+log(n + 1)-log(mtt)+(n)*((log(n+1)-log(mtt))+log(t-tlast0()))-((n+1)/(mtt))*(t-tlast0())-lgamma(1+n))")

expect_equal(
rxToSE(transit(n, mtt)),
"exp(log(podo())+(log(n+1)-log(mtt))+(n)*((log(n+1)-log(mtt))+ log(t-tlast()))-((n + 1)/(mtt))*(t-tlast())-lgamma(1+n))")
"exp(log(podo0())+(log(n+1)-log(mtt))+(n)*((log(n+1)-log(mtt))+ log(t-tlast0()))-((n + 1)/(mtt))*(t-tlast0())-lgamma(1+n))")

tmp <- rxode("d/dt(depot) <- transit(n, mtt, bio)-ka*depot\nd/dt(center)=ka*depot-kel*center")

tmp2 <- rxS(tmp)
tmp3 <- tmp2$rx__d_dt_depot__
expect_equal(rxFromSE(tmp3), "-ka*depot+exp(n*(-log(mtt)+log1p(n)+log(t-tlast(depot)))-(t-tlast(depot))*(1+n)/mtt-log(mtt)+log(bio*podo(depot))+log1p(n)-lgamma1p(n))")
expect_equal(rxFromSE(tmp3), "-ka*depot+exp(n*(-log(mtt)+log1p(n)+log(t-tlast0(depot)))-(1+n)*(t-tlast0(depot))/mtt-log(mtt)+log(bio*podo0(depot))+log1p(n)-lgamma1p(n))")

tmp <- rxode("d/dt(depot) <- transit(n, mtt) - ka*depot\nd/dt(center)=ka*depot-kel*center")
tmp2 <- rxS(tmp)
tmp3 <- tmp2$rx__d_dt_depot__
expect_equal(rxFromSE(tmp3), "-ka*depot+exp(n*(-log(mtt)+log1p(n)+log(t-tlast(depot)))-(t-tlast(depot))*(1+n)/mtt-log(mtt)+log1p(n)+log(podo(depot))-lgamma1p(n))")
expect_equal(rxFromSE(tmp3), "-ka*depot+exp(n*(-log(mtt)+log1p(n)+log(t-tlast0(depot)))-(1+n)*(t-tlast0(depot))/mtt-log(mtt)+log1p(n)+log(podo0(depot))-lgamma1p(n))")

})

Expand Down Expand Up @@ -519,6 +520,13 @@ rxTest({
expect_error(rxToSE("tad(matt+f)"))
})

test_that("tad0()", {
expect_equal(rxToSE("tad0()"), "(t-tlast0())")
expect_equal(rxToSE("tad0(matt)"), "(t-tlast0(matt))")
expect_error(rxToSE("tad0(matt,f)"))
expect_error(rxToSE("tad0(matt+f)"))
})

test_that("tafd()", {
expect_equal(rxToSE("tafd()"), "(t-tfirst())")
expect_equal(rxToSE("tafd(matt)"), "(t-tfirst(matt))")
Expand Down
Loading
Loading