diff options
-rw-r--r-- | NEWS.md | 6 | ||||
-rw-r--r-- | R/mkinmod.R | 34 | ||||
-rw-r--r-- | man/mkinmod.Rd | 13 |
3 files changed, 39 insertions, 14 deletions
@@ -3,7 +3,11 @@ ## MINOR CHANGES - `vignettes/compiled_models.html`: Show the performance improvement factor actually obtained when building the vignette, as well as mkin version, some system info and the CPU model used for building the vignette. -- `GNUMakefile`,`vignettes/*`: Clean up vignette generation and include table of contents in HTML vignettes +- `GNUMakefile`,`vignettes/*`: Clean up vignette generation and include table of contents in HTML vignettes. + +## BUG FIXES + +- `mkinmod.R()`: When generating the C code for the derivatives, only declare the time variable when it is needed and remove the '-W-no-unused-variable' compiler flag as the C compiler used in the CRAN checks on Solaris does not know it. # CHANGES in mkin VERSION 0.9-36 diff --git a/R/mkinmod.R b/R/mkinmod.R index 72c4652a..27716899 100644 --- a/R/mkinmod.R +++ b/R/mkinmod.R @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/> }}}
-mkinmod <- function(..., use_of_ff = "min", speclist = NULL, quiet = FALSE)
+mkinmod <- function(..., use_of_ff = "min", speclist = NULL, quiet = FALSE, verbose = FALSE)
{
if (is.null(speclist)) spec <- list(...)
else spec <- speclist
@@ -273,11 +273,12 @@ mkinmod <- function(..., use_of_ff = "min", speclist = NULL, quiet = FALSE) model$coefmat <- m
}#}}}
- # Create a function compiled from C code if more than one observed {{{
+ # Try to create a function compiled from C code if more than one observed {{{
# variable and gcc is available
if (length(obs_vars) > 1) {
if (Sys.which("gcc") != "") {
+ # Translate the R code for the derivatives to C code
diffs.C <- paste(diffs, collapse = ";\n")
diffs.C <- paste0(diffs.C, ";")
@@ -313,10 +314,18 @@ mkinmod <- function(..., use_of_ff = "min", speclist = NULL, quiet = FALSE) diffs.C <- gsub(pattern, replacement, diffs.C)
}
- if (!quiet) message("Compiling differential equation model from auto-generated C code...")
+ derivs_sig <- signature(n = "integer", t = "numeric", y = "numeric",
+ f = "numeric", rpar = "numeric", ipar = "integer")
+
+ # Declare the time variable in the body of the function if it is used
+ derivs_code <- if (spec[[1]]$type %in% c("FOMC", "DFOP", "HS")) {
+ paste0("double time = *t;\n", diffs.C)
+ } else {
+ diffs.C
+ }
+ # Define the function initializing the parameters
npar <- length(parms)
-
initpar_code <- paste0(
"static double parms [", npar, "];\n",
paste0("#define ", parms, " parms[", 0:(npar - 1), "]\n", collapse = ""),
@@ -326,14 +335,17 @@ mkinmod <- function(..., use_of_ff = "min", speclist = NULL, quiet = FALSE) " odeparms(&N, parms);\n",
"}\n\n")
- derivs_code <- paste0("double time = *t;\n", diffs.C)
- derivs_sig <- signature(n = "integer", t = "numeric", y = "numeric",
- f = "numeric", rpar = "numeric", ipar = "integer")
+ # Try to build a shared library
+ cf <- try(cfunction(list(func = derivs_sig), derivs_code,
+ otherdefs = initpar_code,
+ verbose = verbose,
+ convention = ".C", language = "C"),
+ silent = TRUE)
- model$cf <- cfunction(list(func = derivs_sig), derivs_code,
- otherdefs = initpar_code,
- cppargs = "-Wno-unused-variable",
- convention = ".C", language = "C")
+ if (!inherits(cf, "try-error")) {
+ if (!quiet) message("Successfully compiled differential equation model from auto-generated C code.")
+ model$cf <- cf
+ }
}
}
# }}}
diff --git a/man/mkinmod.Rd b/man/mkinmod.Rd index f6a8fe5d..35372919 100644 --- a/man/mkinmod.Rd +++ b/man/mkinmod.Rd @@ -13,7 +13,7 @@ in the FOCUS and NAFTA guidance documents are used.
}
\usage{
-mkinmod(..., use_of_ff = "min", speclist = NULL, quiet = FALSE)
+mkinmod(..., use_of_ff = "min", speclist = NULL, quiet = FALSE, verbose = FALSE)
}
\arguments{
\item{...}{
@@ -45,6 +45,10 @@ mkinmod(..., use_of_ff = "min", speclist = NULL, quiet = FALSE) \item{quiet}{
Should messages be suppressed?
}
+ \item{verbose}{
+ If \code{TRUE}, passed to \code{\link{cfunction}} if applicable to give
+ detailed information about the C function being built.
+ }
}
\value{
A list of class \code{mkinmod} for use with \code{\link{mkinfit}}, containing
@@ -80,7 +84,7 @@ mkinmod(..., use_of_ff = "min", speclist = NULL, quiet = FALSE) # Specify the SFO model (this is not needed any more, as we can now mkinfit("SFO", ...)
SFO <- mkinmod(parent = list(type = "SFO"))
-# One parent compound, one metabolite, both single first order.
+# One parent compound, one metabolite, both single first order
SFO_SFO <- mkinmod(
parent = mkinsub("SFO", "m1"),
m1 = mkinsub("SFO"))
@@ -90,6 +94,11 @@ SFO_SFO <- mkinmod( parent = list(type = "SFO", to = "m1"),
m1 = list(type = "SFO"))
+# Show details of creating the C function
+SFO_SFO <- mkinmod(
+ parent = mkinsub("SFO", "m1"),
+ m1 = mkinsub("SFO"), verbose = TRUE)
+
# If we have several parallel metabolites
# (compare tests/testthat/test_synthetic_data_for_UBA_2014.R)
m_synth_DFOP_par <- mkinmod(parent = mkinsub("DFOP", c("M1", "M2")),
|