Nothing
### ============================================================================
### Check events data set
### Changes version 1.11: event can be an R-function, even if DLL model
### continueeroot: to continue even if a root is found
### ============================================================================
checkevents <- function (events, times, vars, dllname, root = FALSE) {
if (is.null(events)) return(list())
if (is.null(events$data) && is.null(events$func) &&
is.null(events$terminalroot)) return(list())
funevent <- events$func
if (root) { # check if root should trigger an event...
Root <- events$root
if (is.null(Root)) Root <- 0
Root <- as.integer(Root)
} else Root <- 0L
maxroot <- events$maxroot
if (is.null(maxroot)) maxroot <- 100 # number of roots to save.
if (maxroot < 0)
stop("events$maxroot should be > 0 in events")
Terminalroot <- events$terminalroot
if (! is.null(Terminalroot) && is.null(funevent))
funevent <- function(t,y,p) return(y) # dummy event function
if (is.null(Terminalroot))
Terminalroot <- 0 # at which roots simulation should continue
## ----------------------
## event in a function
## ----------------------
if (!is.null(funevent)) {
if (inherits (funevent, "CFunc")) {
funevent <- body(funevent)[[2]]
Type <- 3
} else if (is.character(funevent)){
if (is.null(dllname))
stop("'dllname' should be given if 'events$func' is a string")
if (is.loaded(funevent, PACKAGE = dllname, type = "") ||
is.loaded(funevent, PACKAGE = dllname, type = "Fortran")) {
funevent <- getNativeSymbolInfo(funevent, PACKAGE = dllname)$address
} else
stop(paste("'events$func' should be loaded ",funevent))
Type <- 3
} else {
Type <- 2 # SHOULD ALSO CHECK THE FUNCTION if R-function....
# if (!is.null(dllname)) KARLINE: removed that 02/07/2011
# stop("'events$func' should be a string, events specified in compiled code if 'dllname' is not NULL")
}
if (Root == 0) {
if (is.null(events$time))
stop("either 'events$time' should be given and contain the times of the events, if 'events$func' is specified and no root function or your solver does not support root functions")
eventtime <- sort(as.double(events$time)) # Karline: sorted that 4-01-2016
if (any(!(eventtime %in% times))) {
warning("Not all event times 'events$time' are in output 'times' so they are automatically included.")
uniqueTimes <- cleanEventTimes(times, eventtime)
if (length(uniqueTimes) < length(times))
warning("Some time steps were very close to events - only the event times are used in these cases.")
times <- sort(c(uniqueTimes, eventtime))
}
} else eventtime <- min(times) - 1 # never reached....
return (list (Time = eventtime, SVar = NULL, Value = NULL,
Method = NULL, Type = as.integer(Type), func = funevent,
Rootsave = as.integer(maxroot), Root = Root,
Terminalroot = as.integer(Terminalroot), newTimes = times)) # added newTimes - Karline 4-01-2016
}
## ----------------------
## event as a data series
## ----------------------
eventdata <- events$data
if (is.matrix(eventdata)) eventdata <- as.data.frame(eventdata)
if (ncol(eventdata) < 3)
stop("'event' should have at least 3 columns: state variable, time, value")
if (!is.data.frame(eventdata))
stop("'event' should be a data.frame with 3(4) columns: state variable, time, value, (method)")
## this should make check < 3 columns obsolete
evtcols <- c("var", "time", "value", "method")
if (!all(evtcols %in% names(eventdata)))
stop("structure of events does not match specification, see help('events')")
## make sure that event data frame has correct order
eventdata <- eventdata[evtcols]
## variables, 1st column should be present
if (is.factor(eventdata[,1]))
eventdata[,1] <- as.character(eventdata[,1])
if (is.character(eventdata[,1])) {
vv <- match(eventdata[,1], vars)
if (is.character(eventdata[,1])) {
vv <- match(eventdata[,1],vars)
if (any(is.na(vv)))
stop("unknown state variable in 'event': ", paste(eventdata[,1][which(is.na(vv))], ","))
eventdata[,1] <- vv
} else if (max(eventdata[,1]) > length(vars))
stop("unknown state variable in 'event': ", paste(eventdata[,1][which(is.na(vv))],","))
eventdata[,1] <- vv
} else if (max(eventdata[,1])>length(vars))
stop("too many state variables in 'event'; should be < ", paste(length(vars)))
## 2nd and 3rd columns should be numeric
if (!is.numeric(eventdata[,2]))
stop("times in 'event', 2nd column should be numeric")
if (!is.numeric(eventdata[,3]))
stop("values in 'event', 3rd column should be numeric")
## Times in 'event' should be embraced by 'times'
rt <- range(times)
ii <- c(which(eventdata[,2] < rt[1]), which(eventdata[,2] > rt[2]))
if (length(ii) > 0)
eventdata <- eventdata [-ii,]
if (any(!(eventdata[,2] %in% times))) {
warning("Not all event times 'events$times' were in output 'times' so they are automatically included.")
uniqueTimes <- cleanEventTimes(times, eventdata[,2])
if (length(uniqueTimes) < length(times))
warning("Some time steps were very close to events - only the event times are used in these cases.")
times <- sort(c(uniqueTimes, eventdata[,2]))
}
if (any(!(eventdata[,2] %in% times))) {
warning("Not all event times 'events$times' where in output 'times' so they are automatically included.")
uniqueTimes <- cleanEventTimes(times, eventdata[,2])
if (length(uniqueTimes) < length(times))
warning("Some time steps were very close to events - only the event times are used in these cases.")
times <- sort(c(uniqueTimes, eventdata[,2]))
}
## check if times are ordered and if not, fix it
if (any(diff(eventdata[,2]) < 0)) {
warning("Time of events ('time' column of 'events') was not ordered.")
ord <- order(eventdata[,2])
eventdata <- eventdata[ord,]
}
## 4th column: method; if not available: "replace" = method 1 - to date: 3 methods
if (ncol(eventdata) ==3)
eventdata$method <- rep(1,nrow(eventdata))
else if (is.numeric(eventdata[,4])) {
if (max(eventdata[,4]) > 3 | min(eventdata[,4]) < 1)
stop("unknown method in 'event': should be >0 and < 4")
} else {
vv <- charmatch(eventdata[,4],c("replace","add","multiply"))
if (any(is.na(vv)))
stop("unknown method in 'event': ", paste(eventdata[,3][which(is.na(vv))],","),
" should be one of 'replace', 'add', 'multiply'")
eventdata$method <- vv
}
## Check the other events elements (see optim code)
con <- list(ties = "notordered", time = NULL, data = NULL, func = NULL, root = NULL)
nmsC <- names(con)
con[(namc <- names(events))] <- events
if (length(noNms <- namc[!namc %in% nmsC]) > 0)
warning("unknown names in events: ", paste(noNms, collapse = ", "))
## Check what needs to be done in case the time series is not "ordered"
if (!identical(con$ties, "ordered")) { # see approx code
## first order with respect to time (2nd col), then to variable (1st col)
if(length(x <- unique(eventdata[,1:2])) < nrow(eventdata)){
ties <- mean
if (missing(ties))
warning("collapsing to unique 'x' values")
eventdata <- aggregate(eventdata[,c(3, 4)], eventdata[,c(1, 2)], ties)
ties <- mean
if (missing(ties))
warning("collapsing to unique 'x' values")
eventdata <- aggregate(eventdata[,c(3,4)], eventdata[,c(1,2)], ties)
}
}
return (list (Time = as.double(eventdata[,2]), SVar = as.integer(eventdata[,1]),
Value = as.double(eventdata[,3]), Method = as.integer(eventdata[,4]),
Rootsave = as.integer(maxroot),
Type = 1L, Root = Root,
Terminalroot = as.integer(Terminalroot),
newTimes = times))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.