Nothing
### ============================================================================
### zvode -- solves ordinary differential equation systems
###
### This is vode for complex numbers
### ============================================================================
zvode <- function(y, times, func, parms, rtol=1e-6, atol=1e-6,
jacfunc=NULL, jactype = "fullint", mf = NULL, verbose=FALSE,
tcrit = NULL, hmin=0, hmax=NULL, hini=0, ynames=TRUE, maxord=NULL,
bandup=NULL, banddown=NULL, maxsteps=5000, dllname=NULL,
initfunc=dllname, initpar=parms, rpar=NULL, ipar=NULL,
nout=0, outnames=NULL, forcings=NULL, initforc = NULL,
fcontrol=NULL, ...) {
### check input
n <- length(y)
if (! is.null(times) && !is.numeric(times))
stop("`times' must be NULL or numeric")
if (!is.function(func) && !is.character(func))
stop("`func' must be a function or character vector")
if (is.character(func) && (is.null(dllname) || !is.character(dllname)))
stop("specify the name of the dll or shared library where func can be found (without extension)")
if (!is.numeric(rtol)) stop("`rtol' must be numeric")
if (!is.numeric(atol)) stop("`atol' must be numeric")
if (!is.null(tcrit) & !is.numeric(tcrit)) stop("`tcrit' must be numeric")
if (!is.null(jacfunc) && !(is.function(jacfunc) || is.character(jacfunc)))
stop(paste(jacfunc," must be a function or character vector"))
if (length(atol) > 1 && length(atol) != n)
stop("`atol' must either be a scalar, or as long as `y'")
if (length(rtol) > 1 && length(rtol) != n)
stop("`rtol' must either be a scalar, or as long as `y'")
if (!is.numeric(hmin)) stop("`hmin' must be numeric")
if (hmin < 0) stop("`hmin' must be a non-negative value")
if (is.null(hmax))
hmax <- if (is.null(times)) 0 else max(abs(diff(times)))
if (!is.numeric(hmax)) stop("`hmax' must be numeric")
if (hmax < 0) stop("`hmax' must be a non-negative value")
if (hmax == Inf) hmax <- 0
if (!is.null(hini))
if(hini < 0) stop("`hini' must be a non-negative value")
if (!is.null(maxord))
if (maxord < 1)
stop("`maxord' must be >1")
### Jacobian, method flag
if (is.null(mf)) {
if (jactype == "fullint" )
imp <- 22 # full, calculated internally
else if (jactype == "fullusr" )
imp <- 21 # full, specified by user function
else if (jactype == "bandusr" )
imp <- 24 # banded, specified by user function
else if (jactype == "bandint" )
imp <- 25 # banded, calculated internally
else
stop("'jactype' must be one of 'fullint', 'fullusr', 'bandusr' or 'bandint' if 'mf' not specified")
} else imp <- mf
if (! imp %in% c(10:17, 20:27, -11,-12,-14,-15,-21, -22, -24: -27))
stop ("method flag 'mf' not allowed")
# check other specifications depending on Jacobian
miter <- abs(imp)%%10
if (miter %in% c(1,4) & is.null(jacfunc))
stop ("'jacfunc' NOT specified; either specify 'jacfunc' or change 'jactype' or 'mf'")
meth <- abs(imp)%/%10 # basic linear multistep method
jsv <- sign(imp)
if (is.null (maxord))
maxord <- ifelse(meth==1,12,5)
if (meth==1 && maxord > 12)
stop ("'maxord' too large: should be <= 12")
if (meth==2 && maxord > 5 )
stop ("'maxord' too large: should be <= 5")
if (miter %in% c(4,5) && is.null(bandup))
stop("'bandup' must be specified if banded Jacobian")
if (miter %in% c(4,5) && is.null(banddown))
stop("'banddown' must be specified if banded Jacobian")
if (is.null(banddown)) banddown <-1
if (is.null(bandup )) bandup <-1
### model and Jacobian function
Func <- NULL
JacFunc <- NULL
## if (miter == 4) Jacobian should have banddown empty rows-vode only!
if (miter == 4 && banddown>0)
erow<-matrix(data=0, ncol=n, nrow=banddown) else erow<-NULL
Ynames <- attr(y,"names")
flist<-list(fmat=0,tmat=0,imat=0,ModelForc=NULL)
ModelInit <- NULL
if (is.character(func) | inherits(func, "CFunc")) { # function specified in a DLL or inline compiled
DLL <- checkDLL(func,jacfunc,dllname,
initfunc,verbose,nout, outnames)
ModelInit <- DLL$ModelInit
Func <- DLL$Func
JacFunc <- DLL$JacFunc
Nglobal <- DLL$Nglobal
Nmtot <- DLL$Nmtot
if (! is.null(forcings))
flist <- checkforcings(forcings,times,dllname,initforc,verbose,fcontrol)
rho <- NULL
if (is.null(ipar)) ipar<-0
if (is.null(rpar)) rpar<-0
if (!is.null(jacfunc)) {
# if (miter == 4) Jacobian should have empty banddown empty rows
# This is so for vode only; other solvers do not need this
# As this is not compatible with other solvers, this option has been
# toggled off (otherwise DLL function might crash)
if (miter == 4&& banddown>0)
stop("The combination of user-supplied banded Jacobian in a dll is NOT allowed")
}
} else {
if(is.null(initfunc))
initpar <- NULL # parameter initialisation not needed if function is not a DLL
rho <- environment(func)
# func and jac are overruled, either including ynames, or not
# This allows to pass the "..." arguments and the parameters
if(ynames) {
Func <- function(time,state) {
attr(state,"names") <- Ynames
func (time,state,parms,...)[1]
}
Func2 <- function(time,state){
attr(state,"names") <- Ynames
func (time,state,parms,...)
}
JacFunc <- function(time,state){
attr(state,"names") <- Ynames
rbind(jacfunc(time,state,parms,...),erow)
}
} else { # no ynames...
Func <- function(time,state)
func (time,state,parms,...)[1]
Func2 <- function(time,state)
func (time,state,parms,...)
JacFunc <- function(time,state)
rbind(jacfunc(time,state,parms,...),erow)
}
## Check function and return the number of output variables +name
FF <- checkFuncComplex(Func2,times,y,rho)
Nglobal<-FF$Nglobal
Nmtot <- FF$Nmtot
if (miter %in% c(1,4)) {
tmp <- eval(JacFunc(times[1], y), rho)
if (!is.matrix(tmp))
stop("Jacobian function must return a matrix\n")
dd <- dim(tmp)
if((miter ==4 && any(dd != c(bandup+banddown+banddown+1,n))) ||
(miter ==1 && any(dd != c(n,n))))
stop("Jacobian dimension not ok")
}
}
### work arrays iwork, rwork
# length of rwork, zwork and iwork
lzw <- n*(maxord+1)+2*n
if(miter %in% c(1,2) && imp>0)
lzw <- lzw + 2*n*n+2
if(miter %in% c(1,2) && imp<0)
lzw <- lzw + n*n
if(miter ==3)
lzw <- lzw + n
if(miter %in% c(4,5) && imp>0)
lzw <- lzw + (3*banddown+2*bandup+2)*n
if(miter %in% c(4,5) && imp<0)
lzw <- lzw + (2*banddown+bandup+1)*n
lrw <- 20 +n
liw <- ifelse(miter %in% c(0,3),30,30+n)
# only first 20 or 30 elements passed; other will be allocated in C-code
iwork <- vector("integer",30)
rwork <- vector("double",20)
rwork[] <- 0.
iwork[] <- 0
iwork[1] <- banddown
iwork[2] <- bandup
iwork[5] <- maxord
iwork[6] <- maxsteps
if(! is.null(tcrit)) rwork[1] <- tcrit
rwork[5] <- hini
rwork[6] <- hmax
rwork[7] <- hmin
### the task to be performed.
if (! is.null(times))
itask <- ifelse (is.null (tcrit), 1,4) else # times specified
itask <- ifelse (is.null (tcrit), 2,5) # only one step
if(is.null(times)) times<-c(0,1e8)
### print to screen...
if (verbose) {
printtask(itask,func,jacfunc)
printM("\n--------------------")
printM("Integration method")
printM("--------------------")
df <- c("method flag, =",
"jsv =",
"meth =",
"miter =")
vals <- c(imp, jsv, meth, miter)
txt <- "; (note: mf = jsv * (10 * meth + miter))"
if (jsv==1) txt<-c(txt,
"; a copy of the Jacobian is saved for reuse in the corrector iteration algorithm" ) else
if (jsv==-1)txt<-c(txt,
"; a copy of the Jacobian is not saved")
if (meth==1)txt<-c(txt,
"; the basic linear multistep method: the implicit Adams method") else
if (meth==2)txt<-c(txt,"; the basic linear multistep method:
based on backward differentiation formulas")
if (miter==0)txt<-c(txt,
"; functional iteration (no Jacobian matrix is involved") else
if (miter==1)txt<-c(txt,
"; chord iteration with a user-supplied full (NEQ by NEQ) Jacobian") else
if (miter==2)txt<-c(txt,
"; chord iteration with an internally generated full Jacobian,
(NEQ extra calls to F per df/dy value)") else
if (miter==3)txt<-c(txt,
"; chord iteration with an internally generated diagonal Jacobian
(1 extra call to F per df/dy evaluation)") else
if (miter==4)txt<-c(txt,
"; chord iteration with a user-supplied banded Jacobian") else
if (miter==5)txt<-c(txt,
"; chord iteration with an internally generated banded Jacobian
(using ML+MU+1 extra calls to F per df/dy evaluation)")
printmessage(df, vals, txt)
}
### calling solver
storage.mode(y) <- "complex"
storage.mode(times) <- "double"
on.exit(.C("unlock_solver"))
out <- .Call("call_zvode", y, times, Func, initpar, rtol, atol,
rho, tcrit, JacFunc, ModelInit, as.integer(itask),
as.double(rwork),as.integer(iwork), as.integer(imp),as.integer(Nglobal),
as.integer(lzw),as.integer(lrw),as.integer(liw), as.complex (rpar),
as.integer(ipar),flist,PACKAGE = "deSolve")
### saving results
nR <- ncol(out)
out [1,] <- as.complex(times[1:nR]) # times not set here...
out <- saveOut(out, y, n, Nglobal, Nmtot, func, Func2,
iin=c(1,12:23), iout=1:13)
attr(out, "type") <- "cvode"
if (verbose) diagnostics(out)
out
}
checkFuncComplex<- function (Func2, times, y, rho) {
## Call func once to figure out whether and how many "global"
## results it wants to return and some other safety checks
if (! is.complex(y))
stop("'y' should be complex, not real")
tmp <- eval(Func2(times[1], y), rho)
if (!is.list(tmp))
stop("Model function must return a list\n")
if (length(tmp[[1]]) != length(y))
stop(paste("The number of derivatives returned by func() (",
length(tmp[[1]]),
") must equal the length of the initial conditions vector (",
length(y),")",sep=""))
if (! is.complex(tmp[[1]]))
stop("derivatives (first element returned by 'func') should be complex, not real")
# use "unlist" here because some output variables are vectors/arrays
Nglobal <- if (length(tmp) > 1)
length(unlist(tmp[-1])) else 0
Nmtot <- attr(unlist(tmp[-1]),"names")
return(list(Nglobal = Nglobal, Nmtot=Nmtot))
}
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.