fitOdeModel {simecol} | R Documentation |
Fit parameters of odeModel
objects to measured data.
fitOdeModel(simObj, whichpar = names(parms(simObj)), obstime, yobs, sd.yobs = as.numeric(lapply(yobs, sd)), initialize = TRUE, debuglevel = 0, fn = ssqOdeModel, method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN", "PORT"), lower = -Inf, upper = Inf, scale.par = 1, control = list(), ...)
simObj |
a valid object of class odeModel , |
whichpar |
character vector with names of parameters which are to
be optimized (subset of parameter names of the simObj ), |
obstime |
vector with time steps for which observational data are available, |
yobs |
data frame with observational data for all or a subset of
state variables. Their names must correspond exacly with existing
names of state variables in the odeModel , |
sd.yobs |
vector of given standard deviations (or scale) for all
observational variables given in yobs . If no standard
deviations (resp. scales) are given, these are estimated from
yobs , |
initialize |
optional boolean value whether the simObj should be re-initialized after the assignment of new parameter values. This can be necessary in certain models to assign consistent values to initial state variables if they depend on parameters. |
debuglevel |
a positive number that specifies the amount of debugging information printed, |
fn |
objective function, i.e. function that returns the quality
criterium that is minimized, defaults to ssqOdeModel , |
method |
optimization method, see nlminb for
the PORT algorithm and optim for all other
methods, |
lower, upper |
bounds of the parameters for method L-BFGS-B, see
optim and for method PORT see nlminb .
The bounds are also respected by other optimizers
by means of an internal transformation of the parameter space (see
p.constrain ). In this case, named vectors are required. |
scale.par |
scaling of parameters for method PORT see
nlminb . In many cases, automatic scaling
(scale.par = 1 ) does well, but sometimes (e.g. if parameter
ranges differ several orders of magnitude) manual adjustment is
required. Often you get a reasonable choice if you set
scale.par = 1/upper . The parameter is ignored by all other
methods. For "Nelder-Mead" , "BFGS" , "CG" and
"SANN" parameter scaling occurs as a side effect of parameter
transformation with p.constrain . |
control |
a list of control parameters for
optim resp. nlminb , |
... |
additional parameters passed to the solver method
(e.g. to lsoda ). |
This function works currently only with odeModel
objects where
parms
is a vector, not a list.
Note also that the control parameters of the PORT algorithm are different from the control parameters of the other optimizers.
A list with the optimized parameters and other information, see
optim
resp. nlminb
for
details.
The interface to the PORT algorithm will change for future R versions.
Gay, D. M. (1990) Usage Summary for Selected Optimization Routines. Computing Science Technical Report No. 153. AT&T Bell Laboratories, Murray Hill, NJ. http://netlib.bell-labs.com/cm/cs/cstr/153.pdf
library(simecol) ## ======== load example model ========= data(chemostat) #source("chemostat.R") ## derive scenarios cs1 <- cs2 <- chemostat ## generate some noisy data parms(cs1)[c("vm", "km")] <- c(2, 10) times(cs1) <- c(from=0, to=20, by=2) yobs <- out(sim(cs1)) obstime <- yobs$time yobs$time <- NULL yobs$S <- yobs$S + rnorm(yobs$S, sd= 0.1 * sd(yobs$S))*2 yobs$X <- yobs$X + rnorm(yobs$X, sd= 0.1 * sd(yobs$X)) ## ======== optimize it! ========= ## time steps for simulation, either small for rk4 fixed step # times(cs2)["by"] <- 0.1 # solver(cs2) <- "rk4" ## or, faster: use lsoda and and return only required steps that are in the data times(cs2) <- obstime solver(cs2) <- "lsoda" ## Nelder-Mead (default) whichpar <- c("vm", "km") res <- fitOdeModel(cs2, whichpar=whichpar, obstime, yobs, debuglevel=0, control=list(trace=TRUE)) res$par ## assign fitted parameters to the model, i.e. as start values for next step parms(cs2)[whichpar] <- res$par ## alternatively, L-BFGS-B (allows lower and upper bounds for parameters) res <- fitOdeModel(cs2, whichpar=c("vm", "km"), obstime, yobs, debuglevel=0, fn = ssqOdeModel, method = "L-BFGS-B", lower = 0, control=list(trace=TRUE), atol=1e-4, rtol=1e-4) res$par ## alternative 2, transform parameters to constrain unconstrained method ## Note: lower and upper are *named* vectors res <- fitOdeModel(cs2, whichpar=c("vm", "km"), obstime, yobs, debuglevel=0, fn = ssqOdeModel, method = "BFGS", lower = c(vm=0, km=0), upper=c(vm=4, km=20), control=list(trace=TRUE), atol=1e-4, rtol=1e-4) res$par ## alternative 3a, use PORT algorithm ## Note: lower and upper are *named* vectors parms(cs2)[whichpar] <- c(vm=1, km=2) lower <- c(vm=0, km=0) upper <- c(vm=4, km=20) res <- fitOdeModel(cs2, whichpar=c("vm", "km"), obstime, yobs, debuglevel=0, fn = ssqOdeModel, method = "PORT", lower = lower, upper = upper, control=list(trace=TRUE), atol=1e-4, rtol=1e-4) res$par ## alternative 3b, PORT algorithm with manual parameter scaling ## Note: lower and upper are *named* vectors res <- fitOdeModel(cs2, whichpar=c("vm", "km"), obstime, yobs, debuglevel=0, fn = ssqOdeModel, method = "PORT", lower = lower, upper = upper, scale.par = 1/upper, control=list(trace=TRUE), atol=1e-4, rtol=1e-4) res$par ## set model parameters to fitted values and simulate again parms(cs2)[whichpar] <- res$par times(cs2) <- c(from=0, to=20, by=1) ysim <- out(sim(cs2)) ## plot results par(mfrow=c(2,1)) plot(obstime, yobs$X, ylim = range(yobs$X, ysim$X)) lines(ysim$time, ysim$X, col="red") plot(obstime, yobs$S, ylim= range(yobs$S, ysim$S)) lines(ysim$time, ysim$S, col="red")