From 98b8c210c91c68d61167d226ac4ede5d6f62f4ca Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Fri, 27 Oct 2023 21:35:14 -0500 Subject: [PATCH 01/27] Start testing udf --- tests/testthat/test-udf.R | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/testthat/test-udf.R diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R new file mode 100644 index 000000000..6a73d708a --- /dev/null +++ b/tests/testthat/test-udf.R @@ -0,0 +1,22 @@ +test_that("udf functions", { + + gg <- function(x, y) { + x + y + } + + f <- rxode2({ + z = gg(x, y) + }) + + + e <- et(1:10) |> as.data.frame() + + e$x <- 1:10 + e$y <- 21:30 + + expect_warning(rxSolve(f, e)) + + d <- suppressWarnings(rxSolve(f, e)) + expect_true(all(d$z == d$x + d$y)) + +}) From 24e0fcbef1e89141fc80507d3c29e3dbf3555616 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sun, 29 Oct 2023 22:29:25 -0500 Subject: [PATCH 02/27] Update udf and add symengine support --- R/symengine.R | 66 ++++++++++++++++++++++++++++++++----- man/reexports.Rd | 1 + src/rxData.cpp | 6 ++-- src/rxode2parse.cpp | 8 +++++ tests/testthat/test-udf.R | 68 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 11 deletions(-) diff --git a/R/symengine.R b/R/symengine.R index 1114b5a1f..1d0e93346 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -471,6 +471,9 @@ rxD <- function(name, derivatives) { } +.rxToSE.envir <- new.env(parent=emptyenv()) +.rxToSE.envir$envir <- NULL + .promoteLinB <- FALSE #' rxode2 to symengine environment #' @@ -491,11 +494,15 @@ rxD <- function(name, derivatives) { #' - `forward` for forward differences #' - `central` for central differences #' - `error` for throwing an error for unknown derivatives +#' +#' @param parent is the parent environment to look for R-based user functions +#' #' @return An rxode2 symengine environment #' @author Matthew L. Fidler #' @export rxToSE <- function(x, envir = NULL, progress = FALSE, - promoteLinSens = TRUE) { + promoteLinSens = TRUE, parent = parent.frame()) { + .rxToSE.envir$parent <- parent assignInMyNamespace(".promoteLinB", promoteLinSens) assignInMyNamespace(".rxIsLhs", FALSE) assignInMyNamespace(".rxLastAssignedDdt", "") @@ -1338,9 +1345,27 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, ) } } else { - stop(sprintf(gettext("function '%s' or its derivatives are not supported in rxode2"), .fun), - call. = FALSE - ) + .udf <- try(get(.fun, envir = .rxToSE.envir$parent, mode="function"), silent =TRUE) + if (inherits(.udf, "try-error")) { + stop(sprintf(gettext("function '%s' or its derivatives are not supported in rxode2"), .fun), + call. = FALSE + ) + } else { + .f <- formals(.udf) + if (any(names(.f) == "...")) { + stop(sprintf(gettext("R user function '%s' has variable number of arguments with'...' and is not supported in rxode2"), .fun), + call. = FALSE + ) + } else if (length(.ret0) == length(.f)) { + .ret0 <- unlist(.ret0) + .ret <- paste0(.fun, "(",paste(.ret0, collapse=", "), ")") + } else { + stop(sprintf(gettext("user function '%s' requires %d arguments (supplied %d)"), .fun, + length(.f), length(.ret0)), + call. = FALSE + ) + } + } } } } @@ -1371,11 +1396,15 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, .rxFromNumDer <- 0L .rxDelta <- (.Machine$double.eps)^(1 / 3) +.rxFromSE.envir <- new.env(parent=emptyenv()) +.rxFromSE.envir$parent <- NULL #' @rdname rxToSE #' @export -rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error")) { +rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), + parent=parent.frame()) { rxReq("symengine") + .rxFromSE.envir$parent <- parent .unknown <- c("central" = 2L, "forward" = 1L, "error" = 0L) assignInMyNamespace(".rxFromNumDer", .unknown[match.arg(unknownDerivatives)]) if (is(substitute(x), "character")) { @@ -2105,9 +2134,30 @@ rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error")) { } stop(paste0(.ret0[[1]], "() takes 0-1 arguments")) } else { - stop(sprintf(gettext("'%s' not supported in symengine->rxode2"), paste(.ret0[[1]])), - call. = FALSE - ) + .fun <- paste(.ret0[[1]]) + .g <- try(get(.fun, envir=.rxFromSE.envir$parent, mode="function"), silent=TRUE) + if (inherits(.g, "try-error")) { + stop(sprintf(gettext("'%s' not supported in symengine->rxode2"), .fun), + call. = FALSE + ) + } else { + .f <- formals(.g) + if (any(names(.f) == "...")) { + stop(sprintf(gettext("R user function '%s' has variable number of arguments with'...' and is not supported in rxode2"), .fun), + call. = FALSE + ) + } else if (length(.ret0) - 1 == length(.f)) { + .ret <- unlist(.ret0) + .fun <- .ret[1] + .args <- .ret[-1] + return(paste0(.fun, "(", paste(.args, collapse = ", "), ")")) + } else { + stop(sprintf(gettext("user function '%s' requires %d arguments (supplied %d)"), .fun, + length(.f), length(.ret0) - 1), + call. = FALSE) + + } + } } } } else { diff --git a/man/reexports.Rd b/man/reexports.Rd index f1310e9e9..365c14ab7 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -82,3 +82,4 @@ below to see their documentation. \item{rxode2random}{\code{\link[rxode2random:dot-cbindOme]{.cbindOme}}, \code{\link[rxode2random:dot-expandPars]{.expandPars}}, \code{\link[rxode2random:dot-vecDf]{.vecDf}}, \code{\link[rxode2random]{cvPost}}, \code{\link[rxode2random]{invWR1d}}, \code{\link[rxode2random]{phi}}, \code{\link[rxode2random]{rinvchisq}}, \code{\link[rxode2random]{rLKJ1}}, \code{\link[rxode2random]{rxGetSeed}}, \code{\link[rxode2random]{rxGetSeed}}, \code{\link[rxode2random]{rxRmvn}}, \code{\link[rxode2random]{rxSeedEng}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random:rxWithSeed]{rxWithPreserveSeed}}, \code{\link[rxode2random]{rxWithSeed}}, \code{\link[rxode2random]{rxWithSeed}}} }} +\value{ Inherited from parent routine } diff --git a/src/rxData.cpp b/src/rxData.cpp index 3580e868d..127d7b4aa 100644 --- a/src/rxData.cpp +++ b/src/rxData.cpp @@ -50,8 +50,6 @@ extern seedEng_t seedEng; #include "rxThreadData.h" //#include "seed.h" -extern "C" uint64_t dtwiddle(const void *p, int i); -extern "C" void calcNradix(int *nbyte, int *nradix, int *spare, uint64_t *maxD, uint64_t *minD); extern "C" void RSprintf(const char *format, ...); extern "C" int getRxThreads(const int64_t n, const bool throttle); extern "C" double *global_InfusionRate(unsigned int mx); @@ -65,6 +63,7 @@ extern "C" int getThrottle(); extern "C" int getRxThreads(const int64_t n, const bool throttle); extern "C" void rxode2_assign_fn_pointers_(const char *mv); extern "C" void setSilentErr(int silent); +extern "C" void _rxode2parse_assignUdf(SEXP in); extern "C" { typedef SEXP (*_rxode2parse_getForder_type)(void); @@ -4403,7 +4402,6 @@ static inline SEXP rxSolve_finalize(const RObject &obj, #ifdef rxSolveT clock_t _lastT0 = clock(); #endif - rxSolveSaveRxSolve(rxSolveDat); rx_solve* rx = getRxSolve_(); // if (rxSolveDat->throttle){ @@ -4737,6 +4735,8 @@ SEXP rxSolve_(const RObject &obj, const List &rxControl, rxSolveFreeObj = object; } } + _rxode2parse_assignUdf(rxSolveDat->mv[RxMv_udf]); + if (rxSolveDat->isRxSolve || rxSolveDat->isEnvironment){ rx_solve* rx = getRxSolve_(); iniRx(rx); diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 2f9f23949..6a4475ad1 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -76,6 +76,14 @@ extern "C" SEXP _rxode2_codeLoaded(void) { END_RCPP } +extern "C" void _rxode2parse_assignUdf(SEXP in) { +BEGIN_RCPP + assignRxode2ParsePtrs(); + Function fun = as(rxode2parse[".setupUdf"]); + fun(in); +VOID_END_RCPP +} + extern "C" SEXP _rxode2_codegen(SEXP c_file, SEXP prefix, SEXP libname, SEXP pMd5, SEXP timeId, SEXP lastMv, SEXP goodFuns) { BEGIN_RCPP assignRxode2ParsePtrs(); diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index 6a73d708a..4342e4db7 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -17,6 +17,74 @@ test_that("udf functions", { expect_warning(rxSolve(f, e)) d <- suppressWarnings(rxSolve(f, e)) + expect_true(all(d$z == d$x + d$y)) + # now modify gg + gg <- function(x, y, z) { + x + y + z + } + + expect_error(rxSolve(f, e)) + + # now modify gg back to 2 arguments + gg <- function(x, y) { + x * y + } + + # different solve results but still runs + + d <- suppressWarnings(rxSolve(f, e)) + + expect_true(all(d$z == d$x * d$y)) + + rm(gg) + + expect_error(rxSolve(f, e)) + + gg <- function(x, ...) { + x + } + + expect_error(rxSolve(f, e)) + + gg <- function(x, y) { + stop("running me") + } + + expect_error(rxSolve(f, e)) + + gg <- function(x, y) { + "running " + } + + x <- suppressWarnings(rxSolve(f, e)) + expect_true(all(is.na(x$z))) + + gg <- function(x, y) { + "3" + } + + x <- rxSolve(f, e) + expect_true(all(x$z == 3)) + + expect_equal(rxToSE("gg(x,y)"), "gg(x, y)") + + expect_error(rxToSE("gg()"), "user function") + + expect_error(rxFromSE("Derivative(gg(a,b),a)"), NA) + + expect_error(rxFromSE("Derivative(gg(a),a)")) + + expect_error(rxFromSE("Derivative(gg(),a)")) + + + gg <- function(x, ...) { + x + } + + expect_error(rxToSE("gg(x,y)")) + + exect_error(rxFromSE("Derivative(gg(a,b),a)")) + }) From f8d7ff8ecfba2313686512aa29c62411aa4c0683 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Mon, 30 Oct 2023 10:37:00 -0500 Subject: [PATCH 03/27] Move C user functions to rxode2parse; enable recompile --- R/rxode2.R | 8 +- R/symengine.R | 78 +- inst/po/en@quot/LC_MESSAGES/R-rxode2.mo | Bin 0 -> 35003 bytes man/rxFun.Rd | 78 - man/rxToSE.Rd | 16 +- man/rxode2.Rd | 132 -- po/R-rxode2.pot | 525 ++++-- po/R-zh_CN.po | 964 +++++++---- po/rxode2.pot | 1299 +++----------- po/zh_CN.po | 2120 +++++++++++------------ src/rxData.cpp | 10 +- src/rxode2parse.cpp | 7 +- tests/testthat/test-udf.R | 27 +- 13 files changed, 2385 insertions(+), 2879 deletions(-) create mode 100644 inst/po/en@quot/LC_MESSAGES/R-rxode2.mo delete mode 100644 man/rxFun.Rd diff --git a/R/rxode2.R b/R/rxode2.R index c9f841877..18c0df0e3 100644 --- a/R/rxode2.R +++ b/R/rxode2.R @@ -411,7 +411,7 @@ rxode2 <- # nolint .rx$.clearME() }) .rx$.rxWithWd(wd, { - .rx$.extraC(extraC) + rxode2parse::.extraC(extraC) if (missing.modName) { .rxDll <- .rx$rxCompile(.mv, debug = debug, @@ -432,7 +432,7 @@ rxode2 <- # nolint }) }) })) - .extraC(extraC) + rxode2parse::.extraC(extraC) .env$compile() .env$get.modelVars <- eval(bquote(function() { with(.(.env), { @@ -1039,7 +1039,7 @@ rxMd5 <- function(model, # Model File rxode2.calculate.sensitivity) .ret <- c( .ret, .tmp, .rxIndLinStrategy, .rxIndLinState, - .linCmtSens, ls(.symengineFs), .rxFullPrint + .linCmtSens, ls(rxode2parse::.symengineFs()), .rxFullPrint ) if (is.null(.md5Rx)) { .tmp <- getLoadedDLLs()$rxode2 @@ -1462,7 +1462,7 @@ rxCompile.rxModelVars <- function(model, # Model cat(.ret) sink() sink(.normalizePath(file.path(.dir, "extraC.h"))) - cat(.extraCnow) + cat(rxode2parse::.extraCnow()) sink() try(dyn.unload(.cDllFile), silent = TRUE) try(unlink(.cDllFile)) diff --git a/R/symengine.R b/R/symengine.R index 1d0e93346..032e8f7a9 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -264,41 +264,7 @@ regIfOrElse <- rex::rex(or(regIf, regElse)) "rt" = 1 ) -.rxSEeqUsr <- NULL - -.rxCcode <- NULL -.symengineFs <- new.env(parent = emptyenv()) - -.extraCnow <- "" -.extraC <- function(extraC = NULL) { - if (!is.null(extraC)) { - if (file.exists(extraC)) { - .ret <- sprintf("#include \"%s\"\n", extraC) - } else { - .ret <- paste(extraC, collapse = "\n") - } - } else { - .ret <- "" - } - if (length(.rxCcode) > 0L) { - .ret <- sprintf("%s\n%s\n", .ret, paste(.rxCcode, collapse = "\n")) - } - assignInMyNamespace(".extraCnow", .ret) - return(invisible()) -} - -#' Add user function to rxode2 -#' -#' This adds a user function to rxode2 that can be called. If needed, -#' these functions can be differentiated by numerical differences or -#' by adding the derivatives to rxode2's internal derivative table -#' with [rxD()] -#' -#' @param name This gives the name of the user function -#' @param args This gives the arguments of the user function -#' @param cCode This is the C-code for the new function -#' @return nothing -#' @author Matthew L. Fidler +#' @inherit rxode2parse::rxFunParse #' @examples #' \donttest{ #' ## Right now rxode2 is not aware of the function f @@ -348,41 +314,13 @@ regIfOrElse <- rex::rex(or(regIf, regElse)) #' } #' @export rxFun <- function(name, args, cCode) { - if (!is.character(name) || length(name) != 1L) { - stop("name argument must be a length-one character vector", call. = FALSE) - } - if (missing(cCode)) stop("a new function requires a C function so it can be used in rxode2", call. = FALSE) - if (any(name == names(.rxSEeqUsr))) { - stop("already defined user function '", name, "', remove it fist ('rxRmFun')", - call. = FALSE - ) - } - suppressWarnings(rxRmFun(name)) - assignInMyNamespace(".rxSEeqUsr", c(.rxSEeqUsr, setNames(length(args), name))) - assignInMyNamespace(".rxCcode", c(.rxCcode, setNames(cCode, name))) - assign(name, symengine::Function(name), envir = .symengineFs) - return(invisible()) + rxode2parse::rxFunParse(name, args, cCode) } #' @rdname rxFun #' @export rxRmFun <- function(name) { - if (!is.character(name) || length(name) != 1L) { - stop("name argument must be a length-one character vector", - call. = FALSE - ) - } - if (!any(name == names(.rxSEeqUsr))) { - warning("no user function '", name, "' to remove", call. = FALSE) - } - .w <- which(name == names(.rxSEeqUsr)) - if (length(.w) == 1L) assignInMyNamespace(".rxSEeqUsr", .rxSEeqUsr[-.w]) - .w <- which(name == names(.rxCcode)) - if (length(.w) == 1L) assignInMyNamespace(".rxCcode", .rxCcode[-.w]) - .rxD <- rxode2parse::rxode2parseD() - if (exists(name, envir = .rxD)) rm(list = name, envir = .rxD) - if (exists(name, envir = .symengineFs)) rm(list = name, envir = .symengineFs) - return(invisible()) + rxode2parse::rxRmFunParse(name) } .SE1p <- c( @@ -1199,7 +1137,7 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, } .ret0 <- c(list(as.character(x[[1]])), lapply(x[-1], .rxToSE, envir = envir)) if (isEnv) envir$..curCall <- .lastCall - .SEeq <- c(.rxSEeq, .rxSEeqUsr) + .SEeq <- c(.rxSEeq, rxode2parse::.rxSEeqUsr()) .curName <- paste(.ret0[[1]]) .nargs <- .SEeq[.curName] if (.promoteLinB && .curName == "linCmtA") { @@ -1888,7 +1826,7 @@ rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), } } .ret0 <- lapply(lapply(x, .stripP), .rxFromSE) - .SEeq <- c(.rxSEeq, .rxSEeqUsr) + .SEeq <- c(.rxSEeq, rxode2parse::.rxSEeqUsr()) .nargs <- .SEeq[paste(.ret0[[1]])] if (!is.na(.nargs)) { if (.nargs == length(.ret0) - 1) { @@ -2232,8 +2170,8 @@ rxS <- function(x, doConst = TRUE, promoteLinSens = FALSE) { .env$rx_yj_ <- symengine::S("2") .env$rx_low_ <- symengine::S("0") .env$rx_hi_ <- symengine::S("1") - if (!is.null(.rxSEeqUsr)) { - sapply(names(.rxSEeqUsr), function(x) { + if (!is.null(rxode2parse::.rxSEeqUsr())) { + sapply(names(rxode2parse::.rxSEeqUsr()), function(x) { assign(.rxFunction(x), x, envir = .env) }) } @@ -3113,7 +3051,7 @@ rxSplitPlusQ <- function(x, level = 0, mult = FALSE) { .rxSupportedFuns <- function(extra = .rxSupportedFunsExtra) { .ret <- c( names(.rxSEsingle), names(.rxSEdouble), names(.rxSEeq), - "linCmt", names(.rxOnly), ls(.symengineFs) + "linCmt", names(.rxOnly), ls(rxode2parse::.symengineFs()) ) if (extra) { .ret <- c(.ret, c( diff --git a/inst/po/en@quot/LC_MESSAGES/R-rxode2.mo b/inst/po/en@quot/LC_MESSAGES/R-rxode2.mo new file mode 100644 index 0000000000000000000000000000000000000000..a435430fe3dd3927ee5a74cce9c2be2b4bca0c0a GIT binary patch literal 35003 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 W$?bOY?vD4bo-=F1%qm+w5&sKUhvkw0 literal 0 HcmV?d00001 diff --git a/man/rxFun.Rd b/man/rxFun.Rd deleted file mode 100644 index 2a8ddbad3..000000000 --- a/man/rxFun.Rd +++ /dev/null @@ -1,78 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/symengine.R -\name{rxFun} -\alias{rxFun} -\alias{rxRmFun} -\title{Add user function to rxode2} -\usage{ -rxFun(name, args, cCode) - -rxRmFun(name) -} -\arguments{ -\item{name}{This gives the name of the user function} - -\item{args}{This gives the arguments of the user function} - -\item{cCode}{This is the C-code for the new function} -} -\value{ -nothing -} -\description{ -This adds a user function to rxode2 that can be called. If needed, -these functions can be differentiated by numerical differences or -by adding the derivatives to rxode2's internal derivative table -with \code{\link[=rxD]{rxD()}} -} -\examples{ -\donttest{ -## Right now rxode2 is not aware of the function f -## Therefore it cannot translate it to symengine or -## Compile a model with it. - -try(rxode2("a=fun(a,b,c)")) - -## Note for this approach to work, it cannot interfere with C -## function names or reserved rxode2 specical terms. Therefore -## f(x) would not work since f is an alias for bioaviability. - -fun <- " -double fun(double a, double b, double c) { - return a*a+b*a+c; -} -" ## C-code for function - -rxFun("fun", c("a", "b", "c"), fun) ## Added function - -## Now rxode2 knows how to translate this function to symengine - -rxToSE("fun(a,b,c)") - -## And will take a central difference when calculating derivatives - -rxFromSE("Derivative(fun(a,b,c),a)") - -## Of course, you could specify the derivative table manually -rxD("fun", list( - function(a, b, c) { - paste0("2*", a, "+", b) - }, - function(a, b, c) { - return(a) - }, - function(a, b, c) { - return("0.0") - } -)) - -rxFromSE("Derivative(fun(a,b,c),a)") - -# You can also remove the functions by `rxRmFun` - -rxRmFun("fun") -} -} -\author{ -Matthew L. Fidler -} diff --git a/man/rxToSE.Rd b/man/rxToSE.Rd index fd636ff4b..85c1f4076 100644 --- a/man/rxToSE.Rd +++ b/man/rxToSE.Rd @@ -7,11 +7,21 @@ \alias{.rxFromSE} \title{rxode2 to symengine environment} \usage{ -rxToSE(x, envir = NULL, progress = FALSE, promoteLinSens = TRUE) +rxToSE( + x, + envir = NULL, + progress = FALSE, + promoteLinSens = TRUE, + parent = parent.frame() +) .rxToSE(x, envir = NULL, progress = FALSE) -rxFromSE(x, unknownDerivatives = c("forward", "central", "error")) +rxFromSE( + x, + unknownDerivatives = c("forward", "central", "error"), + parent = parent.frame() +) .rxFromSE(x) } @@ -26,6 +36,8 @@ variables in.} \item{promoteLinSens}{Promote solved linear compartment systems to sensitivity-based solutions.} +\item{parent}{is the parent environment to look for R-based user functions} + \item{unknownDerivatives}{When handling derivatives from unknown functions, the translator will translate into different types of numeric derivatives. The currently supported methods are: diff --git a/man/rxode2.Rd b/man/rxode2.Rd index eaf57c157..e9a843855 100644 --- a/man/rxode2.Rd +++ b/man/rxode2.Rd @@ -209,138 +209,6 @@ suggest the package emphasis on pharmacometrics modeling, including pharmacokinetics (PK), pharmacodynamics (PD), disease progression, drug-disease modeling, etc. -The ODE-based model specification may be coded inside four places: -\itemize{ -\item Inside a \code{rxode2({})} block statements: -}\if{html}{\out{ - -}} - - -\if{html}{\out{
}}\preformatted{library(rxode2) -mod <- rxode2(\{ - # simple assignment - C2 <- centr/V2 - - # time-derivative assignment - d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; -\}) -}\if{html}{\out{
}} -\itemize{ -\item Inside a \code{rxode2("")} string statement: -}\if{html}{\out{ - -}} - - -\if{html}{\out{
}}\preformatted{mod <- rxode2(" - # simple assignment - C2 <- centr/V2 - - # time-derivative assignment - d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; -") -}\if{html}{\out{
}} -\itemize{ -\item In a file name to be loaded by rxode2: -}\if{html}{\out{ - -}} - - -\if{html}{\out{
}}\preformatted{writeLines(" - # simple assignment - C2 <- centr/V2 - - # time-derivative assignment - d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; -", "modelFile.rxode2") -mod <- rxode2(filename='modelFile.rxode2') -unlink("modelFile.rxode2") -}\if{html}{\out{
}} -\itemize{ -\item In a model function which can be parsed by \code{rxode2}: -}\if{html}{\out{ - -}} - - -\if{html}{\out{
}}\preformatted{mod <- function() \{ - model(\{ - # simple assignment - C2 <- centr/V2 - - # time-derivative assignment - d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; - \}) -\} - -mod <- rxode2(mod) # or simply mod() if the model is at the end of the function - -# These model functions often have residual components and initial -# (`ini(\{\})`) conditions attached as well. For example the -# theophylline model can be written as: - -one.compartment <- function() \{ - ini(\{ - tka <- 0.45 # Log Ka - tcl <- 1 # Log Cl - tv <- 3.45 # Log V - eta.ka ~ 0.6 - eta.cl ~ 0.3 - eta.v ~ 0.1 - add.sd <- 0.7 - \}) - model(\{ - ka <- exp(tka + eta.ka) - cl <- exp(tcl + eta.cl) - v <- exp(tv + eta.v) - d/dt(depot) = -ka * depot - d/dt(center) = ka * depot - cl / v * center - cp = center / v - cp ~ add(add.sd) - \}) -\} - -# after parsing the model -mod <- one.compartment() -}\if{html}{\out{
}} - -For the block statement, character string or text file an internal -\code{rxode2} compilation manager translates the ODE system into C, compiles -it and loads it into the R session. The call to \code{rxode2} produces an -object of class \code{rxode2} which consists of a list-like structure -(environment) with various member functions. - -For the last type of model (a model function), a call to \code{rxode2} -creates a parsed \code{rxode2} ui that can be translated to the \code{rxode2} -compilation model. - -\if{html}{\out{
}}\preformatted{mod$simulationModel -}\if{html}{\out{
}} - -\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_a90252941d02394f0f947e0dd27a357d model (ready). -## x$state: depot, center -## x$stateExtra: cp -## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp -## x$lhs: ka, cl, v, cp, ipredSim, sim -}\if{html}{\out{
}} - -\if{html}{\out{
}}\preformatted{# or -mod$simulationIniModel -}\if{html}{\out{
}} - -\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_52f891d68103e40fefec0501b2b1d177 model (ready). -## x$state: depot, center -## x$stateExtra: cp -## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp -## x$lhs: ka, cl, v, cp, ipredSim, sim -}\if{html}{\out{
}} - -This is the same type of function required for \code{nlmixr2} estimation and -can be extended and modified by model piping. For this reason will be -focused on in the documentation. - This basic model specification consists of one or more statements optionally terminated by semi-colons \verb{;} and optional comments (comments are delimited by \verb{#} and an end-of-line). diff --git a/po/R-rxode2.pot b/po/R-rxode2.pot index 74c05d35c..f519349d8 100644 --- a/po/R-rxode2.pot +++ b/po/R-rxode2.pot @@ -1,184 +1,190 @@ msgid "" msgstr "" -"Project-Id-Version: Rxode2 1.1.0\n" -"POT-Creation-Date: 2021-05-26 10:39\n" +"Project-Id-Version: rxode2 2.0.14.9000\n" +"POT-Creation-Date: 2023-10-30 08:03\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" - -msgid "Rxode2 requires 'rtools' for custom models\nPlease download from http://cran.r-project.org/bin/windows/Rtools/,\ninstall and restart your R session before proceeding" +msgid "unsupported expression for ini({}) block" msgstr "" -msgid "'modName' has to be a single length character" +msgid "unsupported expression of ini({}) block" msgstr "" -msgid "'extraC' needs to point to a file that exists and is readable" +msgid "do not know how to convert this to an `ini` expression" msgstr "" -msgid "'collapseModel' needs to be logical" +msgid "error converting character vector to model({}) expression" msgstr "" -msgid "'indLin' needs to be logical" +msgid "unsupported expression of model({}) block" msgstr "" -msgid "'debug' needs to be logical" +msgid "do not know how to convert this to an `model` expression" msgstr "" -msgid "'package' needs to a single character for the package name" +msgid "cannot convert to rxUi object" msgstr "" -msgid "with packages 'modName' is required" +msgid "could not convert to rxUi object" msgstr "" -msgid "must specify exactly one of 'model' or 'filename'" +msgid "'" msgstr "" -msgid "cannot delete Dll in package" +msgid "' needs to be a rxUi model" msgstr "" -msgid "'$parse' is no longer supported" +msgid "there must be at least one prediction in the model({}) block" msgstr "" -msgid "cannot update package model" +msgid ". Use `~` for predictions" msgstr "" -msgid "cannot figure out how to handle the model argument" +msgid "' needs to be a single endpoint model" msgstr "" -msgid "sensitivities do not make sense for models without ODEs" +msgid "' needs to be a (transformably) normal model" msgstr "" -msgid "Jacobians do not make sense for models without ODEs" +msgid "' needs to be a normal model" msgstr "" -msgid "Do not know how to add %s to Rxode2 solved object %s" +msgid "' needs to be a completely mu-referenced model (ie tcl+eta.cl)" msgstr "" -msgid "unknown model" +msgid "' residual parameters cannot depend on the model calculated parameters" msgstr "" -msgid "model" +msgid "' can only have population estimates" msgstr "" -msgid "cannot create Rxode2 model" +msgid "' needs to be a mixed effect model" msgstr "" -msgid "Rxode2 already building model, waiting for lock file removal" +msgid "' can only have random effects on ID" msgstr "" -msgid "lock file: \"%s\"" +msgid "generate defines" msgstr "" -msgid "." +msgid "Copy header to inst directory" msgstr "" -msgid "error building model on another thread" +msgid "generate rxResidualError and update documentation" msgstr "" -msgid "do not need to recompile, minimal change to model detected" +msgid "done" msgstr "" -msgid "unloaded all Rxode2 dlls before loading the current DLL" +msgid "generate rxReservedKeywords and update documentation" msgstr "" -msgid "something went wrong in compilation" +msgid "generate rxSyntaxFunctions and update documentation" msgstr "" -msgid "'removeJac' is no longer supported" +msgid "generate rxode2_control.h" msgstr "" -msgid "'removeSens' is no longer supported" +msgid "querying default rxode2 object contents" msgstr "" -msgid "simulation summaries must be between 0 and 1" +msgid "saved!" msgstr "" msgid "summarizing data..." msgstr "" -msgid "done" +msgid "rxode2 doesn't support '%s' translation for 'omega' translation" msgstr "" -msgid "Rxode2 doesn't support '%s' translation for 'omega' translation" +msgid "do not know how to handle type '%s'" msgstr "" -msgid "do not know how to handle type '%s'" +msgid "rxode2 only supports THETA[#] and ETA[#] numbers" msgstr "" -msgid "Rxode2 only supports THETA[#] and ETA[#] numbers" +msgid "cannot find lambda" msgstr "" -msgid "cannot supply both 'by' and 'length.out'" +msgid "cannot find additive standard deviation for '" msgstr "" -msgid "improper arguments to 'et'" +msgid "; this parameter could be estimated by another endpoint, to fix move outside of error expression." msgstr "" -msgid "when supplying vectors of 'time', 'amt' they need to be the same size" +msgid "for propF() or powF(), f must be part of the model and not estimated" msgstr "" -msgid "only a single evid 'evid' can be specified ('%s')" +msgid "cannot find proportional standard deviation" msgstr "" -msgid "', '" +msgid "cannot find power standard deviation" msgstr "" -msgid "only a single compartment 'cmt' can be specified ('%s')" +msgid "cannot find exponent of power expression" msgstr "" -msgid "only a single rate 'rate' can be specified ('%s')" +msgid "cannot find additive standard deviation" msgstr "" -msgid "only a single duration 'dur' can be specified ('%s')" +msgid "cannot find pow standard deviation" msgstr "" -msgid "'nsim' is ignored when simulating event tables" +msgid "cannot find pow exponent" msgstr "" -msgid "requires package 'units'" +msgid "t distribution needs a proper degrees of freedom specified" msgstr "" -msgid "the only valid number defining a unit is '1', signifying a unitless unit" +msgid "last element in ordinal simulation of c(p1=0, p2=0.5, ...) must be a number, not a named number" msgstr "" -msgid "clearing both amount and time units\nfor more precise control use 'et(amountUnits=\"\")' or 'et(timeUnits=\"\")'" +msgid "names for ordinal simulation incorrect" msgstr "" -msgid "'deparse.level' not used with Rxode2 event tables" +msgid "not enough categories to estimate" msgstr "" -msgid "'length.out' makes no sense with event tables" +msgid "uiModel must be a evaluated UI model by rxode2(modelFunction) or modelFunction()" msgstr "" -msgid "'each' makes no sense with event tables" +msgid "old transform not in the proper format" msgstr "" -msgid "'evid' is unitless" +msgid "you cannot combine 't' and 'cauchy' distributions" msgstr "" -msgid "there are no individuals left to solve in %s data" +msgid "you cannot combine 't' and 'dnorm' distributions" msgstr "" -msgid "'ID' missing in '%s' dataset\nindividual parameters are assumed to have the same order as the event dataset" +msgid "you cannot combine 'dnorm' and 'cauchy' distributions" msgstr "" -msgid "unable to detect 'ID' correctly in '%s' dataset\nindividual parameters are assumed to have the same order as the dataset" +msgid "you cannot combine 'cauchy' and 'dnorm' distributions" msgstr "" -msgid "dates can only be specified by one of: 'DATE', 'DAT1', 'DAT2', 'DAT3' / 'TIME'" +msgid "the left handed side of the error expression (function: '" msgstr "" -msgid "dates formatted as MONTH-DAY or DAY alone are not supported in this conversion" +msgid "') can only be functions with 'linCmt' or 'll'" msgstr "" -msgid "date/time format was not correctly specified" +msgid "endpoint parameter(s) missing, duplicated, or defined with '~':" msgstr "" -msgid "cannot figure out numeric time" +msgid "," +msgstr "" + +msgid "a rxode2 ui model must have more than error definition(s) in the `model({})` block" +msgstr "" + +msgid "install.packages('shiny') to use genShinyApp.template()" msgstr "" msgid "need 'amt' aesthetic" @@ -193,52 +199,166 @@ msgstr "" msgid "stat_cens requires the following aesthetics: upper, lower or cens (and optionally limit)" msgstr "" +msgid "unknown variable expression:" +msgstr "" + +msgid "rxode2 does not know how to handle this modelExtract object" +msgstr "" + +msgid "out" +msgstr "" + +msgid "could not build model for inclusion in package" +msgstr "" + msgid "'package' needs to be specified" msgstr "" -msgid "'log=\"%s\"' not supported" +msgid "some etas defaulted to non-mu referenced, possible parsing error:" msgstr "" -msgid "needs units" +msgid "as a work-around try putting the mu-referenced expression on a simple line" msgstr "" -msgid "needs \"ggplot2\" 3.3.0" +msgid "currently do not support IOV etc" msgstr "" -msgid "this is only used in 'data.table'" +msgid "syntax/parsing errors (see above) and additionally:" msgstr "" -msgid "'rxIndLinState' list element '%s' must be a unnamed character vector" +msgid "syntax/parsing errors:" msgstr "" -msgid "'%s' is from '%s' and cannot be used in this context" +msgid "syntax/parsing errors, see above" msgstr "" -msgid "specified %s initial conditions when there are only %s states" +msgid "cannot find parameter '" msgstr "" -msgid "only one 'initCondition=' supported" +msgid "trying to fix '" msgstr "" -msgid "this was not generated from nlmixr, loading into symengine" +msgid "', but already fixed" msgstr "" -msgid "cannot identify parameters for sensitivity analysis\n with nlmixr an 'eta' initial estimate must use '~'" +msgid "trying to unfix '" msgstr "" -msgid "none of the predictions depend on 'ETA'" +msgid "', but already unfixed" msgstr "" -msgid "some of the predictions do not depend on 'ETA'" +msgid "piping for '" msgstr "" -msgid "parameters:" +msgid "' failed, the estimate should only be 1 value" msgstr "" -msgid "," +msgid "the '" +msgstr "" + +msgid "' piping lower, estimate, and/or upper estimate is in the wrong order" +msgstr "" + +msgid "the new label for '" +msgstr "" + +msgid "' must be a character string" +msgstr "" + +msgid "'append' must be NULL, logical, numeric, or character" +msgstr "" + +msgid "Cannot find parameter '" +msgstr "" + +msgid "parameter '" +msgstr "" + +msgid "' set to be moved after itself, no change in order made" +msgstr "" + +msgid "only theta parameters can be moved. '" +msgstr "" + +msgid "' is not a theta parameter" +msgstr "" + +msgid "a NULL value for '" +msgstr "" + +msgid "' piping does not make sense" +msgstr "" + +msgid "to assign a new label, use '%s <- label(\"%s\")'" +msgstr "" + +msgid "invalid expr for ini() modification" +msgstr "" + +msgid "cannot figure out what to do with the ini({}) function" msgstr "" -msgid "cannot figure out PK parameters to convert" +msgid "cannot find '" +msgstr "" + +msgid "' in lhs model, cannot append" +msgstr "" + +msgid "the variable '" +msgstr "" + +msgid "' must be in the defined the model for piping this: '" +msgstr "" + +msgid "with single endpoint model prediction '" +msgstr "" + +msgid "' is changed to '" +msgstr "" + +msgid "the error '" +msgstr "" + +msgid "' is not in the multiple-endpoint model and cannot be modified" +msgstr "" + +msgid "do not know where to put label" +msgstr "" + +msgid "cannot figure out what to do with the unnamed vector" +msgstr "" + +msgid "cannot figure out what to do with the unnamed list" +msgstr "" + +msgid "one of the list items supplied to piping is non-numeric" +msgstr "" + +msgid "vectors and list need to be named numeric expression" +msgstr "" + +msgid "the `sim` endpoints requested in the plot do not exist in the solved object:" +msgstr "" + +msgid "some `sim` requested items do not exist in the solved object and were ignored:" +msgstr "" + +msgid "sim." +msgstr "" + +msgid "the items requested in the plot do not exist in the solved object:" +msgstr "" + +msgid "some requested items do not exist in the solved object and were ignored:" +msgstr "" + +msgid "needs \"ggplot2\" 3.3.0" +msgstr "" + +msgid "'rxIndLinState' list element '%s' must be a unnamed character vector" +msgstr "" + +msgid "'%s' is from '%s' and cannot be used in this context" msgstr "" msgid "unsupported lhs in optimize expression" @@ -277,28 +397,22 @@ msgstr "" msgid "calculate symbolic inverse: t(chol.mat) %*% chol.mat ..." msgstr "" -msgid "initial 'omega' matrix inverse is non-positive definite" -msgstr "" - -msgid "zero matrix" -msgstr "" - -msgid "================================================================================" +msgid "." msgstr "" -msgid "Rxode2 compiled with dparser '" +msgid "initial 'omega' matrix inverse is non-positive definite" msgstr "" -msgid "' but dparser '" +msgid "zero matrix" msgstr "" -msgid "dparser" +msgid "object is wrong type for `rxUiGet`" msgstr "" -msgid "' is loaded\nRecompile Rxode2 with the this version of dparser" +msgid "================================================================================" msgstr "" -msgid "Rxode2 compiled with PreciseSums '" +msgid "rxode2 compiled with PreciseSums '" msgstr "" msgid "' but PreciseSums '" @@ -307,13 +421,16 @@ msgstr "" msgid "PreciseSums" msgstr "" -msgid "' is loaded\nRecompile Rxode2 with the this version of PreciseSums" +msgid "' is loaded\nRecompile rxode2 with the this version of PreciseSums" +msgstr "" + +msgid "rxode2 compiled with rxode2parse with a different solving structure" msgstr "" -msgid "Rtools is not set up correctly!\n\nYou need a working Rtools installation for Rxode2 to compile models" +msgid "can try: install.packages('rxode2', type='source')" msgstr "" -msgid "Rxode2" +msgid "rxode2" msgstr "" msgid "using" @@ -328,7 +445,7 @@ msgstr "" msgid "========================================" msgstr "" -msgid "Rxode2 has not detected OpenMP support and will run in single-threaded mode" +msgid "rxode2 has not detected OpenMP support and will run in single-threaded mode" msgstr "" msgid "sysname" @@ -346,7 +463,94 @@ msgstr "" msgid "; To get best performance enable OpenMP" msgstr "" -msgid "detected new version of Rxode2, cleaning cache" +msgid "detected new version of rxode2, cleaning cache" +msgstr "" + +msgid "'modName' has to be a single length character" +msgstr "" + +msgid "'extraC' needs to point to a file that exists and is readable" +msgstr "" + +msgid "'collapseModel' needs to be logical" +msgstr "" + +msgid "'indLin' needs to be logical" +msgstr "" + +msgid "'debug' needs to be logical" +msgstr "" + +msgid "'package' needs to a single character for the package name" +msgstr "" + +msgid "with packages 'modName' is required" +msgstr "" + +msgid "must specify exactly one of 'model' or 'filename'" +msgstr "" + +msgid "model functions can only be called with one argument" +msgstr "" + +msgid "cannot delete Dll in package" +msgstr "" + +msgid "'$parse' is no longer supported" +msgstr "" + +msgid "cannot update package model" +msgstr "" + +msgid "cannot figure out how to handle the model argument" +msgstr "" + +msgid "sensitivities do not make sense for models without ODEs" +msgstr "" + +msgid "Jacobians do not make sense for models without ODEs" +msgstr "" + +msgid "Do not know how to add %s to rxode2 solved object %s" +msgstr "" + +msgid "unknown model" +msgstr "" + +msgid "model" +msgstr "" + +msgid "cannot create rxode2 model" +msgstr "" + +msgid "cannot seem to remove '" +msgstr "" + +msgid "rxode2 already building model, waiting for lock file removal" +msgstr "" + +msgid "lock file: \"%s\"" +msgstr "" + +msgid "error building model on another thread" +msgstr "" + +msgid "do not need to recompile, minimal change to model detected" +msgstr "" + +msgid "unloaded all rxode2 dlls before loading the current DLL" +msgstr "" + +msgid "something went wrong in compilation" +msgstr "" + +msgid "'removeJac' is no longer supported" +msgstr "" + +msgid "'removeSens' is no longer supported" +msgstr "" + +msgid "need an rxode2-type object to extract model variables" msgstr "" msgid "'df' must be greater than 0" @@ -361,10 +565,7 @@ msgstr "" msgid "'shape' cannot be 0" msgstr "" -msgid "'rate'/'scale' cannot be 0" -msgstr "" - -msgid "specify 'rate' or 'scale' but not both" +msgid "'rate' cannot be 0" msgstr "" msgid "'df1' cannot be 0" @@ -373,9 +574,6 @@ msgstr "" msgid "'df2' cannot be 0" msgstr "" -msgid "'rate' cannot be 0" -msgstr "" - msgid "'df' cannot be 0" msgstr "" @@ -385,19 +583,25 @@ msgstr "" msgid "when 'gamma' is not 1, 'tmax' cannot be infinite" msgstr "" -msgid "duplicate arguments do not make sense" +msgid "'transitAbs' is no longer supported, use 'evid=7' instead" +msgstr "" + +msgid "unused argument:" msgstr "" msgid "covariates can no longer be specified by 'covs' include them in the event dataset" msgstr "" +msgid "'maxSS' must be larger than 'minSS'" +msgstr "" + msgid "events can be pipeline or solving arguments not both" msgstr "" -msgid "need an Rxode2 compiled model as the start of the pipeline" +msgid "need an rxode2 compiled model as the start of the pipeline" msgstr "" -msgid "need an Rxode2 events as a part of the pipeline" +msgid "need an rxode2 events as a part of the pipeline" msgstr "" msgid "'events' in pipeline AND in solving arguments, please provide just one" @@ -409,12 +613,18 @@ msgstr "" msgid "'inits' in pipeline AND in solving arguments, please provide just one" msgstr "" +msgid "duplicate arguments do not make sense" +msgstr "" + msgid "covariates can no longer be specified by 'covs'\n include them in the event dataset\n\nindividual covariates: Can be specified by a 'iCov' dataset\n each each individual covariate has a value\n\ntime varying covariates: modify input event data-frame or\n 'eventTable' to include covariates(https://tinyurl.com/y52wfc2y)\n\nEach approach needs the covariates named to match the variable in the model" msgstr "" msgid "'iCov' has information contained in parameters/event data\nduplicate columns: '%s'" msgstr "" +msgid "', '" +msgstr "" + msgid "'theta' cannot be a data.frame" msgstr "" @@ -457,10 +667,19 @@ msgstr "" msgid "'iCov' must be an input dataset" msgstr "" +msgid "Unsupported type of model trying to be solved" +msgstr "" + +msgid "'sensCmt' must be lower than the number of compartments 'ncmt'" +msgstr "" + +msgid "'rxControl' must be a rxode2 control options list" +msgstr "" + msgid "name argument must be a length-one character vector" msgstr "" -msgid "a new function requires a C function so it can be used in Rxode2" +msgid "a new function requires a C function so it can be used in rxode2" msgstr "" msgid "already defined user function '" @@ -475,12 +694,6 @@ msgstr "" msgid "' to remove" msgstr "" -msgid "cannot take a second derivative" -msgstr "" - -msgid "bad 'linCmtB' derivative" -msgstr "" - msgid "derivatives must be a list of functions with at least 1 element" msgstr "" @@ -526,7 +739,7 @@ msgstr "" msgid "'transit' can only take 2-3 arguments" msgstr "" -msgid "'%s' only acceps 1 argument" +msgid "'%s' only accepts 1 argument" msgstr "" msgid "'%s' only acceps 2 arguments" @@ -547,7 +760,13 @@ msgstr "" msgid "'expit' requires 1-3 arguments" msgstr "" -msgid "function '%s' or its derivatives are not supported in Rxode2" +msgid "function '%s' or its derivatives are not supported in rxode2" +msgstr "" + +msgid "R user function '%s' has variable number of arguments with'...' and is not supported in rxode2" +msgstr "" + +msgid "user function '%s' requires %d arguments (supplied %d)" msgstr "" msgid "[...] expressions not supported" @@ -556,6 +775,9 @@ msgstr "" msgid "'polygamma' takes 2 arguments" msgstr "" +msgid "'%s' only acceps 1 argument" +msgstr "" + msgid "'%s' takes %s arguments" msgstr "" @@ -571,7 +793,7 @@ msgstr "" msgid "' using numerical differences instead" msgstr "" -msgid "Rxode2/symengine does not know how to take a derivative of '%s'" +msgid "rxode2/symengine does not know how to take a derivative of '%s'" msgstr "" msgid "'Derivative' conversion only takes one function and one argument" @@ -580,10 +802,10 @@ msgstr "" msgid "() takes 0-1 arguments" msgstr "" -msgid "'%s' not supported in symengine->Rxode2" +msgid "'%s' not supported in symengine->rxode2" msgstr "" -msgid "Rxode2 doesn't support '%s' translation for 'Omega' translation" +msgid "rxode2 doesn't support '%s' translation for 'Omega' translation" msgstr "" msgid "do not know how to handle type" @@ -655,7 +877,82 @@ msgstr "" msgid "'." msgstr "" -msgid "package \"%s\" needed for this function to work" +msgid "cannot figure out what to do with model assignment" +msgstr "" + +msgid "cannot figure out what to do with ini assignment" +msgstr "" + +msgid "wrong input for 'x' in .bodySetRxUi" +msgstr "" + +msgid "cannot figure out how to assign this to the with rxode()<-" +msgstr "" + +msgid "do not know how to assign this" +msgstr "" + +msgid "the first model does not have variables that are used by the second model" +msgstr "" + +msgid "there needs to be at least one population parameter in 'model1'" +msgstr "" + +msgid "cannot remove from compressed 'rxUi'\nfirst decompress with `rxode2::rxUiDecompress()'" +msgstr "" + +msgid "control must be a list-like object" +msgstr "" + +msgid "cannot assign value to compressed 'rxUi'\nfirst decompress with `rxode2::rxUiDecompress()'" +msgstr "" + +msgid "to rename a variable you need to use 'newName=oldName' syntax" +msgstr "" + +msgid "to rename a variable you need to use '" +msgstr "" + +msgid "=oldName' syntax" +msgstr "" + +msgid "=oldName' syntax, where oldName is a variable" +msgstr "" + +msgid "the new variable '" +msgstr "" + +msgid "' is already present in the model; cannot replace '" +msgstr "" + +msgid "' with '" +msgstr "" + +msgid "the old variable '" +msgstr "" + +msgid "' is not present in the model and cannot be renamed to '" +msgstr "" + +msgid "unknown expression" +msgstr "" + +msgid "rxode2 model function can only have one 'ini({})' block" +msgstr "" + +msgid "rxode2 model function requires one 'model({})' block" +msgstr "" + +msgid "'model({})' is not on the last line of the function, rearranging; function cannot be called directly to produce model object" +msgstr "" + +msgid "the parameter(s) '" +msgstr "" + +msgid "' cannot be an error and between subject variability" +msgstr "" + +msgid "rxode2 does not know how to handle this model statement" msgstr "" msgid "'wd' is depreciated" diff --git a/po/R-zh_CN.po b/po/R-zh_CN.po index a8bd303d7..ff8ce0742 100644 --- a/po/R-zh_CN.po +++ b/po/R-zh_CN.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: rxode2 1.1.0\n" -"POT-Creation-Date: 2021-05-26 10:39\n" +"POT-Creation-Date: 2023-10-30 08:03\n" "PO-Revision-Date: 2023-07-03 00:00\n" "Last-Translator: FuYongchao <3212418315@qq.com>\n" "Language-Team: FuYongchao <3212418315@qq.com>\n" @@ -10,429 +10,661 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" +#, fuzzy +msgid "unsupported expression for ini({}) block" +msgstr "" -msgid "rxode2 requires 'rtools' for custom models\n" -"Please download from http://cran.r-project.org/bin/windows/Rtools/,\n" -"install and restart your R session before proceeding" -msgstr "rxode2的自定义模型“rtools”\n" -"请从http://cran.r-project.org/bin/windows/Rtools/下载rtools,\n" -"在完成rtools安装与重新启动R会话后,继续之前流程" - -msgid "'modName' has to be a single length character" -msgstr "“modName”必须是字符串类型的标量或单个长度的字符型向量" +#, fuzzy +msgid "unsupported expression of ini({}) block" +msgstr "" -msgid "'extraC' needs to point to a file that exists and is readable" -msgstr "“extraC”需要指向一个存在并且可读的文件" +#, fuzzy +msgid "do not know how to convert this to an `ini` expression" +msgstr "\"(errors)\"/\"(PRED)\"" -msgid "'collapseModel' needs to be logical" -msgstr "“collapseModel”需要合乎逻辑" +msgid "error converting character vector to model({}) expression" +msgstr "" -msgid "'indLin' needs to be logical" -msgstr "“indLin”需要合乎逻辑" +#, fuzzy +msgid "unsupported expression of model({}) block" +msgstr "" -msgid "'debug' needs to be logical" -msgstr "“调试(debug)”需要合乎逻辑" +#, fuzzy +msgid "do not know how to convert this to an `model` expression" +msgstr "" -msgid "'package' needs to a single character for the package name" -msgstr "“添加包”需要一个字符作为添加包的名称" +msgid "cannot convert to rxUi object" +msgstr "" -msgid "with packages 'modName' is required" -msgstr "“modName”添加包是必需的" +msgid "could not convert to rxUi object" +msgstr "" -msgid "must specify exactly one of 'model' or 'filename'" -msgstr "必须准确指定“model”(模型)或“filename”(文件名)之一" +#, fuzzy +msgid "'" +msgstr "'." -msgid "cannot delete Dll in package" -msgstr "无法删除添加包中的 Dll" +#, fuzzy +msgid "' needs to be a rxUi model" +msgstr "(debug)" -msgid "'$parse' is no longer supported" -msgstr "“$parse”不再被支持" +msgid "there must be at least one prediction in the model({}) block" +msgstr "" -msgid "cannot update package model" -msgstr "无法更新添加包模型" +msgid ". Use `~` for predictions" +msgstr "" -msgid "cannot figure out how to handle the model argument" -msgstr "无法弄清楚如何处理模型参数" +msgid "' needs to be a single endpoint model" +msgstr "" -msgid "sensitivities do not make sense for models without ODEs" -msgstr "灵敏度对于没有常微分方程的模型没有意义" +msgid "' needs to be a (transformably) normal model" +msgstr "" -msgid "Jacobians do not make sense for models without ODEs" -msgstr "雅可比算法对于没有常微分方程的模型没有意义" +#, fuzzy +msgid "' needs to be a normal model" +msgstr "(debug)" -msgid "Do not know how to add %s to rxode2 solved object %s" -msgstr "不知道如何将 %s 添加到 rxode2 已求解对象 %s" +msgid "' needs to be a completely mu-referenced model (ie tcl+eta.cl)" +msgstr "" -msgid "unknown model" -msgstr "未知的模型" +msgid "' residual parameters cannot depend on the model calculated parameters" +msgstr "" -msgid "model" -msgstr "模型" +msgid "' can only have population estimates" +msgstr "" -msgid "cannot create rxode2 model" -msgstr "无法创建 rxode2 模型" +msgid "' needs to be a mixed effect model" +msgstr "" -msgid "rxode2 already building model, waiting for lock file removal" -msgstr "rxode2 已经构建模型,正在等待锁定文件删除" +msgid "' can only have random effects on ID" +msgstr "" -msgid "lock file: \"%s\"" -msgstr "锁定文件:“%s”" +msgid "generate defines" +msgstr "" -msgid "." -msgstr "." +msgid "Copy header to inst directory" +msgstr "" -msgid "error building model on another thread" -msgstr "在另一个线程上构建模型时出错" +msgid "generate rxResidualError and update documentation" +msgstr "" -msgid "do not need to recompile, minimal change to model detected" -msgstr "无需重新编译,检测到对模型的最小更改" +msgid "done" +msgstr "" -msgid "unloaded all rxode2 dlls before loading the current DLL" -msgstr "在加载当前 DLL 之前卸载了所有 rxode2 dll" +msgid "generate rxReservedKeywords and update documentation" +msgstr "" -msgid "something went wrong in compilation" -msgstr "编译时出错" +msgid "generate rxSyntaxFunctions and update documentation" +msgstr "" -msgid "'removeJac' is no longer supported" -msgstr "“removeJac”不再被支持" +msgid "generate rxode2_control.h" +msgstr "" -msgid "'removeSens' is no longer supported" -msgstr "“removeSens”不再被支持" +msgid "querying default rxode2 object contents" +msgstr "" -msgid "simulation summaries must be between 0 and 1" -msgstr "模拟摘要必须介于 0 和 1 之间" +msgid "saved!" +msgstr "" msgid "summarizing data..." -msgstr "汇总数据..." - -msgid "done" -msgstr "已做完" +msgstr "..." msgid "rxode2 doesn't support '%s' translation for 'omega' translation" -msgstr "rxode2 不支持对的'omega'转换的'%s'转换" +msgstr "rxode2 'omega''%s'" msgid "do not know how to handle type '%s'" -msgstr "不知道如何处理类型 '%s'" +msgstr " '%s'" msgid "rxode2 only supports THETA[#] and ETA[#] numbers" -msgstr "rxode2 仅支持 THETA[#] 和 ETA[#] 数字" +msgstr "rxode2 THETA[#] ETA[#] " + +msgid "cannot find lambda" +msgstr "" + +msgid "cannot find additive standard deviation for '" +msgstr "" + +msgid "" +"; this parameter could be estimated by another endpoint, to fix move outside " +"of error expression." +msgstr "" -msgid "cannot supply both 'by' and 'length.out'" -msgstr "不能同时提供“by”和“length.out”" +msgid "for propF() or powF(), f must be part of the model and not estimated" +msgstr "" -msgid "improper arguments to 'et'" -msgstr "对“et”的不当参数" +msgid "cannot find proportional standard deviation" +msgstr "" -msgid "when supplying vectors of 'time', 'amt' they need to be the same size" -msgstr "当提供“time”、“amt”的向量时,它们需要具有相同的大小" +msgid "cannot find power standard deviation" +msgstr "" -msgid "only a single evid 'evid' can be specified ('%s')" -msgstr "只有一个 evid 'evid'能用于描述('%s')" +msgid "cannot find exponent of power expression" +msgstr "" -msgid "', '" -msgstr "', '" +msgid "cannot find additive standard deviation" +msgstr "" -msgid "only a single compartment 'cmt' can be specified ('%s')" -msgstr "只有单个房室“cmt”能用于描述(“%s”)" +msgid "cannot find pow standard deviation" +msgstr "" -msgid "only a single rate 'rate' can be specified ('%s')" -msgstr "只有单个速率“rate”能用于描述(“%s”)" +msgid "cannot find pow exponent" +msgstr "" -msgid "only a single duration 'dur' can be specified ('%s')" -msgstr "只有单个持续时间“dur”能用于描述(“%s”)" +msgid "t distribution needs a proper degrees of freedom specified" +msgstr "" -msgid "'nsim' is ignored when simulating event tables" -msgstr "模拟事件表时“nsim”被忽略" +msgid "" +"last element in ordinal simulation of c(p1=0, p2=0.5, ...) must be a number, " +"not a named number" +msgstr "" -msgid "requires package 'units'" -msgstr "需要“unites”添加包" +msgid "names for ordinal simulation incorrect" +msgstr "" -msgid "the only valid number defining a unit is '1', signifying a unitless unit" -msgstr "唯一有效的作为单位的数字是“1”,表示单位是没有单位" +msgid "not enough categories to estimate" +msgstr "" -msgid "clearing both amount and time units\n" -"for more precise control use 'et(amountUnits=\"\")' or 'et(timeUnits=\"\")'" -msgstr "清除\"amout(药量)\"和\"time(时间)\"的单位\n" -"要进行更精确的控制,请使用“et(amountUnits=\"\")”或“et(timeUnits=\"\")”" +msgid "" +"uiModel must be a evaluated UI model by rxode2(modelFunction) or " +"modelFunction()" +msgstr "" -msgid "'deparse.level' not used with rxode2 event tables" -msgstr "“deparse.level”未与 rxode2 事件表一起使用" +msgid "old transform not in the proper format" +msgstr "" -msgid "'length.out' makes no sense with event tables" -msgstr "“length.out”对事件表毫无意义" +msgid "you cannot combine 't' and 'cauchy' distributions" +msgstr "" -msgid "'each' makes no sense with event tables" -msgstr "“each”对于事件表毫无意义" +msgid "you cannot combine 't' and 'dnorm' distributions" +msgstr "" -msgid "'evid' is unitless" -msgstr "“evid”是无单位的" +msgid "you cannot combine 'dnorm' and 'cauchy' distributions" +msgstr "" -msgid "there are no individuals left to solve in %s data" -msgstr "%s 数据中没有需要求解的个体" +msgid "you cannot combine 'cauchy' and 'dnorm' distributions" +msgstr "" -msgid "'ID' missing in '%s' dataset\n" -"individual parameters are assumed to have the same order as the event dataset" -msgstr "“%s”数据集中缺少“ID”\n" -"假定各个参数的顺序与事件数据集的顺序相同" +msgid "the left handed side of the error expression (function: '" +msgstr "" -msgid "unable to detect 'ID' correctly in '%s' dataset\n" -"individual parameters are assumed to have the same order as the dataset" -msgstr "无法正确检测“%s”数据集中的“ID”\n" -"假定各个参数的顺序与数据集相同" +msgid "') can only be functions with 'linCmt' or 'll'" +msgstr "" -msgid "dates can only be specified by one of: 'DATE', 'DAT1', 'DAT2', 'DAT3' / 'TIME'" -msgstr "日期只能由以下之一指定:“DATE”、“DAT1”、“DAT2”、“DAT3”/“TIME”" +msgid "endpoint parameter(s) missing, duplicated, or defined with '~':" +msgstr "" -msgid "dates formatted as MONTH-DAY or DAY alone are not supported in this conversion" -msgstr "此转换不支持日期格式化为月-日或仅日" +msgid "," +msgstr "," -msgid "date/time format was not correctly specified" -msgstr "未正确指定日期/时间格式" +msgid "" +"a rxode2 ui model must have more than error definition(s) in the `model({})` " +"block" +msgstr "" -msgid "cannot figure out numeric time" -msgstr "无法计算数字时间" +msgid "install.packages('shiny') to use genShinyApp.template()" +msgstr "" msgid "need 'amt' aesthetic" -msgstr "需要“amt”的美学" +msgstr "amt" msgid "need 'x' aesthetic" -msgstr "需要“x”的美学" +msgstr "x" msgid "stat_cens cannot have lower aesthetic with cens aesthetic" -msgstr "stat_cens有cens的美学不允许存在lower的美学" +msgstr "stat_censcenslower" -msgid "stat_cens requires the following aesthetics: upper, lower or cens (and optionally limit)" -msgstr "stat_cens需要以下的美学:\"上限(upper)\"、\"下限(lower)\"或\"删失(cens)\"(以及可选的\"定量限(limit)\")" +msgid "" +"stat_cens requires the following aesthetics: upper, lower or cens (and " +"optionally limit)" +msgstr "stat_cens\"(upper)\"\"(lower)\"\"(cens)\"\"(limit)\"" + +#, fuzzy +msgid "unknown variable expression:" +msgstr "" + +#, fuzzy +msgid "rxode2 does not know how to handle this modelExtract object" +msgstr "\"(errors)\"/\"(PRED)\"" + +msgid "out" +msgstr "" + +msgid "could not build model for inclusion in package" +msgstr "" msgid "'package' needs to be specified" -msgstr "需要指定“package”(添加包)" +msgstr "package()" + +msgid "some etas defaulted to non-mu referenced, possible parsing error:" +msgstr "" + +msgid "" +"as a work-around try putting the mu-referenced expression on a simple line" +msgstr "" -msgid "'log=\"%s\"' not supported" -msgstr "“log=”%s“'不被支持" +msgid "currently do not support IOV etc" +msgstr "" -msgid "needs units" -msgstr "需要单位" +msgid "syntax/parsing errors (see above) and additionally:" +msgstr "" -msgid "needs \"ggplot2\" 3.3.0" -msgstr "需要“ggplot2” 3.3.0" +msgid "syntax/parsing errors:" +msgstr "" -msgid "this is only used in 'data.table'" -msgstr "这仅在“data.table”中使用" +msgid "syntax/parsing errors, see above" +msgstr "" -msgid "'rxIndLinState' list element '%s' must be a unnamed character vector" -msgstr "'rxIndLinState' 列表元素 '%s' 必须是未命名的字符向量" +#, fuzzy +msgid "cannot find parameter '" +msgstr "PK" -msgid "'%s' is from '%s' and cannot be used in this context" -msgstr "“%s”来自“%s”,不能在此上下文中使用" +msgid "trying to fix '" +msgstr "" -msgid "specified %s initial conditions when there are only %s states" -msgstr "当这些是仅%s状态时,描述 %s 初始条件" +msgid "', but already fixed" +msgstr "" -msgid "only one 'initCondition=' supported" -msgstr "仅支持一个“initCondition=”" +msgid "trying to unfix '" +msgstr "" -msgid "this was not generated from nlmixr, loading into symengine" -msgstr "这不是由nlmixr生成的,加载到Symengine中" +msgid "', but already unfixed" +msgstr "" -msgid "cannot identify parameters for sensitivity analysis\n" -" with nlmixr an 'eta' initial estimate must use '~'" -msgstr "无法识别灵敏度分析的参数\n" -" 使用nlmixr时,“eta”初始估计必须使用“~”" +msgid "piping for '" +msgstr "" + +msgid "' failed, the estimate should only be 1 value" +msgstr "" -msgid "none of the predictions depend on 'ETA'" -msgstr "没有一个预测依赖于“ETA”" +msgid "the '" +msgstr "" -msgid "some of the predictions do not depend on 'ETA'" -msgstr "一些预测不依赖于“ETA”" +msgid "' piping lower, estimate, and/or upper estimate is in the wrong order" +msgstr "" -msgid "parameters:" -msgstr "参数:" +msgid "the new label for '" +msgstr "" -msgid "," -msgstr "," +#, fuzzy +msgid "' must be a character string" +msgstr "df 0" + +msgid "'append' must be NULL, logical, numeric, or character" +msgstr "" + +msgid "Cannot find parameter '" +msgstr "" + +#, fuzzy +msgid "parameter '" +msgstr ":" + +msgid "' set to be moved after itself, no change in order made" +msgstr "" + +msgid "only theta parameters can be moved. '" +msgstr "" + +msgid "' is not a theta parameter" +msgstr "" + +msgid "a NULL value for '" +msgstr "" + +#, fuzzy +msgid "' piping does not make sense" +msgstr "\"duplicate()\"" + +msgid "to assign a new label, use '%s <- label(\"%s\")'" +msgstr "" + +msgid "invalid expr for ini() modification" +msgstr "" + +#, fuzzy +msgid "cannot figure out what to do with the ini({}) function" +msgstr "" + +msgid "cannot find '" +msgstr "" + +msgid "' in lhs model, cannot append" +msgstr "" + +msgid "the variable '" +msgstr "" + +msgid "' must be in the defined the model for piping this: '" +msgstr "" + +msgid "with single endpoint model prediction '" +msgstr "" + +msgid "' is changed to '" +msgstr "" + +msgid "the error '" +msgstr "" + +msgid "' is not in the multiple-endpoint model and cannot be modified" +msgstr "" + +#, fuzzy +msgid "do not know where to put label" +msgstr "" + +#, fuzzy +msgid "cannot figure out what to do with the unnamed vector" +msgstr "" + +#, fuzzy +msgid "cannot figure out what to do with the unnamed list" +msgstr "" -msgid "cannot figure out PK parameters to convert" -msgstr "无法找出要转换的PK参数" +msgid "one of the list items supplied to piping is non-numeric" +msgstr "" + +msgid "vectors and list need to be named numeric expression" +msgstr "" + +msgid "" +"the `sim` endpoints requested in the plot do not exist in the solved object:" +msgstr "" + +msgid "" +"some `sim` requested items do not exist in the solved object and were " +"ignored:" +msgstr "" + +msgid "sim." +msgstr "" + +msgid "the items requested in the plot do not exist in the solved object:" +msgstr "" + +msgid "" +"some requested items do not exist in the solved object and were ignored:" +msgstr "" + +msgid "needs \"ggplot2\" 3.3.0" +msgstr "ggplot2 3.3.0" + +msgid "'rxIndLinState' list element '%s' must be a unnamed character vector" +msgstr "'rxIndLinState' '%s' " + +msgid "'%s' is from '%s' and cannot be used in this context" +msgstr "%s%s" msgid "unsupported lhs in optimize expression" -msgstr "优化表达式中不支持lhs" +msgstr "lhs" msgid "cannot divide by zero" -msgstr "不能除以零" +msgstr "" msgid "error optimizing expression, try 'optExpression=FALSE'" -msgstr "优化表达式时出错,请尝试“optExpression=FALSE”" +msgstr "optExpression=FALSE" msgid "'iCov' in a pipline is no longer supported" -msgstr "管道中的“iCov”不再被支持" +msgstr "iCov" msgid "unknown arguments in 'rxParams'" -msgstr "在“rxParams”中由未知的参数" +msgstr "rxParams" -msgid "unknown arguments in 'rxParams': %s\n" +msgid "" +"unknown arguments in 'rxParams': %s\n" "try piping to 'rxSolve'" -msgstr "在“rxParams”中由未知的参数: %s\n" -"尝试管道连接到“rxSolve”" +msgstr "" +"rxParams %s\n" +"rxSolve" msgid "unsupported expression" -msgstr "不支持的表达式" +msgstr "" msgid "using the first solved parameters for rxShiny" -msgstr "使用 rxShiny 的第一个已求解参数" +msgstr " rxShiny " msgid "this has to be a matrix of all 1s or 0s" -msgstr "这必须是一个全是1或0的矩阵" +msgstr "10" msgid "diagonal elements must be non-zero" -msgstr "对角线元素必须不为零" +msgstr "" msgid "diagonal form:" -msgstr "对角线形式:" +msgstr ":" msgid "calculate symbolic inverse: t(chol.mat) %*% chol.mat ..." -msgstr "计算符号逆: t(chol.mat) %*% chol.mat ..." +msgstr " t(chol.mat) %*% chol.mat ..." + +msgid "." +msgstr "." msgid "initial 'omega' matrix inverse is non-positive definite" -msgstr "初始“omega”矩阵逆是非正定的" +msgstr "omega" msgid "zero matrix" -msgstr "零矩阵" +msgstr "" + +msgid "object is wrong type for `rxUiGet`" +msgstr "" msgid "================================================================================" msgstr "================================================================================" -msgid "rxode2 compiled with dparser '" -msgstr "rxode2编译自dparser '" - -msgid "' but dparser '" -msgstr "'但是dparser'" - -msgid "dparser" -msgstr "dparser" - -msgid "' is loaded\n" -"Recompile rxode2 with the this version of dparser" -msgstr "' 已加载\n" -"使用此版本的 dparser 重新编译 rxode2" - msgid "rxode2 compiled with PreciseSums '" -msgstr "rxode2编译自PrecisionSums '" +msgstr "rxode2PrecisionSums '" msgid "' but PreciseSums '" -msgstr "'但是PreciseSums'" +msgstr "'PreciseSums'" msgid "PreciseSums" msgstr "PreciseSums" -msgid "' is loaded\n" +msgid "" +"' is loaded\n" "Recompile rxode2 with the this version of PreciseSums" -msgstr "' 已加载\n" -"使用此版本的 PrecisionSums 重新编译 rxode2" +msgstr "" +"' \n" +" PrecisionSums rxode2" -msgid "Rtools is not set up correctly!\n" -"\n" -"You need a working Rtools installation for rxode2 to compile models" -msgstr "Rtools设置不正确!\n" -"\n" -"您需要一个有效的 Rtools 安装来编译模型" +msgid "rxode2 compiled with rxode2parse with a different solving structure" +msgstr "" + +msgid "can try: install.packages('rxode2', type='source')" +msgstr "" msgid "rxode2" msgstr "rxode2" msgid "using" -msgstr "使用" +msgstr "" msgid "threads (see ?getRxThreads)" -msgstr "线程(请参阅?getRxThreads)" +msgstr "?getRxThreads" msgid "no cache: create with `rxCreateCache()`" -msgstr "无缓存:使用 'rxCreateCache()' 创建" +msgstr " 'rxCreateCache()' " msgid "========================================" msgstr "========================================" -msgid "rxode2 has not detected OpenMP support and will run in single-threaded mode" -msgstr "rxode2 未检测到 OpenMP 支持,将在单线程模式下运行" +msgid "" +"rxode2 has not detected OpenMP support and will run in single-threaded mode" +msgstr "rxode2 OpenMP " msgid "sysname" -msgstr "系统名称" +msgstr "" msgid "Darwin" msgstr "Darwin" msgid "This is a Mac. Please read https://mac.r-project.org/openmp/" -msgstr "这是一台Mac。请阅读 https://mac.r-project.org/openmp/" +msgstr "Mac https://mac.r-project.org/openmp/" msgid "The system is" -msgstr "该系统是" +msgstr "" msgid "; To get best performance enable OpenMP" -msgstr ";要获得最佳性能,请启用 OpenMP" +msgstr "; OpenMP" msgid "detected new version of rxode2, cleaning cache" -msgstr "检测到新版本的 rxode2,正在清理缓存" +msgstr " rxode2" + +msgid "'modName' has to be a single length character" +msgstr "modName" + +msgid "'extraC' needs to point to a file that exists and is readable" +msgstr "extraC" + +msgid "'collapseModel' needs to be logical" +msgstr "collapseModel" + +msgid "'indLin' needs to be logical" +msgstr "indLin" + +msgid "'debug' needs to be logical" +msgstr "(debug)" + +msgid "'package' needs to a single character for the package name" +msgstr "" + +msgid "with packages 'modName' is required" +msgstr "modName" + +msgid "must specify exactly one of 'model' or 'filename'" +msgstr "model()filename()" + +msgid "model functions can only be called with one argument" +msgstr "" + +msgid "cannot delete Dll in package" +msgstr " Dll" + +msgid "'$parse' is no longer supported" +msgstr "$parse" + +msgid "cannot update package model" +msgstr "" + +msgid "cannot figure out how to handle the model argument" +msgstr "" + +msgid "sensitivities do not make sense for models without ODEs" +msgstr "" + +msgid "Jacobians do not make sense for models without ODEs" +msgstr "" + +msgid "Do not know how to add %s to rxode2 solved object %s" +msgstr " %s rxode2 %s" + +msgid "unknown model" +msgstr "" + +msgid "model" +msgstr "" + +msgid "cannot create rxode2 model" +msgstr " rxode2 " + +#, fuzzy +msgid "cannot seem to remove '" +msgstr " rxode2 " + +msgid "rxode2 already building model, waiting for lock file removal" +msgstr "rxode2 " + +msgid "lock file: \"%s\"" +msgstr "%s" + +msgid "error building model on another thread" +msgstr "" + +msgid "do not need to recompile, minimal change to model detected" +msgstr "" + +msgid "unloaded all rxode2 dlls before loading the current DLL" +msgstr " DLL rxode2 dll" + +msgid "something went wrong in compilation" +msgstr "" + +msgid "'removeJac' is no longer supported" +msgstr "removeJac" + +msgid "'removeSens' is no longer supported" +msgstr "removeSens" + +msgid "need an rxode2-type object to extract model variables" +msgstr "" msgid "'df' must be greater than 0" -msgstr "“df”必须大于 0" +msgstr "df 0" msgid "'shape1' cannot be 0" -msgstr "“shape1”不能为 0" +msgstr "shape1 0" msgid "'shape2' cannot be 0" -msgstr "“shape2”不能为 0" +msgstr "shape2 0" msgid "'shape' cannot be 0" -msgstr "“shape”不能为 0" +msgstr "shape 0" -msgid "'rate'/'scale' cannot be 0" -msgstr "“rate”(输注速率)/“scale”(缩放)不能为 0" - -msgid "specify 'rate' or 'scale' but not both" -msgstr "描述“rate”或“scale”,但不能同时描述两者" +msgid "'rate' cannot be 0" +msgstr "rate 0" msgid "'df1' cannot be 0" -msgstr "“df1”不能为 0" +msgstr "df1 0" msgid "'df2' cannot be 0" -msgstr "“df2”不能为 0" - -msgid "'rate' cannot be 0" -msgstr "“rate”不能为 0" +msgstr "df2 0" msgid "'df' cannot be 0" -msgstr "“df”不能为 0" +msgstr "df 0" msgid "'scale' cannot be 0" -msgstr "“scale”不能为 0" +msgstr "scale 0" msgid "when 'gamma' is not 1, 'tmax' cannot be infinite" -msgstr "当“Gamma”不是1时,“tmax”不能是无穷大" +msgstr "Gamma1tmax" -msgid "duplicate arguments do not make sense" -msgstr "\"duplicate(创建副本)\"的参数没有意义" +#, fuzzy +msgid "'transitAbs' is no longer supported, use 'evid=7' instead" +msgstr "$parse" -msgid "covariates can no longer be specified by 'covs' include them in the event dataset" -msgstr "协变量不能再由“covs”描述,将它们包含在事件数据集中" +msgid "unused argument:" +msgstr "" + +msgid "" +"covariates can no longer be specified by 'covs' include them in the event " +"dataset" +msgstr "covs" + +#, fuzzy +msgid "'maxSS' must be larger than 'minSS'" +msgstr "df 0" msgid "events can be pipeline or solving arguments not both" -msgstr "事件可以是管道或求解参数,而不是两者兼而有之" +msgstr "" msgid "need an rxode2 compiled model as the start of the pipeline" -msgstr "需要一个已编译的rxode2模型作为管道的开始" +msgstr "rxode2" msgid "need an rxode2 events as a part of the pipeline" -msgstr "需要 rxode2 事件作为管道的一部分" +msgstr " rxode2 " msgid "'events' in pipeline AND in solving arguments, please provide just one" -msgstr "管道中的“事件”(events)和求解参数,请只提供一个" +msgstr "(events)" msgid "'params' in pipeline AND in solving arguments, please provide just one" -msgstr "管道中的“参数”(params)和求解参数,请只提供一个" +msgstr "(params)" msgid "'inits' in pipeline AND in solving arguments, please provide just one" -msgstr "管道中的“inits”和求解参数,请只提供一个" +msgstr "inits" + +msgid "duplicate arguments do not make sense" +msgstr "\"duplicate()\"" -msgid "covariates can no longer be specified by 'covs'\n" +msgid "" +"covariates can no longer be specified by 'covs'\n" " include them in the event dataset\n" "\n" "individual covariates: Can be specified by a 'iCov' dataset\n" @@ -442,286 +674,310 @@ msgid "covariates can no longer be specified by 'covs'\n" " 'eventTable' to include covariates(https://tinyurl.com/y52wfc2y)\n" "\n" "Each approach needs the covariates named to match the variable in the model" -msgstr "协变量不能再由“covs”描述\n" -" 将它们包含在事件数据集中\n" +msgstr "" +"covs\n" +" \n" +"\n" +"iCov\n" +" \n" "\n" -"单个协变量:可由“iCov”数据集指定\n" -" 每个协变量都有一个值\n" "\n" -"时变协变量:修改输入事件数据框或\n" -" 包含协变量的“事件表”(https://tinyurl.com/y52wfc2y)\n" +" https://tinyurl.com/y52wfc2y\n" "\n" -"每种方法都需要命名的协变量来匹配模型中的变量" +"" -msgid "'iCov' has information contained in parameters/event data\n" +msgid "" +"'iCov' has information contained in parameters/event data\n" "duplicate columns: '%s'" -msgstr "“iCov”包含参数/事件数据中包含的信息\n" -"创建列的副本:“%s”" +msgstr "" +"iCov/\n" +"%s" + +msgid "', '" +msgstr "', '" msgid "'theta' cannot be a data.frame" -msgstr "“theta”不能是一个\"数据帧(data.frame)\"" +msgstr "theta\"(data.frame)\"" msgid "'theta' can only have 1 row" -msgstr "“theta”只能有 1 行" +msgstr "theta 1 " msgid "name specification for 'theta' is ignored" -msgstr "“theta”的名称描述已被丢弃" +msgstr "theta" msgid "'eta' cannot be a data.frame" -msgstr "“eta”不能是一个\"数据帧(data.frame)\"" +msgstr "eta\"(data.frame)\"" msgid "'eta' can only have 1 row" -msgstr "“eta”只能有 1 行" +msgstr "eta 1 " msgid "name specification for 'eta' is ignored" -msgstr "“eta”的名称描述已被丢弃" +msgstr "eta" msgid "cannot specify 'params' and 'theta'/'eta' at the same time" -msgstr "不能同时指定“params”和“theta”/“eta”" +msgstr "paramstheta/eta" msgid "Cannot detect an event data frame to merge 'iCov'" -msgstr "无法检测到要合并“iCov”的事件数据框" +msgstr "iCov" msgid "to use 'iCov' you must have an id in your event table" -msgstr "要使用“iCov”,您必须在事件表中有一个 id" +msgstr "iCov id" msgid "'iCov' and 'id' mismatch" -msgstr "“iCov”和“id”不匹配" +msgstr "iCovid" msgid "iCov has duplicate IDs, cannot continue" -msgstr "iCov 有重复的 ID,无法继续" +msgstr "iCov ID" msgid "combining iCov and events dropped some event information" -msgstr "结合iCov和事件丢弃了一些事件信息" +msgstr "iCov" msgid "combining iCov and events dropped some iCov information" -msgstr "结合iCov和事件丢弃了一些iCov信息" +msgstr "iCoviCov" msgid "'iCov' must be an input dataset" -msgstr "“iCov”必须是输入数据集" +msgstr "iCov" + +msgid "Unsupported type of model trying to be solved" +msgstr "" + +msgid "'sensCmt' must be lower than the number of compartments 'ncmt'" +msgstr "" + +msgid "'rxControl' must be a rxode2 control options list" +msgstr "" msgid "name argument must be a length-one character vector" -msgstr "\"名称(name)\"参数必须是长度为一的字符向量" +msgstr "\"(name)\"" msgid "a new function requires a C function so it can be used in rxode2" -msgstr "一个新函数需要一个C函数,这样它就能在 rxode2 中使用" +msgstr "C rxode2 " msgid "already defined user function '" -msgstr "已定义的用户函数”" +msgstr "" msgid "', remove it fist ('rxRmFun')" -msgstr "',应首先移除它('rxRmFun')" +msgstr "''rxRmFun'" msgid "no user function '" -msgstr "无用户函数 '" +msgstr " '" msgid "' to remove" -msgstr "'要移除" - -msgid "cannot take a second derivative" -msgstr "不能取二阶导数" - -msgid "bad 'linCmtB' derivative" -msgstr "坏的“linCmtB”衍生" +msgstr "'" msgid "derivatives must be a list of functions with at least 1 element" -msgstr "导数必须是至少包含 1 个元素的函数列表" +msgstr " 1 " msgid "replacing defined derivatives for '%s'" -msgstr "替换 '%s' 的定义导数" +msgstr " '%s' " msgid "only 'THETA[#]' or 'ETA[#]' are supported" -msgstr "仅支持“THETA[#]”或“ETA[#]”" +msgstr "THETA[#]ETA[#]" msgid "() must be used with a state" -msgstr "() 必须与状态一起使用" +msgstr "() " msgid "() can have 0-1 arguments" -msgstr "() 可以有 0-1 个参数" +msgstr "() 0-1 " msgid "() takes 1-2 arguments" -msgstr "() 需要 1-2 个参数" +msgstr "() 1-2 " msgid "() must be used with a variable" -msgstr "() 必须与变量一起使用" +msgstr "() " msgid "(" msgstr "(" msgid ", #) must have an integer for the number of lagged doses" -msgstr ", #) 必须有一个整数用于滞后的给药" +msgstr " #) " msgid "'psigamma' takes 2 arguments" -msgstr "“psigamma”接收 2 个参数" +msgstr "psigamma 2 " msgid "'log1pmx' only takes 1 argument" -msgstr "'log1pmx' 只接收 1 个参数" +msgstr "'log1pmx' 1 " msgid "'choose' takes 2 arguments" -msgstr "“choose”接收 2 个参数" +msgstr "choose 2 " msgid "'lchoose' takes 2 arguments" -msgstr "'lchoose' 接收 2 个参数" +msgstr "'lchoose' 2 " msgid "'pnorm' can only take 1-3 arguments" -msgstr "“pnorm”只接收1-3个参数" +msgstr "pnorm1-3" msgid "'transit' can only take 2-3 arguments" -msgstr "“transit”只接收2-3 个参数" +msgstr "transit2-3 " -msgid "'%s' only acceps 1 argument" -msgstr "'%s' 仅接受 1 个参数" +#, fuzzy +msgid "'%s' only accepts 1 argument" +msgstr "'%s' 1 " msgid "'%s' only acceps 2 arguments" -msgstr "'%s' 仅接受 2 个参数" +msgstr "'%s' 2 " msgid "'%s' takes %s arguments (has %s)" -msgstr "'%s' 接收 %s 参数(具有 %s)" +msgstr "'%s' %s %s" msgid "'probitInv' requires 1-3 arguments" -msgstr "“probitInv”需要 1-3 个参数" +msgstr "probitInv 1-3 " msgid "'probit' requires 1-3 arguments" -msgstr "“probit”需要 1-3 个参数" +msgstr "probit 1-3 " msgid "'logit' requires 1-3 arguments" -msgstr "“logit”需要 1-3 个参数" +msgstr "logit 1-3 " msgid "'expit' requires 1-3 arguments" -msgstr "“expit”需要 1-3 个参数" +msgstr "expit 1-3 " msgid "function '%s' or its derivatives are not supported in rxode2" -msgstr "函数 '%s' 或其导数在 rxode2 中不受支持" +msgstr " '%s' rxode2 " + +#, fuzzy +msgid "" +"R user function '%s' has variable number of arguments with'...' and is not " +"supported in rxode2" +msgstr " '%s' rxode2 " + +msgid "user function '%s' requires %d arguments (supplied %d)" +msgstr "" msgid "[...] expressions not supported" -msgstr "[...]不支持的表达式" +msgstr "[...]" msgid "'polygamma' takes 2 arguments" -msgstr "“polygamma”接收 2 个参数" +msgstr "polygamma 2 " + +msgid "'%s' only acceps 1 argument" +msgstr "'%s' 1 " msgid "'%s' takes %s arguments" -msgstr "'%s' 接收 %s 参数" +msgstr "'%s' %s " msgid "only forward and central differences are supported" -msgstr "仅支持前向和中心差分" +msgstr "" msgid "cannot figure out the '%s' derivative with respect to '%s'" -msgstr "无法计算出相对于“%s”的“%s”导数" +msgstr "%s%s" msgid "an error occurred looking up the derivative for '" -msgstr "查找'" +msgstr "'" msgid "' using numerical differences instead" -msgstr "'导数时遇到一个错误,因此改用数值差分" +msgstr "'" msgid "rxode2/symengine does not know how to take a derivative of '%s'" -msgstr "rxode2/symengine 不知道如何取 '%s' 的导数" +msgstr "rxode2/symengine '%s' " msgid "'Derivative' conversion only takes one function and one argument" -msgstr "“Derivative”转换只需要一个函数和一个参数" +msgstr "Derivative" msgid "() takes 0-1 arguments" -msgstr "() 接收 0-1 个参数" +msgstr "() 0-1 " msgid "'%s' not supported in symengine->rxode2" -msgstr "“%s”在符号引擎>rxode2 中不受支持" +msgstr "%s>rxode2 " msgid "rxode2 doesn't support '%s' translation for 'Omega' translation" -msgstr "rxode2 不支持对的'Omega'转换的'%s'转换" +msgstr "rxode2 'Omega''%s'" msgid "do not know how to handle type" -msgstr "不知道如何处理类型" +msgstr "" msgid "'lnorm' can only be in an error function" -msgstr "“lnorm”只能在误差函数中" +msgstr "lnorm" msgid "'lnorm' cannot be used with other data transformations" -msgstr "“lnorm”不能与其他数据转换一起使用" +msgstr "lnorm" msgid "'logitNorm' can only be in an error function" -msgstr "“logitNorm”只能在误差函数中" +msgstr "logitNorm" msgid "'logitNorm' cannot be used with other data transformations" -msgstr "“logitNorm”不能与其他数据转换一起使用" +msgstr "logitNorm" msgid "'probitNorm' can only be in an error function" -msgstr "“probitNorm”只能在误差函数中" +msgstr "probitNorm" msgid "'probitNorm' cannot be used with other data transformations" -msgstr "“probitNorm”不能与其他数据转换一起使用" +msgstr "probitNorm" msgid "'boxCox' can only be in an error function" -msgstr "“boxCox”只能在误差函数中" +msgstr "boxCox" msgid "'boxCox' cannot be used with other data transformations" -msgstr "“boxCox”不能与其他数据转换一起使用" +msgstr "boxCox" msgid "'yeoJohnson' can only be in an error function" -msgstr "“yeoJohnson”只能在误差函数中" +msgstr "yeoJohnson" msgid "'yeoJohnson' cannot be used with other data transformations" -msgstr "“yeoJohnson”不能与其他数据转换一起使用" +msgstr "yeoJohnson" msgid "'add' can only be in an error function" -msgstr "“add”只能在误差函数中" +msgstr "add" msgid "'for' is not supported" -msgstr "“for”不被支持" +msgstr "for" msgid "The PK function should not return anything" -msgstr "PK 函数不应返回任何内容" +msgstr "PK " msgid "'prop' can only be in an error function" -msgstr "“prop”只能在误差函数中" +msgstr "prop" msgid "'propT' can only be in an error function" -msgstr "“propT”只能在误差函数中" +msgstr "propT" msgid "'pow' can only be in an error function" -msgstr "“pow”只能在误差函数中" +msgstr "pow" msgid "'powT' can only be in an error function" -msgstr "“powT”只能在误差函数中" +msgstr "powT" msgid "use 'return' for errors" -msgstr "对\"误差(errors)\"使用“return”" +msgstr "\"(errors)\"return" -msgid "errors and predictions need to have the same conditions ('if'/'then' statements)" -msgstr "误差和预测需要具有相同的条件(“if”/“then”语句)" +msgid "" +"errors and predictions need to have the same conditions ('if'/'then' " +"statements)" +msgstr "if/then" msgid "do not know how to handle this error/pred combination" -msgstr "不知道如何处理此\"误差(errors)\"/\"预测(PRED)\"组合" +msgstr "\"(errors)\"/\"(PRED)\"" msgid "Don't know how to handle type '" -msgstr "不知道如何处理类型 '" +msgstr " '" msgid "'." msgstr "'." -msgid "package \"%s\" needed for this function to work" -msgstr "此函数正常工作需要的添加包“%s”" - -msgid "'wd' is depreciated" -msgstr "“wd”已折旧(此处指清理的意思)" - -msgid "'rxSetSum' has been moved to rxSolve(...,sum=)" -msgstr "'rxSetSum' 已移至rxSolve(...,sum=)" +#, fuzzy +msgid "cannot figure out what to do with model assignment" +msgstr "" -msgid "'rxSetProd' has been moved to rxSolve(...,sum=)" -msgstr "'rxSetProd' 已移至rxSolve(...,sum=)" +#, fuzzy +msgid "cannot figure out what to do with ini assignment" +msgstr "" -msgid "provide either threads= or percent= but not both" -msgstr "提供threads=或percent=,但不能同时提供两者" +msgid "wrong input for 'x' in .bodySetRxUi" +msgstr "" -msgid "percent= is provided but is length" -msgstr "提供百分比=,但是长度" +#, fuzzy +msgid "cannot figure out how to assign this to the with rxode()<-" +msgstr "" -msgid "percent==" -msgstr "百分比==" +#, fuzzy +msgid "do not know how to assign this" +msgstr "" -msgid "but should be a number between 2 and 100" -msgstr "但应该是 2 到 100 之间的数字" +msgid "" +"the first model does not have variables that are used by the second model" +msgstr "" -msgid "%s%s" -msgstr "%s%s" +msgid "there needs to be at least one population parameter in 'model1'" +msgstr "" +msgid "" \ No newline at end of file diff --git a/po/rxode2.pot b/po/rxode2.pot index bf835be77..36b6d273d 100644 --- a/po/rxode2.pot +++ b/po/rxode2.pot @@ -1,14 +1,14 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the RxODE package. +# This file is distributed under the same license as the rxode2 package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: RxODE 1.1.0\n" +"Project-Id-Version: rxode2 2.0.14.9000\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-26 10:39-0500\n" +"POT-Creation-Date: 2023-10-30 08:03-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,1515 +17,716 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: cvPost.cpp:148 -msgid "'shape' must be non-negative" -msgstr "" - -#: cvPost.cpp:169 -msgid "dimension, 'd' of correlation matrix must be > 1" -msgstr "" - -#: cvPost.cpp:172 -msgid "'eta' must be >= 1" -msgstr "" - -#: cvPost.cpp:217 -msgid "" -"log standard deviation size needs to be the same size as the log standard " -"error of the estimate" -msgstr "" - -#: cvPost.cpp:243 -msgid "'nu' must be greater than 'd'-1" -msgstr "" - -#: cvPost.cpp:316 -msgid "unknown 'diagXformType' transformation" -msgstr "" - -#: cvPost.cpp:368 -#, c-format -msgid "variable 'type': Unrecognized cvPost type='%s'" -msgstr "" - -#: cvPost.cpp:371 -msgid "variable 'type': Can only use type string or integer[1,3]" -msgstr "" - -#: cvPost.cpp:472 -#, c-format -msgid "variable 'diagXformType': Unrecognized transformation '%s'" -msgstr "" - -#: cvPost.cpp:477 -msgid "" -"variable 'diagXformType': Can only use transformation string or integer[1,6]" -msgstr "" - -#: cvPost.cpp:483 -msgid "" -"'n' is determined by the 'omega' argument which contains the simulated " -"standard deviations" -msgstr "" - -#: cvPost.cpp:496 -msgid "" -"when sampling from correlation priors to create covariance matrices, the " -"input must be a matrix of standard deviations" -msgstr "" - -#: cvPost.cpp:500 -msgid "" -"'omega' needs to be a matrix or a numeric vector that can be converted to a " -"matrix" -msgstr "" - -#: cvPost.cpp:520 -msgid "'thetaMat' needs 'params' to be non-NULL" -msgstr "" - -#: cvPost.cpp:535 -msgid "" -"when specifying 'thetaMat', 'omega', or 'sigma' the parameters cannot be a " -"'data.frame'/'matrix'" -msgstr "" - -#: cvPost.cpp:546 -msgid "'thetaMat' must be a symmetric, positive definite matrix" -msgstr "" - -#: cvPost.cpp:593 -msgid "'theta' must be the same size as 'thetaMat'" -msgstr "" - -#: cvPost.cpp:716 -msgid "'omega' must be symmetric, positive definite" -msgstr "" - -#: cvPost.cpp:735 -msgid "'omega' needs to be a matrix or lotri matrix" -msgstr "" - -#: cvPost.cpp:773 cvPost.cpp:814 rxData.cpp:2840 -#, c-format -msgid "" -"provided multi-subject data (n=%d) trying to simulate a different number of " -"subjects (n=%d)" -msgstr "" - -#: cvPost.cpp:935 -msgid "'sigma' must be symmetric, positive definite" -msgstr "" - -#: cvPost.cpp:950 -msgid "'sigma' needs to be a matrix or lotri matrix" -msgstr "" - -#: cvPost.cpp:1087 -msgid "un-handled nesting information" -msgstr "" - -#: cvPost.cpp:1111 -msgid "cannot find 'id' column in dataset" -msgstr "" - -#: cvPost.cpp:1124 -msgid "'omega' must be a list/lotri/matrix" -msgstr "" - -#: dop853.c:401 dop853.c:668 -#, c-format -msgid "exit of dop853 at x = %.16e\n" -msgstr "" - -#: dop853.c:412 -#, c-format -msgid "exit of dop853 at x = %.16e, more than nmax = %li are needed\n" -msgstr "" - -#: dop853.c:421 -#, c-format -msgid "exit of dop853 at x = %.16e, step size too small h = %.16e\n" -msgstr "" - -#: dop853.c:553 -#, c-format -msgid "the problem seems to become stiff at x = %.16e\n" -msgstr "" - -#: dop853.c:724 -#, c-format -msgid "system too big, max. n = %u\n" -msgstr "" - -#: dop853.c:734 -#, c-format -msgid "wrong input, nmax = %li\n" -msgstr "" - -#: dop853.c:744 -#, c-format -msgid "curious input, meth = %i\n" -msgstr "" - -#: dop853.c:758 -#, c-format -msgid "wrong input, iout = %i\n" -msgstr "" - -#: dop853.c:766 -#, c-format -msgid "curious input, nrdens = %u\n" -msgstr "" - -#: dop853.c:787 -msgid "not enough free memory for rcont12345678&indir\n" -msgstr "" - -#: dop853.c:795 -msgid "" -"warning : when nrdens = n there is no need allocating memory for icont\n" -msgstr "" - -#: dop853.c:801 -#, c-format -msgid "insufficient storage for icont, min. licont = %u\n" -msgstr "" - -#: dop853.c:974 -#, c-format -msgid "no dense output available for %uth component" -msgstr "" - -#: et.cpp:142 rxData.cpp:5164 -#, c-format -msgid "partial match of '%s' to '%s'" -msgstr "" - -#: et.cpp:403 -msgid "event table was not updated (no dose/sampling windows)" -msgstr "" - -#: et.cpp:480 -msgid "" -"windows need to be a list of observation windows, each of 2 elements e.g. " -"list(c(0,2), c(2,7))" -msgstr "" - -#: et.cpp:482 -msgid "windows need to be ordered list(c(2,0)) is invalid" -msgstr "" - -#: et.cpp:881 et.cpp:898 -#, c-format -msgid "unknown method: '%s'" -msgstr "" - -#: et.cpp:939 etTran.cpp:451 -msgid "can only specify either 'amt' or 'value'" -msgstr "" - -#: et.cpp:943 etTran.cpp:455 -msgid "can only specify either 'cmt', 'ytype', 'state' or 'var'" -msgstr "" - -#: et.cpp:951 -msgid "can only specify either 'duration' or 'dur'" -msgstr "" - -#: et.cpp:959 -msgid "need a 'time' column" -msgstr "" - -#: et.cpp:969 -msgid "using 'mdv' instead of 'method'" -msgstr "" - -#: et.cpp:979 -msgid "using 'evid' instead of 'mdv'" -msgstr "" - -#: et.cpp:994 -msgid "'ID' type is unknown" -msgstr "" - -#: et.cpp:1081 -msgid "can not figure out how to import the compartment variable" -msgstr "" - -#: et.cpp:1152 et.cpp:1154 -msgid "replacement/multiplication events cannot be combined with infusions" -msgstr "" - -#: et.cpp:1168 -msgid "old RxODE 'evid' values are not supported with string compartments" -msgstr "" - -#: et.cpp:1381 -msgid "" -"'amt'/'time' needs units to convert the rate to the right units to import " -"the data" -msgstr "" - -#: et.cpp:1636 -msgid "'do.sampling' is not supported with dose windows" -msgstr "" - -#: et.cpp:1658 -msgid "" -"dosing window you need to specify window in order, e.g. " -"'et(time=list(c(0,2)),amt=3)'" -msgstr "" - -#: et.cpp:1661 -msgid "dosing time or time windows must only be 1-2 elements" -msgstr "" - -#: et.cpp:1922 -msgid "cannot mix named compartments and integer compartments" -msgstr "" - -#: et.cpp:2026 et.cpp:2188 -msgid "cannot add more 'ID's to this event table" -msgstr "" - -#: et.cpp:2256 -msgid "can only have one of the following: 'amt', 'dose'" -msgstr "" - -#: et.cpp:2263 -msgid "" -"can only have one of the following: 'ii', 'dosing.interval', " -"'dosingInterval' or 'dosing_interval'" -msgstr "" - -#: et.cpp:2283 -msgid "" -"can only have one of the following: 'cmt', 'dosing.to', 'dose.to', 'state'" -msgstr "" - -#: et.cpp:2292 -msgid "" -"can only have one of the following: 'amount.units', 'amt.units', 'dose.units'" -msgstr "" - -#: et.cpp:2299 -msgid "" -"can only have one of the following: 'time.units', 'timeUnits', 'time_units'" -msgstr "" - -#: et.cpp:2307 -msgid "can only have one of the following: 'add.sampling', 'do.sampling'" -msgstr "" - -#: et.cpp:2315 -msgid "can only have one of the following: 'time', 'start.time', 'from'" -msgstr "" - -#: et.cpp:2321 -msgid "can only have one of the following: 'nbrDoses', 'nbr.doses'" -msgstr "" - -#: et.cpp:2336 -msgid "can only have one of the following: 'dur', 'duration'" -msgstr "" - -#: et.cpp:2343 -#, c-format -msgid "unused argument '%s'" -msgstr "" - -#: et.cpp:2354 et.cpp:2359 et.cpp:2374 et.cpp:2379 -msgid "" -"multiple event tables supplied, not sure what to do; try 'c', 'rbind', 'seq' " -"or 'rep'" -msgstr "" - -#: et.cpp:2397 et.cpp:2405 et.cpp:2650 et.cpp:2673 et.cpp:2708 et.cpp:2729 -#: et.cpp:2736 et.cpp:2747 et.cpp:2766 et.cpp:2831 et.cpp:2859 et.cpp:2882 -#: et.cpp:2895 et.cpp:2924 et.cpp:2928 et.cpp:2937 et.cpp:3061 et.cpp:3069 -#, c-format -msgid "'%s' cannot be a vector" -msgstr "" - -#: et.cpp:2561 et.cpp:2565 -msgid "nothing done" -msgstr "" - -#: et.cpp:2611 -#, c-format -msgid "cannot mix named and integer compartments in '%s'" -msgstr "" - -#: et.cpp:2619 -#, c-format -msgid "'%s' compartment cannot be a vector" -msgstr "" - -#: et.cpp:2631 -#, c-format -msgid "'%s' cannot be zero" -msgstr "" - -#: et.cpp:2635 -#, c-format -msgid "'%s' cannot be an vector" -msgstr "" - -#: et.cpp:2638 -#, c-format -msgid "'%s' must be an integer or a character" -msgstr "" - -#: et.cpp:2677 -#, c-format -msgid "turning off compartments can only be done when '%s'=2" -msgstr "" - -#: et.cpp:2680 -#, c-format -msgid "zero '%s' cannot be used with '%s'" -msgstr "" - -#: et.cpp:2683 -#, c-format -msgid "'%s' requires an '%s'" -msgstr "" - -#: et.cpp:2687 -#, c-format -msgid "'%s' is ignored when '%s'=2 or '%s'=3" -msgstr "" - -#: et.cpp:2710 et.cpp:2717 et.cpp:2720 et.cpp:2731 et.cpp:2738 -#, c-format -msgid "'%s' needs a '%s'" -msgstr "" - -#: et.cpp:2725 -#, c-format -msgid "can not specify '%s' and '%s' for a dose, please pick one" -msgstr "" - -#: et.cpp:2749 -msgid "'ii' needs a 'dose'/'amt'" -msgstr "" - -#: et.cpp:2760 -msgid "dosing interval of zero makes no sense with multiple dose events" -msgstr "" - -#: et.cpp:2768 et.cpp:2900 -#, c-format -msgid "non-zero '%s' needs a '%s'" -msgstr "" - -#: et.cpp:2805 et.cpp:2808 et.cpp:2811 -#, c-format -msgid "can only specify '%s' or '%s', not both" -msgstr "" - -#: et.cpp:2817 -#, c-format -msgid "'%s' can only have one item" -msgstr "" - -#: et.cpp:2820 -#, c-format -msgid "'%s' must be logical" -msgstr "" - -#: et.cpp:2827 -#, c-format -msgid "cannot specify '%s' and '%s' for a dose, please pick one" -msgstr "" - -#: et.cpp:2838 -msgid "-1 and -2 rates do not make sense with units" -msgstr "" - -#: et.cpp:2843 -#, c-format -msgid "'%s' is cannot be converted and added to this table" -msgstr "" - -#: et.cpp:2850 -#, c-format -msgid "" -"steady state constant infusion dosing records must have '%s=-1' or positive " -"rate" -msgstr "" - -#: et.cpp:2869 -#, c-format -msgid "'%s' cannot be converted and added to this table" -msgstr "" - -#: et.cpp:2930 -#, c-format -msgid "number of doses must be at least one ('%s': %d)" -msgstr "" - -#: et.cpp:2939 -#, c-format -msgid "'%s' can only be used with positive inter-dose intervals ('%s')" -msgstr "" - -#: et.cpp:2949 -#, c-format -msgid "'%s' does not make sense with multiple dosing times" -msgstr "" - -#: et.cpp:2978 -msgid "dosing windows can only have 1-2 items in them" -msgstr "" - -#: et.cpp:2987 -#, c-format -msgid "" -"'%s' requires non zero additional doses ('%s') or steady state dosing ('%s': " -"%f, '%s': %d; '%s': %d), reset '%s' to zero." -msgstr "" - -#: et.cpp:2993 -#, c-format -msgid "'%s' must be 1 when specifying a steady-state constant infusion" -msgstr "" - -#: et.cpp:2996 -#, c-format -msgid "'%s' must be 0, 1 or 2" -msgstr "" - -#: et.cpp:2999 -#, c-format -msgid "'%s' required with '%s'" -msgstr "" - -#: et.cpp:3003 -#, c-format -msgid "'%s' cannot be used with steady state constant infusion" -msgstr "" - -#: et.cpp:3006 -#, c-format -msgid "steady state ('%s') is not supported with dosing windows" -msgstr "" - -#: et.cpp:3009 -#, c-format -msgid "additional doses must be positive ('%s'=%d)" -msgstr "" - -#: et.cpp:3012 -#, c-format -msgid "additional doses require an inter-dose interval ('%s')" -msgstr "" - -#: et.cpp:3017 -#, c-format -msgid "for steady state infusions, you need %s=0, %s>0, %s=1, %s=0" -msgstr "" - -#: et.cpp:3030 -msgid "dosing time window lists can have 1-2 numeric entries in them" -msgstr "" - -#: et.cpp:3035 -msgid "dosing window list needs to be numeric values only" -msgstr "" - -#: et.cpp:3088 -msgid "cannot figure out what type of 'EventTable' you are trying to create" -msgstr "" - -#: et.cpp:3173 et.cpp:3176 -msgid "cannot have event tables with integer and character 'cmt'" -msgstr "" - -#: et.cpp:3261 -#, c-format -msgid "" -"assumed a dose interval of %.1f between event tables; use 'ii' to adjust" -msgstr "" - -#: et.cpp:3347 -msgid "no events table found for 'seq'/'rep'/'rbind'/'c'" -msgstr "" - -#: et.cpp:3468 -msgid "'wait' cannot be a vector" -msgstr "" - -#: etTran.cpp:141 -#, c-format -msgid "" -"negative compartments on non-ode 'cmt' (%s) does not make sense (id: %s, " -"row: %d)" -msgstr "" - -#: etTran.cpp:276 etTran.cpp:286 -#, c-format -msgid "" -"negative compartments on non-ode 'cmt' (%s) does not make sense (id: %s row: " -"%d)" -msgstr "" - -#: etTran.cpp:307 -msgid "should not reach here" -msgstr "" - -#: etTran.cpp:471 -msgid "cannot keep 'evid'; try 'addDosing'" -msgstr "" - -#: etTran.cpp:616 -msgid "'time' is required in dataset" -msgstr "" - -#: etTran.cpp:708 -msgid "steady state column ('ss') needs to be an integer" -msgstr "" - -#: etTran.cpp:719 -msgid "event id ('evid') needs to be an integer" -msgstr "" - -#: etTran.cpp:728 -msgid "missing DV ('mdv') needs to be an integer" -msgstr "" - -#: etTran.cpp:742 -msgid "missing dependent variable ('mdv') needs to be an integer" -msgstr "" - -#: etTran.cpp:750 -msgid "'rate' needs to be a number" -msgstr "" - -#: etTran.cpp:759 -msgid "'dur' needs to be a number" -msgstr "" - -#: etTran.cpp:774 -msgid "amount ('amt') needs to be a number" -msgstr "" - -#: etTran.cpp:782 -msgid "inter-dose interval ('ii') needs to be a number" -msgstr "" - -#: etTran.cpp:790 -msgid "number of additional doses ('addl') needs to be an integer" -msgstr "" - -#: etTran.cpp:798 -msgid "dependent variable ('dv') needs to be a number" -msgstr "" - -#: etTran.cpp:806 -msgid "censoring variable ('cens') needs to be a number" -msgstr "" - -#: etTran.cpp:814 -msgid "limit variable ('limit') needs to be a number" -msgstr "" - -#: etTran.cpp:863 -#, c-format -msgid "censoring column can only be -1, 0 or 1 (id: %s, row: %d)" -msgstr "" - -#: etTran.cpp:888 -#, c-format -msgid "infinite times are not allowed (id: %s, row: %d)" -msgstr "" - -#: etTran.cpp:946 -#, c-format -msgid "" -"steady state records cannot be on negative compartments (id: %s, row: %d)" -msgstr "" - -#: etTran.cpp:976 -#, c-format -msgid "" -"when using steady state constant infusion modeling duration does not make " -"sense (id: %s, row: %d)" +#: approx.c:181 +msgid "solve data is not loaded" msgstr "" -#: etTran.cpp:995 +#: dop853.c:403 dop853.c:670 #, c-format -msgid "" -"specifying duration with a steady state constant infusion makes no sense " -"(id: %s row: %d)" +msgid "exit of dop853 at x = %.16e\n" msgstr "" -#: etTran.cpp:1001 etTran.cpp:1007 +#: dop853.c:414 #, c-format -msgid "" -"specifying duration with a steady state constant infusion makes no sense " -"(id: %d row: %d)" +msgid "exit of dop853 at x = %.16e, more than nmax = %li are needed\n" msgstr "" -#: etTran.cpp:1018 +#: dop853.c:423 #, c-format -msgid "'rate' and/or 'dur' are not specified correctly (id: %d row: %d)" +msgid "exit of dop853 at x = %.16e, step size too small h = %.16e\n" msgstr "" -#: etTran.cpp:1036 +#: dop853.c:555 #, c-format -msgid "" -"'amt' or 'dur'/'rate' are non-zero therefore MDV cannot = 0 (id: %s row: %d)" -msgstr "" - -#: etTran.cpp:1074 -msgid "'addl' is ignored with observations" +msgid "the problem seems to become stiff at x = %.16e\n" msgstr "" -#: etTran.cpp:1096 etTran.cpp:1180 +#: dop853.c:726 #, c-format -msgid "'limit' (%f) cannot equal 'dv' (%f) id: %s row: %d" +msgid "system too big, max. n = %u\n" msgstr "" -#: etTran.cpp:1129 +#: dop853.c:736 #, c-format -msgid "'cmt' and 'dvid' specify different compartments (id: %s row: %d)" -msgstr "" - -#: etTran.cpp:1150 -msgid "'DVID'/'CMT' translation:\n" +msgid "wrong input, nmax = %li\n" msgstr "" -#: etTran.cpp:1156 +#: dop853.c:746 #, c-format -msgid "" -"'dvid'->'cmt' or 'cmt' on observation record on a undefined compartment (use " -"'cmt()' 'dvid()') id: %s row: %d" +msgid "curious input, meth = %i\n" msgstr "" -#: etTran.cpp:1195 +#: dop853.c:760 #, c-format -msgid "'mdv' cannot be 0 when 'evid'=1 id: %s row: %d" -msgstr "" - -#: etTran.cpp:1212 -msgid "'addl' is ignored with 'EVID=2'" -msgstr "" - -#: etTran.cpp:1215 -msgid "'ss' is ignored with 'EVID=2'" -msgstr "" - -#: etTran.cpp:1257 -msgid "'addl' is ignored with 'EVID=3'" -msgstr "" - -#: etTran.cpp:1260 -msgid "'ss' is ignored with 'EVID=3'" +msgid "wrong input, iout = %i\n" msgstr "" -#: etTran.cpp:1284 +#: dop853.c:768 #, c-format -msgid "'mdv' cannot be 0 when 'evid'=4 id: %s row: %d" +msgid "curious input, nrdens = %u\n" msgstr "" -#: etTran.cpp:1310 -#, c-format -msgid "cannot have an infusion event with a replacement event (id: %s row: %d)" +#: dop853.c:789 +msgid "not enough free memory for rcont12345678&indir\n" msgstr "" -#: etTran.cpp:1317 -#, c-format +#: dop853.c:797 msgid "" -"cannot have an infusion event with a multiplication event (id: %s row: %d)" -msgstr "" - -#: etTran.cpp:1328 -msgid "'rate' or 'dur' is ignored with classic RxODE 'EVID's" -msgstr "" - -#: etTran.cpp:1332 -msgid "'ss' is ignored with classic RxODE 'EVID's" -msgstr "" - -#: etTran.cpp:1353 -#, c-format -msgid "'ss' with 'addl' not supported (id: %s row: %d)" +"warning : when nrdens = n there is no need allocating memory for icont\n" msgstr "" -#: etTran.cpp:1364 +#: dop853.c:803 #, c-format -msgid "'amt' value NA or 0 for dose event (id: %s row: %d)" +msgid "insufficient storage for icont, min. licont = %u\n" msgstr "" -#: etTran.cpp:1402 +#: dop853.c:976 #, c-format -msgid "" -"'amt' value NA for dose event; (id: %s, amt: %f, evid: %d RxODE evid: %d, " -"row: %d)" -msgstr "" - -#: etTran.cpp:1480 -msgid "" -"there are evid=3/4 records in an incorrectly sorted dataset, system is " -"reset, but time is not reset" -msgstr "" - -#: etTran.cpp:1537 -msgid "censoring missing 'DV' values do not make sense" -msgstr "" - -#: etTran.cpp:1590 -msgid "no rows in event table or input data" -msgstr "" - -#: etTran.cpp:1612 -msgid "empty data" -msgstr "" - -#: etTran.cpp:1628 -msgid "while censoring is included in dataset, no observations are censored" -msgstr "" - -#: etTran.cpp:1632 -msgid "'dv' and 'limit' swapped since 'limit' > 'dv'" -msgstr "" - -#: etTran.cpp:1753 -msgid "number of individuals not calculated correctly" -msgstr "" - -#: etTran.cpp:1908 -msgid "corrupted event table" -msgstr "" - -#: etTran.cpp:2022 -msgid "" -"\n" -"with negative times, compartments initialize at first negative observed " -"time\n" -"with positive times, compartments initialize at time zero\n" -"use 'rxSetIni0(FALSE)' to initialize at first observed time\n" -"this warning is displayed once per session" +msgid "no dense output available for %uth component" msgstr "" -#: expandGrid.cpp:73 +#: expandGrid.cpp:83 msgid "unanticipated input for rxExpandGrid_" msgstr "" -#: expm.cpp:211 +#: expm.cpp:215 msgid "requested tolerance is too high" msgstr "" -#: expm.cpp:410 +#: expm.cpp:413 #, c-format msgid "unsupported indLin code: %d" msgstr "" -#: forder.cpp:62 +#: forder.cpp:44 #, c-format msgid "" "ignoring invalid %s==\"%s\"\n" " not an integer >= 1\n" "remove any characters that are not a digit [0-9]\n" -" See ?RxODE::setDTthreads" +" See ?rxode2::setDTthreads" msgstr "" -#: forder.cpp:88 +#: forder.cpp:70 #, c-format msgid "" -"ignoring invalid RXODE_NUM_PROCS_PERCENT==%d.\n" +"ignoring invalid rxode2_NUM_PROCS_PERCENT==%d.\n" "If used it must be an integer between 2 and 100. Default is 50. See ?" "rxSetThreads" msgstr "" -#: forder.cpp:124 +#: forder.cpp:106 msgid "'verbose' must be TRUE or FALSE" msgstr "" -#: forder.cpp:127 +#: forder.cpp:109 msgid "" "This installation of data.table has not been compiled with OpenMP support.\n" msgstr "" -#: forder.cpp:132 +#: forder.cpp:114 #, c-format msgid " omp_get_num_procs() %d\n" msgstr "" -#: forder.cpp:133 +#: forder.cpp:115 #, c-format -msgid " RXODE_NUM_PROCS_PERCENT %s\n" +msgid " rxode2_NUM_PROCS_PERCENT %s\n" msgstr "" -#: forder.cpp:134 +#: forder.cpp:116 #, c-format -msgid " RXODE_NUM_THREADS %s\n" +msgid " rxode2_NUM_THREADS %s\n" msgstr "" -#: forder.cpp:135 +#: forder.cpp:117 #, c-format -msgid " RXODE_THROTTLE %s\n" +msgid " rxode2_THROTTLE %s\n" msgstr "" -#: forder.cpp:136 +#: forder.cpp:118 #, c-format msgid " omp_get_thread_limit() %d\n" msgstr "" -#: forder.cpp:137 +#: forder.cpp:119 #, c-format msgid " omp_get_max_threads() %d\n" msgstr "" -#: forder.cpp:138 +#: forder.cpp:120 #, c-format msgid " OMP_THREAD_LIMIT %s\n" msgstr "" -#: forder.cpp:139 +#: forder.cpp:121 #, c-format msgid " OMP_NUM_THREADS %s\n" msgstr "" -#: forder.cpp:141 +#: forder.cpp:123 #, c-format -msgid " RxODE is using %d threads with throttle==%d. See ?setRxthreads.\n" +msgid " rxode2 is using %d threads with throttle==%d. See ?setRxthreads.\n" msgstr "" -#: forder.cpp:149 +#: forder.cpp:131 msgid "'throttle' must be a single number, non-NA, and >=1" msgstr "" -#: forder.cpp:163 +#: forder.cpp:145 msgid "threads= must be either NULL or a single number >= 0 See ?setRxthreads" msgstr "" -#: forder.cpp:167 +#: forder.cpp:149 msgid "internal error: percent= must be TRUE or FALSE at C level" msgstr "" -#: forder.cpp:170 +#: forder.cpp:152 #, c-format msgid "" "internal error: threads==%d should be between 2 and 100 (percent=TRUE at C " "level)" msgstr "" -#: intdy.c:50 -#, c-format -msgid "[intdy] k = %d illegal\n" -msgstr "" - -#: intdy.c:55 -#, c-format -msgid "intdy -- t = %g illegal. t not in interval tcur - _rxC(hu) to tcur\n" +#: handle_evid.c:44 +msgid "could not find a start to the infusion #1" msgstr "" -#: lincmt.c:39 lincmt.c:46 -msgid "could not find a start to the infusion" +#: handle_evid.c:51 +msgid "could not find a start to the infusion #2" msgstr "" -#: lincmt.c:51 lincmt.c:58 +#: handle_evid.c:57 handle_evid.c:65 msgid "could not find an end to the infusion" msgstr "" -#: lincmt.c:200 -msgid "solve data is not loaded" -msgstr "" - -#: lincmt.c:1879 -msgid "not an integer/real" -msgstr "" - -#: lincmt.c:1897 lincmt.c:2007 lincmt.c:2179 -msgid "The dimensions of the parameters must match" -msgstr "" - -#: lincmt.c:2394 -msgid "'ncmt' needs to be 1-3" -msgstr "" - -#: lincmt.c:2397 -msgid "'inp' needs to be list/data frame" +#: intdy.c:52 +#, c-format +msgid "[intdy] k = %d illegal\n" msgstr "" -#: lincmtB.cpp:181 +#: intdy.c:57 #, c-format -msgid "invalid trans (2 cmt trans %d)\n" +msgid "intdy -- t = %g illegal. t not in interval tcur - _rxC(hu) to tcur\n" msgstr "" -#: lsoda.c:221 +#: lsoda.c:223 #, c-format msgid "[lsoda] illegal itask = %d\n" msgstr "" -#: lsoda.c:226 +#: lsoda.c:228 #, c-format msgid "[lsoda] ixpr = %d is illegal\n" msgstr "" -#: lsoda.c:230 +#: lsoda.c:232 msgid "[lsoda] mxstep < 0\n" msgstr "" -#: lsoda.c:235 +#: lsoda.c:237 msgid "[lsoda] mxhnil < 0\n" msgstr "" -#: lsoda.c:240 +#: lsoda.c:242 #, c-format msgid "[lsoda] mxordn = %d is less than 0\n" msgstr "" -#: lsoda.c:246 +#: lsoda.c:248 #, c-format msgid "[lsoda] mxords = %d is less than 0\n" msgstr "" -#: lsoda.c:253 +#: lsoda.c:255 msgid "[lsoda] hmax < 0.\n" msgstr "" -#: lsoda.c:260 +#: lsoda.c:262 msgid "[lsoda] hmin < 0.\n" msgstr "" -#: lsoda.c:490 +#: lsoda.c:492 #, c-format msgid "unhandled error message: %s\n" msgstr "" -#: lsoda.c:768 +#: lsoda.c:770 #, c-format msgid "lsoda -- warning..internal t = %g and _rxC(h) = %g are\n" msgstr "" -#: lsoda.c:769 +#: lsoda.c:771 msgid " such that in the machine, t + _rxC(h) = t on the next step\n" msgstr "" -#: lsoda.c:770 +#: lsoda.c:772 msgid " solver will continue anyway.\n" msgstr "" -#: lsoda.c:772 +#: lsoda.c:774 #, c-format msgid "lsoda -- above warning has been issued %d times,\n" msgstr "" -#: lsoda.c:773 +#: lsoda.c:775 msgid " it will not be issued again for this problem\n" msgstr "" -#: lsoda.c:805 +#: lsoda.c:807 msgid "[lsoda] a switch to the stiff method has occurred " msgstr "" -#: lsoda.c:807 +#: lsoda.c:809 msgid "[lsoda] a switch to the nonstiff method has occurred" msgstr "" -#: lsoda.c:808 +#: lsoda.c:810 #, c-format msgid "at t = %g, tentative step size _rxC(h) = %g, step _rxC(nst) = %d\n" msgstr "" -#: par_solve.cpp:2729 -msgid "'alag(.)'/'rate(.)'/'dur(.)' cannot depend on the state values" -msgstr "" - -#: par_solve.cpp:2733 -msgid "could not solve the system" -msgstr "" - -#: par_solve.cpp:2735 -msgid "" -"some ID(s) could not solve the ODEs correctly; These values are replaced " -"with 'NA'" -msgstr "" - -#: par_solve.cpp:2807 -#, c-format -msgid "one or more covariates were all 'NA' for subject 'id=%d'" -msgstr "" - -#: par_solve.cpp:3230 -#, c-format -msgid "dose to compartment %d ignored (not in system; 'id=%d')" -msgstr "" - -#: parseLinCmt.c:39 -msgid " with first order absorption\n" -msgstr "" - -#: prja.c:42 +#: prja.c:44 msgid "[prja] _rxC(miter) != 2\n" msgstr "" -#: rxData.cpp:296 +#: rxData.cpp:298 msgid "column(s) in 'drop' were not in solved data" msgstr "" -#: rxData.cpp:444 +#: rxData.cpp:453 #, c-format msgid "refusing to simulate %d items" msgstr "" -#: rxData.cpp:451 +#: rxData.cpp:466 rxData.cpp:470 +msgid "'sigma' is not a matrix" +msgstr "" + +#: rxData.cpp:474 msgid "matrix must be a square matrix" msgstr "" -#: rxData.cpp:459 +#: rxData.cpp:482 msgid "matrix must have named dimensions (try 'lotri')" msgstr "" -#: rxData.cpp:491 +#: rxData.cpp:514 msgid "" "lower bounds needs to be a named vector, a single value or exactly the same " "size" msgstr "" -#: rxData.cpp:511 +#: rxData.cpp:534 msgid "" "upper bounds needs to be a named vector, a single value or exactly the same " "size" msgstr "" -#: rxData.cpp:527 +#: rxData.cpp:550 msgid "t distribution not yet supported" msgstr "" -#: rxData.cpp:807 -msgid "cannot figure out the model variables" -msgstr "" - -#: rxData.cpp:837 rxData.cpp:855 -msgid "class:\t" -msgstr "" - -#: rxData.cpp:843 rxData.cpp:861 -msgid "need an RxODE-type object to extract model variables" -msgstr "" - -#: rxData.cpp:851 -msgid "a NULL object does not have any RxODE model variables" +#: rxData.cpp:884 +msgid "a NULL object does not have any rxode2 model variables" msgstr "" -#: rxData.cpp:896 +#: rxData.cpp:919 msgid "can only lookup one state at a time" msgstr "" -#: rxData.cpp:899 +#: rxData.cpp:922 msgid "only one state variable should be input" msgstr "" -#: rxData.cpp:909 +#: rxData.cpp:932 #, c-format msgid "cannot locate compartment \"%s\"" msgstr "" -#: rxData.cpp:1148 +#: rxData.cpp:1177 msgid "" "only one estimate per named list item; use 'list(x=1)' instead of " "'list(x=1:2)'" msgstr "" -#: rxData.cpp:1155 +#: rxData.cpp:1184 msgid "incompatible initial estimate" msgstr "" -#: rxData.cpp:1210 +#: rxData.cpp:1239 #, c-format msgid "" "trying to scale the same compartment by 'scale=c(%s=%f,...)' and 'S%d=%f' " "choose one" msgstr "" -#: rxData.cpp:1221 +#: rxData.cpp:1250 #, c-format msgid "" "trying to scale the same compartment by 'scale=c(%s=%f,...)' and 's%d=%f' " "choose one" msgstr "" -#: rxData.cpp:1245 -msgid "scaled a compartment that is not defined by the RxODE model" +#: rxData.cpp:1274 +msgid "scaled a compartment that is not defined by the rxode2 model" msgstr "" -#: rxData.cpp:1374 +#: rxData.cpp:1521 msgid "could not allocate memory for solving parameters" msgstr "" -#: rxData.cpp:1418 +#: rxData.cpp:1565 msgid "memory for residual errors could not be allocated" msgstr "" -#: rxData.cpp:1425 +#: rxData.cpp:1572 msgid "cannot allocate memory to simulate the residuals" msgstr "" -#: rxData.cpp:1484 +#: rxData.cpp:1638 rxData.cpp:3030 msgid "'thetaMat' must be a named matrix" msgstr "" -#: rxData.cpp:1492 rxData.cpp:2868 +#: rxData.cpp:1646 rxData.cpp:3255 msgid "'thetaMat' must be symmetric" msgstr "" -#: rxData.cpp:1513 -msgid "'thetaMat' is ignored since nStud <= 1" +#: rxData.cpp:1668 +msgid "" +"'thetaMat' is ignored since nStud <= 1\n" +"use 'simVariability = TRUE' to override." msgstr "" -#: rxData.cpp:1553 +#: rxData.cpp:1715 #, c-format msgid "parameter '%s' was not simulated in 'thetaMat'" msgstr "" -#: rxData.cpp:1562 +#: rxData.cpp:1726 rxData.cpp:1738 #, c-format msgid "'%s' must be a named matrix" msgstr "" -#: rxData.cpp:1572 +#: rxData.cpp:1747 +#, c-format +msgid "error calculating 'chol(%s)'" +msgstr "" + +#: rxData.cpp:1750 #, c-format -msgid "'%s' must be symmetric" +msgid "" +"error trying to correct '%s' to be a symmetric, positive definite matrix" msgstr "" -#: rxData.cpp:1692 -msgid "requires 'params'" +#: rxData.cpp:1754 +#, c-format +msgid "corrected '%s' to be a symmetric, positive definite matrix" msgstr "" -#: rxData.cpp:1697 +#: rxData.cpp:1948 msgid "'params' must be a named vector" msgstr "" -#: rxData.cpp:1718 +#: rxData.cpp:1969 msgid "multi-subject simulation without without 'omega'" msgstr "" -#: rxData.cpp:2069 +#: rxData.cpp:2325 msgid "ran out of memory during 'updateSolveEnvPost'" msgstr "" -#: rxData.cpp:2399 +#: rxData.cpp:2728 msgid "No additional parameters were specified, returning original object" msgstr "" -#: rxData.cpp:2478 +#: rxData.cpp:2807 msgid "can not update object" msgstr "" -#: rxData.cpp:2525 +#: rxData.cpp:2859 msgid "'from' must be of length 1" msgstr "" -#: rxData.cpp:2533 +#: rxData.cpp:2867 msgid "'to' must be of length 1" msgstr "" -#: rxData.cpp:2543 +#: rxData.cpp:2877 msgid "'by' must be of length 1" msgstr "" -#: rxData.cpp:2551 +#: rxData.cpp:2885 msgid "'length.out' must be of length 1" msgstr "" -#: rxData.cpp:2557 -msgid "cannot use both 'by' and 'length.out' for RxODE simulations" +#: rxData.cpp:2891 +msgid "cannot use both 'by' and 'length.out' for rxode2 simulations" +msgstr "" + +#: rxData.cpp:2991 +msgid "rxode2 only supports 500 factors" +msgstr "" + +#: rxData.cpp:3039 +msgid "error calculating 'chol(thetaMat)'" +msgstr "" + +#: rxData.cpp:3042 +msgid "" +"error trying to correct 'thetaMat' to be a symmetric, positive definite " +"matrix" +msgstr "" + +#: rxData.cpp:3045 +msgid "corrected 'thetaMat' to be a symmetric, positive definite matrix" msgstr "" -#: rxData.cpp:2654 -msgid "RxODE only supports 500 factors" +#: rxData.cpp:3181 +msgid "" +"when specifying 'thetaMat' the parameters cannot be a 'data.frame'/'matrix'." msgstr "" -#: rxData.cpp:2797 +#: rxData.cpp:3227 +#, c-format msgid "" -"when specifying 'thetaMat', 'omega', or 'sigma' the parameters cannot be a " -"'data.frame'/'matrix'." +"provided multi-subject data (n=%d) trying to simulate a different number of " +"subjects (n=%d)" msgstr "" -#: rxData.cpp:2920 rxData.cpp:2943 rxData.cpp:2952 +#: rxData.cpp:3314 rxData.cpp:3332 rxData.cpp:3341 msgid "" "if parameters are not named, they must match the order and size of the " "parameters in the model" msgstr "" -#: rxData.cpp:3030 +#: rxData.cpp:3420 msgid "can not allocate enough memory to load 'evid'" msgstr "" -#: rxData.cpp:3074 +#: rxData.cpp:3463 msgid "nothing to solve" msgstr "" -#: rxData.cpp:3128 +#: rxData.cpp:3516 msgid "can not allocate memory for the covariates" msgstr "" -#: rxData.cpp:3215 +#: rxData.cpp:3604 msgid "data must be ordered by 'ID' and 'TIME' variables" msgstr "" -#: rxData.cpp:3285 +#: rxData.cpp:3674 msgid "cannot allocate enough memory to sort input parameters" msgstr "" -#: rxData.cpp:3416 +#: rxData.cpp:3804 msgid "'resample' must be NULL or a character vector" msgstr "" -#: rxData.cpp:3525 +#: rxData.cpp:3913 msgid "nPopPar != 1 but parameters are specified as a NumericVector" msgstr "" -#: rxData.cpp:3636 +#: rxData.cpp:3957 rxData.cpp:4924 rxData.cpp:4933 rxData.cpp:4941 +#: rxData.cpp:4949 rxData.cpp:4957 rxData.cpp:4966 rxData.cpp:4974 +#: rxData.cpp:4981 rxData.cpp:4988 rxData.cpp:4995 rxData.cpp:5002 +#: rxData.cpp:5009 rxData.cpp:5018 rxData.cpp:5028 rxData.cpp:5037 +#: rxData.cpp:5043 rxData.cpp:5050 rxData.cpp:5057 +msgid "ran out of memory" +msgstr "" + +#: rxData.cpp:4027 msgid "Something is wrong" msgstr "" -#: rxData.cpp:3699 +#: rxData.cpp:4045 msgid "aborted solve" msgstr "" -#: rxData.cpp:3723 +#: rxData.cpp:4069 #, c-format msgid "" "exited from at least one while after %d iterations, (increase with " "`rxSolve(..., maxwhile=#)`)" msgstr "" -#: rxData.cpp:4066 +#: rxData.cpp:4411 msgid "zero 'thetaMat' specified, no uncertainty in fixed effects" msgstr "" -#: rxData.cpp:4069 +#: rxData.cpp:4414 msgid "zero 'omega', no variability from random-effects" msgstr "" -#: rxData.cpp:4072 +#: rxData.cpp:4417 msgid "zero 'sigma', no unexplained variability" msgstr "" -#: rxData.cpp:4090 +#: rxData.cpp:4435 msgid "" "dropped key column, returning data.frame instead of special solved data.frame" msgstr "" -#: rxData.cpp:4285 +#: rxData.cpp:4629 msgid "control list not setup correctly" msgstr "" -#: rxData.cpp:4348 -msgid "cannot solve without event information" +#: rxData.cpp:4691 +msgid "" +"cannot solve without event information\n" +"this can occur when the data frame you are providing does not have the " +"column 'time'" msgstr "" -#: rxData.cpp:4358 +#: rxData.cpp:4701 msgid "cannot update this object" msgstr "" -#: rxData.cpp:4414 -msgid "cannot load RxODE dlls for this model" -msgstr "" - -#: rxData.cpp:4467 -msgid "" -"thread safe method, but results may depend on system/load, using 1 core (can " -"change with `cores=`)" +#: rxData.cpp:4759 +msgid "cannot load rxode2 dlls for this model" msgstr "" -#: rxData.cpp:4478 rxData.cpp:4495 +#: rxData.cpp:4828 rxData.cpp:4847 msgid "not thread safe method, using 1 core" msgstr "" -#: rxData.cpp:4487 -msgid "thread safe method, but results may depend on system/load" +#: rxData.cpp:4856 +msgid "since throwing warning with NA time, change to single threaded" msgstr "" -#: rxData.cpp:4551 +#: rxData.cpp:5123 msgid "'infSSstep' needs to be positive" msgstr "" -#: rxData.cpp:4599 -msgid "assumed transit compartment model since 'podo' is in the model" -msgstr "" - -#: rxData.cpp:4635 +#: rxData.cpp:5194 msgid "unknown covariate interpolation specified" msgstr "" -#: rxData.cpp:4726 +#: rxData.cpp:5292 #, c-format msgid "" -"number of parameters (%d) solved by RxODE for multi-subject data needs to be " -"a multiple of the number of subjects (%d)" +"number of parameters (%d) solved by rxode2 for multi-subject data needs to " +"be a multiple of the number of subjects (%d)" msgstr "" -#: rxData.cpp:4844 +#: rxData.cpp:5415 msgid "could not allocate enough memory for solving" msgstr "" -#: rxData.cpp:5237 +#: rxData.cpp:5740 +#, c-format +msgid "partial match of '%s' to '%s'" +msgstr "" + +#: rxData.cpp:5813 msgid "cannot update nonexistent parameters" msgstr "" -#: rxData.cpp:5492 -msgid "Can not figure out the RxODE object" +#: rxData.cpp:6068 +msgid "Can not figure out the rxode2 object" msgstr "" -#: rxData.cpp:5597 rxData.cpp:5640 +#: rxData.cpp:6182 rxData.cpp:6225 msgid "can not figure out the DLL for this object" msgstr "" -#: rxData.cpp:5828 +#: rxData.cpp:6426 msgid "package-based models cannot be unloaded" msgstr "" -#: rxData.cpp:5875 +#: rxData.cpp:6473 msgid "package-based models cannot be deleted" msgstr "" -#: rxInv.cpp:34 +#: rxInv.cpp:36 msgid "matrix seems singular; Using pseudo-inverse\n" msgstr "" -#: rxInv.cpp:55 rxInv.cpp:59 +#: rxInv.cpp:57 rxInv.cpp:61 msgid "can not invert in 'rxToCholOmega'" msgstr "" -#: rxInv.cpp:126 +#: rxInv.cpp:128 msgid "theta number must be positive for 'd(omegaInv)'" msgstr "" -#: rxInv.cpp:130 +#: rxInv.cpp:132 msgid "theta number must be positive for 'd(D)'" msgstr "" -#: rxInv.cpp:163 +#: rxInv.cpp:165 msgid "error in 'rxSymInvCholEnvCalculate' environment" msgstr "" -#: rxInv.cpp:176 +#: rxInv.cpp:178 msgid "theta for omega calculations not setup yet" msgstr "" -#: rxInv.cpp:274 +#: rxInv.cpp:276 #, c-format msgid "theta has to have %d elements" msgstr "" -#: rxInv.cpp:277 +#: rxInv.cpp:279 msgid "Can only assign 'theta' in this environment" msgstr "" -#: sbuf.c:165 -#, c-format -msgid "encoding error in 'addLine' format: '%s' n: %d; errno: %d" -msgstr "" - -#: threefry.cpp:46 threefry.cpp:118 threefry.cpp:701 -msgid "n should be a positive integer" -msgstr "" - -#: threefry.cpp:47 threefry.cpp:119 threefry.cpp:626 threefry.cpp:702 -msgid "'ncores' has to be greater than one" -msgstr "" - -#: threefry.cpp:480 +#: rxode2_df.cpp:143 #, c-format -msgid "dimension wrong in 'gradpsi' (d=%d)" -msgstr "" - -#: threefry.cpp:582 -msgid "covariance matrix is ill-conditioned and method failed (truncated mvn)" -msgstr "" - -#: threefry.cpp:628 -msgid "'lower' and 'upper' must have the same number of elements." -msgstr "" - -#: threefry.cpp:629 msgid "" -"'sigma' must be a square matrix with the same dimension as 'upper' and " -"'lower'" -msgstr "" - -#: threefry.cpp:631 -msgid "'lower' is bigger than 'upper' for at least one item" +"The simulated residual errors do not match the model specification (%d=%d)" msgstr "" -#: threefry.cpp:641 -msgid "truncated multivariate normal may fail as covariance matrix is singular" +#: rxode2_df.cpp:217 +msgid "'alag(.)'/'rate(.)'/'dur(.)' cannot depend on the state values" msgstr "" -#: threefry.cpp:678 -msgid "acceptance probability smaller than 0.001" +#: rxode2_df.cpp:227 +msgid "could not solve the system" msgstr "" -#: threefry.cpp:681 -msgid "could not sample from truncated normal" +#: rxode2_df.cpp:229 +msgid "" +"some ID(s) could not solve the ODEs correctly; These values are replaced " +"with 'NA'" msgstr "" -#: threefry.cpp:683 +#: rxode2_df.cpp:782 #, c-format -msgid "sample of size %d which is smaller than requested 'n' returned" -msgstr "" - -#: threefry.cpp:1447 -msgid "when 'sigma' is a list, it has to have at least 1 element" -msgstr "" - -#: threefry.cpp:1450 -msgid "'sigma' must be a list of square symmetric matrices" +msgid "dose to compartment %d ignored (not in system; 'id=%d')" msgstr "" -#: threefry.cpp:1461 +#: sbuf.c:182 #, c-format -msgid "'sigma' list element %d does not match dimension of first matrix" -msgstr "" - -#: threefry.cpp:1499 -msgid "'mu' length must match 'sigma' dimensions" -msgstr "" - -#: threefry.cpp:1649 -msgid "'prob' function should return a vector the same length as the input" -msgstr "" - -#: utilc.c:60 utilc.c:88 -msgid "'n' must be greater than 0" -msgstr "" - -#: utilc.c:178 -msgid "'phi' requires numeric values" +msgid "encoding error in 'addLine' format: '%s' n: %d; errno: %d" msgstr "" -#: utilc.c:201 utilc.c:256 utilc.c:311 utilc.c:366 utilc.c:423 utilc.c:479 -#: utilc.c:535 utilc.c:593 utilc.c:655 +#: utilc.c:70 utilc.c:125 utilc.c:180 utilc.c:235 utilc.c:292 utilc.c:348 +#: utilc.c:404 utilc.c:462 utilc.c:524 msgid "'a' needs to be a number" msgstr "" -#: utilc.c:209 utilc.c:264 utilc.c:319 utilc.c:374 utilc.c:431 utilc.c:487 -#: utilc.c:543 utilc.c:601 utilc.c:663 +#: utilc.c:78 utilc.c:133 utilc.c:188 utilc.c:243 utilc.c:300 utilc.c:356 +#: utilc.c:412 utilc.c:470 utilc.c:532 msgid "'z' needs to be a number" msgstr "" -#: utilc.c:233 utilc.c:288 utilc.c:343 utilc.c:399 utilc.c:456 utilc.c:512 -#: utilc.c:568 utilc.c:629 utilc.c:691 +#: utilc.c:102 utilc.c:157 utilc.c:212 utilc.c:268 utilc.c:325 utilc.c:381 +#: utilc.c:437 utilc.c:498 utilc.c:560 msgid "inconsistent sizes" msgstr "" -#: utilc.c:719 utilc.c:729 utilc.c:772 utilc.c:782 utilc.c:825 utilc.c:835 -#: utilc.c:879 utilc.c:889 +#: utilc.c:588 utilc.c:598 utilc.c:641 utilc.c:651 utilc.c:694 utilc.c:704 +#: utilc.c:748 utilc.c:758 msgid "'low' must be a numeric of length 1" msgstr "" -#: utilc.c:722 utilc.c:736 utilc.c:775 utilc.c:789 utilc.c:828 utilc.c:842 -#: utilc.c:882 utilc.c:896 +#: utilc.c:591 utilc.c:605 utilc.c:644 utilc.c:658 utilc.c:697 utilc.c:711 +#: utilc.c:751 utilc.c:765 msgid "'high' must be a numeric of length 1" msgstr "" -#: utilc.c:739 utilc.c:792 utilc.c:845 utilc.c:899 +#: utilc.c:608 utilc.c:661 utilc.c:714 utilc.c:768 msgid "'high' must be greater than 'low'" msgstr "" diff --git a/po/zh_CN.po b/po/zh_CN.po index 34dbb3c04..6f80c0612 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Rxode2 1.1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-26 10:39-0500\n" +"POT-Creation-Date: 2023-10-30 08:03-0500\n" "PO-Revision-Date: 2023-07-03 00:00\n" "Last-Translator: FuYongchao <3212418315@qq.com>\n" "Language-Team: FuYongchao <3212418315@qq.com>\n" @@ -17,1440 +17,1420 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: cvPost.cpp:148 -msgid "'shape' must be non-negative" -msgstr "“shape(形状因子)”参数的值必须是非负数的" +#: approx.c:181 +msgid "solve data is not loaded" +msgstr "" -#: cvPost.cpp:169 -msgid "dimension, 'd' of correlation matrix must be > 1" -msgstr "维度数,相关矩阵的维度数“d”必须> 1" +#: dop853.c:403 dop853.c:670 +#, c-format +msgid "exit of dop853 at x = %.16e\n" +msgstr " x = %.16e,dop853\n" -#: cvPost.cpp:172 -msgid "'eta' must be >= 1" -msgstr "“eta”必须>= 1" +#: dop853.c:414 +#, c-format +msgid "exit of dop853 at x = %.16e, more than nmax = %li are needed\n" +msgstr " x = %.16edop853 nmax = %li\n" -#: cvPost.cpp:217 -msgid "log standard deviation size needs to be the same size as the log standard error of the estimate" -msgstr "对数标准差的数量需要与估计值的对数标准误的数量相同" +#: dop853.c:423 +#, c-format +msgid "exit of dop853 at x = %.16e, step size too small h = %.16e\n" +msgstr " x = %.16edop853 h = %.16e\n" -#: cvPost.cpp:243 -msgid "'nu' must be greater than 'd'-1" -msgstr "Wishart分布的自由度“nu”必须大于“d(维数)”-1" +#: dop853.c:555 +#, c-format +msgid "the problem seems to become stiff at x = %.16e\n" +msgstr " x = %.16e \n" -#: cvPost.cpp:316 -msgid "unknown 'diagXformType' transformation" -msgstr "未知的“diagXformType(对角线矩阵X的实现类型)”转换" +#: dop853.c:726 +#, c-format +msgid "system too big, max. n = %u\n" +msgstr " n = %u\n" -#: cvPost.cpp:368 +#: dop853.c:736 #, c-format -msgid "variable 'type': Unrecognized cvPost type='%s'" -msgstr "变量 'type': 无法识别的cvPost类型='%s'" +msgid "wrong input, nmax = %li\n" +msgstr "nmax = %li\n" -#: cvPost.cpp:371 -msgid "variable 'type': Can only use type string or integer[1,3]" -msgstr "变量 'type':只能使用字符串或整数[1,3]" +#: dop853.c:746 +#, c-format +msgid "curious input, meth = %i\n" +msgstr "meth = %i\n" -#: cvPost.cpp:472 +#: dop853.c:760 #, c-format -msgid "variable 'diagXformType': Unrecognized transformation '%s'" -msgstr "变量 'diagXformType(对角线矩阵X的实现类型)':无法识别的实现类型 '%s'" +msgid "wrong input, iout = %i\n" +msgstr "iout = %i\n" -#: cvPost.cpp:477 -msgid "variable 'diagXformType': Can only use transformation string or integer[1,6]" -msgstr "变量 'diagXformType(对角线矩阵X的实现类型)':只能使用字符串或整数[1,6]表示实现类型" +#: dop853.c:768 +#, c-format +msgid "curious input, nrdens = %u\n" +msgstr "nrdens = %u\n" -#: cvPost.cpp:483 -msgid "'n' is determined by the 'omega' argument which contains the simulated standard deviations" -msgstr "‘n’由包含模拟标准差的‘omega’参数确定" +#: dop853.c:789 +msgid "not enough free memory for rcont12345678&indir\n" +msgstr " rcont12345678indir\n" -#: cvPost.cpp:496 -msgid "when sampling from correlation priors to create covariance matrices, the input must be a matrix of standard deviations" -msgstr "从相关性先验中抽样以创建协方差矩阵时,输入必须是一个标准差矩阵" +#: dop853.c:797 +msgid "" +"warning : when nrdens = n there is no need allocating memory for icont\n" +msgstr "nrdens = n icont \n" -#: cvPost.cpp:500 -msgid "'omega' needs to be a matrix or a numeric vector that can be converted to a matrix" -msgstr "‘n’由包含模拟标准差的‘omega’参数确定" +#: dop853.c:803 +#, c-format +msgid "insufficient storage for icont, min. licont = %u\n" +msgstr "icont licont = %u\n" -#: cvPost.cpp:520 -msgid "'thetaMat' needs 'params' to be non-NULL" -msgstr "“thetaMat”需要“参数”为\"非空(non-NULL)\"" +#: dop853.c:976 +#, c-format +msgid "no dense output available for %uth component" +msgstr " %u " -#: cvPost.cpp:535 -msgid "when specifying 'thetaMat', 'omega', or 'sigma' the parameters cannot be a 'data.frame'/'matrix'" -msgstr "指定“thetaMat”、“omega”或“sigma”时,参数不能是一个“data.frame”/“matrix”" +#: expandGrid.cpp:83 +msgid "unanticipated input for rxExpandGrid_" +msgstr "rxExpandGrid_" -#: cvPost.cpp:546 -msgid "'thetaMat' must be a symmetric, positive definite matrix" -msgstr "“thetaMat”必须是对称的正定矩阵" +#: expm.cpp:215 +msgid "requested tolerance is too high" +msgstr "(tolerance)" -#: cvPost.cpp:593 -msgid "'theta' must be the same size as 'thetaMat'" -msgstr "“theta”必须与“thetaMat”大小相同" +#: expm.cpp:413 +#, c-format +msgid "unsupported indLin code: %d" +msgstr "indLin %d" -#: cvPost.cpp:716 -msgid "'omega' must be symmetric, positive definite" -msgstr "“omega”必须是对称的、正定的" +#: forder.cpp:44 +#, fuzzy, c-format +msgid "" +"ignoring invalid %s==\"%s\"\n" +" not an integer >= 1\n" +"remove any characters that are not a digit [0-9]\n" +" See ?rxode2::setDTthreads" +msgstr "" +" %s==%s\n" +" >= 1\n" +"[0-9]\n" +"?Rxode2::setDTthreads" -#: cvPost.cpp:735 -msgid "'omega' needs to be a matrix or lotri matrix" -msgstr "“omega”需要是\"矩阵(matrix)\"或\"lotri matrix\"类型" +#: forder.cpp:70 +#, fuzzy, c-format +msgid "" +"ignoring invalid rxode2_NUM_PROCS_PERCENT==%d.\n" +"If used it must be an integer between 2 and 100. Default is 50. See ?" +"rxSetThreads" +msgstr "" +"RXODE2_NUM_PROCS_PERCENT==%d\n" +" 2 100 50?rxSetThreads" -#: cvPost.cpp:773 cvPost.cpp:814 rxData.cpp:2840 -#, c-format -msgid "provided multi-subject data (n=%d) trying to simulate a different number of subjects (n=%d)" -msgstr "提供多个体数据(n=%d)尝试模拟不同数量的受试者 (n=%d)" +#: forder.cpp:106 +msgid "'verbose' must be TRUE or FALSE" +msgstr "verbose(TRUE)(FALSE)" -#: cvPost.cpp:935 -msgid "'sigma' must be symmetric, positive definite" -msgstr "“sigma”必须是对称的、正定的" +#: forder.cpp:109 +msgid "" +"This installation of data.table has not been compiled with OpenMP support.\n" +msgstr "data.tableOpenMP\n" -#: cvPost.cpp:950 -msgid "'sigma' needs to be a matrix or lotri matrix" -msgstr "“sigma”需要是\"矩阵(matrix)\"或\"lotri matrix\"类型" +#: forder.cpp:114 +#, c-format +msgid " omp_get_num_procs() %d\n" +msgstr " omp_get_num_procs() %d\n" -#: cvPost.cpp:1087 -msgid "un-handled nesting information" -msgstr "未处理的嵌套信息" +#: forder.cpp:115 +#, fuzzy, c-format +msgid " rxode2_NUM_PROCS_PERCENT %s\n" +msgstr " RXODE2_NUM_PROCS_PERCENT %s\n" -#: cvPost.cpp:1111 -msgid "cannot find 'id' column in dataset" -msgstr "在数据集中找不到“id”列" +#: forder.cpp:116 +#, fuzzy, c-format +msgid " rxode2_NUM_THREADS %s\n" +msgstr " RXODE2_NUM_THREADS %s\n" -#: cvPost.cpp:1124 -msgid "'omega' must be a list/lotri/matrix" -msgstr "“omega”必须是\"列表(list)\"/lotri/\"矩阵(matrix)\"类型" +#: forder.cpp:117 +#, fuzzy, c-format +msgid " rxode2_THROTTLE %s\n" +msgstr " RXODE2_THROTTLE %s\n" -#: dop853.c:401 dop853.c:668 +#: forder.cpp:118 #, c-format -msgid "exit of dop853 at x = %.16e\n" -msgstr "在 x = %.16e处,退出dop853\n" +msgid " omp_get_thread_limit() %d\n" +msgstr " omp_get_thread_limit() %d\n" -#: dop853.c:412 +#: forder.cpp:119 #, c-format -msgid "exit of dop853 at x = %.16e, more than nmax = %li are needed\n" -msgstr "在 x = %.16e处退出dop853,需要超过 nmax = %li\n" +msgid " omp_get_max_threads() %d\n" +msgstr " omp_get_max_threads() %d\n" -#: dop853.c:421 +#: forder.cpp:120 #, c-format -msgid "exit of dop853 at x = %.16e, step size too small h = %.16e\n" -msgstr "在 x = %.16e处退出dop853,步长太小 h = %.16e\n" +msgid " OMP_THREAD_LIMIT %s\n" +msgstr " OMP_THREAD_LIMIT %s\n" -#: dop853.c:553 +#: forder.cpp:121 #, c-format -msgid "the problem seems to become stiff at x = %.16e\n" -msgstr "问题似乎在 x = %.16e 时变得刚性\n" +msgid " OMP_NUM_THREADS %s\n" +msgstr " OMP_NUM_THREADS %s\n" -#: dop853.c:724 -#, c-format -msgid "system too big, max. n = %u\n" -msgstr "系统太大,最大值 n = %u\n" +#: forder.cpp:123 +#, fuzzy, c-format +msgid " rxode2 is using %d threads with throttle==%d. See ?setRxthreads.\n" +msgstr " Rxode2 %dthrottle==%d?setRxthreads\n" -#: dop853.c:734 -#, c-format -msgid "wrong input, nmax = %li\n" -msgstr "错误的输入,nmax = %li\n" +#: forder.cpp:131 +msgid "'throttle' must be a single number, non-NA, and >=1" +msgstr "throttleNA >=1" -#: dop853.c:744 -#, c-format -msgid "curious input, meth = %i\n" -msgstr "奇异的输入,meth = %i\n" +#: forder.cpp:145 +msgid "threads= must be either NULL or a single number >= 0 See ?setRxthreads" +msgstr "threads=NULL>=0?setRxthreads" -#: dop853.c:758 -#, c-format -msgid "wrong input, iout = %i\n" -msgstr "错误的输入,iout = %i\n" +#: forder.cpp:149 +msgid "internal error: percent= must be TRUE or FALSE at C level" +msgstr "percent()= CTRUEFALSE" -#: dop853.c:766 +#: forder.cpp:152 #, c-format -msgid "curious input, nrdens = %u\n" -msgstr "奇异的输入,nrdens = %u\n" +msgid "" +"internal error: threads==%d should be between 2 and 100 (percent=TRUE at C " +"level)" +msgstr "threads==%d 2 100 C percent()=TRUE" -#: dop853.c:787 -msgid "not enough free memory for rcont12345678&indir\n" -msgstr "没有足够的可用内存用于 rcont12345678和indir\n" +#: handle_evid.c:44 +#, fuzzy +msgid "could not find a start to the infusion #1" +msgstr "" + +#: handle_evid.c:51 +#, fuzzy +msgid "could not find a start to the infusion #2" +msgstr "" -#: dop853.c:795 -msgid "warning : when nrdens = n there is no need allocating memory for icont\n" -msgstr "警告:当nrdens = n时,不需要为 icont 分配内存\n" +#: handle_evid.c:57 handle_evid.c:65 +msgid "could not find an end to the infusion" +msgstr "" -#: dop853.c:801 +#: intdy.c:52 #, c-format -msgid "insufficient storage for icont, min. licont = %u\n" -msgstr "icont的存储空间不足,最小 licont = %u\n" +msgid "[intdy] k = %d illegal\n" +msgstr "[intdy] k = %d \n" -#: dop853.c:974 +#: intdy.c:57 #, c-format -msgid "no dense output available for %uth component" -msgstr "没有可用于第 %u 分量的密集输出" +msgid "intdy -- t = %g illegal. t not in interval tcur - _rxC(hu) to tcur\n" +msgstr "intdy -- t = %g ttcur - _rxChutcur\n" -#: et.cpp:142 rxData.cpp:5164 +#: lsoda.c:223 #, c-format -msgid "partial match of '%s' to '%s'" -msgstr "“%s”与“%s”部分匹配" +msgid "[lsoda] illegal itask = %d\n" +msgstr "[lsoda]itask = %d\n" -#: et.cpp:403 -msgid "event table was not updated (no dose/sampling windows)" -msgstr "事件表未更新(无给药/采样时间窗)" +#: lsoda.c:228 +#, c-format +msgid "[lsoda] ixpr = %d is illegal\n" +msgstr "[lsoda] ixpr = %d\n" -#: et.cpp:480 -msgid "windows need to be a list of observation windows, each of 2 elements e.g. list(c(0,2), c(2,7))" -msgstr "时间窗必须是观测的时间窗的\"列表(list)\",每个时间窗有两个元素,例如列表(C(0,2)、C(2,7))" +#: lsoda.c:232 +msgid "[lsoda] mxstep < 0\n" +msgstr "[lsoda]mxstep< 0\n" -#: et.cpp:482 -msgid "windows need to be ordered list(c(2,0)) is invalid" -msgstr "Windows需要排序,list(c(2,0))无效" +#: lsoda.c:237 +msgid "[lsoda] mxhnil < 0\n" +msgstr "[lsoda] mxhnil < 0\n" -#: et.cpp:881 et.cpp:898 +#: lsoda.c:242 #, c-format -msgid "unknown method: '%s'" -msgstr "未知的方法:“%s”" - -#: et.cpp:939 etTran.cpp:451 -msgid "can only specify either 'amt' or 'value'" -msgstr "只能指定“amt”或“value”" +msgid "[lsoda] mxordn = %d is less than 0\n" +msgstr "[lsoda] mxordn = %d0\n" -#: et.cpp:943 etTran.cpp:455 -msgid "can only specify either 'cmt', 'ytype', 'state' or 'var'" -msgstr "只能指定“cmt”、“ytype”、“state”或“var”" +#: lsoda.c:248 +#, c-format +msgid "[lsoda] mxords = %d is less than 0\n" +msgstr "[lsoda] mxords = %d0\n" -#: et.cpp:951 -msgid "can only specify either 'duration' or 'dur'" -msgstr "只能指定“duration”或“dur”" +#: lsoda.c:255 +msgid "[lsoda] hmax < 0.\n" +msgstr "[lsoda] hmax < 0.\n" -#: et.cpp:959 -msgid "need a 'time' column" -msgstr "需要一个“time(时间)”列" +#: lsoda.c:262 +msgid "[lsoda] hmin < 0.\n" +msgstr "[lsoda] hmin < 0.\n" -#: et.cpp:969 -msgid "using 'mdv' instead of 'method'" -msgstr "应使用“mdv”而不是“method”" +#: lsoda.c:492 +#, c-format +msgid "unhandled error message: %s\n" +msgstr " %s\n" -#: et.cpp:979 -msgid "using 'evid' instead of 'mdv'" -msgstr "应使用“evid”而不是“mdv”" +#: lsoda.c:770 +#, c-format +msgid "lsoda -- warning..internal t = %g and _rxC(h) = %g are\n" +msgstr "lsoda -- .. t = %g _rxCh = %g \n" -#: et.cpp:994 -msgid "'ID' type is unknown" -msgstr "“ID”的类型未知" +#: lsoda.c:771 +msgid " such that in the machine, t + _rxC(h) = t on the next step\n" +msgstr " t _rxCh = t\n" -#: et.cpp:1081 -msgid "can not figure out how to import the compartment variable" -msgstr "无法弄清楚如何导入\"compartment(房室)\"变量" +#: lsoda.c:772 +msgid " solver will continue anyway.\n" +msgstr " \n" -#: et.cpp:1152 et.cpp:1154 -msgid "replacement/multiplication events cannot be combined with infusions" -msgstr "\"替换(replacement)\"/\"倍数(multiplication)\"事件不能与输注联合使用" +#: lsoda.c:774 +#, c-format +msgid "lsoda -- above warning has been issued %d times,\n" +msgstr "lsoda -- %d \n" -#: et.cpp:1168 -msgid "old Rxode2 'evid' values are not supported with string compartments" -msgstr "文本型房室不支持旧版 Rxode2的“evid”值" +#: lsoda.c:775 +msgid " it will not be issued again for this problem\n" +msgstr " \n" -#: et.cpp:1381 -msgid "'amt'/'time' needs units to convert the rate to the right units to import the data" -msgstr "“amt”/“time”需要单位将速率转换为正确的单位以导入数据" +#: lsoda.c:807 +msgid "[lsoda] a switch to the stiff method has occurred " +msgstr "[LSODA] " -#: et.cpp:1636 -msgid "'do.sampling' is not supported with dose windows" -msgstr "给药时间窗不支持\"do.sampling\"" +#: lsoda.c:809 +msgid "[lsoda] a switch to the nonstiff method has occurred" +msgstr "[LSODA] " -#: et.cpp:1658 -msgid "dosing window you need to specify window in order, e.g. 'et(time=list(c(0,2)),amt=3)'" -msgstr "给药时间窗您需要按顺序指定时间窗,例如'et(time=list(c(0,2)),amt=3)'" +#: lsoda.c:810 +#, c-format +msgid "at t = %g, tentative step size _rxC(h) = %g, step _rxC(nst) = %d\n" +msgstr " t = %g _rxCh = %g _rxCnst = %d\n" -#: et.cpp:1661 -msgid "dosing time or time windows must only be 1-2 elements" -msgstr "给药时间或时间时间窗只能是1~2个元素" +#: prja.c:44 +msgid "[prja] _rxC(miter) != 2\n" +msgstr "[prja] _rxC(miter) != 2\n" -#: et.cpp:1922 -msgid "cannot mix named compartments and integer compartments" -msgstr "不能混合使用命名的房室和整数房室" +#: rxData.cpp:298 +msgid "column(s) in 'drop' were not in solved data" +msgstr "drop()" -#: et.cpp:2026 et.cpp:2188 -msgid "cannot add more 'ID's to this event table" -msgstr "无法向此事件表添加更多“ID”" +#: rxData.cpp:453 +#, c-format +msgid "refusing to simulate %d items" +msgstr " %d " -#: et.cpp:2256 -msgid "can only have one of the following: 'amt', 'dose'" -msgstr "只能具有以下其中一项:“amt”、“dose”" +#: rxData.cpp:466 rxData.cpp:470 +#, fuzzy +msgid "'sigma' is not a matrix" +msgstr "'%s' " -#: et.cpp:2263 -msgid "can only have one of the following: 'ii', 'dosing.interval', 'dosingInterval' or 'dosing_interval'" -msgstr "只能具有以下其中一项:“ii”、“dosing.interval”、“dosingInterva”或“dosing_interval”" +#: rxData.cpp:474 +msgid "matrix must be a square matrix" +msgstr "" -#: et.cpp:2283 -msgid "can only have one of the following: 'cmt', 'dosing.to', 'dose.to', 'state'" -msgstr "只能具有以下其中一项:“cmt”、“dosing.to”、“dose.to”、“state”" +#: rxData.cpp:482 +msgid "matrix must have named dimensions (try 'lotri')" +msgstr "lotri" -#: et.cpp:2292 -msgid "can only have one of the following: 'amount.units', 'amt.units', 'dose.units'" -msgstr "只能具有以下之一:“'amount.units”、“'amt.units”、“dose.units”" +#: rxData.cpp:514 +msgid "" +"lower bounds needs to be a named vector, a single value or exactly the same " +"size" +msgstr "" -#: et.cpp:2299 -msgid "can only have one of the following: 'time.units', 'timeUnits', 'time_units'" -msgstr "只能具有以下其中一项:“time.units”、“timeUnits”、“time_units”" +#: rxData.cpp:534 +msgid "" +"upper bounds needs to be a named vector, a single value or exactly the same " +"size" +msgstr "" -#: et.cpp:2307 -msgid "can only have one of the following: 'add.sampling', 'do.sampling'" -msgstr "只能具有以下其中一项:“add.sampling”、“do.sampling”" +#: rxData.cpp:550 +msgid "t distribution not yet supported" +msgstr "t" -#: et.cpp:2315 -msgid "can only have one of the following: 'time', 'start.time', 'from'" -msgstr "只能具有以下其中一项:“time”、“start.time”、“from”" +#: rxData.cpp:884 +#, fuzzy +msgid "a NULL object does not have any rxode2 model variables" +msgstr "NULL Rxode2 " -#: et.cpp:2321 -msgid "can only have one of the following: 'nbrDoses', 'nbr.doses'" -msgstr "只能具有以下其中一项:“nbrDoses”、“nbr.doses”" +#: rxData.cpp:919 +msgid "can only lookup one state at a time" +msgstr "" -#: et.cpp:2336 -msgid "can only have one of the following: 'dur', 'duration'" -msgstr "只能具有以下其中一项:“dur”、“duration”" +#: rxData.cpp:922 +msgid "only one state variable should be input" +msgstr "" -#: et.cpp:2343 +#: rxData.cpp:932 #, c-format -msgid "unused argument '%s'" -msgstr "未使用的参数 '%s'" - -#: et.cpp:2354 et.cpp:2359 et.cpp:2374 et.cpp:2379 -msgid "multiple event tables supplied, not sure what to do; try 'c', 'rbind', 'seq' or 'rep'" -msgstr "提供了多个事件表,不知道该如何使用;尝试“c”、“rbind”、“seq”或“rep”" +msgid "cannot locate compartment \"%s\"" +msgstr "%s" -#: et.cpp:2397 et.cpp:2405 et.cpp:2650 et.cpp:2673 et.cpp:2708 et.cpp:2729 -#: et.cpp:2736 et.cpp:2747 et.cpp:2766 et.cpp:2831 et.cpp:2859 et.cpp:2882 -#: et.cpp:2895 et.cpp:2924 et.cpp:2928 et.cpp:2937 et.cpp:3061 et.cpp:3069 -#, c-format -msgid "'%s' cannot be a vector" -msgstr "'%s' 不能是一个向量" +#: rxData.cpp:1177 +msgid "" +"only one estimate per named list item; use 'list(x=1)' instead of " +"'list(x=1:2)'" +msgstr "\"list()\";'list(x=1)'list(x=1:2)" -#: et.cpp:2561 et.cpp:2565 -msgid "nothing done" -msgstr "什么也没做" +#: rxData.cpp:1184 +msgid "incompatible initial estimate" +msgstr "" -#: et.cpp:2611 +#: rxData.cpp:1239 #, c-format -msgid "cannot mix named and integer compartments in '%s'" -msgstr "不能在 '%s' 中混合使用命名的房室和整数房室" +msgid "" +"trying to scale the same compartment by 'scale=c(%s=%f,...)' and 'S%d=%f' " +"choose one" +msgstr "\"(scale)\"scale=c%s=%f,...S%d=%f" -#: et.cpp:2619 +#: rxData.cpp:1250 #, c-format -msgid "'%s' compartment cannot be a vector" -msgstr "“%s”房室不能是一个向量" +msgid "" +"trying to scale the same compartment by 'scale=c(%s=%f,...)' and 's%d=%f' " +"choose one" +msgstr "\"(scale)\"scale=c%s=%f,...s%d=%f" -#: et.cpp:2631 -#, c-format -msgid "'%s' cannot be zero" -msgstr "'%s' 不能为零" +#: rxData.cpp:1274 +#, fuzzy +msgid "scaled a compartment that is not defined by the rxode2 model" +msgstr "\"(scale)\" Rxode2 " -#: et.cpp:2635 -#, c-format -msgid "'%s' cannot be an vector" -msgstr "'%s' 不能是一个向量" +#: rxData.cpp:1521 +msgid "could not allocate memory for solving parameters" +msgstr "" -#: et.cpp:2638 -#, c-format -msgid "'%s' must be an integer or a character" -msgstr "'%s' 必须是\"整数型(integer)\"或\"字符型(character)\"" +#: rxData.cpp:1565 +msgid "memory for residual errors could not be allocated" +msgstr "" -#: et.cpp:2677 -#, c-format -msgid "turning off compartments can only be done when '%s'=2" -msgstr "仅能在 '%s' = 2 时才能关闭房室" +#: rxData.cpp:1572 +msgid "cannot allocate memory to simulate the residuals" +msgstr "" -#: et.cpp:2680 -#, c-format -msgid "zero '%s' cannot be used with '%s'" -msgstr "零个“%s”不能与“%s”一起使用" +#: rxData.cpp:1638 rxData.cpp:3030 +msgid "'thetaMat' must be a named matrix" +msgstr "thetaMat" -#: et.cpp:2683 -#, c-format -msgid "'%s' requires an '%s'" -msgstr "“%s”需要是一个“%s”" +#: rxData.cpp:1646 rxData.cpp:3255 +msgid "'thetaMat' must be symmetric" +msgstr "thetaMat" -#: et.cpp:2687 +#: rxData.cpp:1668 +#, fuzzy +msgid "" +"'thetaMat' is ignored since nStud <= 1\n" +"use 'simVariability = TRUE' to override." +msgstr "'thetaMat' nStud <= 1" + +#: rxData.cpp:1715 #, c-format -msgid "'%s' is ignored when '%s'=2 or '%s'=3" -msgstr "当“%s”=2 或“%s”=3 时,将忽略“%s”" +msgid "parameter '%s' was not simulated in 'thetaMat'" +msgstr " '%s' 'thetaMat' " -#: et.cpp:2710 et.cpp:2717 et.cpp:2720 et.cpp:2731 et.cpp:2738 +#: rxData.cpp:1726 rxData.cpp:1738 #, c-format -msgid "'%s' needs a '%s'" -msgstr "“%s”需要一个“%s”" +msgid "'%s' must be a named matrix" +msgstr "'%s' " -#: et.cpp:2725 +#: rxData.cpp:1747 #, c-format -msgid "can not specify '%s' and '%s' for a dose, please pick one" -msgstr "不能指定“%s”和“%s”作为给药,请选择一个" +msgid "error calculating 'chol(%s)'" +msgstr "" -#: et.cpp:2749 -msgid "'ii' needs a 'dose'/'amt'" -msgstr "“ii(给药间隔)”需要“dose(给药)”/“amt(药量)”" +#: rxData.cpp:1750 +#, fuzzy, c-format +msgid "" +"error trying to correct '%s' to be a symmetric, positive definite matrix" +msgstr "thetaMat" -#: et.cpp:2760 -msgid "dosing interval of zero makes no sense with multiple dose events" -msgstr "给药间隔为零对于多次给药事件毫无意义" +#: rxData.cpp:1754 +#, fuzzy, c-format +msgid "corrected '%s' to be a symmetric, positive definite matrix" +msgstr "thetaMat" -#: et.cpp:2768 et.cpp:2900 -#, c-format -msgid "non-zero '%s' needs a '%s'" -msgstr "非零'%s' 需要一个'%s'" +#: rxData.cpp:1948 +msgid "'params' must be a named vector" +msgstr "params()" -#: et.cpp:2805 et.cpp:2808 et.cpp:2811 -#, c-format -msgid "can only specify '%s' or '%s', not both" -msgstr "只能指定“%s”或“%s”,不能同时指定两者" +#: rxData.cpp:1969 +msgid "multi-subject simulation without without 'omega'" +msgstr "'omega'" -#: et.cpp:2817 -#, c-format -msgid "'%s' can only have one item" -msgstr "'%s' 只能有一个项目" +#: rxData.cpp:2325 +msgid "ran out of memory during 'updateSolveEnvPost'" +msgstr "updateSolveEnvPost" -#: et.cpp:2820 -#, c-format -msgid "'%s' must be logical" -msgstr "'%s' 必须是逻辑的" +#: rxData.cpp:2728 +msgid "No additional parameters were specified, returning original object" +msgstr "" -#: et.cpp:2827 -#, c-format -msgid "cannot specify '%s' and '%s' for a dose, please pick one" -msgstr "不能为给药指定“%s”和“%s”,请选择一个" +#: rxData.cpp:2807 +msgid "can not update object" +msgstr "" -#: et.cpp:2838 -msgid "-1 and -2 rates do not make sense with units" -msgstr "-1 和 -2 速率(rate)对单位没有意义" +#: rxData.cpp:2859 +msgid "'from' must be of length 1" +msgstr "from 1" -#: et.cpp:2843 -#, c-format -msgid "'%s' is cannot be converted and added to this table" -msgstr "“%s”是无法被转换并添加到此表中" +#: rxData.cpp:2867 +msgid "'to' must be of length 1" +msgstr "to 1" -#: et.cpp:2850 -#, c-format -msgid "steady state constant infusion dosing records must have '%s=-1' or positive rate" -msgstr "稳态恒速输注给药记录必须具有“%s=-1”或正数的速率(rate)" +#: rxData.cpp:2877 +msgid "'by' must be of length 1" +msgstr "by 1" -#: et.cpp:2869 -#, c-format -msgid "'%s' cannot be converted and added to this table" -msgstr "“%s”无法被转换并添加到此表中" +#: rxData.cpp:2885 +msgid "'length.out' must be of length 1" +msgstr "length.out 1" -#: et.cpp:2930 -#, c-format -msgid "number of doses must be at least one ('%s': %d)" -msgstr "给药数必须至少为一(“%s”: %d)" +#: rxData.cpp:2891 +#, fuzzy +msgid "cannot use both 'by' and 'length.out' for rxode2 simulations" +msgstr "bylength.outRxode2" -#: et.cpp:2939 -#, c-format -msgid "'%s' can only be used with positive inter-dose intervals ('%s')" -msgstr "“%s”只能与正数的给药间隔(“%s”)一起使用" +#: rxData.cpp:2991 +#, fuzzy +msgid "rxode2 only supports 500 factors" +msgstr "Rxode2 500 " -#: et.cpp:2949 -#, c-format -msgid "'%s' does not make sense with multiple dosing times" -msgstr "'%s' 在多次给药时没有意义" +#: rxData.cpp:3039 +msgid "error calculating 'chol(thetaMat)'" +msgstr "" -#: et.cpp:2978 -msgid "dosing windows can only have 1-2 items in them" -msgstr "给药时间窗只能有1-2个项" +#: rxData.cpp:3042 +#, fuzzy +msgid "" +"error trying to correct 'thetaMat' to be a symmetric, positive definite " +"matrix" +msgstr "thetaMat" -#: et.cpp:2987 -#, c-format -msgid "'%s' requires non zero additional doses ('%s') or steady state dosing ('%s': %f, '%s': %d; '%s': %d), reset '%s' to zero." -msgstr "“%s”需要非零额外附加给药(“%s”)或稳态给药(“%s”:%f,“%s”:%d;“%s”: %d),将“%s”重置为零。" +#: rxData.cpp:3045 +#, fuzzy +msgid "corrected 'thetaMat' to be a symmetric, positive definite matrix" +msgstr "thetaMat" -#: et.cpp:2993 -#, c-format -msgid "'%s' must be 1 when specifying a steady-state constant infusion" -msgstr "当描述为稳态恒速输注时,'%s' 必须为 1" +#: rxData.cpp:3181 +#, fuzzy +msgid "" +"when specifying 'thetaMat' the parameters cannot be a 'data.frame'/'matrix'." +msgstr "thetaMatomegasigmadata.frame/matrix" -#: et.cpp:2996 +#: rxData.cpp:3227 #, c-format -msgid "'%s' must be 0, 1 or 2" -msgstr "'%s' 必须为 0、1 或 2" +msgid "" +"provided multi-subject data (n=%d) trying to simulate a different number of " +"subjects (n=%d)" +msgstr "n=%d n=%d" -#: et.cpp:2999 -#, c-format -msgid "'%s' required with '%s'" -msgstr "“%s”和“%s”是必需的" +#: rxData.cpp:3314 rxData.cpp:3332 rxData.cpp:3341 +msgid "" +"if parameters are not named, they must match the order and size of the " +"parameters in the model" +msgstr "" -#: et.cpp:3003 -#, c-format -msgid "'%s' cannot be used with steady state constant infusion" -msgstr "'%s' 不能与稳态恒速输注一起使用" +#: rxData.cpp:3420 +msgid "can not allocate enough memory to load 'evid'" +msgstr "evid" -#: et.cpp:3006 -#, c-format -msgid "steady state ('%s') is not supported with dosing windows" -msgstr "给药时间窗不支持稳定状态('%s')" +#: rxData.cpp:3463 +msgid "nothing to solve" +msgstr "" -#: et.cpp:3009 -#, c-format -msgid "additional doses must be positive ('%s'=%d)" -msgstr "额外的附加给药必须为正数('%s'=%d)" +#: rxData.cpp:3516 +msgid "can not allocate memory for the covariates" +msgstr "" -#: et.cpp:3012 -#, c-format -msgid "additional doses require an inter-dose interval ('%s')" -msgstr "额外的附加给药需要给药间隔(“%s”)" +#: rxData.cpp:3604 +msgid "data must be ordered by 'ID' and 'TIME' variables" +msgstr "IDTIME" -#: et.cpp:3017 -#, c-format -msgid "for steady state infusions, you need %s=0, %s>0, %s=1, %s=0" -msgstr "对于稳态输注,您需要 %s=0、%s>0、%s=1、%s=0" +#: rxData.cpp:3674 +msgid "cannot allocate enough memory to sort input parameters" +msgstr "" -#: et.cpp:3030 -msgid "dosing time window lists can have 1-2 numeric entries in them" -msgstr "给药时间窗列表中可以包含1-2个数字项" +#: rxData.cpp:3804 +msgid "'resample' must be NULL or a character vector" +msgstr "resample() NULL " -#: et.cpp:3035 -msgid "dosing window list needs to be numeric values only" -msgstr "给药时间窗列表只需要是数值的值" +#: rxData.cpp:3913 +msgid "nPopPar != 1 but parameters are specified as a NumericVector" +msgstr "nPopPar != 1" + +#: rxData.cpp:3957 rxData.cpp:4924 rxData.cpp:4933 rxData.cpp:4941 +#: rxData.cpp:4949 rxData.cpp:4957 rxData.cpp:4966 rxData.cpp:4974 +#: rxData.cpp:4981 rxData.cpp:4988 rxData.cpp:4995 rxData.cpp:5002 +#: rxData.cpp:5009 rxData.cpp:5018 rxData.cpp:5028 rxData.cpp:5037 +#: rxData.cpp:5043 rxData.cpp:5050 rxData.cpp:5057 +msgid "ran out of memory" +msgstr "" -#: et.cpp:3088 -msgid "cannot figure out what type of 'EventTable' you are trying to create" -msgstr "无法弄清楚您尝试创建的“事件表”类型" +#: rxData.cpp:4027 +msgid "Something is wrong" +msgstr "" -#: et.cpp:3173 et.cpp:3176 -msgid "cannot have event tables with integer and character 'cmt'" -msgstr "事件表中整数和字符“cmt”不能混合使用" +#: rxData.cpp:4045 +msgid "aborted solve" +msgstr "" -#: et.cpp:3261 +#: rxData.cpp:4069 #, c-format -msgid "assumed a dose interval of %.1f between event tables; use 'ii' to adjust" -msgstr "假设事件表之间的给药间隔为%.1f;使用“ii”进行调整" +msgid "" +"exited from at least one while after %d iterations, (increase with " +"`rxSolve(..., maxwhile=#)`)" +msgstr "%d(' rxSolve(,maxwhile = #))" -#: et.cpp:3347 -msgid "no events table found for 'seq'/'rep'/'rbind'/'c'" -msgstr "未找到用于“seq”/“rep”/“rbind”/“c”的事件表" +#: rxData.cpp:4411 +msgid "zero 'thetaMat' specified, no uncertainty in fixed effects" +msgstr "thetaMat" -#: et.cpp:3468 -msgid "'wait' cannot be a vector" -msgstr "“wait”不能是向量" +#: rxData.cpp:4414 +msgid "zero 'omega', no variability from random-effects" +msgstr "omega" -#: etTran.cpp:141 -#, c-format -msgid "negative compartments on non-ode 'cmt' (%s) does not make sense (id: %s, row: %d)" -msgstr "non-ode 'cmt'(%s)上的负数房室没有意义(ID: %s, 行: %d)" +#: rxData.cpp:4417 +msgid "zero 'sigma', no unexplained variability" +msgstr "sigma" -#: etTran.cpp:276 etTran.cpp:286 -#, c-format -msgid "negative compartments on non-ode 'cmt' (%s) does not make sense (id: %s row: %d)" -msgstr "non-ode 'cmt'(%s)上的负数房室没有意义(ID: %s, 行: %d)" +#: rxData.cpp:4435 +msgid "" +"dropped key column, returning data.frame instead of special solved data.frame" +msgstr "data.framedata.frame" + +#: rxData.cpp:4629 +msgid "control list not setup correctly" +msgstr "" -#: etTran.cpp:307 -msgid "should not reach here" -msgstr "不应该到达这里" +#: rxData.cpp:4691 +msgid "" +"cannot solve without event information\n" +"this can occur when the data frame you are providing does not have the " +"column 'time'" +msgstr "" + +#: rxData.cpp:4701 +msgid "cannot update this object" +msgstr "" + +#: rxData.cpp:4759 +#, fuzzy +msgid "cannot load rxode2 dlls for this model" +msgstr " Rxode2 dll" + +#: rxData.cpp:4828 rxData.cpp:4847 +msgid "not thread safe method, using 1 core" +msgstr " 1 " -#: etTran.cpp:471 -msgid "cannot keep 'evid'; try 'addDosing'" -msgstr "不能保持“evid”;尝试“adDosing”" +#: rxData.cpp:4856 +msgid "since throwing warning with NA time, change to single threaded" +msgstr "" -#: etTran.cpp:616 -msgid "'time' is required in dataset" -msgstr "数据集中需要“time”" +#: rxData.cpp:5123 +msgid "'infSSstep' needs to be positive" +msgstr "infSSstep" -#: etTran.cpp:708 -msgid "steady state column ('ss') needs to be an integer" -msgstr "稳态列 ('ss') 需要是一个整数" +#: rxData.cpp:5194 +msgid "unknown covariate interpolation specified" +msgstr "" -#: etTran.cpp:719 -msgid "event id ('evid') needs to be an integer" -msgstr "事件id列('evid') 需要为整数" +#: rxData.cpp:5292 +#, fuzzy, c-format +msgid "" +"number of parameters (%d) solved by rxode2 for multi-subject data needs to " +"be a multiple of the number of subjects (%d)" +msgstr "Rxode2%d" -#: etTran.cpp:728 -msgid "missing DV ('mdv') needs to be an integer" -msgstr "视为因变量缺失列('mdv') 需要是一个整数" +#: rxData.cpp:5415 +msgid "could not allocate enough memory for solving" +msgstr "" -#: etTran.cpp:742 -msgid "missing dependent variable ('mdv') needs to be an integer" -msgstr "视为因变量缺失列('MDV') 需要是一个整数" +#: rxData.cpp:5740 +#, c-format +msgid "partial match of '%s' to '%s'" +msgstr "%s%s" -#: etTran.cpp:750 -msgid "'rate' needs to be a number" -msgstr "“rate(速率)”列需要是一个数字" +#: rxData.cpp:5813 +msgid "cannot update nonexistent parameters" +msgstr "" -#: etTran.cpp:759 -msgid "'dur' needs to be a number" -msgstr "“dur(持续时长)”列需要是一个数字" +#: rxData.cpp:6068 +#, fuzzy +msgid "Can not figure out the rxode2 object" +msgstr " Rxode2 " -#: etTran.cpp:774 -msgid "amount ('amt') needs to be a number" -msgstr "药量(“amt”)列需要是一个数字" +#: rxData.cpp:6182 rxData.cpp:6225 +msgid "can not figure out the DLL for this object" +msgstr " DLL" -#: etTran.cpp:782 -msgid "inter-dose interval ('ii') needs to be a number" -msgstr "给药间隔列('ii') 需要是一个数字" +#: rxData.cpp:6426 +msgid "package-based models cannot be unloaded" +msgstr "\"(unloaded)\"" -#: etTran.cpp:790 -msgid "number of additional doses ('addl') needs to be an integer" -msgstr "额外的附件给药次数列('addl') 需要是一个整数" +#: rxData.cpp:6473 +msgid "package-based models cannot be deleted" +msgstr "" -#: etTran.cpp:798 -msgid "dependent variable ('dv') needs to be a number" -msgstr "因变量列('dv') 需要是一个数字" +#: rxInv.cpp:36 +msgid "matrix seems singular; Using pseudo-inverse\n" +msgstr ";\n" -#: etTran.cpp:806 -msgid "censoring variable ('cens') needs to be a number" -msgstr "删失变量列(“cens”)需要是一个数字" +#: rxInv.cpp:57 rxInv.cpp:61 +msgid "can not invert in 'rxToCholOmega'" +msgstr "rxToCholOmega" -#: etTran.cpp:814 -msgid "limit variable ('limit') needs to be a number" -msgstr "定量限变量列(“limit”)需要是一个数字" +#: rxInv.cpp:128 +msgid "theta number must be positive for 'd(omegaInv)'" +msgstr "theta'd(omegaInv)'" -#: etTran.cpp:863 -#, c-format -msgid "censoring column can only be -1, 0 or 1 (id: %s, row: %d)" -msgstr "删失列只能为 -1、0 或 1(id: %s,row: %d)" +#: rxInv.cpp:132 +msgid "theta number must be positive for 'd(D)'" +msgstr "theta''d(D)'" -#: etTran.cpp:888 -#, c-format -msgid "infinite times are not allowed (id: %s, row: %d)" -msgstr "不允许无穷大的时间(id: %s,row: %d)" +#: rxInv.cpp:165 +msgid "error in 'rxSymInvCholEnvCalculate' environment" +msgstr "rxSymInvCholEnvCalculate" -#: etTran.cpp:946 -#, c-format -msgid "steady state records cannot be on negative compartments (id: %s, row: %d)" -msgstr "达到稳态的记录不能位负数的房室上(id: %s,row: %d)" +#: rxInv.cpp:178 +msgid "theta for omega calculations not setup yet" +msgstr "omegatheta" -#: etTran.cpp:976 +#: rxInv.cpp:276 #, c-format -msgid "when using steady state constant infusion modeling duration does not make sense (id: %s, row: %d)" -msgstr "使用稳态恒速输注建模时,输注持续时间没有意义(id: %s,row: %d)" +msgid "theta has to have %d elements" +msgstr "theta %d " -#: etTran.cpp:995 -#, c-format -msgid "specifying duration with a steady state constant infusion makes no sense (id: %s row: %d)" -msgstr "使用稳态恒速输注时,指定输注持续时长没有意义(id: %s,row: %d)" +#: rxInv.cpp:279 +msgid "Can only assign 'theta' in this environment" +msgstr "theta" -#: etTran.cpp:1001 etTran.cpp:1007 +#: rxode2_df.cpp:143 #, c-format -msgid "specifying duration with a steady state constant infusion makes no sense (id: %d row: %d)" -msgstr "使用稳态恒速输注时,指定输注持续时长没有意义(id: %d, row: %d)" +msgid "" +"The simulated residual errors do not match the model specification (%d=%d)" +msgstr "" -#: etTran.cpp:1018 -#, c-format -msgid "'rate' and/or 'dur' are not specified correctly (id: %d row: %d)" -msgstr "未正确指定“rate”和/或“dur”(id: %s,row: %d)" +#: rxode2_df.cpp:217 +msgid "'alag(.)'/'rate(.)'/'dur(.)' cannot depend on the state values" +msgstr "'alag.'/'rate.'/'dur.' " -#: etTran.cpp:1036 -#, c-format -msgid "'amt' or 'dur'/'rate' are non-zero therefore MDV cannot = 0 (id: %s row: %d)" -msgstr "“amt”或“dur”/“rate”不为零,因此MDV不能= 0(id: %s, row: %d)" +#: rxode2_df.cpp:227 +msgid "could not solve the system" +msgstr "" -#: etTran.cpp:1074 -msgid "'addl' is ignored with observations" -msgstr "“addl”被观测忽略" +#: rxode2_df.cpp:229 +msgid "" +"some ID(s) could not solve the ODEs correctly; These values are replaced " +"with 'NA'" +msgstr " ID ;NA" -#: etTran.cpp:1096 etTran.cpp:1180 +#: rxode2_df.cpp:782 #, c-format -msgid "'limit' (%f) cannot equal 'dv' (%f) id: %s row: %d" -msgstr "“limit”(%f)不能等于“dv”(%f) id: %s, row: %d" +msgid "dose to compartment %d ignored (not in system; 'id=%d')" +msgstr " %d ;'id=%d'" -#: etTran.cpp:1129 +#: sbuf.c:182 #, c-format -msgid "'cmt' and 'dvid' specify different compartments (id: %s row: %d)" -msgstr "“cmt”和“dvid”指了不同的房室(id: %s, row: %d)" +msgid "encoding error in 'addLine' format: '%s' n: %d; errno: %d" +msgstr "addLine%sn%d;errno %d" -#: etTran.cpp:1150 -msgid "'DVID'/'CMT' translation:\n" -msgstr "“DVID”/“CMT”转换:\n" +#: utilc.c:70 utilc.c:125 utilc.c:180 utilc.c:235 utilc.c:292 utilc.c:348 +#: utilc.c:404 utilc.c:462 utilc.c:524 +msgid "'a' needs to be a number" +msgstr "a" -#: etTran.cpp:1156 -#, c-format -msgid "'dvid'->'cmt' or 'cmt' on observation record on a undefined compartment (use 'cmt()' 'dvid()') id: %s row: %d" -msgstr "'dvid'->'cmt' 或 'cmt' 在未定义的房室上的观测记录上(使用 'cmt()' 'dvid()') id: %s row: %d" +#: utilc.c:78 utilc.c:133 utilc.c:188 utilc.c:243 utilc.c:300 utilc.c:356 +#: utilc.c:412 utilc.c:470 utilc.c:532 +msgid "'z' needs to be a number" +msgstr "z" -#: etTran.cpp:1195 -#, c-format -msgid "'mdv' cannot be 0 when 'evid'=1 id: %s row: %d" -msgstr "当“evid”=1时,“mdv” 不能为 0,id: %s, row: %d" +#: utilc.c:102 utilc.c:157 utilc.c:212 utilc.c:268 utilc.c:325 utilc.c:381 +#: utilc.c:437 utilc.c:498 utilc.c:560 +msgid "inconsistent sizes" +msgstr "" -#: etTran.cpp:1212 -msgid "'addl' is ignored with 'EVID=2'" -msgstr "“EVID=2”,“addl”被忽略" +#: utilc.c:588 utilc.c:598 utilc.c:641 utilc.c:651 utilc.c:694 utilc.c:704 +#: utilc.c:748 utilc.c:758 +msgid "'low' must be a numeric of length 1" +msgstr "low 1 " -#: etTran.cpp:1215 -msgid "'ss' is ignored with 'EVID=2'" -msgstr "“EVID=2”,“ss”被忽略" +#: utilc.c:591 utilc.c:605 utilc.c:644 utilc.c:658 utilc.c:697 utilc.c:711 +#: utilc.c:751 utilc.c:765 +msgid "'high' must be a numeric of length 1" +msgstr "high 1 " -#: etTran.cpp:1257 -msgid "'addl' is ignored with 'EVID=3'" -msgstr "“EVID=2”,“addl”被忽略" +#: utilc.c:608 utilc.c:661 utilc.c:714 utilc.c:768 +msgid "'high' must be greater than 'low'" +msgstr "highlow" -#: etTran.cpp:1260 -msgid "'ss' is ignored with 'EVID=3'" -msgstr "“EVID=2”,“ss”被忽略" +#~ msgid "'shape' must be non-negative" +#~ msgstr "shape()" -#: etTran.cpp:1284 -#, c-format -msgid "'mdv' cannot be 0 when 'evid'=4 id: %s row: %d" -msgstr "当“evid”=4时,“mdv” 不能为 0, id: %s, row: %d" +#~ msgid "dimension, 'd' of correlation matrix must be > 1" +#~ msgstr "d> 1" -#: etTran.cpp:1310 -#, c-format -msgid "cannot have an infusion event with a replacement event (id: %s row: %d)" -msgstr "\"替换(replacement)\"事件不能具有输注事件(id: %s, row: %d)" +#~ msgid "'eta' must be >= 1" +#~ msgstr "eta>= 1" -#: etTran.cpp:1317 -#, c-format -msgid "cannot have an infusion event with a multiplication event (id: %s row: %d)" -msgstr "\"倍数(multiplication)\"事件不能具有输注事件(id: %s, row: %d)" +#~ msgid "" +#~ "log standard deviation size needs to be the same size as the log standard " +#~ "error of the estimate" +#~ msgstr "" -#: etTran.cpp:1328 -msgid "'rate' or 'dur' is ignored with classic Rxode2 'EVID's" -msgstr "“rate”或“dur”在经典Rxode2 'EVID'中被忽略" +#~ msgid "'nu' must be greater than 'd'-1" +#~ msgstr "Wishartnud()-1" -#: etTran.cpp:1332 -msgid "'ss' is ignored with classic Rxode2 'EVID's" -msgstr "“ss”在经典Rxode2 'EVID'中被忽略" +#~ msgid "unknown 'diagXformType' transformation" +#~ msgstr "diagXformType(X)" -#: etTran.cpp:1353 #, c-format -msgid "'ss' with 'addl' not supported (id: %s row: %d)" -msgstr "不支持带有“addl”的“ss”(id: %s, row: %d)" +#~ msgid "variable 'type': Unrecognized cvPost type='%s'" +#~ msgstr " 'type' cvPost='%s'" -#: etTran.cpp:1364 -#, c-format -msgid "'amt' value NA or 0 for dose event (id: %s row: %d)" -msgstr "给药事件的“amt”值为NA或为0(id: %s, row: %d)" +#~ msgid "variable 'type': Can only use type string or integer[1,3]" +#~ msgstr " 'type'[13]" -#: etTran.cpp:1402 #, c-format -msgid "'amt' value NA for dose event; (id: %s, amt: %f, evid: %d Rxode2 evid: %d, row: %d)" -msgstr "给药事件的“amt”值为NA;(id: %s, amt: %f, evid: %d Rxode2 evid: %d, row: %d)" +#~ msgid "variable 'diagXformType': Unrecognized transformation '%s'" +#~ msgstr " 'diagXformType(X)' '%s'" -#: etTran.cpp:1480 -msgid "there are evid=3/4 records in an incorrectly sorted dataset, system is reset, but time is not reset" -msgstr "数据集中存在错误排序的evid=3或4记录,系统已重置,但时间未重置" +#~ msgid "" +#~ "variable 'diagXformType': Can only use transformation string or " +#~ "integer[1,6]" +#~ msgstr " 'diagXformType(X)'[16]" -#: etTran.cpp:1537 -msgid "censoring missing 'DV' values do not make sense" -msgstr "删失缺失的“DV”值没有意义" +#~ msgid "" +#~ "'n' is determined by the 'omega' argument which contains the simulated " +#~ "standard deviations" +#~ msgstr "nomega" -#: etTran.cpp:1590 -msgid "no rows in event table or input data" -msgstr "事件表或输入数据中没有数据行" +#~ msgid "" +#~ "when sampling from correlation priors to create covariance matrices, the " +#~ "input must be a matrix of standard deviations" +#~ msgstr "" -#: etTran.cpp:1612 -msgid "empty data" -msgstr "空数据" +#~ msgid "" +#~ "'omega' needs to be a matrix or a numeric vector that can be converted to " +#~ "a matrix" +#~ msgstr "nomega" -#: etTran.cpp:1628 -msgid "while censoring is included in dataset, no observations are censored" -msgstr "虽然数据集中包含删失,但不会对任何观测值进行删失" +#~ msgid "'thetaMat' needs 'params' to be non-NULL" +#~ msgstr "thetaMat\"(non-NULL)\"" -#: etTran.cpp:1632 -msgid "'dv' and 'limit' swapped since 'limit' > 'dv'" -msgstr "“dv”和“limit”交换,因为“limit”>“dv”" +#~ msgid "" +#~ "when specifying 'thetaMat', 'omega', or 'sigma' the parameters cannot be " +#~ "a 'data.frame'/'matrix'" +#~ msgstr "thetaMatomegasigmadata.frame/matrix" -#: etTran.cpp:1753 -msgid "number of individuals not calculated correctly" -msgstr "个体数量没有被计算正确" +#~ msgid "'theta' must be the same size as 'thetaMat'" +#~ msgstr "thetathetaMat" -#: etTran.cpp:1908 -msgid "corrupted event table" -msgstr "事件表已损坏" +#~ msgid "'omega' must be symmetric, positive definite" +#~ msgstr "omega" -#: etTran.cpp:2022 -msgid "\n" -"with negative times, compartments initialize at first negative observed time\n" -"with positive times, compartments initialize at time zero\n" -"use 'rxSetIni0(FALSE)' to initialize at first observed time\n" -"this warning is displayed once per session" -msgstr "\n" -"当时间为负数时,房室在第一次负数的观察时间初始化\n" -"当时间为正数时,房室在时间0初始化\n" -"使用'rxSetIni0(FALSE)',在第一次观测的时间初始化\n" -"此警告在每个会话中显示一次" +#~ msgid "'omega' needs to be a matrix or lotri matrix" +#~ msgstr "omega\"(matrix)\"\"lotri matrix\"" -#: expandGrid.cpp:73 -msgid "unanticipated input for rxExpandGrid_" -msgstr "意料之外的rxExpandGrid_输入" +#~ msgid "'sigma' must be symmetric, positive definite" +#~ msgstr "sigma" -#: expm.cpp:211 -msgid "requested tolerance is too high" -msgstr "请求的公差(tolerance)太高" +#~ msgid "'sigma' needs to be a matrix or lotri matrix" +#~ msgstr "sigma\"(matrix)\"\"lotri matrix\"" -#: expm.cpp:410 -#, c-format -msgid "unsupported indLin code: %d" -msgstr "不支持的indLin代码: %d" +#~ msgid "un-handled nesting information" +#~ msgstr "" -#: forder.cpp:62 -#, c-format -msgid "ignoring invalid %s==\"%s\"\n" -" not an integer >= 1\n" -"remove any characters that are not a digit [0-9]\n" -" See ?Rxode2::setDTthreads" -msgstr "忽略无效的 %s==“%s”\n" -"不是一个整数 >= 1\n" -"删除任何不是数字[0-9]的字符\n" -"请参阅?Rxode2::setDTthreads" +#~ msgid "cannot find 'id' column in dataset" +#~ msgstr "id" -#: forder.cpp:88 -#, c-format -msgid "ignoring invalid RXODE2_NUM_PROCS_PERCENT==%d.\n" -"If used it must be an integer between 2 and 100. Default is 50. See ?rxSetThreads" -msgstr "忽略无效的RXODE2_NUM_PROCS_PERCENT==%d。\n" -"如果使用,它必须是介于 2 和 100 之间的整数。默认值为 50。请参阅?rxSetThreads" +#~ msgid "'omega' must be a list/lotri/matrix" +#~ msgstr "omega\"(list)\"/lotri/\"(matrix)\"" -#: forder.cpp:124 -msgid "'verbose' must be TRUE or FALSE" -msgstr "“verbose”必须为逻辑值真(TRUE)或假(FALSE)" +#~ msgid "event table was not updated (no dose/sampling windows)" +#~ msgstr "/" -#: forder.cpp:127 -msgid "This installation of data.table has not been compiled with OpenMP support.\n" -msgstr "此data.table安装没有在OpenMP支持下编译。\n" +#~ msgid "" +#~ "windows need to be a list of observation windows, each of 2 elements e.g. " +#~ "list(c(0,2), c(2,7))" +#~ msgstr "\"(list)\"C02C27" -#: forder.cpp:132 -#, c-format -msgid " omp_get_num_procs() %d\n" -msgstr " omp_get_num_procs() %d\n" +#~ msgid "windows need to be ordered list(c(2,0)) is invalid" +#~ msgstr "Windowslist(c(2,0))" -#: forder.cpp:133 #, c-format -msgid " RXODE2_NUM_PROCS_PERCENT %s\n" -msgstr " RXODE2_NUM_PROCS_PERCENT %s\n" +#~ msgid "unknown method: '%s'" +#~ msgstr "%s" -#: forder.cpp:134 -#, c-format -msgid " RXODE2_NUM_THREADS %s\n" -msgstr " RXODE2_NUM_THREADS %s\n" +#~ msgid "can only specify either 'amt' or 'value'" +#~ msgstr "amtvalue" -#: forder.cpp:135 -#, c-format -msgid " RXODE2_THROTTLE %s\n" -msgstr " RXODE2_THROTTLE %s\n" +#~ msgid "can only specify either 'cmt', 'ytype', 'state' or 'var'" +#~ msgstr "cmtytypestatevar" -#: forder.cpp:136 -#, c-format -msgid " omp_get_thread_limit() %d\n" -msgstr " omp_get_thread_limit() %d\n" +#~ msgid "can only specify either 'duration' or 'dur'" +#~ msgstr "durationdur" -#: forder.cpp:137 -#, c-format -msgid " omp_get_max_threads() %d\n" -msgstr " omp_get_max_threads() %d\n" +#~ msgid "need a 'time' column" +#~ msgstr "time()" -#: forder.cpp:138 -#, c-format -msgid " OMP_THREAD_LIMIT %s\n" -msgstr " OMP_THREAD_LIMIT %s\n" +#~ msgid "using 'mdv' instead of 'method'" +#~ msgstr "mdvmethod" -#: forder.cpp:139 -#, c-format -msgid " OMP_NUM_THREADS %s\n" -msgstr " OMP_NUM_THREADS %s\n" +#~ msgid "using 'evid' instead of 'mdv'" +#~ msgstr "evidmdv" -#: forder.cpp:141 -#, c-format -msgid " Rxode2 is using %d threads with throttle==%d. See ?setRxthreads.\n" -msgstr " Rxode2 正在使用%d个线程和throttle==%d。请参阅?setRxthreads。\n" +#~ msgid "'ID' type is unknown" +#~ msgstr "ID" -#: forder.cpp:149 -msgid "'throttle' must be a single number, non-NA, and >=1" -msgstr "“throttle”必须是单个数字,非NA且 >=1" +#~ msgid "can not figure out how to import the compartment variable" +#~ msgstr "\"compartment()\"" -#: forder.cpp:163 -msgid "threads= must be either NULL or a single number >= 0 See ?setRxthreads" -msgstr "threads=必须是NULL或单个>=0的数字。请参阅?setRxthreads" +#~ msgid "replacement/multiplication events cannot be combined with infusions" +#~ msgstr "\"(replacement)\"/\"(multiplication)\"" -#: forder.cpp:167 -msgid "internal error: percent= must be TRUE or FALSE at C level" -msgstr "内部错误:percent(百分比)= 在C级别必须为TRUE或FALSE" +#~ msgid "old Rxode2 'evid' values are not supported with string compartments" +#~ msgstr " Rxode2evid" -#: forder.cpp:170 -#, c-format -msgid "internal error: threads==%d should be between 2 and 100 (percent=TRUE at C level)" -msgstr "内部错误:threads==%d 应介于 2 和 100 之间(C 级别的percent(百分比)=TRUE)" +#~ msgid "" +#~ "'amt'/'time' needs units to convert the rate to the right units to import " +#~ "the data" +#~ msgstr "amt/time" -#: intdy.c:50 -#, c-format -msgid "[intdy] k = %d illegal\n" -msgstr "[intdy] k = %d 非法\n" +#~ msgid "'do.sampling' is not supported with dose windows" +#~ msgstr "\"do.sampling\"" -#: intdy.c:55 -#, c-format -msgid "intdy -- t = %g illegal. t not in interval tcur - _rxC(hu) to tcur\n" -msgstr "intdy -- t = %g 非法。t没有在tcur - _rxC(hu)到tcur的间隔中\n" +#~ msgid "" +#~ "dosing window you need to specify window in order, e.g. " +#~ "'et(time=list(c(0,2)),amt=3)'" +#~ msgstr "'et(time=list(c(0,2)),amt=3)'" -#: lincmt.c:39 lincmt.c:46 -msgid "could not find a start to the infusion" -msgstr "找不到输注的开始" +#~ msgid "dosing time or time windows must only be 1-2 elements" +#~ msgstr "1~2" -#: lincmt.c:51 lincmt.c:58 -msgid "could not find an end to the infusion" -msgstr "找不到输注的终止" +#~ msgid "cannot mix named compartments and integer compartments" +#~ msgstr "" -#: lincmt.c:200 -msgid "solve data is not loaded" -msgstr "求解数据未加载" +#~ msgid "cannot add more 'ID's to this event table" +#~ msgstr "ID" -#: lincmt.c:1879 -msgid "not an integer/real" -msgstr "不是整数/实数" +#~ msgid "can only have one of the following: 'amt', 'dose'" +#~ msgstr "amtdose" -#: lincmt.c:1897 lincmt.c:2007 lincmt.c:2179 -msgid "The dimensions of the parameters must match" -msgstr "参数的维数必须匹配" +#~ msgid "" +#~ "can only have one of the following: 'ii', 'dosing.interval', " +#~ "'dosingInterval' or 'dosing_interval'" +#~ msgstr "iidosing.intervaldosingIntervadosing_interval" -#: lincmt.c:2394 -msgid "'ncmt' needs to be 1-3" -msgstr "“ncmt”需要为 1~3" +#~ msgid "" +#~ "can only have one of the following: 'cmt', 'dosing.to', 'dose.to', 'state'" +#~ msgstr "cmtdosing.todose.tostate" -#: lincmt.c:2397 -msgid "'inp' needs to be list/data frame" -msgstr "“inp”需要是\"列表(list)\"/\"数据框(data frame)\"类型" +#~ msgid "" +#~ "can only have one of the following: 'amount.units', 'amt.units', 'dose." +#~ "units'" +#~ msgstr "'amount.units'amt.unitsdose.units" -#: lincmtB.cpp:181 -#, c-format -msgid "invalid trans (2 cmt trans %d)\n" -msgstr "无效的\"trans(参数化方式)\"(2 cmt trans %d)\n" +#~ msgid "" +#~ "can only have one of the following: 'time.units', 'timeUnits', " +#~ "'time_units'" +#~ msgstr "time.unitstimeUnitstime_units" -#: lsoda.c:221 -#, c-format -msgid "[lsoda] illegal itask = %d\n" -msgstr "[lsoda]非法itask = %d\n" +#~ msgid "can only have one of the following: 'add.sampling', 'do.sampling'" +#~ msgstr "add.samplingdo.sampling" -#: lsoda.c:226 -#, c-format -msgid "[lsoda] ixpr = %d is illegal\n" -msgstr "[lsoda] ixpr = %d是非法的\n" +#~ msgid "can only have one of the following: 'time', 'start.time', 'from'" +#~ msgstr "timestart.timefrom" -#: lsoda.c:230 -msgid "[lsoda] mxstep < 0\n" -msgstr "[lsoda]mxstep< 0\n" +#~ msgid "can only have one of the following: 'nbrDoses', 'nbr.doses'" +#~ msgstr "nbrDosesnbr.doses" -#: lsoda.c:235 -msgid "[lsoda] mxhnil < 0\n" -msgstr "[lsoda] mxhnil < 0\n" +#~ msgid "can only have one of the following: 'dur', 'duration'" +#~ msgstr "durduration" -#: lsoda.c:240 #, c-format -msgid "[lsoda] mxordn = %d is less than 0\n" -msgstr "[lsoda] mxordn = %d小于0\n" +#~ msgid "unused argument '%s'" +#~ msgstr " '%s'" + +#~ msgid "" +#~ "multiple event tables supplied, not sure what to do; try 'c', 'rbind', " +#~ "'seq' or 'rep'" +#~ msgstr ";crbindseqrep" -#: lsoda.c:246 #, c-format -msgid "[lsoda] mxords = %d is less than 0\n" -msgstr "[lsoda] mxords = %d小于0\n" +#~ msgid "'%s' cannot be a vector" +#~ msgstr "'%s' " -#: lsoda.c:253 -msgid "[lsoda] hmax < 0.\n" -msgstr "[lsoda] hmax < 0.\n" +#~ msgid "nothing done" +#~ msgstr "" -#: lsoda.c:260 -msgid "[lsoda] hmin < 0.\n" -msgstr "[lsoda] hmin < 0.\n" +#, c-format +#~ msgid "cannot mix named and integer compartments in '%s'" +#~ msgstr " '%s' " -#: lsoda.c:490 #, c-format -msgid "unhandled error message: %s\n" -msgstr "未处理的错误消息: %s\n" +#~ msgid "'%s' compartment cannot be a vector" +#~ msgstr "%s" -#: lsoda.c:768 #, c-format -msgid "lsoda -- warning..internal t = %g and _rxC(h) = %g are\n" -msgstr "lsoda -- 警告..内部 t = %g 和 _rxC(h) = %g 是\n" +#~ msgid "'%s' cannot be zero" +#~ msgstr "'%s' " -#: lsoda.c:769 -msgid " such that in the machine, t + _rxC(h) = t on the next step\n" -msgstr " 这样在机器中,下一步的t _rxC(h) = t\n" +#, c-format +#~ msgid "'%s' cannot be an vector" +#~ msgstr "'%s' " -#: lsoda.c:770 -msgid " solver will continue anyway.\n" -msgstr " 无论如何,求解器将继续。\n" +#, c-format +#~ msgid "'%s' must be an integer or a character" +#~ msgstr "'%s' \"(integer)\"\"(character)\"" -#: lsoda.c:772 #, c-format -msgid "lsoda -- above warning has been issued %d times,\n" -msgstr "lsoda -- 以上警告已发出 %d 次,\n" +#~ msgid "turning off compartments can only be done when '%s'=2" +#~ msgstr " '%s' = 2 " -#: lsoda.c:773 -msgid " it will not be issued again for this problem\n" -msgstr " 不会因此问题再次发出\n" +#, c-format +#~ msgid "zero '%s' cannot be used with '%s'" +#~ msgstr "%s%s" -#: lsoda.c:805 -msgid "[lsoda] a switch to the stiff method has occurred " -msgstr "[LSODA] 已切换到刚性方法 " +#, c-format +#~ msgid "'%s' requires an '%s'" +#~ msgstr "%s%s" -#: lsoda.c:807 -msgid "[lsoda] a switch to the nonstiff method has occurred" -msgstr "[LSODA] 已切换到非刚性方法" +#, c-format +#~ msgid "'%s' is ignored when '%s'=2 or '%s'=3" +#~ msgstr "%s=2 %s=3 %s" -#: lsoda.c:808 #, c-format -msgid "at t = %g, tentative step size _rxC(h) = %g, step _rxC(nst) = %d\n" -msgstr "在 t = %g 时,暂定步长 _rxC(h) = %g,步长 _rxC(nst) = %d\n" +#~ msgid "'%s' needs a '%s'" +#~ msgstr "%s%s" -#: par_solve.cpp:2729 -msgid "'alag(.)'/'rate(.)'/'dur(.)' cannot depend on the state values" -msgstr "'alag(.)'/'rate(.)'/'dur(.)' 不能依赖于状态值" +#, c-format +#~ msgid "can not specify '%s' and '%s' for a dose, please pick one" +#~ msgstr "%s%s" -#: par_solve.cpp:2733 -msgid "could not solve the system" -msgstr "无法求解系统" +#~ msgid "'ii' needs a 'dose'/'amt'" +#~ msgstr "ii()dose()/amt()" -#: par_solve.cpp:2735 -msgid "some ID(s) could not solve the ODEs correctly; These values are replaced with 'NA'" -msgstr "某些 ID 无法正确求解常微分方程;这些值将替换为“NA”" +#~ msgid "dosing interval of zero makes no sense with multiple dose events" +#~ msgstr "" -#: par_solve.cpp:2807 #, c-format -msgid "one or more covariates were all 'NA' for subject 'id=%d'" -msgstr "一个或多个协变量都是“NA”,受试者“id=%d”" +#~ msgid "non-zero '%s' needs a '%s'" +#~ msgstr "'%s' '%s'" -#: par_solve.cpp:3230 #, c-format -msgid "dose to compartment %d ignored (not in system; 'id=%d')" -msgstr "忽略房室 %d 的给药(不在系统中;'id=%d')" +#~ msgid "can only specify '%s' or '%s', not both" +#~ msgstr "%s%s" -#: parseLinCmt.c:39 -msgid " with first order absorption\n" -msgstr " 具有一阶速率吸收\n" - -#: prja.c:42 -msgid "[prja] _rxC(miter) != 2\n" -msgstr "[prja] _rxC(miter) != 2\n" +#, c-format +#~ msgid "'%s' can only have one item" +#~ msgstr "'%s' " -#: rxData.cpp:296 -msgid "column(s) in 'drop' were not in solved data" -msgstr "“drop(丢弃)”中的列不在已求解的数据中" +#, c-format +#~ msgid "'%s' must be logical" +#~ msgstr "'%s' " -#: rxData.cpp:444 #, c-format -msgid "refusing to simulate %d items" -msgstr "拒绝模拟 %d 项" +#~ msgid "cannot specify '%s' and '%s' for a dose, please pick one" +#~ msgstr "%s%s" -#: rxData.cpp:451 -msgid "matrix must be a square matrix" -msgstr "矩阵必须是方阵" +#~ msgid "-1 and -2 rates do not make sense with units" +#~ msgstr "-1 -2 (rate)" -#: rxData.cpp:459 -msgid "matrix must have named dimensions (try 'lotri')" -msgstr "矩阵必须具有命名的维度(尝试“lotri”)" +#, c-format +#~ msgid "'%s' is cannot be converted and added to this table" +#~ msgstr "%s" -#: rxData.cpp:491 -msgid "lower bounds needs to be a named vector, a single value or exactly the same size" -msgstr "下限需要是命名向量、单个值或完全相同的大小" +#, c-format +#~ msgid "" +#~ "steady state constant infusion dosing records must have '%s=-1' or " +#~ "positive rate" +#~ msgstr "%s=-1(rate)" -#: rxData.cpp:511 -msgid "upper bounds needs to be a named vector, a single value or exactly the same size" -msgstr "上限必须是命名向量、单个值或完全相同的大小" +#, c-format +#~ msgid "'%s' cannot be converted and added to this table" +#~ msgstr "%s" -#: rxData.cpp:527 -msgid "t distribution not yet supported" -msgstr "尚不支持t分布" +#, c-format +#~ msgid "number of doses must be at least one ('%s': %d)" +#~ msgstr "%s %d" -#: rxData.cpp:807 -msgid "cannot figure out the model variables" -msgstr "无法计算出模型变量" +#, c-format +#~ msgid "'%s' can only be used with positive inter-dose intervals ('%s')" +#~ msgstr "%s%s" -#: rxData.cpp:837 rxData.cpp:855 -msgid "class:\t" -msgstr "class:\t" +#, c-format +#~ msgid "'%s' does not make sense with multiple dosing times" +#~ msgstr "'%s' " -#: rxData.cpp:843 rxData.cpp:861 -msgid "need an Rxode2-type object to extract model variables" -msgstr "需要一个 Rxode2 类型的对象来提取模型变量" +#~ msgid "dosing windows can only have 1-2 items in them" +#~ msgstr "1-2" -#: rxData.cpp:851 -msgid "a NULL object does not have any Rxode2 model variables" -msgstr "一个NULL对象没有任何 Rxode2 模型变量" +#, c-format +#~ msgid "" +#~ "'%s' requires non zero additional doses ('%s') or steady state dosing " +#~ "('%s': %f, '%s': %d; '%s': %d), reset '%s' to zero." +#~ msgstr "%s%s%s%f%s%d;%s %d%s" -#: rxData.cpp:896 -msgid "can only lookup one state at a time" -msgstr "一次只能查找一个状态" +#, c-format +#~ msgid "'%s' must be 1 when specifying a steady-state constant infusion" +#~ msgstr "'%s' 1" -#: rxData.cpp:899 -msgid "only one state variable should be input" -msgstr "只应输入一个状态变量" +#, c-format +#~ msgid "'%s' must be 0, 1 or 2" +#~ msgstr "'%s' 01 2" -#: rxData.cpp:909 #, c-format -msgid "cannot locate compartment \"%s\"" -msgstr "找不到区间“%s”" +#~ msgid "'%s' required with '%s'" +#~ msgstr "%s%s" -#: rxData.cpp:1148 -msgid "only one estimate per named list item; use 'list(x=1)' instead of 'list(x=1:2)'" -msgstr "每个命名\"list(列表)\"项只有一个估计值;使用“'list(x=1)”而不是“'list(x=1:2)”" +#, c-format +#~ msgid "'%s' cannot be used with steady state constant infusion" +#~ msgstr "'%s' " -#: rxData.cpp:1155 -msgid "incompatible initial estimate" -msgstr "不能共存的初始估计" +#, c-format +#~ msgid "steady state ('%s') is not supported with dosing windows" +#~ msgstr "'%s'" -#: rxData.cpp:1210 #, c-format -msgid "trying to scale the same compartment by 'scale=c(%s=%f,...)' and 'S%d=%f' choose one" -msgstr "尝试\"缩放(scale)\"相同房室通过“scale=c(%s=%f,...)”和“S%d=%f”选择一个" +#~ msgid "additional doses must be positive ('%s'=%d)" +#~ msgstr "'%s'=%d" -#: rxData.cpp:1221 #, c-format -msgid "trying to scale the same compartment by 'scale=c(%s=%f,...)' and 's%d=%f' choose one" -msgstr "尝试\"缩放(scale)\"相同房室通过“scale=c(%s=%f,...)”和“s%d=%f”选择一个" +#~ msgid "additional doses require an inter-dose interval ('%s')" +#~ msgstr "%s" -#: rxData.cpp:1245 -msgid "scaled a compartment that is not defined by the Rxode2 model" -msgstr "\"缩放(scale)\"了未由 Rxode2 模型定义的房室" +#, c-format +#~ msgid "for steady state infusions, you need %s=0, %s>0, %s=1, %s=0" +#~ msgstr " %s=0%s>0%s=1%s=0" -#: rxData.cpp:1374 -msgid "could not allocate memory for solving parameters" -msgstr "无法为求解参数分配内存" +#~ msgid "dosing time window lists can have 1-2 numeric entries in them" +#~ msgstr "1-2" -#: rxData.cpp:1418 -msgid "memory for residual errors could not be allocated" -msgstr "无为法残差分配内存" +#~ msgid "dosing window list needs to be numeric values only" +#~ msgstr "" -#: rxData.cpp:1425 -msgid "cannot allocate memory to simulate the residuals" -msgstr "无法分配内存用于模拟残差" +#~ msgid "cannot figure out what type of 'EventTable' you are trying to create" +#~ msgstr "" -#: rxData.cpp:1484 -msgid "'thetaMat' must be a named matrix" -msgstr "“thetaMat”必须是已命名的矩阵" +#~ msgid "cannot have event tables with integer and character 'cmt'" +#~ msgstr "cmt" -#: rxData.cpp:1492 rxData.cpp:2868 -msgid "'thetaMat' must be symmetric" -msgstr "“thetaMat”必须是对称的" +#, c-format +#~ msgid "" +#~ "assumed a dose interval of %.1f between event tables; use 'ii' to adjust" +#~ msgstr "%.1f;ii" -#: rxData.cpp:1513 -msgid "'thetaMat' is ignored since nStud <= 1" -msgstr "'thetaMat' 被忽略,因为 nStud <= 1" +#~ msgid "no events table found for 'seq'/'rep'/'rbind'/'c'" +#~ msgstr "seq/rep/rbind/c" -#: rxData.cpp:1553 -#, c-format -msgid "parameter '%s' was not simulated in 'thetaMat'" -msgstr "参数 '%s' 未在 'thetaMat' 中模拟" +#~ msgid "'wait' cannot be a vector" +#~ msgstr "wait" -#: rxData.cpp:1562 #, c-format -msgid "'%s' must be a named matrix" -msgstr "'%s' 必须是已命名的矩阵" +#~ msgid "" +#~ "negative compartments on non-ode 'cmt' (%s) does not make sense (id: %s, " +#~ "row: %d)" +#~ msgstr "non-ode 'cmt'%sID %s %d" -#: rxData.cpp:1572 #, c-format -msgid "'%s' must be symmetric" -msgstr "'%s' 必须是对称的" +#~ msgid "" +#~ "negative compartments on non-ode 'cmt' (%s) does not make sense (id: %s " +#~ "row: %d)" +#~ msgstr "non-ode 'cmt'%sID %s %d" -#: rxData.cpp:1692 -msgid "requires 'params'" -msgstr "需要“params(参数)”" +#~ msgid "should not reach here" +#~ msgstr "" -#: rxData.cpp:1697 -msgid "'params' must be a named vector" -msgstr "“params(参数)”必须是一个已命名的向量" +#~ msgid "cannot keep 'evid'; try 'addDosing'" +#~ msgstr "evid;adDosing" -#: rxData.cpp:1718 -msgid "multi-subject simulation without without 'omega'" -msgstr "多个体模拟时缺少'omega'" +#~ msgid "'time' is required in dataset" +#~ msgstr "time" -#: rxData.cpp:2069 -msgid "ran out of memory during 'updateSolveEnvPost'" -msgstr "在“updateSolveEnvPost”期间内存不足" +#~ msgid "steady state column ('ss') needs to be an integer" +#~ msgstr " 'ss' " -#: rxData.cpp:2399 -msgid "No additional parameters were specified, returning original object" -msgstr "未指定其他参数,返回原始对象" +#~ msgid "event id ('evid') needs to be an integer" +#~ msgstr "id'evid' " -#: rxData.cpp:2478 -msgid "can not update object" -msgstr "无法更新对象" +#~ msgid "missing DV ('mdv') needs to be an integer" +#~ msgstr "'mdv' " -#: rxData.cpp:2525 -msgid "'from' must be of length 1" -msgstr "“from”的长度必须为 1" +#~ msgid "missing dependent variable ('mdv') needs to be an integer" +#~ msgstr "'MDV' " -#: rxData.cpp:2533 -msgid "'to' must be of length 1" -msgstr "“to”的长度必须为 1" +#~ msgid "'rate' needs to be a number" +#~ msgstr "rate()" -#: rxData.cpp:2543 -msgid "'by' must be of length 1" -msgstr "“by”的长度必须为 1" +#~ msgid "'dur' needs to be a number" +#~ msgstr "dur()" -#: rxData.cpp:2551 -msgid "'length.out' must be of length 1" -msgstr "“length.out”的长度必须为 1" +#~ msgid "amount ('amt') needs to be a number" +#~ msgstr "amt" -#: rxData.cpp:2557 -msgid "cannot use both 'by' and 'length.out' for Rxode2 simulations" -msgstr "不能同时使用“by”和“length.out”进行Rxode2模拟" +#~ msgid "inter-dose interval ('ii') needs to be a number" +#~ msgstr "'ii' " -#: rxData.cpp:2654 -msgid "Rxode2 only supports 500 factors" -msgstr "Rxode2 仅支持 500 个因子" +#~ msgid "number of additional doses ('addl') needs to be an integer" +#~ msgstr "'addl' " -#: rxData.cpp:2797 -msgid "when specifying 'thetaMat', 'omega', or 'sigma' the parameters cannot be a 'data.frame'/'matrix'." -msgstr "当指定“thetaMat”、“omega”或“sigma”时,参数不能是“data.frame”/“matrix”。" +#~ msgid "dependent variable ('dv') needs to be a number" +#~ msgstr "'dv' " -#: rxData.cpp:2920 rxData.cpp:2943 rxData.cpp:2952 -msgid "if parameters are not named, they must match the order and size of the parameters in the model" -msgstr "如果未命名参数,则它们必须与模型中参数的顺序和大小匹配" +#~ msgid "censoring variable ('cens') needs to be a number" +#~ msgstr "cens" -#: rxData.cpp:3030 -msgid "can not allocate enough memory to load 'evid'" -msgstr "无法分配足够的内存来加载“evid”" +#~ msgid "limit variable ('limit') needs to be a number" +#~ msgstr "limit" -#: rxData.cpp:3074 -msgid "nothing to solve" -msgstr "没有什么可求解的" +#, c-format +#~ msgid "censoring column can only be -1, 0 or 1 (id: %s, row: %d)" +#~ msgstr " -10 1id %srow %d" -#: rxData.cpp:3128 -msgid "can not allocate memory for the covariates" -msgstr "无法为协变量分配内存" +#, c-format +#~ msgid "infinite times are not allowed (id: %s, row: %d)" +#~ msgstr "id %srow %d" -#: rxData.cpp:3215 -msgid "data must be ordered by 'ID' and 'TIME' variables" -msgstr "数据必须按“ID”和“TIME”变量排序" +#, c-format +#~ msgid "" +#~ "steady state records cannot be on negative compartments (id: %s, row: %d)" +#~ msgstr "id %srow %d" -#: rxData.cpp:3285 -msgid "cannot allocate enough memory to sort input parameters" -msgstr "无法分配足够的内存来对输入参数进行排序" +#, c-format +#~ msgid "" +#~ "when using steady state constant infusion modeling duration does not make " +#~ "sense (id: %s, row: %d)" +#~ msgstr "id %srow %d" -#: rxData.cpp:3416 -msgid "'resample' must be NULL or a character vector" -msgstr "“resample”(重采样)必须为 NULL 或字符向量" +#, c-format +#~ msgid "" +#~ "specifying duration with a steady state constant infusion makes no sense " +#~ "(id: %s row: %d)" +#~ msgstr "id %srow %d" -#: rxData.cpp:3525 -msgid "nPopPar != 1 but parameters are specified as a NumericVector" -msgstr "nPopPar != 1,但参数被指定为数字向量" +#, c-format +#~ msgid "" +#~ "specifying duration with a steady state constant infusion makes no sense " +#~ "(id: %d row: %d)" +#~ msgstr "id %d, row %d" -#: rxData.cpp:3636 -msgid "Something is wrong" -msgstr "有点不对劲" +#, c-format +#~ msgid "'rate' and/or 'dur' are not specified correctly (id: %d row: %d)" +#~ msgstr "rate/durid %srow %d" -#: rxData.cpp:3699 -msgid "aborted solve" -msgstr "中止求解" +#, c-format +#~ msgid "" +#~ "'amt' or 'dur'/'rate' are non-zero therefore MDV cannot = 0 (id: %s row: " +#~ "%d)" +#~ msgstr "amtdur/rateMDV= 0id %s, row %d" + +#~ msgid "'addl' is ignored with observations" +#~ msgstr "addl" -#: rxData.cpp:3723 #, c-format -msgid "exited from at least one while after %d iterations, (increase with `rxSolve(..., maxwhile=#)`)" -msgstr "在%d次迭代后至少一段时间退出,(增加' rxSolve(…,maxwhile = #)”)" +#~ msgid "'limit' (%f) cannot equal 'dv' (%f) id: %s row: %d" +#~ msgstr "limit%fdv%f id %s, row %d" -#: rxData.cpp:4066 -msgid "zero 'thetaMat' specified, no uncertainty in fixed effects" -msgstr "“thetaMat”指定为零,固定效应没有不确定性" +#, c-format +#~ msgid "'cmt' and 'dvid' specify different compartments (id: %s row: %d)" +#~ msgstr "cmtdvidid %s, row %d" -#: rxData.cpp:4069 -msgid "zero 'omega', no variability from random-effects" -msgstr "“omega”指定为零,没有来自于随即效应的变异" +#~ msgid "'DVID'/'CMT' translation:\n" +#~ msgstr "DVID/CMT:\n" -#: rxData.cpp:4072 -msgid "zero 'sigma', no unexplained variability" -msgstr "“sigma”指定为零,没有不确定性" +#, c-format +#~ msgid "" +#~ "'dvid'->'cmt' or 'cmt' on observation record on a undefined compartment " +#~ "(use 'cmt()' 'dvid()') id: %s row: %d" +#~ msgstr "'dvid'->'cmt' 'cmt' 'cmt()' 'dvid()' id %s row %d" -#: rxData.cpp:4090 -msgid "dropped key column, returning data.frame instead of special solved data.frame" -msgstr "丢弃的键列,返回data.frame而不是特殊已求解的data.frame" +#, c-format +#~ msgid "'mdv' cannot be 0 when 'evid'=1 id: %s row: %d" +#~ msgstr "evid=1,mdv 0id %s, row %d" -#: rxData.cpp:4285 -msgid "control list not setup correctly" -msgstr "控制列表设置不正确" +#~ msgid "'addl' is ignored with 'EVID=2'" +#~ msgstr "EVID=2addl" -#: rxData.cpp:4348 -msgid "cannot solve without event information" -msgstr "没有事件信息无法求解" +#~ msgid "'ss' is ignored with 'EVID=2'" +#~ msgstr "EVID=2ss" -#: rxData.cpp:4358 -msgid "cannot update this object" -msgstr "无法更新此对象" +#~ msgid "'addl' is ignored with 'EVID=3'" +#~ msgstr "EVID=2addl" -#: rxData.cpp:4414 -msgid "cannot load Rxode2 dlls for this model" -msgstr "无法加载此模型的 Rxode2 dll" +#~ msgid "'ss' is ignored with 'EVID=3'" +#~ msgstr "EVID=2ss" -#: rxData.cpp:4467 -msgid "thread safe method, but results may depend on system/load, using 1 core (can change with `cores=`)" -msgstr "线程安全方法,但结果可能取决于系统/负载,使用 1 个内核(可以使用“cores=”修改)" +#, c-format +#~ msgid "'mdv' cannot be 0 when 'evid'=4 id: %s row: %d" +#~ msgstr "evid=4mdv 0, id %s, row %d" -#: rxData.cpp:4478 rxData.cpp:4495 -msgid "not thread safe method, using 1 core" -msgstr "非线程安全方法,使用 1 个内核" +#, c-format +#~ msgid "" +#~ "cannot have an infusion event with a replacement event (id: %s row: %d)" +#~ msgstr "\"(replacement)\"id %s, row %d" -#: rxData.cpp:4487 -msgid "thread safe method, but results may depend on system/load" -msgstr "线程安全方法,但结果可能取决于系统/负载" +#, c-format +#~ msgid "" +#~ "cannot have an infusion event with a multiplication event (id: %s row: %d)" +#~ msgstr "\"(multiplication)\"id %s, row %d" -#: rxData.cpp:4551 -msgid "'infSSstep' needs to be positive" -msgstr "“infSSstep”需要是正数" +#~ msgid "'rate' or 'dur' is ignored with classic Rxode2 'EVID's" +#~ msgstr "ratedurRxode2 'EVID'" -#: rxData.cpp:4599 -msgid "assumed transit compartment model since 'podo' is in the model" -msgstr "假设是转移室模型,因为“podo”在模型中" +#~ msgid "'ss' is ignored with classic Rxode2 'EVID's" +#~ msgstr "ssRxode2 'EVID'" -#: rxData.cpp:4635 -msgid "unknown covariate interpolation specified" -msgstr "未知的协变量插值指定" +#, c-format +#~ msgid "'ss' with 'addl' not supported (id: %s row: %d)" +#~ msgstr "addlssid %s, row %d" -#: rxData.cpp:4726 #, c-format -msgid "number of parameters (%d) solved by Rxode2 for multi-subject data needs to be a multiple of the number of subjects (%d)" -msgstr "用于多个体数据通过Rxode2已求解的参数数量(%d),应是多个体量的倍数" +#~ msgid "'amt' value NA or 0 for dose event (id: %s row: %d)" +#~ msgstr "amtNA0id %s, row %d" -#: rxData.cpp:4844 -msgid "could not allocate enough memory for solving" -msgstr "无法分配足够的内存用于求解" +#, c-format +#~ msgid "" +#~ "'amt' value NA for dose event; (id: %s, amt: %f, evid: %d Rxode2 evid: " +#~ "%d, row: %d)" +#~ msgstr "amtNA;(id: %s, amt: %f, evid: %d Rxode2 evid: %d, row: %d)" -#: rxData.cpp:5237 -msgid "cannot update nonexistent parameters" -msgstr "无法更新不存在的参数" +#~ msgid "" +#~ "there are evid=3/4 records in an incorrectly sorted dataset, system is " +#~ "reset, but time is not reset" +#~ msgstr "evid=34" -#: rxData.cpp:5492 -msgid "Can not figure out the Rxode2 object" -msgstr "无法找出 Rxode2 对象" +#~ msgid "censoring missing 'DV' values do not make sense" +#~ msgstr "DV" -#: rxData.cpp:5597 rxData.cpp:5640 -msgid "can not figure out the DLL for this object" -msgstr "无法找出此对象的 DLL" +#~ msgid "no rows in event table or input data" +#~ msgstr "" -#: rxData.cpp:5828 -msgid "package-based models cannot be unloaded" -msgstr "无法\"卸载(unloaded)\"基于包的模型" +#~ msgid "empty data" +#~ msgstr "" -#: rxData.cpp:5875 -msgid "package-based models cannot be deleted" -msgstr "无法删除基于包的模型" +#~ msgid "while censoring is included in dataset, no observations are censored" +#~ msgstr "" -#: rxInv.cpp:34 -msgid "matrix seems singular; Using pseudo-inverse\n" -msgstr "矩阵似乎是单数;使用伪逆矩阵\n" +#~ msgid "'dv' and 'limit' swapped since 'limit' > 'dv'" +#~ msgstr "dvlimitlimit>dv" -#: rxInv.cpp:55 rxInv.cpp:59 -msgid "can not invert in 'rxToCholOmega'" -msgstr "不能在“rxToCholOmega”中反转" +#~ msgid "number of individuals not calculated correctly" +#~ msgstr "" -#: rxInv.cpp:126 -msgid "theta number must be positive for 'd(omegaInv)'" -msgstr "theta数量必须为'd(omegaInv)'的正数" +#~ msgid "corrupted event table" +#~ msgstr "" -#: rxInv.cpp:130 -msgid "theta number must be positive for 'd(D)'" -msgstr "theta数量必须为''d(D)'的正数" +#~ msgid "" +#~ "\n" +#~ "with negative times, compartments initialize at first negative observed " +#~ "time\n" +#~ "with positive times, compartments initialize at time zero\n" +#~ "use 'rxSetIni0(FALSE)' to initialize at first observed time\n" +#~ "this warning is displayed once per session" +#~ msgstr "" +#~ "\n" +#~ "\n" +#~ "0\n" +#~ "'rxSetIni0(FALSE)'\n" +#~ "" -#: rxInv.cpp:163 -msgid "error in 'rxSymInvCholEnvCalculate' environment" -msgstr "“rxSymInvCholEnvCalculate”环境中的报错" +#~ msgid "not an integer/real" +#~ msgstr "/" -#: rxInv.cpp:176 -msgid "theta for omega calculations not setup yet" -msgstr "用于omega计算的theta尚未设置" +#~ msgid "The dimensions of the parameters must match" +#~ msgstr "" -#: rxInv.cpp:274 -#, c-format -msgid "theta has to have %d elements" -msgstr "theta必须有 %d 个元素" +#~ msgid "'ncmt' needs to be 1-3" +#~ msgstr "ncmt 1~3" -#: rxInv.cpp:277 -msgid "Can only assign 'theta' in this environment" -msgstr "只能在此环境中分配“theta”" +#~ msgid "'inp' needs to be list/data frame" +#~ msgstr "inp\"(list)\"/\"(data frame)\"" -#: sbuf.c:165 #, c-format -msgid "encoding error in 'addLine' format: '%s' n: %d; errno: %d" -msgstr "“addLine”格式的编码错误:“%s”n:%d;errno: %d" +#~ msgid "invalid trans (2 cmt trans %d)\n" +#~ msgstr "\"trans()\"2 cmt trans %d\n" + +#, c-format +#~ msgid "one or more covariates were all 'NA' for subject 'id=%d'" +#~ msgstr "NAid=%d" + +#~ msgid " with first order absorption\n" +#~ msgstr " \n" -#: threefry.cpp:46 threefry.cpp:118 threefry.cpp:701 -msgid "n should be a positive integer" -msgstr "n 应为正整数" +#~ msgid "cannot figure out the model variables" +#~ msgstr "" -#: threefry.cpp:47 threefry.cpp:119 threefry.cpp:626 threefry.cpp:702 -msgid "'ncores' has to be greater than one" -msgstr "“ncores”必须大于 1" +#~ msgid "class:\t" +#~ msgstr "class:\t" + +#~ msgid "need an Rxode2-type object to extract model variables" +#~ msgstr " Rxode2 " -#: threefry.cpp:480 #, c-format -msgid "dimension wrong in 'gradpsi' (d=%d)" -msgstr "“gradpsi”(d=%d)中的维度数错误" +#~ msgid "'%s' must be symmetric" +#~ msgstr "'%s' " -#: threefry.cpp:582 -msgid "covariance matrix is ill-conditioned and method failed (truncated mvn)" -msgstr "协方差矩阵\"病态(ill-conditioned)\"且方法失败(截断多元正太分布)" +#~ msgid "requires 'params'" +#~ msgstr "params()" -#: threefry.cpp:628 -msgid "'lower' and 'upper' must have the same number of elements." -msgstr "“下”和“上”必须具有相同数量的元素。" +#~ msgid "cannot solve without event information" +#~ msgstr "" -#: threefry.cpp:629 -msgid "'sigma' must be a square matrix with the same dimension as 'upper' and 'lower'" -msgstr "“sigma”必须是与“上”和“下”维度相同的方阵" +#~ msgid "" +#~ "thread safe method, but results may depend on system/load, using 1 core " +#~ "(can change with `cores=`)" +#~ msgstr "/ 1 cores=" -#: threefry.cpp:631 -msgid "'lower' is bigger than 'upper' for at least one item" -msgstr "至少一项的“较低”大于“较高”" +#~ msgid "thread safe method, but results may depend on system/load" +#~ msgstr "/" -#: threefry.cpp:641 -msgid "truncated multivariate normal may fail as covariance matrix is singular" -msgstr "截断的多元正态可能会失败,因为协方差矩阵是奇异的" +#~ msgid "assumed transit compartment model since 'podo' is in the model" +#~ msgstr "podo" -#: threefry.cpp:678 -msgid "acceptance probability smaller than 0.001" -msgstr "接受概率小于 0.001" +#~ msgid "n should be a positive integer" +#~ msgstr "n " -#: threefry.cpp:681 -msgid "could not sample from truncated normal" -msgstr "无法从截断正态采样" +#~ msgid "'ncores' has to be greater than one" +#~ msgstr "ncores 1" -#: threefry.cpp:683 #, c-format -msgid "sample of size %d which is smaller than requested 'n' returned" -msgstr "返回的样本量 %d 小于请求的“n”" +#~ msgid "dimension wrong in 'gradpsi' (d=%d)" +#~ msgstr "gradpsid=%d" -#: threefry.cpp:1447 -msgid "when 'sigma' is a list, it has to have at least 1 element" -msgstr "当“sigma”是一个列表时,它必须至少有 1 个元素" +#~ msgid "" +#~ "covariance matrix is ill-conditioned and method failed (truncated mvn)" +#~ msgstr "\"(ill-conditioned)\"" -#: threefry.cpp:1450 -msgid "'sigma' must be a list of square symmetric matrices" -msgstr "“sigma”必须是包含有对称方阵的\"列表(list)\"" +#~ msgid "'lower' and 'upper' must have the same number of elements." +#~ msgstr "" -#: threefry.cpp:1461 -#, c-format -msgid "'sigma' list element %d does not match dimension of first matrix" -msgstr "“sigma”列表元素 %d 与第一个矩阵的维度数不匹配" +#~ msgid "" +#~ "'sigma' must be a square matrix with the same dimension as 'upper' and " +#~ "'lower'" +#~ msgstr "sigma" -#: threefry.cpp:1499 -msgid "'mu' length must match 'sigma' dimensions" -msgstr "“mu”长度必须与“sigma”维度数匹配" +#~ msgid "'lower' is bigger than 'upper' for at least one item" +#~ msgstr "" -#: threefry.cpp:1649 -msgid "'prob' function should return a vector the same length as the input" -msgstr "“prob”函数应返回与输入长度相同的向量" +#~ msgid "" +#~ "truncated multivariate normal may fail as covariance matrix is singular" +#~ msgstr "" -#: utilc.c:60 utilc.c:88 -msgid "'n' must be greater than 0" -msgstr "“n”必须大于 0" +#~ msgid "acceptance probability smaller than 0.001" +#~ msgstr " 0.001" -#: utilc.c:178 -msgid "'phi' requires numeric values" -msgstr "“phi”需要是数值" +#~ msgid "could not sample from truncated normal" +#~ msgstr "" -#: utilc.c:201 utilc.c:256 utilc.c:311 utilc.c:366 utilc.c:423 utilc.c:479 -#: utilc.c:535 utilc.c:593 utilc.c:655 -msgid "'a' needs to be a number" -msgstr "“a”需要是一个数字" +#, c-format +#~ msgid "sample of size %d which is smaller than requested 'n' returned" +#~ msgstr " %d n" -#: utilc.c:209 utilc.c:264 utilc.c:319 utilc.c:374 utilc.c:431 utilc.c:487 -#: utilc.c:543 utilc.c:601 utilc.c:663 -msgid "'z' needs to be a number" -msgstr "“z”需要是一个数字" +#~ msgid "when 'sigma' is a list, it has to have at least 1 element" +#~ msgstr "sigma 1 " -#: utilc.c:233 utilc.c:288 utilc.c:343 utilc.c:399 utilc.c:456 utilc.c:512 -#: utilc.c:568 utilc.c:629 utilc.c:691 -msgid "inconsistent sizes" -msgstr "不一致的大小" +#~ msgid "'sigma' must be a list of square symmetric matrices" +#~ msgstr "sigma\"(list)\"" -#: utilc.c:719 utilc.c:729 utilc.c:772 utilc.c:782 utilc.c:825 utilc.c:835 -#: utilc.c:879 utilc.c:889 -msgid "'low' must be a numeric of length 1" -msgstr "“low”必须是长度为 1 的数字" +#, c-format +#~ msgid "'sigma' list element %d does not match dimension of first matrix" +#~ msgstr "sigma %d " -#: utilc.c:722 utilc.c:736 utilc.c:775 utilc.c:789 utilc.c:828 utilc.c:842 -#: utilc.c:882 utilc.c:896 -msgid "'high' must be a numeric of length 1" -msgstr "“high”必须是长度为 1 的数字" +#~ msgid "'mu' length must match 'sigma' dimensions" +#~ msgstr "musigma" -#: utilc.c:739 utilc.c:792 utilc.c:845 utilc.c:899 -msgid "'high' must be greater than 'low'" -msgstr "“high”必须大于“low”" +#~ msgid "'prob' function should return a vector the same length as the input" +#~ msgstr "prob" + +#~ msgid "'n' must be greater than 0" +#~ msgstr "n 0" +#~ msgid "'phi' requires numeric values" +#~ msgstr "phi" diff --git a/src/rxData.cpp b/src/rxData.cpp index 127d7b4aa..fb6bd5c57 100644 --- a/src/rxData.cpp +++ b/src/rxData.cpp @@ -63,7 +63,7 @@ extern "C" int getThrottle(); extern "C" int getRxThreads(const int64_t n, const bool throttle); extern "C" void rxode2_assign_fn_pointers_(const char *mv); extern "C" void setSilentErr(int silent); -extern "C" void _rxode2parse_assignUdf(SEXP in); +extern "C" int _rxode2parse_assignUdf(SEXP in); extern "C" { typedef SEXP (*_rxode2parse_getForder_type)(void); @@ -4735,8 +4735,12 @@ SEXP rxSolve_(const RObject &obj, const List &rxControl, rxSolveFreeObj = object; } } - _rxode2parse_assignUdf(rxSolveDat->mv[RxMv_udf]); - + if (_rxode2parse_assignUdf(rxSolveDat->mv[RxMv_udf])) { + Function rxode2 = getRxFn("rxode2"); + object = rxode2(object); + rxSolveDat->mv = rxModelVars(object); + rxSolveFreeObj = object; + } if (rxSolveDat->isRxSolve || rxSolveDat->isEnvironment){ rx_solve* rx = getRxSolve_(); iniRx(rx); diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 6a4475ad1..9d4f1f7a1 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -76,12 +76,15 @@ extern "C" SEXP _rxode2_codeLoaded(void) { END_RCPP } -extern "C" void _rxode2parse_assignUdf(SEXP in) { +extern "C" int _rxode2parse_assignUdf(SEXP in) { + int _ret; BEGIN_RCPP assignRxode2ParsePtrs(); Function fun = as(rxode2parse[".setupUdf"]); - fun(in); + LogicalVector needRecompile = fun(in); + int _ret = needRecompile[0]; VOID_END_RCPP + return _ret; } extern "C" SEXP _rxode2_codegen(SEXP c_file, SEXP prefix, SEXP libname, SEXP pMd5, SEXP timeId, SEXP lastMv, SEXP goodFuns) { diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index 4342e4db7..18068a4f6 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -85,6 +85,31 @@ test_that("udf functions", { expect_error(rxToSE("gg(x,y)")) - exect_error(rxFromSE("Derivative(gg(a,b),a)")) + expect_error(rxFromSE("Derivative(gg(a,b),a)")) + + ## manual functions in C vs R functions + + gg <- function(x, y) { + x + y + } + + x <- rxSolve(f, e) + + # now add a C function with different values + + rxFun("gg", c("x", "y"), + "double gg(double x, double y) { return x*y;}") + + gg <- function(x, y, z) { + x + y + z + } + + expect_error(rxSolve(f, e)) + + gg <- function(x, y) { + x + y + } + + expect_true(all(d$z == d$x * d$y)) }) From 3ad8ba949984b51d4047da8e453e3c3c02f52829 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 31 Oct 2023 09:26:58 -0500 Subject: [PATCH 04/27] Add if/else handling AND make sure the arguments are not assinged --- R/symengine.R | 346 +++++++++++++++++++++++++++++++++++++- tests/testthat/test-udf.R | 85 ++++++++++ 2 files changed, 430 insertions(+), 1 deletion(-) diff --git a/R/symengine.R b/R/symengine.R index 032e8f7a9..006c86229 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -2476,7 +2476,7 @@ rxErrEnvF$probitNorm <- function(est, low = "0", hi = "1") { stop("'probitNorm' can only be in an error function", call. = FALSE) } if (!is.null(rxErrEnv.lambda)) { - if (rxErrEnv.yj != "1") { + if (rxErrEenv.yj != "1") { if (rxErrEnv.yj != "6" &&rxErrEnv.yj != "7") { print(rxErrEnv.yj) stop("'probitNorm' cannot be used with other data transformations", call. = FALSE) @@ -3076,3 +3076,347 @@ rxSplitPlusQ <- function(x, level = 0, mult = FALSE) { rxSupportedFuns <- function() { .rxSupportedFuns(FALSE) } + +.rxFunEq <- 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, + "log" = 1, + "sin" = 1, + "sinh" = 1, + "sqrt" = 1, + "tan" = 1, + "tanh" = 1, + ## C's math.h library + "floor" = 1, + "round" = 1, + "ceil" = 1, + "trunc" = 1, + ## Special R functions + "bessel_i" = 3, + "bessel_j" = 2, + "bessel_k" = 3, + "bessel_y" = 2, + "logspace_add" = 2, + "logspace_sub" = 2, + "fmax2" = 2, + "fmin2" = 2, + "sign" = 1, + "fsign" = 2, + "fprec" = 2, + "fround" = 2, + "ftrunc" = 2, + "transit" = NA, + "gammaq" = 2, + "gammapDer" = 2, + "gammapInv" = 2, + "gammapInva" = 2, + "gammaqInv" = 2, + "gammaqInva" = 2, + "lowergamma" = 2, + "uppergamma" = 2) + +.rxOnly <- c( + ## Now random number generators + "rnorm" = NA, + "rxnorm" = NA, + "rxbinom" = 2, + "rbinom" = 2, + "rxcauchy" = NA, + "rcauchy" = NA, + "rchisq" = 1, + "rxchisq" = 1, + "rexp" = 1, + "rxexp" = 1, + "rbeta" = 2, + "rxbeta" = 2, + "rgeom" = 1, + "rxgeom" = 1, + "rxpois" = 1, + "rpois" = 1, + "rxt" = 1, + "rt" = 1 +) + + +.rxFun2cNameOrAtomic <- function(x, envir) { + # see if it is a reserved rxode2 name/function for name clashes + x <- as.character(x) + if (!exists("res", envir=envir)) { + envir$res <- c(rxSupportedFuns(), + rxReservedKeywords[, 1], + strsplit(paste(rxReservedKeywords[, 3],collapse=","),"[,]+")[[1]]) + } + if (x %in% envir$funs) { + return(paste0("_qf_", x)) + } + x +} + +.rxFun2cArithmeticOperators <- function(x, envir) { + if (length(x) == 3) { + if (identical(x[[1]], quote(`/`))) { + .x2 <- x[[2]] + .x3 <- x[[3]] + ## df(%s)/dy(%s) + if (identical(.x2, quote(`d`)) && + identical(.x3[[1]], quote(`dt`))) { + if (length(.x3[[2]]) == 1) { + .state <- as.character(.x3[[2]]) # .rxToSE(.x3[[2]], envir = envir) + } else { + .state <- .rxFun2c(.x3[[2]], envir = envir) + } + stop("d/dt(", .state, ") not supported in functions for translation") + } else { + if (length(.x2) == 2 && length(.x3) == 2) { + if (identical(.x2[[1]], quote(`df`)) && + identical(.x3[[1]], quote(`dy`))) { + if (length(.x2[[2]]) == 1) { + .state <- as.character(.x2[[2]]) + } else { + .state <- .rxFun2c(.x2[[2]], envir = envir) + } + if (length(.x3[[2]]) == 1) { + .var <- as.character(.x3[[2]]) + } else { + .var <- .rxFun2c(.x3[[2]], envir = envir) + } + stop("df(", .state, ")/dy(", .var, ") statements are not supported in translation", + call. = FALSE) + } + } + .ret <- paste0( + .rxFun2c(.x2, envir = envir), + as.character(x[[1]]), + .rxFun2c(.x3, envir = envir) + ) + } + } else if (identical(x[[1]], quote(`^`)) || + identical(x[[1]], quote(`**`))) { + if (is.numeric(x[[3]]) && + checkmate::checkIntegerish(x[[3]])) { + return(paste0("R_pow_di(", .rxFun2c(x[[2]], envir = envir), ",", + as.character(x[[3]]), ")")) + } else { + return(paste0("R_pow(", .rxFun2c(x[[2]], envir=envir), ",", + .rxFun2c(x[[3]], envir=envir), ")")) + } + } else { + .ret <- paste0( + .rxFun2c(x[[2]], envir = envir), + as.character(x[[1]]), + .rxFun2c(x[[3]], envir = envir) + ) + } + return(.ret) + } else { + ## Unary Operators + return(paste( + as.character(x[[1]]), + .rxFun2c(x[[2]], envir = envir) + )) + } +} +.rxFun2cAssignOperators <- function(x, envir = envir) { + if (identical(x[[1]], quote(`~`))) { + stop("formulas or other expressions with '~` are not supported in translation", + call.=FALSE) + } + if (as.character(x[[2]]) %in% envir$args) { + stop("cannot assign argument '", as.character(x[[2]]), + "' in functions converted to C", + call.=FALSE) + } + .lhs <- .rxFun2cNameOrAtomic(x[[2]], envir=envir) + if (!(.lhs %in% envir$args)) { + envir$vars <- c(envir$vars, .lhs) + } + envir$didAssign <- TRUE + .pre <- paste0(rep(" ", envir$n), collapse="") + return(paste0(.pre, "_lastValue = ", .lhs, " = ", + .rxFun2c(x[[3]], envir=envir), ";\n")) +} + +.rxFun2cSquareBracket <- function(x, envir) { + stop("bracket expressions (ie ret[3]) are not supported in translation", + call. = FALSE) +} + +.rxFun2cLogic <- function(x, envir) { + if (identical(x[[1]], quote(`!`))) { + return(paste0("!(", .rxFun2c(x[[2]], envir=envir), ")")) + } else if (identical(x[[1]], quote(`&`))) { + return(paste0(.rxFun2c(x[[2]], envir=envir), " && ", + .rxFun2c(x[[3]], envir=envir))) + } else if (identical(x[[1]], quote(`|`))) { + return(paste0(.rxFun2c(x[[2]], envir=envir), " || ", + .rxFun2c(x[[3]], envir=envir))) + } else { + return(paste0(.rxFun2c(x[[2]], envir=envir), " ", as.character(x[[1]]), " ", + .rxFun2c(x[[3]], envir=envir))) + } +} + +.rxFun2cIf <- function(x, envir) { + .logic <- .rxFun2c(x[[2]], envir=envir) + .pre <- paste0(rep(" ", envir$n), collapse="") + .ret <- paste(.pre, "if (", .logic, ") "); + .ret <- paste0(.ret, .rxFun2c(x[[3]], envir=envir)) + + if (length(x) == 3) { + envir$isExpr <- TRUE + return(.ret) + } + .ret <- sub("else +if", "else if", paste0(.ret, .pre, "else ", .rxFun2c(x[[4]], envir=envir))) + envir$isExpr <- TRUE + return(.ret) +} + +.rxFun2cCall <- function(x, envir) { + if (identical(x[[1]], quote(`{`))) { + .ret <- "{\n" + envir$n <- envir$n + 2 + .ret <- paste0(.ret, + paste(vapply(seq_along(x)[-1], + function(i) { + .cur <- x[[i]] + .last <- envir$didAssign + .expr <- envir$isExpr + on.exit({ + assign("isExpr", .expr, envir=envir) + assign("didAssign", .last, envir=envir) + }) + envir$didAssign <- FALSE + .cur <- .rxFun2c(.cur, envir=envir) + if(!envir$didAssign && !envir$isExpr) { + .pre <- paste0(rep(" ", envir$n), collapse="") + return(paste0(.pre, "_lastValue = ", .cur, ";\n")) + } + .cur + }, character(1), USE.NAMES = FALSE), + collapse="")) + envir$n <- envir$n - 2 + .pre <- paste0(rep(" ", envir$n), collapse="") + .ret <- paste0(.ret, .pre, "}\n") + return(.ret) + } else if (identical(x[[1]], quote(`(`))) { + return(paste0("(", .rxFun2c(x[[2]], envir = envir), ")")) + } else if (identical(x[[1]], quote(`&`)) || + identical(x[[1]], quote(`&&`)) || + identical(x[[1]], quote(`==`)) || + identical(x[[1]], quote(`||`)) || + identical(x[[1]], quote(`|`)) || + identical(x[[1]], quote(`>`)) || + identical(x[[1]], quote(`<`)) || + identical(x[[1]], quote(`<=`)) || + identical(x[[1]], quote(`>=`)) || + identical(x[[1]], quote(`!=`)) || + identical(x[[1]], quote(`!`)) + ){ + return(.rxFun2cLogic(x, envir=envir)) + } else if (identical(x[[1]], quote(`*`)) || + identical(x[[1]], quote(`**`)) || + identical(x[[1]], quote(`^`)) || + identical(x[[1]], quote(`+`)) || + identical(x[[1]], quote(`-`)) || + identical(x[[1]], quote(`/`))) { + return(.rxFun2cArithmeticOperators(x, envir = envir)) + } else if (identical(x[[1]], quote(`=`)) || + identical(x[[1]], quote(`<-`)) || + identical(x[[1]], quote(`~`))) { + return(.rxFun2cAssignOperators(x, envir)) + } else if (identical(x[[1]], quote(`[`))) { + return(.rxFun2cSquareBracket(x, envir = envir)) + } else if (identical(x[[1]], quote(`if`))) { + return(.rxFun2cIf(x, envir = envir)) + } else { + # supported functions + if (identical(x[[1]], quote(`return`))) { + .pre <- paste0(rep(" ", envir$n), collapse="") + envir$didAssign <- TRUE + return(paste0(.pre, "return (", .rxFun2c(x[[2]], envir=envir), ");\n")) + } + .ret0 <- lapply(x, .stripP) + .FunEq <- c(.rxFunEq, rxode2parse::.rxSEeqUsr()) + .curName <- paste(.ret0[[1]]) + .nargs <- .FunEq[.curName] + if (!is.na(.nargs)) { + if (.nargs == length(.ret0) - 1) { + return(paste0(.curName, "(", + paste(vapply(seq_along(.ret0)[-1], + function(i) { + .rxFun2c(.ret0[[i]], envir=envir) + }, character(1), USE.NAMES=FALSE), + collapse=","), + ")")) + } + } + stop("cannot translate function '", .curName, "'", + call.=FALSE) + } +} + +#' @rdname rxToSE +#' @export +.rxFun2c <- function(x, envir) { + if (is.name(x) || is.atomic(x)) { + return(.rxFun2cNameOrAtomic(x, envir=envir)) + } else if (is.call(x)) { + return(.rxFun2cCall(x, envir = envir)) + } else { + stop("unsupported expression", call. = FALSE) + } +} + +rxFun2c <- function(fun) { + .env <- new.env(parent=emptyenv()) + .env$vars <- character(0) + .funName <- as.character(substitute(fun)) + .f <- formals(fun) + .env$args <- names(.f) + .env$n <- 2 + .env$isExpr <- FALSE + if (any(.env$args == "...")) { + stop("functions with ... in them are not supported", + call. =FALSE) + } + .start <- paste0("double ", .funName, "(", paste(paste("double ", .env$args), collapse=", "), + ") {\n") + + .body <- as.list(body(fun)) + .body <- paste(vapply(seq_along(.body)[-1], function(i) { + .extra <- .extra2 <- "" + .cur <- .body[[i]] + .env$didAssign <- FALSE + .cur <- .rxFun2c(.cur, envir=.env) + if(!.env$didAssign && !.env$isExpr) { + .pre <- paste0(rep(" ", .env$n), collapse="") + return(paste0(.pre, "_lastValue = ", .cur, ";\n")) + } + .env$isExpr <- FALSE + .cur + }, + character(1), USE.NAMES=FALSE), collapse="") + + .start <- paste0(.start, + paste0(" double ", + paste(paste0(c("_lastValue", unique(.env$vars)), "=NA_REAL"), collapse=","), + ";\n")) + .stop <- " return _lastValue;\n}\n" + .cCode <- paste0(.start, .body, .stop) + list(name=.funName, + args=.env$args, + cCode=.cCode) +} diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index 18068a4f6..44dd0b937 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -112,4 +112,89 @@ test_that("udf functions", { expect_true(all(d$z == d$x * d$y)) + udf <- function(x, y) { + a <- x + y + b <- a ^ 2 + a + b + } + + expect_true(grepl("R_pow_di[(]", rxFun2c(udf)$cCode)) + + udf <- function(x, y) { + a <- x + y + b <- a ^ x + a + b + } + + expect_true(grepl("R_pow[(]", rxFun2c(udf)$cCode)) + + udf <- function(x, y) { + a <- x + y + b <- cos(a) + x + a + b + } + + expect_true(grepl("cos[(]", rxFun2c(udf)$cCode)) + + udf <- function(x, y) { + if (a < b) { + return(b ^ 2) + } + a + b + } + + expect_true(grepl("if [(]", rxFun2c(udf)$cCode)) + + + udf <- function(x, y) { + a <- x + b <- x ^ 2 + a + if (a < b) { + return(b ^ 2) + } else { + a + b + } + } + + expect_true(grepl("else [{]", rxFun2c(udf)$cCode)) + + udf <- function(x, y) { + a <- x + b <- x ^ 2 + a + if (a < b) { + return(b ^ 2) + } else if (a > b + 3) { + return(a + b) + } + a ^ 2 + b ^ 2 + } + + expect_true(grepl("else if [(]", rxFun2c(udf)$cCode)) + + + udf <- function(x, y) { + a <- x + b <- x ^ 2 + a + if (a < b) { + return(b ^ 2) + } else if (a > b + 3) { + b <- 3 + if (a > 2) { + a <- 2 + } + return(a + b) + } + a ^ 2 + b ^ 2 + } + + expect_true(grepl("else if [(]", rxFun2c(udf)$cCode)) + + udf <- function(x, y) { + a <- x + y + x <- a ^ 2 + x + } + + expect_error(rxFun2c(udf)$cCode) + }) From c592f970667501beb235cf4488fd9fdfcfff4f40 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 31 Oct 2023 10:34:56 -0500 Subject: [PATCH 05/27] Update examples to show R->C conversion of function --- R/symengine.R | 73 +++++++++++++++++++++++++--- man/rxode2.Rd | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+), 7 deletions(-) diff --git a/R/symengine.R b/R/symengine.R index 006c86229..13db5ab85 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -265,17 +265,24 @@ regIfOrElse <- rex::rex(or(regIf, regElse)) ) #' @inherit rxode2parse::rxFunParse +#' @param name This can either give the name of the user function or +#' be a simple R function that you wish to convert to C. If you +#' have rxode2 convert the R function to C, the name of the function +#' will match the function name provided and the number of arguments +#' will match the R function provided. Hence, if you are providing +#' an R function for conversion to C, the rest of the arguments are +#' implied. #' @examples #' \donttest{ -#' ## Right now rxode2 is not aware of the function f +#' ## Right now rxode2 is not aware of the function fun #' ## Therefore it cannot translate it to symengine or #' ## Compile a model with it. #' #' try(rxode2("a=fun(a,b,c)")) #' #' ## Note for this approach to work, it cannot interfere with C -#' ## function names or reserved rxode2 specical terms. Therefore -#' ## f(x) would not work since f is an alias for bioaviability. +#' ## function names or reserved rxode2 special terms. Therefore +#' ## f(x) would not work since f is an alias for bioavailability. #' #' fun <- " #' double fun(double a, double b, double c) { @@ -311,9 +318,59 @@ regIfOrElse <- rex::rex(or(regIf, regElse)) #' # You can also remove the functions by `rxRmFun` #' #' rxRmFun("fun") +#' +#' # you can also use R functions directly in rxode2 +#' +#' +#' gg <- function(x, y) { +#' x + y +#' } +#' +#' f <- rxode2({ +#' z = gg(x, y) +#' }) +#' +#' +#' e <- et(1:10) |> as.data.frame() +#' +#' e$x <- 1:10 +#' e$y <- 21:30 +#' +#' rxSolve(f, e) +#' +#' # Note that since it touches R, it can only run single-threaded. +#' # There are also requirements for the function: +#' # +#' # 1. It accepts one value per argument (numeric) +#' # +#' # 2. It returns one numeric value +#' +#' # If it is a simple function (like gg) you can also convert it to C +#' # using rxFun and load it into rxode2 +#' +#' rxFun(gg) +#' +#' rxSolve(f, e) +#' +#' # to stop the recompile simply reassign the function +#' f <- rxode2(f) +#' +#' rxSolve(f, e) +#' +#' rxRmFun("gg") +#' rm(gg) +#' rm(f) #' } #' @export rxFun <- function(name, args, cCode) { + if (missing(args) && missing(cCode)) { + .funName <- as.character(substitute(name)) + .lst <- rxFun2c(name, name=.funName) + .ret <- do.call(rxode2parse::rxFunParse, .lst) + message("converted R function '", .lst$name, "' to C with code:") + message(.lst$cCode) + return(invisible()) + } rxode2parse::rxFunParse(name, args, cCode) } @@ -3368,8 +3425,6 @@ rxSupportedFuns <- function() { } } -#' @rdname rxToSE -#' @export .rxFun2c <- function(x, envir) { if (is.name(x) || is.atomic(x)) { return(.rxFun2cNameOrAtomic(x, envir=envir)) @@ -3380,10 +3435,14 @@ rxSupportedFuns <- function() { } } -rxFun2c <- function(fun) { +rxFun2c <- function(fun, name) { .env <- new.env(parent=emptyenv()) .env$vars <- character(0) - .funName <- as.character(substitute(fun)) + if (!missing(name)) { + .funName <- name + } else { + .funName <- as.character(substitute(fun)) + } .f <- formals(fun) .env$args <- names(.f) .env$n <- 2 diff --git a/man/rxode2.Rd b/man/rxode2.Rd index e9a843855..c6e519bb6 100644 --- a/man/rxode2.Rd +++ b/man/rxode2.Rd @@ -209,6 +209,138 @@ suggest the package emphasis on pharmacometrics modeling, including pharmacokinetics (PK), pharmacodynamics (PD), disease progression, drug-disease modeling, etc. +The ODE-based model specification may be coded inside four places: +\itemize{ +\item Inside a \code{rxode2({})} block statements: +}\if{html}{\out{ + +}} + + +\if{html}{\out{
}}\preformatted{library(rxode2) +mod <- rxode2(\{ + # simple assignment + C2 <- centr/V2 + + # time-derivative assignment + d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; +\}) +}\if{html}{\out{
}} +\itemize{ +\item Inside a \code{rxode2("")} string statement: +}\if{html}{\out{ + +}} + + +\if{html}{\out{
}}\preformatted{mod <- rxode2(" + # simple assignment + C2 <- centr/V2 + + # time-derivative assignment + d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; +") +}\if{html}{\out{
}} +\itemize{ +\item In a file name to be loaded by rxode2: +}\if{html}{\out{ + +}} + + +\if{html}{\out{
}}\preformatted{writeLines(" + # simple assignment + C2 <- centr/V2 + + # time-derivative assignment + d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; +", "modelFile.rxode2") +mod <- rxode2(filename='modelFile.rxode2') +unlink("modelFile.rxode2") +}\if{html}{\out{
}} +\itemize{ +\item In a model function which can be parsed by \code{rxode2}: +}\if{html}{\out{ + +}} + + +\if{html}{\out{
}}\preformatted{mod <- function() \{ + model(\{ + # simple assignment + C2 <- centr/V2 + + # time-derivative assignment + d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; + \}) +\} + +mod <- rxode2(mod) # or simply mod() if the model is at the end of the function + +# These model functions often have residual components and initial +# (`ini(\{\})`) conditions attached as well. For example the +# theophylline model can be written as: + +one.compartment <- function() \{ + ini(\{ + tka <- 0.45 # Log Ka + tcl <- 1 # Log Cl + tv <- 3.45 # Log V + eta.ka ~ 0.6 + eta.cl ~ 0.3 + eta.v ~ 0.1 + add.sd <- 0.7 + \}) + model(\{ + ka <- exp(tka + eta.ka) + cl <- exp(tcl + eta.cl) + v <- exp(tv + eta.v) + d/dt(depot) = -ka * depot + d/dt(center) = ka * depot - cl / v * center + cp = center / v + cp ~ add(add.sd) + \}) +\} + +# after parsing the model +mod <- one.compartment() +}\if{html}{\out{
}} + +For the block statement, character string or text file an internal +\code{rxode2} compilation manager translates the ODE system into C, compiles +it and loads it into the R session. The call to \code{rxode2} produces an +object of class \code{rxode2} which consists of a list-like structure +(environment) with various member functions. + +For the last type of model (a model function), a call to \code{rxode2} +creates a parsed \code{rxode2} ui that can be translated to the \code{rxode2} +compilation model. + +\if{html}{\out{
}}\preformatted{mod$simulationModel +}\if{html}{\out{
}} + +\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_d670952790aeef6ec09729654f5533fa model (ready). +## x$state: depot, center +## x$stateExtra: cp +## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp +## x$lhs: ka, cl, v, cp, ipredSim, sim +}\if{html}{\out{
}} + +\if{html}{\out{
}}\preformatted{# or +mod$simulationIniModel +}\if{html}{\out{
}} + +\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_2875062832076b4d6009c463ce5eaf6e model (ready). +## x$state: depot, center +## x$stateExtra: cp +## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp +## x$lhs: ka, cl, v, cp, ipredSim, sim +}\if{html}{\out{
}} + +This is the same type of function required for \code{nlmixr2} estimation and +can be extended and modified by model piping. For this reason will be +focused on in the documentation. + This basic model specification consists of one or more statements optionally terminated by semi-colons \verb{;} and optional comments (comments are delimited by \verb{#} and an end-of-line). From b0cfb7a5e1213cd5d0cbb7d56505e61a82434481 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 31 Oct 2023 10:35:20 -0500 Subject: [PATCH 06/27] Add rxFun man --- man/rxFun.Rd | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 man/rxFun.Rd diff --git a/man/rxFun.Rd b/man/rxFun.Rd new file mode 100644 index 000000000..09ed635e6 --- /dev/null +++ b/man/rxFun.Rd @@ -0,0 +1,126 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/symengine.R +\name{rxFun} +\alias{rxFun} +\alias{rxRmFun} +\title{Add user function to rxode2} +\usage{ +rxFun(name, args, cCode) + +rxRmFun(name) +} +\arguments{ +\item{name}{This can either give the name of the user function or +be a simple R function that you wish to convert to C. If you +have rxode2 convert the R function to C, the name of the function +will match the function name provided and the number of arguments +will match the R function provided. Hence, if you are providing +an R function for conversion to C, the rest of the arguments are +implied.} + +\item{args}{This gives the arguments of the user function} + +\item{cCode}{This is the C-code for the new function} +} +\value{ +nothing +} +\description{ +This adds a user function to rxode2 that can be called. If needed, +these functions can be differentiated by numerical differences or +by adding the derivatives to rxode2's internal derivative table +with \code{\link[=rxD]{rxD()}} +} +\examples{ +\donttest{ +## Right now rxode2 is not aware of the function fun +## Therefore it cannot translate it to symengine or +## Compile a model with it. + +try(rxode2("a=fun(a,b,c)")) + +## Note for this approach to work, it cannot interfere with C +## function names or reserved rxode2 special terms. Therefore +## f(x) would not work since f is an alias for bioavailability. + +fun <- " +double fun(double a, double b, double c) { + return a*a+b*a+c; +} +" ## C-code for function + +rxFun("fun", c("a", "b", "c"), fun) ## Added function + +## Now rxode2 knows how to translate this function to symengine + +rxToSE("fun(a,b,c)") + +## And will take a central difference when calculating derivatives + +rxFromSE("Derivative(fun(a,b,c),a)") + +## Of course, you could specify the derivative table manually +rxD("fun", list( + function(a, b, c) { + paste0("2*", a, "+", b) + }, + function(a, b, c) { + return(a) + }, + function(a, b, c) { + return("0.0") + } +)) + +rxFromSE("Derivative(fun(a,b,c),a)") + +# You can also remove the functions by `rxRmFun` + +rxRmFun("fun") + +# you can also use R functions directly in rxode2 + + +gg <- function(x, y) { + x + y +} + +f <- rxode2({ + z = gg(x, y) +}) + + +e <- et(1:10) |> as.data.frame() + +e$x <- 1:10 +e$y <- 21:30 + +rxSolve(f, e) + +# Note that since it touches R, it can only run single-threaded. +# There are also requirements for the function: +# +# 1. It accepts one value per argument (numeric) +# +# 2. It returns one numeric value + +# If it is a simple function (like gg) you can also convert it to C +# using rxFun and load it into rxode2 + +rxFun(gg) + +rxSolve(f, e) + +# to stop the recompile simply reassign the function +f <- rxode2(f) + +rxSolve(f, e) + +rxRmFun("gg") +rm(gg) +rm(f) +} +} +\author{ +Matthew L. Fidler +} From a10400335ace65f9f363e3473913bf21b58327fc Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 31 Oct 2023 19:40:37 -0500 Subject: [PATCH 07/27] more udf fixes --- R/rxUiGet.R | 7 ++- R/rxode2.R | 27 ++++++---- R/rxsolve.R | 24 ++++++--- inst/include/rxode2_control.h | 96 +---------------------------------- man/as.rxUi.Rd | 21 ++++---- man/rxFun.Rd | 2 +- man/rxSolve.Rd | 14 ++++- man/rxode2.Rd | 26 ++++++++-- src/rxData.cpp | 6 ++- src/rxode2parse.cpp | 20 ++++++++ tests/testthat/test-udf.R | 3 ++ tests/testthat/test-ui.R | 1 + 12 files changed, 116 insertions(+), 131 deletions(-) diff --git a/R/rxUiGet.R b/R/rxUiGet.R index 9d26a76db..2e4c79a71 100644 --- a/R/rxUiGet.R +++ b/R/rxUiGet.R @@ -24,6 +24,11 @@ #' @export `$.rxUi` <- function(obj, arg, exact = TRUE) { + # need to assign environment correctly for UDF + rxode2parse::.udfEnvSet(parent.frame(1)) + # Keep it locked to avoid environment nesting nightmare + rxode2parse::.udfEnvLock() + on.exit(rxode2parse::.udfEnvLock(FALSE)) rxUiGet(.uiToRxUiGet(obj=obj, arg=arg, exact=exact)) } @@ -200,7 +205,7 @@ attr(rxUiGet.funPrint, "desc") <- "Normalized, quoted model function (for printi rxUiGet.fun <- function(x, ...) { .ret <- rxUiGet.funPrint(x, ...) .ret2 <- function() { - + } body(.ret2) <- as.call(.ret) .ret2 diff --git a/R/rxode2.R b/R/rxode2.R index 18c0df0e3..d35b8ada4 100644 --- a/R/rxode2.R +++ b/R/rxode2.R @@ -83,6 +83,8 @@ NA_LOGICAL <- NA # nolint #' print on every step (except ME/indLin), otherwise when `FALSE` #' print only when calculating the `d/dt` #' +#' @inheritParams rxode2parse::rxode2parse +#' #' @details #' #' The `Rx` in the name `rxode2` is meant to suggest the @@ -142,7 +144,7 @@ NA_LOGICAL <- NA # nolint #' #' `atol`: a numeric absolute tolerance (1e-08 by default); #' -#' `rtol`: a numeric relative tolerance (1e-06 by default).e +#' `rtol`: a numeric relative tolerance (1e-06 by default). #' #' The output of \dQuote{solve} is a matrix with as many rows as there #' are sampled time points and as many columns as system variables @@ -273,7 +275,9 @@ rxode2 <- # nolint linCmtSens = c("linCmtA", "linCmtB", "linCmtC"), indLin = FALSE, verbose = FALSE, - fullPrint=getOption("rxode2.fullPrint", FALSE)) { + fullPrint=getOption("rxode2.fullPrint", FALSE), + envir=parent.frame()) { + rxode2parse::.udfEnvSet(envir) assignInMyNamespace(".rxFullPrint", fullPrint) rxSuppressMsg() rxode2parse::rxParseSuppressMsg() @@ -633,23 +637,28 @@ rxGetModel <- function(model, calcSens = NULL, calcJac = NULL, collapseModel = N model <- model[-length(model)] } model <- paste(model, collapse = "\n") - } else if (is(model, "function") || is(model, "call")) { + } else if (inherits(model, "function") || inherits(model, "call")) { model <- deparse(body(model)) if (model[1] == "{") { model <- model[-1] model <- model[-length(model)] } model <- paste(model, collapse = "\n") - } else if (is(model, "name")) { + } else if (inherits(model, "name")) { model <- eval(model) - } else if (is(model, "character") || is(model, "rxModelText")) { + } else if (inherits(model, "character") || inherits(model, "rxModelText")) { model <- as.vector(model) - } else if (is(model, "rxode2")) { + } else if (inherits(model, "rxode2")) { model <- rxModelVars(model) ## class(model) <- NULL; - } else if (is(model, "rxModelVars")) { + } else if (inherits(model, "rxModelVars")) { + } else if (inherits(model, "rxDll")) { + model <- model$args$model } else { - stop("cannot figure out how to handle the model argument", call. = FALSE) + model <- rxModelVars(model) + if (!inherits(model, "rxModelVars")) { + stop("cannot figure out how to handle the model argument", call. = FALSE) + } } .ret <- rxModelVars(model) if (!is.null(calcSens)) { @@ -1039,7 +1048,7 @@ rxMd5 <- function(model, # Model File rxode2.calculate.sensitivity) .ret <- c( .ret, .tmp, .rxIndLinStrategy, .rxIndLinState, - .linCmtSens, ls(rxode2parse::.symengineFs()), .rxFullPrint + .linCmtSens, rxode2parse::.udfMd5Info(), .rxFullPrint ) if (is.null(.md5Rx)) { .tmp <- getLoadedDLLs()$rxode2 diff --git a/R/rxsolve.R b/R/rxsolve.R index 34a52723e..d736a0d2e 100644 --- a/R/rxsolve.R +++ b/R/rxsolve.R @@ -1,4 +1,4 @@ - #' Options, Solving & Simulation of an ODE/solved system +#' Options, Solving & Simulation of an ODE/solved system #' #' This uses rxode2 family of objects, file, or model specification to #' solve a ODE system. There are many options for a solved rxode2 @@ -575,6 +575,8 @@ #' #' @inheritParams odeMethodToInt #' +#' @inheritParams rxode2parse::rxode2parse +#' #' @param useStdPow This uses C's `pow` for exponentiation instead of #' R's `R_pow` or `R_pow_di`. By default this is `FALSE` #' @@ -720,7 +722,8 @@ rxSolve <- function(object, params = NULL, events = NULL, inits = NULL, addlKeepsCov=FALSE, addlDropSs=TRUE, ssAtDoseTime=TRUE, - ss2cancelAllPending=FALSE) { + ss2cancelAllPending=FALSE, + envir=parent.frame()) { if (is.null(object)) { .xtra <- list(...) .nxtra <- names(.xtra) @@ -1122,7 +1125,9 @@ rxSolve <- function(object, params = NULL, events = NULL, inits = NULL, addlDropSs=addlDropSs, ssAtDoseTime=ssAtDoseTime, ss2cancelAllPending=ss2cancelAllPending, + envir=envir, .zeros=unique(.zeros) + ) class(.ret) <- "rxControl" return(.ret) @@ -1238,7 +1243,7 @@ rxSolve.rxUi <- function(object, params = NULL, events = NULL, inits = NULL, ... if (is.null(.lst$omega) && is.null(.lst$sigma)) { .pred <- TRUE if (!.hasIpred && any(rxModelVars(.lst[[1]])$lhs == "ipredSim")) { - .lst$drop <- c(.lst$drop, "ipredSim") + .lst$drop <- c(.lst$drop, "ipredSim") } } .ret <- do.call("rxSolve.default", .lst) @@ -1300,7 +1305,7 @@ rxSolve.nlmixr2FitCore <- rxSolve.nlmixr2FitData #' @rdname rxSolve #' @export rxSolve.default <- function(object, params = NULL, events = NULL, inits = NULL, ..., - theta = NULL, eta = NULL) { + theta = NULL, eta = NULL, envir=parent.frame()) { on.exit({ .clearPipe() .asFunctionEnv$rx <- NULL @@ -1394,7 +1399,7 @@ rxSolve.default <- function(object, params = NULL, events = NULL, inits = NULL, if (any(names(.lst) == ".setupOnly")) { .setupOnly <- .lst$.setupOnly } - .ctl <- rxControl(..., events = events, params = params) + .ctl <- rxControl(..., events = events, params = params, envir=envir) if (.ctl$addCov && length(.ctl$keep) > 0) { .mv <- rxModelVars(object) .both <- intersect(.mv$params, .ctl$keep) @@ -1406,7 +1411,7 @@ rxSolve.default <- function(object, params = NULL, events = NULL, inits = NULL, .w <- which(names(.ctl) == "keep") .ctl[[.w]] <- .keep .ctl <- do.call(rxControl, - c(.ctl, list(events = events, params = params))) + c(.ctl, list(events = events, params = params, envir=envir))) } } @@ -1671,6 +1676,7 @@ rxSolve.default <- function(object, params = NULL, events = NULL, inits = NULL, } .minfo(sprintf("omega/sigma items treated as zero: '%s'", paste(.ctl$.zeros, collapse="', '"))) } + if (rxode2.debug) { .envReset$ret <- .collectWarnings(rxSolveSEXP(object, .ctl, .nms, .xtra, params, events, inits, @@ -1797,6 +1803,7 @@ solve.rxSolve <- function(a, b, ...) { n[n == "b"] <- "" } names(lst) <- n + lst$envir <- parent.frame(1) do.call("rxSolve", lst, envir = parent.frame(1)) } @@ -2004,8 +2011,9 @@ drop_units.rxSolve <- function(x) { #' @rdname rxSolve #' @export -rxControl <- function(..., params = NULL, events = NULL, inits = NULL) { - rxSolve(object = NULL, params = params, events = events, inits = inits, ...) +rxControl <- function(..., params = NULL, events = NULL, inits = NULL, envir=parent.frame()) { + rxSolve(object = NULL, params = params, events = events, inits = inits, ..., + envir=envir) } #' @export diff --git a/inst/include/rxode2_control.h b/inst/include/rxode2_control.h index d84e1f0f0..fec561cf8 100644 --- a/inst/include/rxode2_control.h +++ b/inst/include/rxode2_control.h @@ -2,99 +2,5 @@ #ifndef __rxode2_control_H__ #define __rxode2_control_H__ #include -#define Rxc_scale 0 -#define Rxc_method 1 -#define Rxc_atol 2 -#define Rxc_rtol 3 -#define Rxc_maxsteps 4 -#define Rxc_hmin 5 -#define Rxc_hmax 6 -#define Rxc_hini 7 -#define Rxc_maxordn 8 -#define Rxc_maxords 9 -#define Rxc_covsInterpolation 10 -#define Rxc_addCov 11 -#define Rxc_returnType 12 -#define Rxc_sigma 13 -#define Rxc_sigmaDf 14 -#define Rxc_nCoresRV 15 -#define Rxc_sigmaIsChol 16 -#define Rxc_sigmaSeparation 17 -#define Rxc_sigmaXform 18 -#define Rxc_nDisplayProgress 19 -#define Rxc_amountUnits 20 -#define Rxc_timeUnits 21 -#define Rxc_addDosing 22 -#define Rxc_stateTrim 23 -#define Rxc_updateObject 24 -#define Rxc_omega 25 -#define Rxc_omegaDf 26 -#define Rxc_omegaIsChol 27 -#define Rxc_omegaSeparation 28 -#define Rxc_omegaXform 29 -#define Rxc_nSub 30 -#define Rxc_thetaMat 31 -#define Rxc_thetaDf 32 -#define Rxc_thetaIsChol 33 -#define Rxc_nStud 34 -#define Rxc_dfSub 35 -#define Rxc_dfObs 36 -#define Rxc_seed 37 -#define Rxc_nsim 38 -#define Rxc_minSS 39 -#define Rxc_maxSS 40 -#define Rxc_strictSS 41 -#define Rxc_infSSstep 42 -#define Rxc_istateReset 43 -#define Rxc_subsetNonmem 44 -#define Rxc_hmaxSd 45 -#define Rxc_maxAtolRtolFactor 46 -#define Rxc_from 47 -#define Rxc_to 48 -#define Rxc_by 49 -#define Rxc_length_out 50 -#define Rxc_iCov 51 -#define Rxc_keep 52 -#define Rxc_keepF 53 -#define Rxc_drop 54 -#define Rxc_warnDrop 55 -#define Rxc_omegaLower 56 -#define Rxc_omegaUpper 57 -#define Rxc_sigmaLower 58 -#define Rxc_sigmaUpper 59 -#define Rxc_thetaLower 60 -#define Rxc_thetaUpper 61 -#define Rxc_indLinPhiM 62 -#define Rxc_indLinPhiTol 63 -#define Rxc_indLinMatExpType 64 -#define Rxc_indLinMatExpOrder 65 -#define Rxc_idFactor 66 -#define Rxc_mxhnil 67 -#define Rxc_hmxi 68 -#define Rxc_warnIdSort 69 -#define Rxc_ssAtol 70 -#define Rxc_ssRtol 71 -#define Rxc_safeZero 72 -#define Rxc_sumType 73 -#define Rxc_prodType 74 -#define Rxc_sensType 75 -#define Rxc_linDiff 76 -#define Rxc_linDiffCentral 77 -#define Rxc_resample 78 -#define Rxc_resampleID 79 -#define Rxc_maxwhile 80 -#define Rxc_cores 81 -#define Rxc_atolSens 82 -#define Rxc_rtolSens 83 -#define Rxc_ssAtolSens 84 -#define Rxc_ssRtolSens 85 -#define Rxc_simVariability 86 -#define Rxc_nLlikAlloc 87 -#define Rxc_useStdPow 88 -#define Rxc_naTimeHandle 89 -#define Rxc_addlKeepsCov 90 -#define Rxc_addlDropSs 91 -#define Rxc_ssAtDoseTime 92 -#define Rxc_ss2cancelAllPending 93 -#define Rxc__zeros 94 + #endif // __rxode2_control_H__ diff --git a/man/as.rxUi.Rd b/man/as.rxUi.Rd index 3256eec73..f54aeb03f 100644 --- a/man/as.rxUi.Rd +++ b/man/as.rxUi.Rd @@ -10,22 +10,25 @@ \alias{as.rxUi.default} \title{As rxode2 ui} \usage{ -as.rxUi(x) +as.rxUi(x, envir = parent.frame()) -\method{as.rxUi}{rxode2}(x) +\method{as.rxUi}{rxode2}(x, envir = parent.frame()) -\method{as.rxUi}{rxode2tos}(x) +\method{as.rxUi}{rxode2tos}(x, envir = parent.frame()) -\method{as.rxUi}{rxModelVars}(x) +\method{as.rxUi}{rxModelVars}(x, envir = parent.frame()) -\method{as.rxUi}{`function`}(x) +\method{as.rxUi}{`function`}(x, envir = parent.frame()) -\method{as.rxUi}{rxUi}(x) +\method{as.rxUi}{rxUi}(x, envir = parent.frame()) -\method{as.rxUi}{default}(x) +\method{as.rxUi}{default}(x, envir = parent.frame()) } \arguments{ \item{x}{Object to convert to \code{rxUi} object} + +\item{envir}{is the environment to look for R user functions +(defaults to parent environment)} } \value{ rxUi object (or error if it cannot be converted) @@ -37,7 +40,7 @@ As rxode2 ui mod1 <- function() { ini({ - # central + # central KA=2.94E-01 CL=1.86E+01 V2=4.02E+01 @@ -47,7 +50,7 @@ mod1 <- function() { # effects Kin=1 Kout=1 - EC50=200 + EC50=200 }) model({ C2 <- centr/V2 diff --git a/man/rxFun.Rd b/man/rxFun.Rd index 09ed635e6..836a7fc2a 100644 --- a/man/rxFun.Rd +++ b/man/rxFun.Rd @@ -29,7 +29,7 @@ nothing This adds a user function to rxode2 that can be called. If needed, these functions can be differentiated by numerical differences or by adding the derivatives to rxode2's internal derivative table -with \code{\link[=rxD]{rxD()}} +with rxode2's \code{rxD} function } \examples{ \donttest{ diff --git a/man/rxSolve.Rd b/man/rxSolve.Rd index 965c99fb6..54f0a6d80 100644 --- a/man/rxSolve.Rd +++ b/man/rxSolve.Rd @@ -133,7 +133,8 @@ rxSolve( addlKeepsCov = FALSE, addlDropSs = TRUE, ssAtDoseTime = TRUE, - ss2cancelAllPending = FALSE + ss2cancelAllPending = FALSE, + envir = parent.frame() ) \method{rxSolve}{`function`}( @@ -228,7 +229,13 @@ rxSolve( \method{solve}{rxEt}(a, b, ...) -rxControl(..., params = NULL, events = NULL, inits = NULL) +rxControl( + ..., + params = NULL, + events = NULL, + inits = NULL, + envir = parent.frame() +) } \arguments{ \item{object}{is a either a rxode2 family of objects, or a file-name @@ -803,6 +810,9 @@ cancels all pending doses like \code{SS=1}. When \code{FALSE} the pending doses not canceled with \code{SS=2} (the infusions started before \code{SS=2} occurred are canceled, though).} +\item{envir}{is the environment to look for R user functions +(defaults to parent environment)} + \item{a}{when using \code{solve()}, this is equivalent to the \code{object} argument. If you specify \code{object} later in the argument list it overwrites this parameter.} diff --git a/man/rxode2.Rd b/man/rxode2.Rd index c6e519bb6..0fa54404b 100644 --- a/man/rxode2.Rd +++ b/man/rxode2.Rd @@ -21,7 +21,8 @@ rxode2( linCmtSens = c("linCmtA", "linCmtB", "linCmtC"), indLin = FALSE, verbose = FALSE, - fullPrint = getOption("rxode2.fullPrint", FALSE) + fullPrint = getOption("rxode2.fullPrint", FALSE), + envir = parent.frame() ) RxODE( @@ -39,7 +40,8 @@ RxODE( linCmtSens = c("linCmtA", "linCmtB", "linCmtC"), indLin = FALSE, verbose = FALSE, - fullPrint = getOption("rxode2.fullPrint", FALSE) + fullPrint = getOption("rxode2.fullPrint", FALSE), + envir = parent.frame() ) rxode( @@ -57,7 +59,8 @@ rxode( linCmtSens = c("linCmtA", "linCmtB", "linCmtC"), indLin = FALSE, verbose = FALSE, - fullPrint = getOption("rxode2.fullPrint", FALSE) + fullPrint = getOption("rxode2.fullPrint", FALSE), + envir = parent.frame() ) } \arguments{ @@ -127,6 +130,9 @@ compartmental model} \item{fullPrint}{When using \code{printf} within the model, if \code{TRUE} print on every step (except ME/indLin), otherwise when \code{FALSE} print only when calculating the \code{d/dt}} + +\item{envir}{is the environment to look for R user functions +(defaults to parent environment)} } \value{ An object (environment) of class \code{rxode2} (see Chambers and Temple Lang (2001)) @@ -226,6 +232,9 @@ mod <- rxode2(\{ d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; \}) }\if{html}{\out{}} + +\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ +}\if{html}{\out{
}} \itemize{ \item Inside a \code{rxode2("")} string statement: }\if{html}{\out{ @@ -241,6 +250,9 @@ mod <- rxode2(\{ d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; ") }\if{html}{\out{}} + +\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ +}\if{html}{\out{
}} \itemize{ \item In a file name to be loaded by rxode2: }\if{html}{\out{ @@ -319,7 +331,9 @@ compilation model. \if{html}{\out{
}}\preformatted{mod$simulationModel }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_d670952790aeef6ec09729654f5533fa model (ready). +\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ + +## rxode2 2.0.14.9000 model named rx_78dcb8ef8275ff5e33a47163f4239e19 model (ready). ## x$state: depot, center ## x$stateExtra: cp ## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp @@ -330,7 +344,9 @@ compilation model. mod$simulationIniModel }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_2875062832076b4d6009c463ce5eaf6e model (ready). +\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ + +## rxode2 2.0.14.9000 model named rx_baef7cfc602529d2843782858fc2f522 model (ready). ## x$state: depot, center ## x$stateExtra: cp ## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp diff --git a/src/rxData.cpp b/src/rxData.cpp index fb6bd5c57..62d3e084b 100644 --- a/src/rxData.cpp +++ b/src/rxData.cpp @@ -64,6 +64,8 @@ extern "C" int getRxThreads(const int64_t n, const bool throttle); extern "C" void rxode2_assign_fn_pointers_(const char *mv); extern "C" void setSilentErr(int silent); extern "C" int _rxode2parse_assignUdf(SEXP in); +extern "C" SEXP _rxode2parse_udfEnvSet(SEXP env, bool lock); +extern "C" SEXP _rxode2parse_udfUnlock(); extern "C" { typedef SEXP (*_rxode2parse_getForder_type)(void); @@ -730,7 +732,7 @@ List rxModelVars_character(const RObject &obj){ if (sobj == ""){ // Blank rxode2 model return rxModelVars_blank(); - } else if (fileExists(sobj)){ + } else if (fileExists(sobj)) { // From file Function f = getRxFn(".rxModelVarsCharacter"); return f(obj); @@ -2473,6 +2475,7 @@ void resetFkeep(); //' @export // [[Rcpp::export]] LogicalVector rxSolveFree(){ + _rxode2parse_udfUnlock(); resetFkeep(); rx_solve* rx = getRxSolve_(); // Free the solve id order @@ -4628,6 +4631,7 @@ SEXP rxSolve_(const RObject &obj, const List &rxControl, rxSolveFree(); stop(_("control list not setup correctly")); } + _rxode2parse_udfEnvSet(rxControl[Rxc_envir], true); maxAtolRtolFactor = asDouble(rxControl[Rxc_maxAtolRtolFactor], "maxAtolRtolFactor"); RObject scale = rxControl[Rxc_scale]; int method = asInt(rxControl[Rxc_method], "method"); diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 9d4f1f7a1..096f77aa2 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -87,6 +87,26 @@ VOID_END_RCPP return _ret; } +extern "C" SEXP _rxode2parse_udfEnvSet(SEXP env, bool lock) { +BEGIN_RCPP + assignRxode2ParsePtrs(); + Function fun = as(rxode2parse[".udfEnvSet"]); + fun(env); + Function fun2 = as(rxode2parse[".udfEnvLock"]); + fun2(lock); + return R_NilValue; + END_RCPP +} + +extern "C" SEXP _rxode2parse_udfUnlock() { + BEGIN_RCPP + assignRxode2ParsePtrs(); + Function fun2 = as(rxode2parse[".udfEnvLock"]); + fun2(false); + return R_NilValue; + END_RCPP + +} extern "C" SEXP _rxode2_codegen(SEXP c_file, SEXP prefix, SEXP libname, SEXP pMd5, SEXP timeId, SEXP lastMv, SEXP goodFuns) { BEGIN_RCPP assignRxode2ParsePtrs(); diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index 44dd0b937..c6073ed52 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -100,6 +100,7 @@ test_that("udf functions", { rxFun("gg", c("x", "y"), "double gg(double x, double y) { return x*y;}") + gg <- function(x, y, z) { x + y + z } @@ -112,6 +113,8 @@ test_that("udf functions", { expect_true(all(d$z == d$x * d$y)) + rxRmFun("gg") + udf <- function(x, y) { a <- x + y b <- a ^ 2 diff --git a/tests/testthat/test-ui.R b/tests/testthat/test-ui.R index d1de7e556..ad08aa5fe 100644 --- a/tests/testthat/test-ui.R +++ b/tests/testthat/test-ui.R @@ -20,6 +20,7 @@ rxTest({ suppressMessages( expect_equal(.rxReplaceCommentWithLabel(cmt), eq) ) + # Leave comment labels in here as they are required for equality testing below one.cmt <- function() { ini({ From 2f6c634077be15809409f3b698eee40ea03552df Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 31 Oct 2023 21:51:03 -0500 Subject: [PATCH 08/27] Fix lag by changing how udf recompile is calculated --- src/rxData.cpp | 10 +++++++--- src/rxode2parse.cpp | 11 ++++++----- tests/testthat/test-lag.R | 2 ++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/rxData.cpp b/src/rxData.cpp index 62d3e084b..1f550a6ca 100644 --- a/src/rxData.cpp +++ b/src/rxData.cpp @@ -63,7 +63,7 @@ extern "C" int getThrottle(); extern "C" int getRxThreads(const int64_t n, const bool throttle); extern "C" void rxode2_assign_fn_pointers_(const char *mv); extern "C" void setSilentErr(int silent); -extern "C" int _rxode2parse_assignUdf(SEXP in); +extern "C" SEXP _rxode2parse_assignUdf(SEXP in); extern "C" SEXP _rxode2parse_udfEnvSet(SEXP env, bool lock); extern "C" SEXP _rxode2parse_udfUnlock(); @@ -4696,7 +4696,7 @@ SEXP rxSolve_(const RObject &obj, const List &rxControl, } getRxModels(); bool didNesting=false; - if (rxSolveDat->updateObject && !rxSolveDat->isRxSolve && !rxSolveDat->isEnvironment){ + if (rxSolveDat->updateObject && !rxSolveDat->isRxSolve && !rxSolveDat->isEnvironment) { if (rxIs(rxCurObj, "rxSolve")){ object = rxCurObj; rxSolveDat->isRxSolve = true; @@ -4739,7 +4739,11 @@ SEXP rxSolve_(const RObject &obj, const List &rxControl, rxSolveFreeObj = object; } } - if (_rxode2parse_assignUdf(rxSolveDat->mv[RxMv_udf])) { + + LogicalVector recompileUdf = _rxode2parse_assignUdf(rxSolveDat->mv[RxMv_udf]); + + if (recompileUdf[0]) { + REprintf("here\n"); Function rxode2 = getRxFn("rxode2"); object = rxode2(object); rxSolveDat->mv = rxModelVars(object); diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 096f77aa2..2e284d1cb 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -76,15 +76,16 @@ extern "C" SEXP _rxode2_codeLoaded(void) { END_RCPP } -extern "C" int _rxode2parse_assignUdf(SEXP in) { - int _ret; +extern "C" SEXP _rxode2parse_assignUdf(SEXP in) { BEGIN_RCPP assignRxode2ParsePtrs(); + if (Rf_length(in) == 0) { + return wrap(LogicalVector::create(false)); + } Function fun = as(rxode2parse[".setupUdf"]); LogicalVector needRecompile = fun(in); - int _ret = needRecompile[0]; -VOID_END_RCPP - return _ret; + return wrap(needRecompile); +END_RCPP } extern "C" SEXP _rxode2parse_udfEnvSet(SEXP env, bool lock) { diff --git a/tests/testthat/test-lag.R b/tests/testthat/test-lag.R index 687903aa6..5251ac9bf 100644 --- a/tests/testthat/test-lag.R +++ b/tests/testthat/test-lag.R @@ -1,8 +1,10 @@ rxTest({ + et <- et(1:10) et$b <- 1:10 test_that("lag()", { + suppressMessages(expect_error(rxode2({ a <- lag() }))) From d9757ec80141a9413581e7498ebc6ac61e91e924 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 31 Oct 2023 22:11:02 -0500 Subject: [PATCH 09/27] Fix etTrans solve --- R/rxsolve.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/rxsolve.R b/R/rxsolve.R index d736a0d2e..9b95379fb 100644 --- a/R/rxsolve.R +++ b/R/rxsolve.R @@ -1138,11 +1138,11 @@ rxSolve <- function(object, params = NULL, events = NULL, inits = NULL, #' @rdname rxSolve #' @export rxSolve.function <- function(object, params = NULL, events = NULL, inits = NULL, ..., - theta = NULL, eta = NULL) { + theta = NULL, eta = NULL, envir=parent.frame()) { .object <- rxode2(object) do.call("rxSolve", c(list(object=.object, params = params, events = events, inits = inits), list(...), - list(theta = theta, eta = eta))) + list(theta = theta, eta = eta, envir=envir))) } .rxSolveFromUi <- function(object, params = NULL, events = NULL, inits = NULL, ..., @@ -1411,7 +1411,7 @@ rxSolve.default <- function(object, params = NULL, events = NULL, inits = NULL, .w <- which(names(.ctl) == "keep") .ctl[[.w]] <- .keep .ctl <- do.call(rxControl, - c(.ctl, list(events = events, params = params, envir=envir))) + c(.ctl, list(events = events, params = params))) } } From 5c69991d4c760fa5cf2aaf743dfa24dfc31b581a Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 31 Oct 2023 22:28:12 -0500 Subject: [PATCH 10/27] Make sure the input make sense --- src/rxode2parse.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 2e284d1cb..3e2ea37df 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -82,6 +82,12 @@ BEGIN_RCPP if (Rf_length(in) == 0) { return wrap(LogicalVector::create(false)); } + if (TYPEOF(in) != INTSXP) { + return wrap(LogicalVector::create(false)); + } + if (Rf_isNull(Rf_getAttrib(in, R_NamesSymbol))) { + return wrap(LogicalVector::create(false)); + } Function fun = as(rxode2parse[".setupUdf"]); LogicalVector needRecompile = fun(in); return wrap(needRecompile); From a210d8403931f78e3345ecf37bb889d4017afd1d Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Wed, 1 Nov 2023 08:42:33 -0500 Subject: [PATCH 11/27] Modify udf tests to be more explicit in what is being tested --- src/rxData.cpp | 1 - src/rxode2parse.cpp | 2 +- tests/testthat/test-udf.R | 243 +++++++++++++++++++++----------------- 3 files changed, 135 insertions(+), 111 deletions(-) diff --git a/src/rxData.cpp b/src/rxData.cpp index 1f550a6ca..5af3f6979 100644 --- a/src/rxData.cpp +++ b/src/rxData.cpp @@ -4743,7 +4743,6 @@ SEXP rxSolve_(const RObject &obj, const List &rxControl, LogicalVector recompileUdf = _rxode2parse_assignUdf(rxSolveDat->mv[RxMv_udf]); if (recompileUdf[0]) { - REprintf("here\n"); Function rxode2 = getRxFn("rxode2"); object = rxode2(object); rxSolveDat->mv = rxModelVars(object); diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 3e2ea37df..50fc97c9c 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -78,7 +78,6 @@ extern "C" SEXP _rxode2_codeLoaded(void) { extern "C" SEXP _rxode2parse_assignUdf(SEXP in) { BEGIN_RCPP - assignRxode2ParsePtrs(); if (Rf_length(in) == 0) { return wrap(LogicalVector::create(false)); } @@ -88,6 +87,7 @@ BEGIN_RCPP if (Rf_isNull(Rf_getAttrib(in, R_NamesSymbol))) { return wrap(LogicalVector::create(false)); } + assignRxode2ParsePtrs(); Function fun = as(rxode2parse[".setupUdf"]); LogicalVector needRecompile = fun(in); return wrap(needRecompile); diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index c6073ed52..d0e1fad8c 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -1,4 +1,9 @@ -test_that("udf functions", { +rxTest({ + e <- et(1:10) |> as.data.frame() + + e$x <- 1:10 + e$y <- 21:30 + gg <- function(x, y) { x + y @@ -9,195 +14,215 @@ test_that("udf functions", { }) - e <- et(1:10) |> as.data.frame() - - e$x <- 1:10 - e$y <- 21:30 + test_that("udf1 works well", { + expect_warning(rxSolve(f, e)) - expect_warning(rxSolve(f, e)) + d <- suppressWarnings(rxSolve(f, e)) - d <- suppressWarnings(rxSolve(f, e)) + expect_true(all(d$z == d$x + d$y)) + }) - expect_true(all(d$z == d$x + d$y)) # now modify gg gg <- function(x, y, z) { x + y + z } - expect_error(rxSolve(f, e)) + + test_that("udf with 3 arguments works", { + expect_error(rxSolve(f, e)) + }) # now modify gg back to 2 arguments gg <- function(x, y) { x * y } - # different solve results but still runs + test_that("when changing gg the results will be different", { + # different solve results but still runs - d <- suppressWarnings(rxSolve(f, e)) + d <- suppressWarnings(rxSolve(f, e)) - expect_true(all(d$z == d$x * d$y)) + expect_true(all(d$z == d$x * d$y)) + }) rm(gg) - expect_error(rxSolve(f, e)) + test_that("Without a udf, the solve errors", { + expect_error(rxSolve(f, e)) + }) + gg <- function(x, ...) { x } - expect_error(rxSolve(f, e)) + test_that("cannot solve with udf functions that have ...", { + expect_error(rxSolve(f, e)) + }) gg <- function(x, y) { stop("running me") } - expect_error(rxSolve(f, e)) + test_that("functions that error will error the solve",{ + expect_error(rxSolve(f, e)) + }) gg <- function(x, y) { "running " } - x <- suppressWarnings(rxSolve(f, e)) - expect_true(all(is.na(x$z))) + + test_that("runs with improper output will return NA", { + x <- suppressWarnings(rxSolve(f, e)) + expect_true(all(is.na(x$z))) + }) gg <- function(x, y) { "3" } - x <- rxSolve(f, e) - expect_true(all(x$z == 3)) - - expect_equal(rxToSE("gg(x,y)"), "gg(x, y)") + test_that("converts to 3 when it is a string", { + x <- suppressWarnings(rxSolve(f, e)) + expect_true(all(x$z == 3)) + }) - expect_error(rxToSE("gg()"), "user function") + test_that("test symengine functions work with udf funs", { + expect_equal(rxToSE("gg(x,y)"), "gg(x, y)") - expect_error(rxFromSE("Derivative(gg(a,b),a)"), NA) + expect_error(rxToSE("gg()"), "user function") - expect_error(rxFromSE("Derivative(gg(a),a)")) + expect_error(rxFromSE("Derivative(gg(a,b),a)"), NA) - expect_error(rxFromSE("Derivative(gg(),a)")) + expect_error(rxFromSE("Derivative(gg(a),a)")) + expect_error(rxFromSE("Derivative(gg(),a)")) + }) gg <- function(x, ...) { x } - expect_error(rxToSE("gg(x,y)")) + test_that("test that functions with ... will error symengine translation", { + expect_error(rxToSE("gg(x,y)")) - expect_error(rxFromSE("Derivative(gg(a,b),a)")) + expect_error(rxFromSE("Derivative(gg(a,b),a)")) + }) ## manual functions in C vs R functions + test_that("R vs C functions", { + gg <- function(x, y) { + x + y + } + x <- suppressWarnings(rxSolve(f, e)) + # now add a C function with different values - gg <- function(x, y) { - x + y - } - - x <- rxSolve(f, e) - - # now add a C function with different values - - rxFun("gg", c("x", "y"), - "double gg(double x, double y) { return x*y;}") + rxFun("gg", c("x", "y"), + "double gg(double x, double y) { return x*y;}") + gg <- function(x, y, z) { + x + y + z + } - gg <- function(x, y, z) { - x + y + z - } + expect_error(rxSolve(f, e)) - expect_error(rxSolve(f, e)) + gg <- function(x, y) { + x + y + } - gg <- function(x, y) { - x + y - } + d <- suppressWarnings(rxSolve(f, e)) - expect_true(all(d$z == d$x * d$y)) + expect_true(all(d$z == d$x * d$y)) - rxRmFun("gg") + rxRmFun("gg") - udf <- function(x, y) { - a <- x + y - b <- a ^ 2 - a + b - } + }) - expect_true(grepl("R_pow_di[(]", rxFun2c(udf)$cCode)) + test_that("c conversion", { - udf <- function(x, y) { - a <- x + y - b <- a ^ x - a + b - } + udf <- function(x, y) { + a <- x + y + b <- a ^ 2 + a + b + } - expect_true(grepl("R_pow[(]", rxFun2c(udf)$cCode)) + expect_true(grepl("R_pow_di[(]", rxFun2c(udf)$cCode)) - udf <- function(x, y) { - a <- x + y - b <- cos(a) + x - a + b - } + udf <- function(x, y) { + a <- x + y + b <- a ^ x + a + b + } - expect_true(grepl("cos[(]", rxFun2c(udf)$cCode)) + expect_true(grepl("R_pow[(]", rxFun2c(udf)$cCode)) - udf <- function(x, y) { - if (a < b) { - return(b ^ 2) + udf <- function(x, y) { + a <- x + y + b <- cos(a) + x + a + b } - a + b - } - - expect_true(grepl("if [(]", rxFun2c(udf)$cCode)) + expect_true(grepl("cos[(]", rxFun2c(udf)$cCode)) - udf <- function(x, y) { - a <- x - b <- x ^ 2 + a - if (a < b) { - return(b ^ 2) - } else { + udf <- function(x, y) { + if (a < b) { + return(b ^ 2) + } a + b } - } - expect_true(grepl("else [{]", rxFun2c(udf)$cCode)) + expect_true(grepl("if [(]", rxFun2c(udf)$cCode)) - udf <- function(x, y) { - a <- x - b <- x ^ 2 + a - if (a < b) { - return(b ^ 2) - } else if (a > b + 3) { - return(a + b) - } - a ^ 2 + b ^ 2 - } - expect_true(grepl("else if [(]", rxFun2c(udf)$cCode)) + udf <- function(x, y) { + a <- x + b <- x ^ 2 + a + if (a < b) { + return(b ^ 2) + } else { + a + b + } + } + expect_true(grepl("else [{]", rxFun2c(udf)$cCode)) - udf <- function(x, y) { - a <- x - b <- x ^ 2 + a - if (a < b) { - return(b ^ 2) - } else if (a > b + 3) { - b <- 3 - if (a > 2) { - a <- 2 + udf <- function(x, y) { + a <- x + b <- x ^ 2 + a + if (a < b) { + return(b ^ 2) + } else if (a > b + 3) { + return(a + b) } - return(a + b) + a ^ 2 + b ^ 2 } - a ^ 2 + b ^ 2 - } - expect_true(grepl("else if [(]", rxFun2c(udf)$cCode)) + expect_true(grepl("else if [(]", rxFun2c(udf)$cCode)) + + udf <- function(x, y) { + a <- x + b <- x ^ 2 + a + if (a < b) { + return(b ^ 2) + } else if (a > b + 3) { + b <- 3 + if (a > 2) { + a <- 2 + } + return(a + b) + } + a ^ 2 + b ^ 2 + } - udf <- function(x, y) { - a <- x + y - x <- a ^ 2 - x - } + expect_true(grepl("else if [(]", rxFun2c(udf)$cCode)) - expect_error(rxFun2c(udf)$cCode) + udf <- function(x, y) { + a <- x + y + x <- a ^ 2 + x + } + expect_error(rxFun2c(udf)$cCode) + }) }) From 9c1b1df6732e05d1e9f6368d2cf4eaa867b5e009 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Wed, 1 Nov 2023 10:41:55 -0500 Subject: [PATCH 12/27] Add ui function $ support --- R/rxUiGet.R | 18 ++++++++--- R/ui.R | 8 +++-- tests/testthat/test-udf.R | 68 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/R/rxUiGet.R b/R/rxUiGet.R index 2e4c79a71..d132d3c03 100644 --- a/R/rxUiGet.R +++ b/R/rxUiGet.R @@ -25,10 +25,20 @@ #' @export `$.rxUi` <- function(obj, arg, exact = TRUE) { # need to assign environment correctly for UDF - rxode2parse::.udfEnvSet(parent.frame(1)) - # Keep it locked to avoid environment nesting nightmare - rxode2parse::.udfEnvLock() - on.exit(rxode2parse::.udfEnvLock(FALSE)) + # + # The model() and rxode2() assign the parent environments for UDF + # parsing, if the object is in that environment lock it and then + # unlock on exit + if (rxode2parse::.udfEnvLockIfExists(obj)) { + # If locked unlock when exiting + on.exit(rxode2parse::.udfEnvLock(FALSE)) + } else if (!rxode2parse::.udfEnvLock(NULL)) { + ## unlocked, look for object in parent frame until global or empty environment + if (rxode2parse::.udfEnvLockIfExists(obj, parent.frame(1))) { + # if locked by this, unlock when exiting + on.exit(rxode2parse::.udfEnvLock(FALSE)) + } + } rxUiGet(.uiToRxUiGet(obj=obj, arg=arg, exact=exact)) } diff --git a/R/ui.R b/R/ui.R index 2cb51aa18..c6f26a7f3 100644 --- a/R/ui.R +++ b/R/ui.R @@ -276,7 +276,11 @@ model <- function(x, ..., append=FALSE, auto=getOption("rxode2.autoVarPiping", T cov=NULL, envir=parent.frame()) { if (is(substitute(x), "{")) { .funName <- try(as.character(as.list(with(envir, match.call()))[[1]]), silent=TRUE) - if (inherits(.funName, "try-error")) .funName <- NULL + if (inherits(.funName, "try-error")){ + .funName <- NULL + } else if (any(.funName == ls(envir=parent.env(envir), all=TRUE))) { + rxode2parse::.udfEnvSet(parent.env(envir)) + } .ini <- .lastIni .iniQ <- .lastIniQ if (is.null(.ini)) { @@ -427,7 +431,7 @@ print.rxUi <-function(x, ...) { #' f <- rxUiCompress(f) #' print(class(f)) #' print(is.environment(f)) -#' +#' rxUiDecompress <- function(ui) { if (!inherits(ui, "rxUi")) return(ui) if (is.environment(ui)) return(ui) diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index d0e1fad8c..7360f0f87 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -225,4 +225,72 @@ rxTest({ expect_error(rxFun2c(udf)$cCode) }) + + test_that("udf with model functions", { + + gg <- function(x, y) { + x/y + } + + # Step 1 - Create a model specification + f <- function() { + ini({ + KA <- .291 + CL <- 18.6 + V2 <- 40.2 + Q <- 10.5 + V3 <- 297.0 + Kin <- 1.0 + Kout <- 1.0 + EC50 <- 200.0 + }) + model({ + # A 4-compartment model, 3 PK and a PD (effect) compartment + # (notice state variable names 'depot', 'centr', 'peri', 'eff') + C2 <- gg(centr, V2) + C3 <- peri/V3 + d/dt(depot) <- -KA*depot + d/dt(centr) <- KA*depot - CL*C2 - Q*C2 + Q*C3 + d/dt(peri) <- Q*C2 - Q*C3 + d/dt(eff) <- Kin - Kout*(1-C2/(EC50+C2))*eff + eff(0) <- 1 + }) + } + + u <- f() + + # this pre-compiles and displays the simulation model + u$simulationModel + + # Step 2 - Create the model input as an EventTable, + # including dosing and observation (sampling) events + + # QD (once daily) dosing for 5 days. + + qd <- eventTable(amount.units = "ug", time.units = "hours") + qd$add.dosing(dose = 10000, nbr.doses = 5, dosing.interval = 24) + + # Sample the system hourly during the first day, every 8 hours + # then after + + qd$add.sampling(0:24) + qd$add.sampling(seq(from = 24 + 8, to = 5 * 24, by = 8)) + + # Step 3 - set starting parameter estimates and initial + # values of the state + + # Step 4 - Fit the model to the data + expect_error(suppressWarnings(solve(u, qd)), NA) + + u1 <- u$simulationModel + + expect_error(suppressWarnings(solve(u1, qd)), NA) + + u2 <- u$simulationIniModel + expect_error(suppressWarnings(solve(u2, qd)), NA) + + expect_error(suppressWarnings(rxSolve(f, qd)), NA) + }) + + }) From 5c7ff035c5d8cb05352803867a033703f3e00728 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Wed, 1 Nov 2023 12:48:04 -0500 Subject: [PATCH 13/27] Take care of case where .funName has length > 1 --- R/ui.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ui.R b/R/ui.R index c6f26a7f3..6ca4df956 100644 --- a/R/ui.R +++ b/R/ui.R @@ -278,7 +278,7 @@ model <- function(x, ..., append=FALSE, auto=getOption("rxode2.autoVarPiping", T .funName <- try(as.character(as.list(with(envir, match.call()))[[1]]), silent=TRUE) if (inherits(.funName, "try-error")){ .funName <- NULL - } else if (any(.funName == ls(envir=parent.env(envir), all=TRUE))) { + } else if (length(.funName) == 1L && exists(.funName, envir=parent.env(envir))) { rxode2parse::.udfEnvSet(parent.env(envir)) } .ini <- .lastIni From 116db18a55a27c297d3f6b33a405c4ee9c9ddd41 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Wed, 1 Nov 2023 17:43:36 -0500 Subject: [PATCH 14/27] Add tests and fixes for rxS() needed for nlmixr udf --- R/symengine.R | 20 +++++++++++++++++++- tests/testthat/test-udf.R | 9 +++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/R/symengine.R b/R/symengine.R index 13db5ab85..de69e48d1 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -497,6 +497,11 @@ rxD <- function(name, derivatives) { #' @export rxToSE <- function(x, envir = NULL, progress = FALSE, promoteLinSens = TRUE, parent = parent.frame()) { + if (!rxode2parse::.udfEnvLock(NULL)) { + rxode2parse::.udfEnvSet(parent) + rxode2parse::.udfEnvLock(TRUE) + on.exit(rxode2parse::.udfEnvLock(FALSE)) + } .rxToSE.envir$parent <- parent assignInMyNamespace(".promoteLinB", promoteLinSens) assignInMyNamespace(".rxIsLhs", FALSE) @@ -1352,6 +1357,7 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, call. = FALSE ) } else if (length(.ret0) == length(.f)) { + assign(.fun, .rxFunction(.fun), envir = envir) .ret0 <- unlist(.ret0) .ret <- paste0(.fun, "(",paste(.ret0, collapse=", "), ")") } else { @@ -1399,6 +1405,11 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), parent=parent.frame()) { rxReq("symengine") + if (!rxode2parse::.udfEnvLock(NULL)) { + rxode2parse::.udfEnvSet(parent) + rxode2parse::.udfEnvLock(TRUE) + on.exit(rxode2parse::.udfEnvLock(FALSE)) + } .rxFromSE.envir$parent <- parent .unknown <- c("central" = 2L, "forward" = 1L, "error" = 0L) assignInMyNamespace(".rxFromNumDer", .unknown[match.arg(unknownDerivatives)]) @@ -2182,7 +2193,12 @@ rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), #' @return rxode2/symengine environment #' @author Matthew Fidler #' @export -rxS <- function(x, doConst = TRUE, promoteLinSens = FALSE) { +rxS <- function(x, doConst = TRUE, promoteLinSens = FALSE, envir=parent.frame()) { + if (!rxode2parse::.udfEnvLock(NULL)) { + rxode2parse::.udfEnvSet(envir) + rxode2parse::.udfEnvLock(TRUE) + on.exit(rxode2parse::.udfEnvLock(FALSE)) + } rxReq("symengine") .cnst <- names(.rxSEreserved) .env <- new.env(parent = loadNamespace("symengine")) @@ -2198,12 +2214,14 @@ rxS <- function(x, doConst = TRUE, promoteLinSens = FALSE) { .env$..doConst <- doConst .rxD <- rxode2parse::rxode2parseD() for (.f in c( + ls(rxode2parse::.symengineFs()), ls(.rxD), "linCmtA", "linCmtB", "rxEq", "rxNeq", "rxGeq", "rxLeq", "rxLt", "rxGt", "rxAnd", "rxOr", "rxNot", "rxTBS", "rxTBSd", "rxTBSd2", "lag", "lead", "rxTBSi" )) { assign(.f, .rxFunction(.f), envir = .env) } + for (.v in seq_along(.rxSEreserved)) { assign(names(.rxSEreserved)[.v], .rxSEreserved[[.v]], envir = .env) } diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index 7360f0f87..32dabdd7e 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -292,5 +292,14 @@ rxTest({ expect_error(suppressWarnings(rxSolve(f, qd)), NA) }) + test_that("symengine load", { + mod <- "tke=THETA[1];\nprop.sd=THETA[2];\neta.ke=ETA[1];\nke=gg(tke,exp(eta.ke));\nipre=gg(10,exp(-ke*t));\nlipre=log(ipre);\nrx_yj_~2;\nrx_lambda_~1;\nrx_low_~0;\nrx_hi_~1;\nrx_pred_f_~ipre;\nrx_pred_~rx_pred_f_;\nrx_r_~(rx_pred_f_*prop.sd)^2;\n" + gg <- function(x, y) { + PreciseSums::psProd(c(x, y)) + } + + rxS(mod, TRUE, TRUE) + + }) }) From 0b4436fa883f42f3af4baa4c5ab0ac9dfb861b35 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Wed, 1 Nov 2023 18:08:23 -0500 Subject: [PATCH 15/27] Fix symengine compiled user functions --- R/symengine.R | 2 +- tests/testthat/test-udf.R | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/R/symengine.R b/R/symengine.R index de69e48d1..16de6f88b 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -2247,7 +2247,7 @@ rxS <- function(x, doConst = TRUE, promoteLinSens = FALSE, envir=parent.frame()) .env$rx_hi_ <- symengine::S("1") if (!is.null(rxode2parse::.rxSEeqUsr())) { sapply(names(rxode2parse::.rxSEeqUsr()), function(x) { - assign(.rxFunction(x), x, envir = .env) + assign(x, .rxFunction(x), envir = .env) }) } ## EulerGamma=0.57721566490153286060651209008240243104215933593992 diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index 32dabdd7e..09e32f817 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -295,11 +295,19 @@ rxTest({ test_that("symengine load", { mod <- "tke=THETA[1];\nprop.sd=THETA[2];\neta.ke=ETA[1];\nke=gg(tke,exp(eta.ke));\nipre=gg(10,exp(-ke*t));\nlipre=log(ipre);\nrx_yj_~2;\nrx_lambda_~1;\nrx_low_~0;\nrx_hi_~1;\nrx_pred_f_~ipre;\nrx_pred_~rx_pred_f_;\nrx_r_~(rx_pred_f_*prop.sd)^2;\n" + gg <- function(x, y) { - PreciseSums::psProd(c(x, y)) + x * y } - rxS(mod, TRUE, TRUE) + expect_error(rxS(mod, TRUE, TRUE), NA) + + rxFun(gg) + + rm(gg) + + expect_error(rxS(mod, TRUE, TRUE), NA) + }) }) From f1f90ab409998f9670bb505814f61e4b570b6837 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Wed, 1 Nov 2023 23:14:00 -0500 Subject: [PATCH 16/27] Some symengine fixes and expansions --- R/symengine.R | 128 +++++++++++++++++++++++++++++++++----- tests/testthat/test-udf.R | 31 ++++++--- 2 files changed, 135 insertions(+), 24 deletions(-) diff --git a/R/symengine.R b/R/symengine.R index 16de6f88b..42347a807 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -366,9 +366,21 @@ rxFun <- function(name, args, cCode) { if (missing(args) && missing(cCode)) { .funName <- as.character(substitute(name)) .lst <- rxFun2c(name, name=.funName) - .ret <- do.call(rxode2parse::rxFunParse, .lst) - message("converted R function '", .lst$name, "' to C with code:") - message(.lst$cCode) + .env <- new.env(parent=emptyenv()) + .env$d <- list() + lapply(seq_along(.lst), function(i) { + .cur <- .lst[[i]] + do.call(rxode2parse::rxFunParse, .cur[1:3]) + message("converted R function '", .cur$name, "' to C (will now use in rxode2)") + ## message(.cur$cCode) + if (length(.cur) == 4L) { + .env$d <- c(.env$d, list(.cur[[4]])) + } + }) + if (length(.env$d) > 0) { + message("Added derivative table for '", .lst[[1]]$name, "'") + rxD(.lst[[1]]$name, .env$d) + } return(invisible()) } rxode2parse::rxFunParse(name, args, cCode) @@ -1346,6 +1358,9 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, } } else { .udf <- try(get(.fun, envir = .rxToSE.envir$parent, mode="function"), silent =TRUE) + if (inherits(.udf, "try-error")) { + .udf <- try(get(.fun, envir = rxode2parse::.udfEnvSet(NULL), mode="function"), silent =TRUE) + } if (inherits(.udf, "try-error")) { stop(sprintf(gettext("function '%s' or its derivatives are not supported in rxode2"), .fun), call. = FALSE @@ -1357,7 +1372,9 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, call. = FALSE ) } else if (length(.ret0) == length(.f)) { - assign(.fun, .rxFunction(.fun), envir = envir) + if (is.environment(envir)){ + assign(.fun, .rxFunction(.fun), envir = envir) + } .ret0 <- unlist(.ret0) .ret <- paste0(.fun, "(",paste(.ret0, collapse=", "), ")") } else { @@ -2142,6 +2159,10 @@ rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), } else { .fun <- paste(.ret0[[1]]) .g <- try(get(.fun, envir=.rxFromSE.envir$parent, mode="function"), silent=TRUE) + if (inherits(.g, "try-error")) { + .g <- try(get(.fun, envir=rxode2parse::.udfEnvSet(NULL), + mode="function"), silent=TRUE) + } if (inherits(.g, "try-error")) { stop(sprintf(gettext("'%s' not supported in symengine->rxode2"), .fun), call. = FALSE @@ -3153,6 +3174,10 @@ rxSupportedFuns <- function() { } .rxFunEq <- c( + "Rx_pow_di"=2, + "Rx_pow"=2, + "R_pow_di"=2, + "R_pow"=2, "lgamma" = 1, "abs" = 1, "acos" = 1, @@ -3305,10 +3330,10 @@ rxSupportedFuns <- function() { } } .rxFun2cAssignOperators <- function(x, envir = envir) { - if (identical(x[[1]], quote(`~`))) { - stop("formulas or other expressions with '~` are not supported in translation", - call.=FALSE) - } + ## if (!envir$isRx && identical(x[[1]], quote(`~`))) { + ## stop("formulas or other expressions with '~` are not supported in translation", + ## call.=FALSE) + ## } if (as.character(x[[2]]) %in% envir$args) { stop("cannot assign argument '", as.character(x[[2]]), "' in functions converted to C", @@ -3320,8 +3345,14 @@ rxSupportedFuns <- function() { } envir$didAssign <- TRUE .pre <- paste0(rep(" ", envir$n), collapse="") - return(paste0(.pre, "_lastValue = ", .lhs, " = ", - .rxFun2c(x[[3]], envir=envir), ";\n")) + if (envir$isRx) { + paste0(.lhs, " <- ", + .rxFun2c(x[[3]], envir=envir), "\n", + "rxLastValue <-", .lhs, "\n") + } else { + paste0(.pre, "_lastValue = ", .lhs, " = ", + .rxFun2c(x[[3]], envir=envir), ";\n") + } } .rxFun2cSquareBracket <- function(x, envir) { @@ -3377,7 +3408,11 @@ rxSupportedFuns <- function() { .cur <- .rxFun2c(.cur, envir=envir) if(!envir$didAssign && !envir$isExpr) { .pre <- paste0(rep(" ", envir$n), collapse="") - return(paste0(.pre, "_lastValue = ", .cur, ";\n")) + if (envir$isRx) { + return(paste0(.pre, "rxLastValue <- ", .cur, "\n")) + } else { + return(paste0(.pre, "_lastValue = ", .cur, ";\n")) + } } .cur }, character(1), USE.NAMES = FALSE), @@ -3419,6 +3454,7 @@ rxSupportedFuns <- function() { } else { # supported functions if (identical(x[[1]], quote(`return`))) { + envir$hasReturn <- TRUE .pre <- paste0(rep(" ", envir$n), collapse="") envir$didAssign <- TRUE return(paste0(.pre, "return (", .rxFun2c(x[[2]], envir=envir), ");\n")) @@ -3453,7 +3489,7 @@ rxSupportedFuns <- function() { } } -rxFun2c <- function(fun, name) { +rxFun2c <- function(fun, name, onlyF=FALSE) { .env <- new.env(parent=emptyenv()) .env$vars <- character(0) if (!missing(name)) { @@ -3465,6 +3501,8 @@ rxFun2c <- function(fun, name) { .env$args <- names(.f) .env$n <- 2 .env$isExpr <- FALSE + .env$isRx <- FALSE + .env$hasReturn <- FALSE if (any(.env$args == "...")) { stop("functions with ... in them are not supported", call. =FALSE) @@ -3480,7 +3518,11 @@ rxFun2c <- function(fun, name) { .cur <- .rxFun2c(.cur, envir=.env) if(!.env$didAssign && !.env$isExpr) { .pre <- paste0(rep(" ", .env$n), collapse="") - return(paste0(.pre, "_lastValue = ", .cur, ";\n")) + if (.env$isRx) { + return(paste0(.pre, "rxLastValue <- ", .cur, "\n")) + } else { + return(paste0(.pre, "_lastValue = ", .cur, ";\n")) + } } .env$isExpr <- FALSE .cur @@ -3493,7 +3535,61 @@ rxFun2c <- function(fun, name) { ";\n")) .stop <- " return _lastValue;\n}\n" .cCode <- paste0(.start, .body, .stop) - list(name=.funName, - args=.env$args, - cCode=.cCode) + .ret <- list(name=.funName, + args=.env$args, + cCode=.cCode) + + if (onlyF) { + return(.ret) + } + if (!.env$hasReturn) { + # Can calculate derivatives + # Firs create an rxode2 like model: + .env <- new.env(parent=emptyenv()) + .env$isRx <- TRUE + .env$args <- names(.f) + .env$n <- 2 + .env$isExpr <- FALSE + .env$hasReturn <- FALSE + .body <- as.list(body(fun)) + .body <- paste(vapply(seq_along(.body)[-1], function(i) { + .extra <- .extra2 <- "" + .cur <- .body[[i]] + .env$didAssign <- FALSE + .cur <- .rxFun2c(.cur, envir=.env) + if(!.env$didAssign && !.env$isExpr) { + .pre <- paste0(rep(" ", .env$n), collapse="") + return(paste0(.pre, "rxLastValue = ", .cur, ";\n")) + } + .env$isExpr <- FALSE + .cur + }, + character(1), USE.NAMES=FALSE), collapse="") + # take out if/else + .body <- rxPrune(.body) + .s <- rxS(.body) + .lastValue <- .s$rxLastValue + return(c(list(.ret), + lapply(.env$args, function(v){ + .v <- symengine::D(.lastValue, symengine::S(v)) + .v <- paste0("function(", paste(.env$args, collapse=", "), ") {\n", rxOptExpr(paste0("rxLastValue=", rxFromSE(.v)), msg=paste0("d(", .funName, ")/d(", v, ")")), + "\nrxLastValue}") + .v <- eval(str2lang(.v)) + .dName <- paste0("rx_", .funName, "_d_", v) + .v <- rxFun2c(.v, .dName, onlyF=TRUE) + #' function(a, b, c) { + #' paste0("2*", a, "+", b) + #' }, + #' + .v2 <- paste0("function(", paste(.env$args, collapse=", "), "){\n", + "paste0(\"", .dName, "(\", ", + paste(.env$args, collapse=", \", \", "), ", \")\")", + "}") + .v2 <- eval(str2lang(.v2)) + c(.v, list(.v2)) + }))) + } else { + message("function contains return statement; derivatives not calculated") + } + return(list(.ret)) } diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index 09e32f817..92eaa9b85 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -1,4 +1,5 @@ rxTest({ + e <- et(1:10) |> as.data.frame() e$x <- 1:10 @@ -147,7 +148,7 @@ rxTest({ a + b } - expect_true(grepl("R_pow_di[(]", rxFun2c(udf)$cCode)) + expect_true(grepl("R_pow_di[(]", rxFun2c(udf)[[1]]$cCode)) udf <- function(x, y) { a <- x + y @@ -155,7 +156,7 @@ rxTest({ a + b } - expect_true(grepl("R_pow[(]", rxFun2c(udf)$cCode)) + expect_true(grepl("R_pow[(]", rxFun2c(udf)[[1]]$cCode)) udf <- function(x, y) { a <- x + y @@ -163,7 +164,7 @@ rxTest({ a + b } - expect_true(grepl("cos[(]", rxFun2c(udf)$cCode)) + expect_true(grepl("cos[(]", rxFun2c(udf)[[1]]$cCode)) udf <- function(x, y) { if (a < b) { @@ -172,7 +173,7 @@ rxTest({ a + b } - expect_true(grepl("if [(]", rxFun2c(udf)$cCode)) + expect_true(grepl("if [(]", rxFun2c(udf)[[1]]$cCode)) udf <- function(x, y) { @@ -185,7 +186,7 @@ rxTest({ } } - expect_true(grepl("else [{]", rxFun2c(udf)$cCode)) + expect_true(grepl("else [{]", rxFun2c(udf)[[1]]$cCode)) udf <- function(x, y) { a <- x @@ -198,7 +199,7 @@ rxTest({ a ^ 2 + b ^ 2 } - expect_true(grepl("else if [(]", rxFun2c(udf)$cCode)) + expect_true(grepl("else if [(]", rxFun2c(udf)[[1]]$cCode)) udf <- function(x, y) { a <- x @@ -215,7 +216,7 @@ rxTest({ a ^ 2 + b ^ 2 } - expect_true(grepl("else if [(]", rxFun2c(udf)$cCode)) + expect_true(grepl("else if [(]", rxFun2c(udf)[[1]]$cCode)) udf <- function(x, y) { a <- x + y @@ -223,7 +224,21 @@ rxTest({ x } - expect_error(rxFun2c(udf)$cCode) + expect_error(rxFun2c(udf)[[1]]$cCode) + + + udf <- function(x, y) { + a <- x + b <- x ^ 2 + a + if (a < b) { + b ^ 2 + } else { + a + b + } + } + + rxFun(udf) + }) test_that("udf with model functions", { From cc8538f9639af0c2742fc20f0ab4403fa4fc2ed7 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Wed, 1 Nov 2023 23:28:16 -0500 Subject: [PATCH 17/27] ::document() changes --- R/symengine.R | 24 ++++++--- inst/include/rxode2_control.h | 97 ++++++++++++++++++++++++++++++++++- man/as.rxUi.Rd | 21 ++++---- man/reexports.Rd | 1 - man/rxFun.Rd | 13 +---- man/rxS.Rd | 5 +- man/rxSolve.Rd | 6 ++- man/rxode2.Rd | 16 ++---- 8 files changed, 136 insertions(+), 47 deletions(-) diff --git a/R/symengine.R b/R/symengine.R index 42347a807..b2a56f15c 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -264,7 +264,10 @@ regIfOrElse <- rex::rex(or(regIf, regElse)) "rt" = 1 ) -#' @inherit rxode2parse::rxFunParse +#' Add/Create C functions for use in rxode2 +#' +#' @inheritParams rxode2parse::rxFunParse +#' #' @param name This can either give the name of the user function or #' be a simple R function that you wish to convert to C. If you #' have rxode2 convert the R function to C, the name of the function @@ -272,6 +275,7 @@ regIfOrElse <- rex::rex(or(regIf, regElse)) #' will match the R function provided. Hence, if you are providing #' an R function for conversion to C, the rest of the arguments are #' implied. +#' @export #' @examples #' \donttest{ #' ## Right now rxode2 is not aware of the function fun @@ -361,7 +365,6 @@ regIfOrElse <- rex::rex(or(regIf, regElse)) #' rm(gg) #' rm(f) #' } -#' @export rxFun <- function(name, args, cCode) { if (missing(args) && missing(cCode)) { .funName <- as.character(substitute(name)) @@ -3489,6 +3492,19 @@ rxSupportedFuns <- function() { } } +#' Calculate derivatives/C code from a R function +#' +#' @param fun Function to convert to C +#' +#' @param name function name to convert to C, implied if needed +#' +#' @param onlyF Only calculate the C for the function, don't calculate the derivatives +#' +#' @return A list with C code and derivative information +#' +#' @keywords internal +#' +#' @noRd rxFun2c <- function(fun, name, onlyF=FALSE) { .env <- new.env(parent=emptyenv()) .env$vars <- character(0) @@ -3577,10 +3593,6 @@ rxFun2c <- function(fun, name, onlyF=FALSE) { .v <- eval(str2lang(.v)) .dName <- paste0("rx_", .funName, "_d_", v) .v <- rxFun2c(.v, .dName, onlyF=TRUE) - #' function(a, b, c) { - #' paste0("2*", a, "+", b) - #' }, - #' .v2 <- paste0("function(", paste(.env$args, collapse=", "), "){\n", "paste0(\"", .dName, "(\", ", paste(.env$args, collapse=", \", \", "), ", \")\")", diff --git a/inst/include/rxode2_control.h b/inst/include/rxode2_control.h index fec561cf8..e54cb3dc8 100644 --- a/inst/include/rxode2_control.h +++ b/inst/include/rxode2_control.h @@ -2,5 +2,100 @@ #ifndef __rxode2_control_H__ #define __rxode2_control_H__ #include - +#define Rxc_scale 0 +#define Rxc_method 1 +#define Rxc_atol 2 +#define Rxc_rtol 3 +#define Rxc_maxsteps 4 +#define Rxc_hmin 5 +#define Rxc_hmax 6 +#define Rxc_hini 7 +#define Rxc_maxordn 8 +#define Rxc_maxords 9 +#define Rxc_covsInterpolation 10 +#define Rxc_addCov 11 +#define Rxc_returnType 12 +#define Rxc_sigma 13 +#define Rxc_sigmaDf 14 +#define Rxc_nCoresRV 15 +#define Rxc_sigmaIsChol 16 +#define Rxc_sigmaSeparation 17 +#define Rxc_sigmaXform 18 +#define Rxc_nDisplayProgress 19 +#define Rxc_amountUnits 20 +#define Rxc_timeUnits 21 +#define Rxc_addDosing 22 +#define Rxc_stateTrim 23 +#define Rxc_updateObject 24 +#define Rxc_omega 25 +#define Rxc_omegaDf 26 +#define Rxc_omegaIsChol 27 +#define Rxc_omegaSeparation 28 +#define Rxc_omegaXform 29 +#define Rxc_nSub 30 +#define Rxc_thetaMat 31 +#define Rxc_thetaDf 32 +#define Rxc_thetaIsChol 33 +#define Rxc_nStud 34 +#define Rxc_dfSub 35 +#define Rxc_dfObs 36 +#define Rxc_seed 37 +#define Rxc_nsim 38 +#define Rxc_minSS 39 +#define Rxc_maxSS 40 +#define Rxc_strictSS 41 +#define Rxc_infSSstep 42 +#define Rxc_istateReset 43 +#define Rxc_subsetNonmem 44 +#define Rxc_hmaxSd 45 +#define Rxc_maxAtolRtolFactor 46 +#define Rxc_from 47 +#define Rxc_to 48 +#define Rxc_by 49 +#define Rxc_length_out 50 +#define Rxc_iCov 51 +#define Rxc_keep 52 +#define Rxc_keepF 53 +#define Rxc_drop 54 +#define Rxc_warnDrop 55 +#define Rxc_omegaLower 56 +#define Rxc_omegaUpper 57 +#define Rxc_sigmaLower 58 +#define Rxc_sigmaUpper 59 +#define Rxc_thetaLower 60 +#define Rxc_thetaUpper 61 +#define Rxc_indLinPhiM 62 +#define Rxc_indLinPhiTol 63 +#define Rxc_indLinMatExpType 64 +#define Rxc_indLinMatExpOrder 65 +#define Rxc_idFactor 66 +#define Rxc_mxhnil 67 +#define Rxc_hmxi 68 +#define Rxc_warnIdSort 69 +#define Rxc_ssAtol 70 +#define Rxc_ssRtol 71 +#define Rxc_safeZero 72 +#define Rxc_sumType 73 +#define Rxc_prodType 74 +#define Rxc_sensType 75 +#define Rxc_linDiff 76 +#define Rxc_linDiffCentral 77 +#define Rxc_resample 78 +#define Rxc_resampleID 79 +#define Rxc_maxwhile 80 +#define Rxc_cores 81 +#define Rxc_atolSens 82 +#define Rxc_rtolSens 83 +#define Rxc_ssAtolSens 84 +#define Rxc_ssRtolSens 85 +#define Rxc_simVariability 86 +#define Rxc_nLlikAlloc 87 +#define Rxc_useStdPow 88 +#define Rxc_naTimeHandle 89 +#define Rxc_addlKeepsCov 90 +#define Rxc_addlDropSs 91 +#define Rxc_ssAtDoseTime 92 +#define Rxc_ss2cancelAllPending 93 +#define Rxc_envir 94 +#define Rxc__zeros 95 #endif // __rxode2_control_H__ diff --git a/man/as.rxUi.Rd b/man/as.rxUi.Rd index f54aeb03f..3256eec73 100644 --- a/man/as.rxUi.Rd +++ b/man/as.rxUi.Rd @@ -10,25 +10,22 @@ \alias{as.rxUi.default} \title{As rxode2 ui} \usage{ -as.rxUi(x, envir = parent.frame()) +as.rxUi(x) -\method{as.rxUi}{rxode2}(x, envir = parent.frame()) +\method{as.rxUi}{rxode2}(x) -\method{as.rxUi}{rxode2tos}(x, envir = parent.frame()) +\method{as.rxUi}{rxode2tos}(x) -\method{as.rxUi}{rxModelVars}(x, envir = parent.frame()) +\method{as.rxUi}{rxModelVars}(x) -\method{as.rxUi}{`function`}(x, envir = parent.frame()) +\method{as.rxUi}{`function`}(x) -\method{as.rxUi}{rxUi}(x, envir = parent.frame()) +\method{as.rxUi}{rxUi}(x) -\method{as.rxUi}{default}(x, envir = parent.frame()) +\method{as.rxUi}{default}(x) } \arguments{ \item{x}{Object to convert to \code{rxUi} object} - -\item{envir}{is the environment to look for R user functions -(defaults to parent environment)} } \value{ rxUi object (or error if it cannot be converted) @@ -40,7 +37,7 @@ As rxode2 ui mod1 <- function() { ini({ - # central + # central KA=2.94E-01 CL=1.86E+01 V2=4.02E+01 @@ -50,7 +47,7 @@ mod1 <- function() { # effects Kin=1 Kout=1 - EC50=200 + EC50=200 }) model({ C2 <- centr/V2 diff --git a/man/reexports.Rd b/man/reexports.Rd index 365c14ab7..f1310e9e9 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -82,4 +82,3 @@ below to see their documentation. \item{rxode2random}{\code{\link[rxode2random:dot-cbindOme]{.cbindOme}}, \code{\link[rxode2random:dot-expandPars]{.expandPars}}, \code{\link[rxode2random:dot-vecDf]{.vecDf}}, \code{\link[rxode2random]{cvPost}}, \code{\link[rxode2random]{invWR1d}}, \code{\link[rxode2random]{phi}}, \code{\link[rxode2random]{rinvchisq}}, \code{\link[rxode2random]{rLKJ1}}, \code{\link[rxode2random]{rxGetSeed}}, \code{\link[rxode2random]{rxGetSeed}}, \code{\link[rxode2random]{rxRmvn}}, \code{\link[rxode2random]{rxSeedEng}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random:rxWithSeed]{rxWithPreserveSeed}}, \code{\link[rxode2random]{rxWithSeed}}, \code{\link[rxode2random]{rxWithSeed}}} }} -\value{ Inherited from parent routine } diff --git a/man/rxFun.Rd b/man/rxFun.Rd index 836a7fc2a..77c8e3c6f 100644 --- a/man/rxFun.Rd +++ b/man/rxFun.Rd @@ -3,7 +3,7 @@ \name{rxFun} \alias{rxFun} \alias{rxRmFun} -\title{Add user function to rxode2} +\title{Add/Create C functions for use in rxode2} \usage{ rxFun(name, args, cCode) @@ -22,14 +22,8 @@ implied.} \item{cCode}{This is the C-code for the new function} } -\value{ -nothing -} \description{ -This adds a user function to rxode2 that can be called. If needed, -these functions can be differentiated by numerical differences or -by adding the derivatives to rxode2's internal derivative table -with rxode2's \code{rxD} function +Add/Create C functions for use in rxode2 } \examples{ \donttest{ @@ -121,6 +115,3 @@ rm(gg) rm(f) } } -\author{ -Matthew L. Fidler -} diff --git a/man/rxS.Rd b/man/rxS.Rd index 898eca1ff..b55404472 100644 --- a/man/rxS.Rd +++ b/man/rxS.Rd @@ -4,7 +4,7 @@ \alias{rxS} \title{Load a model into a symengine environment} \usage{ -rxS(x, doConst = TRUE, promoteLinSens = FALSE) +rxS(x, doConst = TRUE, promoteLinSens = FALSE, envir = parent.frame()) } \arguments{ \item{x}{rxode2 object} @@ -13,6 +13,9 @@ rxS(x, doConst = TRUE, promoteLinSens = FALSE) \item{promoteLinSens}{Promote solved linear compartment systems to sensitivity-based solutions.} + +\item{envir}{default is \code{NULL}; Environment to put symengine +variables in.} } \value{ rxode2/symengine environment diff --git a/man/rxSolve.Rd b/man/rxSolve.Rd index 54f0a6d80..f90f627a3 100644 --- a/man/rxSolve.Rd +++ b/man/rxSolve.Rd @@ -144,7 +144,8 @@ rxSolve( inits = NULL, ..., theta = NULL, - eta = NULL + eta = NULL, + envir = parent.frame() ) \method{rxSolve}{rxUi}( @@ -194,7 +195,8 @@ rxSolve( inits = NULL, ..., theta = NULL, - eta = NULL + eta = NULL, + envir = parent.frame() ) \method{update}{rxSolve}(object, ...) diff --git a/man/rxode2.Rd b/man/rxode2.Rd index 0fa54404b..1a7a3c176 100644 --- a/man/rxode2.Rd +++ b/man/rxode2.Rd @@ -180,7 +180,7 @@ consisting of the following list of strings and functions: `atol`: a numeric absolute tolerance (1e-08 by default); - `rtol`: a numeric relative tolerance (1e-06 by default).e + `rtol`: a numeric relative tolerance (1e-06 by default). The output of \\dQuote\{solve\} is a matrix with as many rows as there are sampled time points and as many columns as system variables @@ -232,9 +232,6 @@ mod <- rxode2(\{ d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; \}) }\if{html}{\out{
}} - -\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ -}\if{html}{\out{
}} \itemize{ \item Inside a \code{rxode2("")} string statement: }\if{html}{\out{ @@ -250,9 +247,6 @@ mod <- rxode2(\{ d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; ") }\if{html}{\out{
}} - -\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ -}\if{html}{\out{
}} \itemize{ \item In a file name to be loaded by rxode2: }\if{html}{\out{ @@ -331,9 +325,7 @@ compilation model. \if{html}{\out{
}}\preformatted{mod$simulationModel }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ - -## rxode2 2.0.14.9000 model named rx_78dcb8ef8275ff5e33a47163f4239e19 model (ready). +\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_8223e497c83db9e334c52254bd575c98 model (ready). ## x$state: depot, center ## x$stateExtra: cp ## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp @@ -344,9 +336,7 @@ compilation model. mod$simulationIniModel }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ - -## rxode2 2.0.14.9000 model named rx_baef7cfc602529d2843782858fc2f522 model (ready). +\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_182c47efea379394bbab84d957305170 model (ready). ## x$state: depot, center ## x$stateExtra: cp ## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp From eaf6b4841cc7ff448c87991723626d3e6e7a81b0 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Thu, 2 Nov 2023 16:21:22 -0500 Subject: [PATCH 18/27] Use unified interface for locking --- R/rxUiGet.R | 9 +-------- R/symengine.R | 12 +++--------- man/reexports.Rd | 1 + 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/R/rxUiGet.R b/R/rxUiGet.R index d132d3c03..66803ecbe 100644 --- a/R/rxUiGet.R +++ b/R/rxUiGet.R @@ -29,15 +29,8 @@ # The model() and rxode2() assign the parent environments for UDF # parsing, if the object is in that environment lock it and then # unlock on exit - if (rxode2parse::.udfEnvLockIfExists(obj)) { - # If locked unlock when exiting + if (rxode2parse::.udfFindAndLock(obj, list(parent.frame(1), parent.frame(2)))) { on.exit(rxode2parse::.udfEnvLock(FALSE)) - } else if (!rxode2parse::.udfEnvLock(NULL)) { - ## unlocked, look for object in parent frame until global or empty environment - if (rxode2parse::.udfEnvLockIfExists(obj, parent.frame(1))) { - # if locked by this, unlock when exiting - on.exit(rxode2parse::.udfEnvLock(FALSE)) - } } rxUiGet(.uiToRxUiGet(obj=obj, arg=arg, exact=exact)) } diff --git a/R/symengine.R b/R/symengine.R index b2a56f15c..c394f3e11 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -512,9 +512,7 @@ rxD <- function(name, derivatives) { #' @export rxToSE <- function(x, envir = NULL, progress = FALSE, promoteLinSens = TRUE, parent = parent.frame()) { - if (!rxode2parse::.udfEnvLock(NULL)) { - rxode2parse::.udfEnvSet(parent) - rxode2parse::.udfEnvLock(TRUE) + if (rxode2parse::.udfFindAndLock(NULL, parent)) { on.exit(rxode2parse::.udfEnvLock(FALSE)) } .rxToSE.envir$parent <- parent @@ -1425,9 +1423,7 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), parent=parent.frame()) { rxReq("symengine") - if (!rxode2parse::.udfEnvLock(NULL)) { - rxode2parse::.udfEnvSet(parent) - rxode2parse::.udfEnvLock(TRUE) + if (rxode2parse::.udfFindAndLock(NULL, parent)) { on.exit(rxode2parse::.udfEnvLock(FALSE)) } .rxFromSE.envir$parent <- parent @@ -2218,9 +2214,7 @@ rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), #' @author Matthew Fidler #' @export rxS <- function(x, doConst = TRUE, promoteLinSens = FALSE, envir=parent.frame()) { - if (!rxode2parse::.udfEnvLock(NULL)) { - rxode2parse::.udfEnvSet(envir) - rxode2parse::.udfEnvLock(TRUE) + if (rxode2parse::.udfFindAndLock(NULL, envir)) { on.exit(rxode2parse::.udfEnvLock(FALSE)) } rxReq("symengine") diff --git a/man/reexports.Rd b/man/reexports.Rd index f1310e9e9..365c14ab7 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -82,3 +82,4 @@ below to see their documentation. \item{rxode2random}{\code{\link[rxode2random:dot-cbindOme]{.cbindOme}}, \code{\link[rxode2random:dot-expandPars]{.expandPars}}, \code{\link[rxode2random:dot-vecDf]{.vecDf}}, \code{\link[rxode2random]{cvPost}}, \code{\link[rxode2random]{invWR1d}}, \code{\link[rxode2random]{phi}}, \code{\link[rxode2random]{rinvchisq}}, \code{\link[rxode2random]{rLKJ1}}, \code{\link[rxode2random]{rxGetSeed}}, \code{\link[rxode2random]{rxGetSeed}}, \code{\link[rxode2random]{rxRmvn}}, \code{\link[rxode2random]{rxSeedEng}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random]{rxSetSeed}}, \code{\link[rxode2random:rxWithSeed]{rxWithPreserveSeed}}, \code{\link[rxode2random]{rxWithSeed}}, \code{\link[rxode2random]{rxWithSeed}}} }} +\value{ Inherited from parent routine } From 82faecf1087ad2a6a45d3fdbd337eb81e544e7ce Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sat, 4 Nov 2023 07:00:40 -0500 Subject: [PATCH 19/27] Adapt to environmental search list --- R/rxUiGet.R | 4 +-- R/rxsolve.R | 13 +++++---- R/symengine.R | 12 +++------ inst/include/rxode2_control.h | 3 +-- src/rxData.cpp | 8 +++--- src/rxode2parse.cpp | 14 +++++----- tests/testthat/test-udf.R | 51 +++++++++++++++++++---------------- 7 files changed, 51 insertions(+), 54 deletions(-) diff --git a/R/rxUiGet.R b/R/rxUiGet.R index 66803ecbe..7ab14730c 100644 --- a/R/rxUiGet.R +++ b/R/rxUiGet.R @@ -29,9 +29,7 @@ # The model() and rxode2() assign the parent environments for UDF # parsing, if the object is in that environment lock it and then # unlock on exit - if (rxode2parse::.udfFindAndLock(obj, list(parent.frame(1), parent.frame(2)))) { - on.exit(rxode2parse::.udfEnvLock(FALSE)) - } + rxode2parse::.udfEnvSet(list(parent.frame(1), parent.frame(2))) rxUiGet(.uiToRxUiGet(obj=obj, arg=arg, exact=exact)) } diff --git a/R/rxsolve.R b/R/rxsolve.R index 9b95379fb..e2582a8d4 100644 --- a/R/rxsolve.R +++ b/R/rxsolve.R @@ -724,6 +724,7 @@ rxSolve <- function(object, params = NULL, events = NULL, inits = NULL, ssAtDoseTime=TRUE, ss2cancelAllPending=FALSE, envir=parent.frame()) { + rxode2parse::.udfEnvSet(list(envir, parent.frame(1))) if (is.null(object)) { .xtra <- list(...) .nxtra <- names(.xtra) @@ -1125,7 +1126,6 @@ rxSolve <- function(object, params = NULL, events = NULL, inits = NULL, addlDropSs=addlDropSs, ssAtDoseTime=ssAtDoseTime, ss2cancelAllPending=ss2cancelAllPending, - envir=envir, .zeros=unique(.zeros) ) @@ -1139,6 +1139,7 @@ rxSolve <- function(object, params = NULL, events = NULL, inits = NULL, #' @export rxSolve.function <- function(object, params = NULL, events = NULL, inits = NULL, ..., theta = NULL, eta = NULL, envir=parent.frame()) { + rxode2parse::.udfEnvSet(list(envir, parent.frame(1))) .object <- rxode2(object) do.call("rxSolve", c(list(object=.object, params = params, events = events, inits = inits), list(...), @@ -1224,7 +1225,8 @@ rxSolve.function <- function(object, params = NULL, events = NULL, inits = NULL, #' @rdname rxSolve #' @export rxSolve.rxUi <- function(object, params = NULL, events = NULL, inits = NULL, ..., - theta = NULL, eta = NULL) { + theta = NULL, eta = NULL, envir=parent.frame()) { + rxode2parse::.udfEnvSet(list(envir, parent.frame(1))) if (inherits(object, "rxUi")) { object <- rxUiDecompress(object) } @@ -1271,7 +1273,8 @@ rxSolve.rxode2tos <- rxSolve.rxUi #' @rdname rxSolve #' @export rxSolve.nlmixr2FitData <- function(object, params = NULL, events = NULL, inits = NULL, ..., - theta = NULL, eta = NULL) { + theta = NULL, eta = NULL, envir=parent.frame()) { + rxode2parse::.udfEnvSet(list(envir, parent.frame(1))) .lst <- .rxSolveFromUi(object, params = params, events = events, inits = inits, ..., theta = theta, eta = eta) .rxControl <- .lst[[2]] .env <- object$env @@ -1306,6 +1309,7 @@ rxSolve.nlmixr2FitCore <- rxSolve.nlmixr2FitData #' @export rxSolve.default <- function(object, params = NULL, events = NULL, inits = NULL, ..., theta = NULL, eta = NULL, envir=parent.frame()) { + rxode2parse::.udfEnvSet(list(envir, parent.frame(1))) on.exit({ .clearPipe() .asFunctionEnv$rx <- NULL @@ -1399,7 +1403,7 @@ rxSolve.default <- function(object, params = NULL, events = NULL, inits = NULL, if (any(names(.lst) == ".setupOnly")) { .setupOnly <- .lst$.setupOnly } - .ctl <- rxControl(..., events = events, params = params, envir=envir) + .ctl <- rxControl(..., events = events, params = params) if (.ctl$addCov && length(.ctl$keep) > 0) { .mv <- rxModelVars(object) .both <- intersect(.mv$params, .ctl$keep) @@ -1803,7 +1807,6 @@ solve.rxSolve <- function(a, b, ...) { n[n == "b"] <- "" } names(lst) <- n - lst$envir <- parent.frame(1) do.call("rxSolve", lst, envir = parent.frame(1)) } diff --git a/R/symengine.R b/R/symengine.R index c394f3e11..b1c315a62 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -512,9 +512,7 @@ rxD <- function(name, derivatives) { #' @export rxToSE <- function(x, envir = NULL, progress = FALSE, promoteLinSens = TRUE, parent = parent.frame()) { - if (rxode2parse::.udfFindAndLock(NULL, parent)) { - on.exit(rxode2parse::.udfEnvLock(FALSE)) - } + rxode2parse::.udfEnvSet(parent) .rxToSE.envir$parent <- parent assignInMyNamespace(".promoteLinB", promoteLinSens) assignInMyNamespace(".rxIsLhs", FALSE) @@ -1423,9 +1421,7 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), parent=parent.frame()) { rxReq("symengine") - if (rxode2parse::.udfFindAndLock(NULL, parent)) { - on.exit(rxode2parse::.udfEnvLock(FALSE)) - } + rxode2parse::.udfEnvSet(parent) .rxFromSE.envir$parent <- parent .unknown <- c("central" = 2L, "forward" = 1L, "error" = 0L) assignInMyNamespace(".rxFromNumDer", .unknown[match.arg(unknownDerivatives)]) @@ -2214,9 +2210,7 @@ rxFromSE <- function(x, unknownDerivatives = c("forward", "central", "error"), #' @author Matthew Fidler #' @export rxS <- function(x, doConst = TRUE, promoteLinSens = FALSE, envir=parent.frame()) { - if (rxode2parse::.udfFindAndLock(NULL, envir)) { - on.exit(rxode2parse::.udfEnvLock(FALSE)) - } + rxode2parse::.udfEnvSet(envir) rxReq("symengine") .cnst <- names(.rxSEreserved) .env <- new.env(parent = loadNamespace("symengine")) diff --git a/inst/include/rxode2_control.h b/inst/include/rxode2_control.h index e54cb3dc8..d84e1f0f0 100644 --- a/inst/include/rxode2_control.h +++ b/inst/include/rxode2_control.h @@ -96,6 +96,5 @@ #define Rxc_addlDropSs 91 #define Rxc_ssAtDoseTime 92 #define Rxc_ss2cancelAllPending 93 -#define Rxc_envir 94 -#define Rxc__zeros 95 +#define Rxc__zeros 94 #endif // __rxode2_control_H__ diff --git a/src/rxData.cpp b/src/rxData.cpp index 5af3f6979..45a4f54b7 100644 --- a/src/rxData.cpp +++ b/src/rxData.cpp @@ -64,8 +64,8 @@ extern "C" int getRxThreads(const int64_t n, const bool throttle); extern "C" void rxode2_assign_fn_pointers_(const char *mv); extern "C" void setSilentErr(int silent); extern "C" SEXP _rxode2parse_assignUdf(SEXP in); -extern "C" SEXP _rxode2parse_udfEnvSet(SEXP env, bool lock); -extern "C" SEXP _rxode2parse_udfUnlock(); +extern "C" SEXP _rxode2parse_udfEnvSet(SEXP udf); +extern "C" SEXP _rxode2parse_udfReset(); extern "C" { typedef SEXP (*_rxode2parse_getForder_type)(void); @@ -2475,7 +2475,7 @@ void resetFkeep(); //' @export // [[Rcpp::export]] LogicalVector rxSolveFree(){ - _rxode2parse_udfUnlock(); + _rxode2parse_udfReset(); resetFkeep(); rx_solve* rx = getRxSolve_(); // Free the solve id order @@ -4631,7 +4631,6 @@ SEXP rxSolve_(const RObject &obj, const List &rxControl, rxSolveFree(); stop(_("control list not setup correctly")); } - _rxode2parse_udfEnvSet(rxControl[Rxc_envir], true); maxAtolRtolFactor = asDouble(rxControl[Rxc_maxAtolRtolFactor], "maxAtolRtolFactor"); RObject scale = rxControl[Rxc_scale]; int method = asInt(rxControl[Rxc_method], "method"); @@ -4740,6 +4739,7 @@ SEXP rxSolve_(const RObject &obj, const List &rxControl, } } + _rxode2parse_udfEnvSet(rxSolveDat->mv[RxMv_udf]); LogicalVector recompileUdf = _rxode2parse_assignUdf(rxSolveDat->mv[RxMv_udf]); if (recompileUdf[0]) { diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 50fc97c9c..5c34a5a4e 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -94,22 +94,20 @@ BEGIN_RCPP END_RCPP } -extern "C" SEXP _rxode2parse_udfEnvSet(SEXP env, bool lock) { +extern "C" SEXP _rxode2parse_udfEnvSet(SEXP udf) { BEGIN_RCPP assignRxode2ParsePtrs(); - Function fun = as(rxode2parse[".udfEnvSet"]); - fun(env); - Function fun2 = as(rxode2parse[".udfEnvLock"]); - fun2(lock); + Function fun = as(rxode2parse[".udfEnvSetUdf"]); + fun(udf); return R_NilValue; END_RCPP } -extern "C" SEXP _rxode2parse_udfUnlock() { +extern "C" SEXP _rxode2parse_udfReset() { BEGIN_RCPP assignRxode2ParsePtrs(); - Function fun2 = as(rxode2parse[".udfEnvLock"]); - fun2(false); + Function fun2 = as(rxode2parse[".udfEnvReset"]); + fun2(); return R_NilValue; END_RCPP diff --git a/tests/testthat/test-udf.R b/tests/testthat/test-udf.R index 92eaa9b85..dd533b9d2 100644 --- a/tests/testthat/test-udf.R +++ b/tests/testthat/test-udf.R @@ -29,7 +29,6 @@ rxTest({ x + y + z } - test_that("udf with 3 arguments works", { expect_error(rxSolve(f, e)) }) @@ -45,6 +44,7 @@ rxTest({ d <- suppressWarnings(rxSolve(f, e)) expect_true(all(d$z == d$x * d$y)) + }) rm(gg) @@ -75,21 +75,24 @@ rxTest({ } - test_that("runs with improper output will return NA", { - x <- suppressWarnings(rxSolve(f, e)) - expect_true(all(is.na(x$z))) + test_that("runs with improper output will error", { + expect_error(rxSolve(f, e)) }) gg <- function(x, y) { "3" } - test_that("converts to 3 when it is a string", { - x <- suppressWarnings(rxSolve(f, e)) - expect_true(all(x$z == 3)) + test_that("error for invalid input", { + expect_error(rxSolve(f, e)) }) + gg <- function(x, y) { + 3L + } + test_that("test symengine functions work with udf funs", { + expect_equal(rxToSE("gg(x,y)"), "gg(x, y)") expect_error(rxToSE("gg()"), "user function") @@ -112,34 +115,32 @@ rxTest({ }) ## manual functions in C vs R functions + + gg <- function(x, y) { + x + y + } + test_that("R vs C functions", { - gg <- function(x, y) { - x + y - } - x <- suppressWarnings(rxSolve(f, e)) - # now add a C function with different values + d <- suppressWarnings(rxSolve(f, e)) + expect_true(all(d$z == d$x + d$y)) + }) - rxFun("gg", c("x", "y"), - "double gg(double x, double y) { return x*y;}") + # now add a C function with different values + rxFun("gg", c("x", "y"), + "double gg(double x, double y) { return x*y;}") - gg <- function(x, y, z) { - x + y + z - } - expect_error(rxSolve(f, e)) + test_that("C functions rule", { - gg <- function(x, y) { - x + y - } d <- suppressWarnings(rxSolve(f, e)) expect_true(all(d$z == d$x * d$y)) - rxRmFun("gg") - }) + rxRmFun("gg") + test_that("c conversion", { udf <- function(x, y) { @@ -238,6 +239,7 @@ rxTest({ } rxFun(udf) + rxRmFun("udf") }) @@ -323,6 +325,9 @@ rxTest({ expect_error(rxS(mod, TRUE, TRUE), NA) + rxRmFun("gg") + }) + }) From 5ecbea436308bf61dea46302007c29a0d45ea8bf Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sat, 4 Nov 2023 12:47:32 -0500 Subject: [PATCH 20/27] Don't run udf functions if they are not needed --- src/rxode2parse.cpp | 11 ++++++++++- tests/testthat/test-backward.R | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 5c34a5a4e..81738ce0d 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -78,7 +78,7 @@ extern "C" SEXP _rxode2_codeLoaded(void) { extern "C" SEXP _rxode2parse_assignUdf(SEXP in) { BEGIN_RCPP - if (Rf_length(in) == 0) { + if (Rf_length(in) == 0 || Rf_length(in) == 1) { return wrap(LogicalVector::create(false)); } if (TYPEOF(in) != INTSXP) { @@ -96,6 +96,15 @@ END_RCPP extern "C" SEXP _rxode2parse_udfEnvSet(SEXP udf) { BEGIN_RCPP + if (Rf_length(udf) == 0 || Rf_length(udf) == 1) { + return R_NilValue; + } + if (TYPEOF(udf) != INTSXP) { + return R_NilValue; + } + if (Rf_isNull(Rf_getAttrib(udf, R_NamesSymbol))) { + return R_NilValue; + } assignRxode2ParsePtrs(); Function fun = as(rxode2parse[".udfEnvSetUdf"]); fun(udf); diff --git a/tests/testthat/test-backward.R b/tests/testthat/test-backward.R index b1e175ff5..0b1a0b774 100644 --- a/tests/testthat/test-backward.R +++ b/tests/testthat/test-backward.R @@ -1,4 +1,5 @@ rxTest({ + ## Dynmodel routines ode <- " dose=200; @@ -169,7 +170,6 @@ rxTest({ x$add.sampling(0.5) expect_equal(as.numeric(x$time[2]), 0.5) }) - x <- solve(mod1, theta, ev, inits) test_that("Add dosing makes sense", { From 4d0ec643fb48e37af653b20aa4187f6418a0b7b4 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sat, 4 Nov 2023 20:17:10 -0500 Subject: [PATCH 21/27] rxC() now will output the C functions from rxFun() --- .Rbuildignore | 1 + src/rxData.cpp | 7 ++++++- src/rxode2parse.cpp | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.Rbuildignore b/.Rbuildignore index 7a4086d65..ad879553c 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -138,3 +138,4 @@ tests/testthat/test-lincmt-parse.R ^/?build/sensitivites.R$ ^CRAN-SUBMISSION$ ^revdep$ +^vignettes/articles$ diff --git a/src/rxData.cpp b/src/rxData.cpp index 45a4f54b7..cb942d115 100644 --- a/src/rxData.cpp +++ b/src/rxData.cpp @@ -66,6 +66,7 @@ extern "C" void setSilentErr(int silent); extern "C" SEXP _rxode2parse_assignUdf(SEXP in); extern "C" SEXP _rxode2parse_udfEnvSet(SEXP udf); extern "C" SEXP _rxode2parse_udfReset(); +extern "C" SEXP _rxode2parse_rxC(SEXP in); extern "C" { typedef SEXP (*_rxode2parse_getForder_type)(void); @@ -6224,7 +6225,11 @@ CharacterVector rxC(RObject obj){ rets = as(e["c"]); } else if (rxIs(obj, "rxDll")){ rets = as(as(obj)["c"]); - } else if (rxIs(obj, "character")){ + } else if (rxIs(obj, "character")) { + Nullable rxCp = _rxode2parse_rxC(obj); + if (!rxCp.isNull()) { + return as(rxCp); + } Function f = getRxFn("rxCompile.character"); RObject newO = f(as(obj)); rets = rxDll(newO); diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 81738ce0d..19e5e5ed3 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -76,6 +76,15 @@ extern "C" SEXP _rxode2_codeLoaded(void) { END_RCPP } +extern "C" SEXP _rxode2parse_rxC(SEXP in) { +BEGIN_RCPP + if (TYPEOF(in) != STRSXP) return R_NilValue; + assignRxode2ParsePtrs(); + Function fun = as(rxode2parse[".rxC"]); + return wrap(fun(in)); +END_RCPP +} + extern "C" SEXP _rxode2parse_assignUdf(SEXP in) { BEGIN_RCPP if (Rf_length(in) == 0 || Rf_length(in) == 1) { From 805a20e81a1cc5e83094716ed33c090a82aefba8 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sat, 4 Nov 2023 20:19:14 -0500 Subject: [PATCH 22/27] Add to news --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index 00df41878..8b75fdd5b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,6 +13,10 @@ ## New features +- User defined functions can now be R functions. For many of these R + functions they can be converted to C with `rxFun()` (you can see the + C code afterwards with `rxC("funName")`) + - Parallel solving of models that require sorting (like modeled lag times, modeled duration etc) now solve in parallel instead of downgrading to single threaded solving From 9111fb3a9af87a66f62c3a778a7e93bfed2a4082 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sat, 4 Nov 2023 21:34:39 -0500 Subject: [PATCH 23/27] Add article for UDF --- R/symengine.R | 21 +++ ...ing-User-Defined-Functions-into-rxode2.Rmd | 159 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 vignettes/articles/Integrating-User-Defined-Functions-into-rxode2.Rmd diff --git a/R/symengine.R b/R/symengine.R index b1c315a62..9b33128b6 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -364,6 +364,27 @@ regIfOrElse <- rex::rex(or(regIf, regElse)) #' rxRmFun("gg") #' rm(gg) #' rm(f) +#' +#' +#' # You can also automatically convert a R function to R code (and +#' # calculate first derivatives) +#' +#' fun <- function(a, b, c) { +#' a^2+b*a+c +#' } +#' +#' rxFun(fun) +#' +#' # You can see the R code if you want with rxC +#' +#' message(rxC("fun")) +#' +#' # you can also remove both the function and the +#' # derivatives with rxRmFun("fun") +#' +#' rxRmFun("fun") +#' +#' #' } rxFun <- function(name, args, cCode) { if (missing(args) && missing(cCode)) { diff --git a/vignettes/articles/Integrating-User-Defined-Functions-into-rxode2.Rmd b/vignettes/articles/Integrating-User-Defined-Functions-into-rxode2.Rmd new file mode 100644 index 000000000..a4497595e --- /dev/null +++ b/vignettes/articles/Integrating-User-Defined-Functions-into-rxode2.Rmd @@ -0,0 +1,159 @@ +--- +title: "Integrating User Defined Functions into rxode2" +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +## User Defined Functions + +```{r setup} +library(rxode2) +``` + +When defining models you may have wished to write a small R function or make a function integrate into `rxode2` somehow. This article discusses 2 ways to do this: + +- A R-based user function which can be loaded as a simple function or in certain circumstances translated to C to run more efficiently + +- A C function that you define and integrate into code + +## R based user functions + +A R-based user function is the most convenient to include in the ODE, but is slower than what you could have done if it was written in `C` , `C++` or some other compiled language. This was requested [in github](https://github.com/nlmixrdevelopment/RxODE/issues/162#issue-568886732) with an appropriate example; However, I will use a very simple example here to simply illustrate the concepts. + +```{r fExample} +newAbs <- function(x) { + if (x < 0) { + -x + } else { + x + } +} +f <- rxode2({ + a <- newAbs(time) +}) + +e <- et(-10, 10, length.out=40) +``` + +Now that the ODE has been compiled the R functions will be called while solving the ODE. Since this is calling R, this forces the parallization to be turned off since R is single-threaded. It also takes more time to solve since it is shuttling back and forth between R and C. Lets see how this very simple function performs: + +```{r benmchmark1} +mb1 <- microbenchmark::microbenchmark(withoutC=suppressWarnings(rxSolve(f,e))) + +library(ggplot2) +autoplot(mb1) + rxTheme() +``` + +Not terribly bad, even though it is shuffling between R and C. + +You can make it a better by converting the functions to C: + +```{r convertC} +# Create C functions automatically with `rxFun()` +rxFun(newAbs) +# Recompile to use the C functions +# Note it would recompile anyway if you didn't do this step, +# it just makes sure that it doesn't recompile every step in +# the benchmark +f <- rxode2({ + a <- newAbs(time) +}) + +mb2 <- microbenchmark::microbenchmark(withC=rxSolve(f,e, cores=1)) + +mb <- rbind(mb1, mb2) +autoplot(mb) + rxTheme() + xgxr::xgx_scale_y_log10() +print(mb) +``` + +The C version is almost twice as fast as the R version. You may have noticed the conversion also created C versions of the first derivative. This is done automatically and gives not just C versions of function, but C versions of the derivatives and registers them with `rxode2`. This allows the C versions to work with not only `rxode2` but `nlmixr2` models. + +This function was setup in advance to allow this type of conversion. In general the derivatives will be calculated if there is not a `return()` statement in the user defined function. This means simply let R return the last value instead of explictly calling out the `return()`. Many people prefer this method of coding. + +Even if there is a `return` function, the function could be converted to `C`. In the github issue, they used a function that would not convert the derivatives: + +```{r fConvNoDer} +# Light +f_R <- function(actRad, k_0, a_k) { + photfac <- a_k * actRad + k_0 + if (photfac > 1) { + photfac = 1 + } + return(photfac) +} + +rxFun(f_R) +``` + +While this is still helpful because some functions have early returns, the `nlmixr2` models requiring derivatives would be calculated be non-optimized finite differences when this occurs. While this gets into the internals of `rxode2` and `nlmixr2` you can see this more easily when calculating the derivatives: + +```{r derExample} +rxFromSE("Derivative(f_R(actRad, k_0, a_k),k_0)") +``` + +Whereas the originally defined function `newAbs()` would use the new derivatives calculated as well: + +```{r derFromC} +rxFromSE("Derivative(newAbs(x),x)") +``` + +In some circumstances, the conversion to C is not possible, though you can still use the R function. + +There are some requirements for R functions to be integrated into the rxode2 system: + +- The function must have a set number of arguments, variable arguments like `f(…)` are currently not allowed. + +- The function is given each argument as a single number, and the function should return a single number + +If these requirements are met you can use the R function in rxode2. Additional requirements for conversion to C include: + +- Any functions that you use within the R function must be understood and available to `rxode2`. + + - Practically speaking if you have `fun2()` which refers to `fun1()`, `fun1()` must be changed to C code and available to `rxode2` before changing the function `fun2()` to C. + +- The functions can include `if`/`else` assignments or simple return statements (either by returning a value or having that value on a line by itself). Special R control structures and functions (like `for` and `lapply`) cannot be present. + +- The function cannot refer to any package functions + +- As mentioned, if the `return()` statement is present, the derivative C functions and `rxode2`'s derivative table is not updated. + +## C based functions + +You can add your own C functions directly into rxode2 as well using `rxFun()`: + +```{r rxFun} +fun <- " + double fun(double a, double b, double c) { + return a*a+b*a+c; + } +" ## C-code for function + +rxFun("fun", c("a", "b", "c"), fun) +``` + +If you wanted you could also use C functions or expressions for the derivatives by using the `rxD()` function: + +```{r rxD} +rxD("fun", list( + function(a, b, c) { # derivative of arg1: a + paste0("2*", a, "+", b) + }, + function(a, b, c) { # derivative of arg2: b + return(a) + }, + function(a, b, c) { # derivative of arg3: c + return("0.0") + } +)) +``` + +Removing the function with `rxRmFun()` will also remove the derivative table: + +```{r rxDrm} +rxRmFun("fun") +``` From dd9ce549f4abd73084b695e41dbe139e8eb0fe2a Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sat, 4 Nov 2023 22:36:00 -0500 Subject: [PATCH 24/27] ::document and use rxode2::rxReservedKeywords --- R/symengine.R | 4 ++-- data/rxReservedKeywords.rda | Bin 736 -> 733 bytes data/rxResidualError.rda | Bin 1691 -> 1694 bytes data/rxSyntaxFunctions.rda | Bin 2451 -> 2446 bytes man/reexports.Rd | 1 - man/rxFun.Rd | 21 +++++++++++++++++++++ man/rxSolve.Rd | 12 ++++++++---- man/rxode2.Rd | 14 ++++++++++++-- 8 files changed, 43 insertions(+), 9 deletions(-) diff --git a/R/symengine.R b/R/symengine.R index 9b33128b6..03c649e1e 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -3268,8 +3268,8 @@ rxSupportedFuns <- function() { x <- as.character(x) if (!exists("res", envir=envir)) { envir$res <- c(rxSupportedFuns(), - rxReservedKeywords[, 1], - strsplit(paste(rxReservedKeywords[, 3],collapse=","),"[,]+")[[1]]) + rxode2::rxReservedKeywords[, 1], + strsplit(paste(rxode2::rxReservedKeywords[, 3],collapse=","),"[,]+")[[1]]) } if (x %in% envir$funs) { return(paste0("_qf_", x)) diff --git a/data/rxReservedKeywords.rda b/data/rxReservedKeywords.rda index 9e7cff144d4614822729e63d65692d7c3df83454..80fc13cd1332ee7e68cacfe73ae72df8290d41e0 100644 GIT binary patch delta 714 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 delta 1683 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 + +\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ +}\if{html}{\out{
}} \itemize{ \item Inside a \code{rxode2("")} string statement: }\if{html}{\out{ @@ -247,6 +250,9 @@ mod <- rxode2(\{ d/dt(centr) <- F*KA*depot - CL*C2 - Q*C2 + Q*C3; ") }\if{html}{\out{
}} + +\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ +}\if{html}{\out{
}} \itemize{ \item In a file name to be loaded by rxode2: }\if{html}{\out{ @@ -325,7 +331,9 @@ compilation model. \if{html}{\out{
}}\preformatted{mod$simulationModel }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_8223e497c83db9e334c52254bd575c98 model (ready). +\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ + +## rxode2 2.0.14.9000 model named rx_4d7e23c27b311c0b8fa7436caae3124f model (ready). ## x$state: depot, center ## x$stateExtra: cp ## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp @@ -336,7 +344,9 @@ compilation model. mod$simulationIniModel }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{## rxode2 2.0.14.9000 model named rx_182c47efea379394bbab84d957305170 model (ready). +\if{html}{\out{
}}\preformatted{## using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ + +## rxode2 2.0.14.9000 model named rx_175d15ed553ae1eccaf047d565b24f55 model (ready). ## x$state: depot, center ## x$stateExtra: cp ## x$params: tka, tcl, tv, add.sd, eta.ka, eta.cl, eta.v, rxerr.cp From 580c2a88eeb61e5cd41f6b617b9c510045bed12f Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sun, 5 Nov 2023 07:51:43 -0600 Subject: [PATCH 25/27] CF fixes --- R/symengine.R | 8 ++++---- R/ui.R | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/R/symengine.R b/R/symengine.R index 03c649e1e..b15c31253 100644 --- a/R/symengine.R +++ b/R/symengine.R @@ -1392,7 +1392,7 @@ rxToSE <- function(x, envir = NULL, progress = FALSE, call. = FALSE ) } else if (length(.ret0) == length(.f)) { - if (is.environment(envir)){ + if (is.environment(envir)) { assign(.fun, .rxFunction(.fun), envir = envir) } .ret0 <- unlist(.ret0) @@ -3390,7 +3390,7 @@ rxSupportedFuns <- function() { .rxFun2cIf <- function(x, envir) { .logic <- .rxFun2c(x[[2]], envir=envir) .pre <- paste0(rep(" ", envir$n), collapse="") - .ret <- paste(.pre, "if (", .logic, ") "); + .ret <- paste(.pre, "if (", .logic, ") ") .ret <- paste0(.ret, .rxFun2c(x[[3]], envir=envir)) if (length(x) == 3) { @@ -3446,7 +3446,7 @@ rxSupportedFuns <- function() { identical(x[[1]], quote(`>=`)) || identical(x[[1]], quote(`!=`)) || identical(x[[1]], quote(`!`)) - ){ + ) { return(.rxFun2cLogic(x, envir=envir)) } else if (identical(x[[1]], quote(`*`)) || identical(x[[1]], quote(`**`)) || @@ -3595,7 +3595,7 @@ rxFun2c <- function(fun, name, onlyF=FALSE) { .s <- rxS(.body) .lastValue <- .s$rxLastValue return(c(list(.ret), - lapply(.env$args, function(v){ + lapply(.env$args, function(v) { .v <- symengine::D(.lastValue, symengine::S(v)) .v <- paste0("function(", paste(.env$args, collapse=", "), ") {\n", rxOptExpr(paste0("rxLastValue=", rxFromSE(.v)), msg=paste0("d(", .funName, ")/d(", v, ")")), "\nrxLastValue}") diff --git a/R/ui.R b/R/ui.R index 6ca4df956..a3c91cf2a 100644 --- a/R/ui.R +++ b/R/ui.R @@ -276,7 +276,7 @@ model <- function(x, ..., append=FALSE, auto=getOption("rxode2.autoVarPiping", T cov=NULL, envir=parent.frame()) { if (is(substitute(x), "{")) { .funName <- try(as.character(as.list(with(envir, match.call()))[[1]]), silent=TRUE) - if (inherits(.funName, "try-error")){ + if (inherits(.funName, "try-error")) { .funName <- NULL } else if (length(.funName) == 1L && exists(.funName, envir=parent.env(envir))) { rxode2parse::.udfEnvSet(parent.env(envir)) From ba4396495c76e7b3b11e8b317f6a3b269f19b926 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sun, 5 Nov 2023 08:00:10 -0600 Subject: [PATCH 26/27] CF fix --- src/rxode2parse.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rxode2parse.cpp b/src/rxode2parse.cpp index 19e5e5ed3..cb64e85b7 100644 --- a/src/rxode2parse.cpp +++ b/src/rxode2parse.cpp @@ -128,8 +128,8 @@ extern "C" SEXP _rxode2parse_udfReset() { fun2(); return R_NilValue; END_RCPP - } + extern "C" SEXP _rxode2_codegen(SEXP c_file, SEXP prefix, SEXP libname, SEXP pMd5, SEXP timeId, SEXP lastMv, SEXP goodFuns) { BEGIN_RCPP assignRxode2ParsePtrs(); From 7d3693970e6289f4545305836b7ced4e7280a064 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Sun, 5 Nov 2023 08:35:49 -0600 Subject: [PATCH 27/27] Add the model function m$eta that rxode2 searches for udf --- R/rxsolve.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/rxsolve.R b/R/rxsolve.R index e2582a8d4..ff76c83e3 100644 --- a/R/rxsolve.R +++ b/R/rxsolve.R @@ -1226,7 +1226,7 @@ rxSolve.function <- function(object, params = NULL, events = NULL, inits = NULL, #' @export rxSolve.rxUi <- function(object, params = NULL, events = NULL, inits = NULL, ..., theta = NULL, eta = NULL, envir=parent.frame()) { - rxode2parse::.udfEnvSet(list(envir, parent.frame(1))) + rxode2parse::.udfEnvSet(list(object$meta, envir, parent.frame(1))) if (inherits(object, "rxUi")) { object <- rxUiDecompress(object) } @@ -1764,6 +1764,7 @@ predict.function <- function(object, ...) { #' @rdname rxSolve #' @export predict.rxUi <- function(object, ...) { + rxode2parse::.udfEnvSet(list(object$meta, parent.frame(1))) rxSolve(object, ...) }