[英]Is there a way to force ode() [deSolve-R package] to provide output at each integration step in the ode function
I would like to extract the value of the state variable at each step of the numerical scheme.我想在数值方案的每个步骤中提取状态变量的值。
The ode() function in the deSolve R package, uses one of the implemented ODE solvers to numerically solve a system of ordinary differential equations. deSolve R 包中的 ode() 函数使用已实现的 ODE 求解器之一对常微分方程组进行数值求解。 To do this it uses a dynamically adjusted integration step based on the value of the Local Truncation Error at the end of each integration.为此,它根据每次积分结束时的局部截断误差值使用动态调整的积分步骤。 The user basically specifies the desired output times which define the timestep grid, that can have a step equal or smaller to the output times.用户基本上指定了定义时间步长网格的所需输出时间,其步长可以等于或小于输出时间。
If we take the Lotka Volterra Predator-Prey model (with logistic prey) as an example:如果我们以 Lotka Volterra Predator-Prey 模型(带有逻辑猎物)为例:
LVmod <- function(Time, State, Pars) {
with(as.list(c(State, Pars)), {
Ingestion <- rIng * Prey * Predator
GrowthPrey <- rGrow * Prey * (1 - Prey/K)
MortPredator <- rMort * Predator
dPrey <- GrowthPrey - Ingestion
dPredator <- Ingestion * assEff - MortPredator
return(list(c(dPrey, dPredator)))
})
}
with the parameters and state variable defined as:参数和状态变量定义为:
pars <- c(rIng = 0.2, # /day, rate of ingestion
rGrow = 1.0, # /day, growth rate of prey
rMort = 0.2 , # /day, mortality rate of predator
assEff = 0.5, # -, assimilation efficiency
K = 10) # mmol/m3, carrying capacity
yini <- c(Prey = 1, Predator = 2)
and output requested at a daily timestep:并在每天的时间步请求输出:
times <- seq(0, 200, by = 1)
out <- ode(yini, times, LVmod, pars)
diagnostics(out)
Looking at the diagnostics we can see that the solver used 282 steps in total while the output is generated for 200 steps (as set in the times object).查看诊断,我们可以看到求解器总共使用了 282 步,而生成的输出是 200 步(如时间对象中设置的那样)。
This difference is a lot bigger for the model that I am running and to do a complete analysis of the stability of my system I need the output at each integration step together with the size of the step.对于我正在运行的模型,这种差异要大得多,为了对系统的稳定性进行完整分析,我需要每个集成步骤的输出以及步骤的大小。 Is there a way to extract this info from ode?有没有办法从 ode 中提取此信息?
So, after a bit of research [1,2]:因此,经过一些研究 [1,2]:
There are two explicit methods that do not adapt the time step: the euler method and the rk4 method.有两种不适应时间步长的显式方法:欧拉方法和rk4方法。 They are implemented in two ways:它们以两种方式实现:
Applied to the LV example, the next two statements both trigger the Euler method, the first using the “special” code with a time step = 1, as imposed by the times argument, the second using the generalized method with a time step set by hini.应用于 LV 示例,接下来的两个语句都触发 Euler 方法,第一个使用时间步长 = 1 的“特殊”代码,如时间参数所强加的,第二个使用时间步长设置为的广义方法希尼。
out.euler <- euler(y = state, times = times, func = LVmod, parms = parameters)
out.rk <- ode(y = state, times = times, func = LVmod, parms = parameters,
method = "euler", hini = 0.01)
In this very simple system using the explicit Euler scheme might make sense, however for more complex systems the rk4 would be advisable even though it is still an explicit scheme.在这个非常简单的系统中,使用显式 Euler 方案可能是有意义的,但是对于更复杂的系统,建议使用 rk4,即使它仍然是一个显式方案。
To conclude:总结:
[1] Soetaert, KER, Petzoldt, T., & Setzer, RW (2010). [1] Soetaert, KER, Petzoldt, T., & Setzer, RW (2010)。 Solving differential equations in R: package deSolve.在 R 中求解微分方程:包 deSolve。 Journal of Statistical Software, 33.统计软件杂志,33。
[2] Soetaert, K., Petzoldt, T., & Setzer, RW (2010). [2] Soetaert, K.、Petzoldt, T. 和 Setzer, RW (2010)。 Package deSolve: solving initial value differential equations in R. J Stat Softw, 33(9), 1-25.包 deSolve:在 R. J Stat Softw, 33(9), 1-25 中求解初值微分方程。
It is possible to watch how the integrator works by putting a print or cat in the model function:可以通过在模型函数中放置 print 或 cat 来观察积分器的工作方式:
library("deSolve")
LVmod <- function(Time, State, Pars) {
with(as.list(c(State, Pars)), {
Ingestion <- rIng * Prey * Predator
GrowthPrey <- rGrow * Prey * (1 - Prey/K)
MortPredator <- rMort * Predator
dPrey <- GrowthPrey - Ingestion
dPredator <- Ingestion * assEff - MortPredator
cat("Time=", Time, "dPrey"=dPrey, "dPredator=", dPredator, "\n")
return(list(c(dPrey, dPredator)))
})
}
This works with both, automatic and fixed step solvers.这适用于自动和固定步长求解器。 Please note however, that automatic steppers may sometimes discard steps and try it again, so time is not always monotonous.但是请注意,自动步进器有时可能会放弃步骤并重试,因此时间并不总是单调的。 If you want to save the data for later use, save the data to a list with <<-, ideally by constructing a closure around the simulation.如果您想保存数据以备后用,请将数据保存到带有 <<- 的列表中,理想情况下通过围绕模拟构建一个闭包。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.