R 将一组常微分方程应用于每个网格单元
我正在开发一个基于代理的模型,以模拟由栖息地多边形(或连接的细胞束)组成的异质景观中传染病的传播。为了简化模型,我考虑了一个包含每个单元的多边形ID的生境网格(或栅格)。此外,我还有与每个多边形ID关联的参数。在每个时间步,多边形中的参数值都会发生变化。因此,数据帧R 将一组常微分方程应用于每个网格单元,r,ode,differential-equations,R,Ode,Differential Equations,我正在开发一个基于代理的模型,以模拟由栖息地多边形(或连接的细胞束)组成的异质景观中传染病的传播。为了简化模型,我考虑了一个包含每个单元的多边形ID的生境网格(或栅格)。此外,我还有与每个多边形ID关联的参数。在每个时间步,多边形中的参数值都会发生变化。因此,数据帧横向(见下文)在每个时间步更新。以下是t=0时的示例: landscape <- data.frame(polygon_ID = seq(1, 10, by = 1), beta
横向
(见下文)在每个时间步更新。以下是t=0时的示例:
landscape <- data.frame(polygon_ID = seq(1, 10, by = 1),
beta = sample(c(100, 200, 400, 600), 10, replace = TRUE),
gamma = sample(c(25, 26, 27, 28), 10, replace = TRUE))
像这样的
# Library *not* require
library(deSolve)
# Parameters: number of polygons, beta, & gamma
n.polys <- 10
beta <- sample(c(100, 200, 400, 600), n.polys, replace = TRUE)
gamma <- sample(c(25, 26, 27, 28), n.polys, replace = TRUE)
# Model defintion
sir_model <- function (t, Y, pars) {
# Break up state variable into parts
S <- Y[1:n.polys]
I <- Y[(n.polys+1):(2 * n.polys)]
R <- Y[(2 * n.polys+1):(3 * n.polys)]
# Calculate rate of change
dSdt <- -beta * S * I
dIdt <- beta * S * I - gamma * I
dRdt <- gamma * I
# Return rates of change after concatenating them
return(list(c(dSdt, dIdt, dRdt)))
}
# Initial conditions
Y.ini <- c(S = rep(99, n.polys), I = rep(1, n.polys), R = rep(0, n.polys))
# Solve the model
ode(y = Y.ini, times = 0:5, func = sir_model, parms = NULL)
#库*不*需要
图书馆(deSolve)
#参数:多边形数、β和γ
n、 多边形您应该查看包含这样一个空间组件的模型包,因为它们具有用于设置网格的辅助函数等。听起来您谈论的是时间可变的参数,这也可以由ReacTran
来适应,但要注意尖锐(即离散)参数的变化会导致数值解算器出现问题。我建议您使用类似于approxfun
的方法(假设多边形相互作用。它们会相互作用吗?)来近似参数。谢谢您的评论。我不知道这个软件包,但它似乎是用于偏微分方程。在我的方程中没有扩散项和平流项。在我基于代理的模型中,栖息地多边形不相互作用。只有宿主个体(即易感、受感染和恢复的个体)才能与其环境进行交互。在这种情况下,ReacTran
是过度杀伤力。是的,您可以通过简单地为S
、I
和R
以及n
中的每一个组合成一个数组的长度n
(其中n
是多边形的数量)的数组来拥有多个非交互多边形。(就个人而言,我会在最后计算N
,以节省时间。)将函数传递给状态变量数组,该数组的长度为4*N
。然后,在模型内部将其分为四个部分。例如,S感谢您的评论。但是如何在给定的时间步长将模型应用于每个多边形?当我运行我的模型时,我获得了所有时间段的S
、I
和R
(在我的例子中,times=seq(0,5,by=1)
)的结果。非常感谢您的回答。在本例中,您将在整个时间段内运行模型(即,时间=0:5)。假设两个单独的总体1和2。种群1由基于代理的模型(ABM)控制,种群2由ODE控制。此外,2型个体的密度取决于1型个体的密度。在我的例子中,我需要在给定的时间步运行ODE,因为栖息地多边形中类型1(S1、I1和R1)的个体密度在每个时间步都会发生变化,并且这种变化由基于代理的模型控制。例如,对于给定的栖息地多边形,S1=5个个体,t=0。当t=1时,1型个体在景观中移动(由ABM控制),因此S1发生变化,等于10。接下来,我应用我的ODE计算栖息地多边形内S1中类型2(S2、I2和R2)个体的密度。因此,我想知道是否有可能在给定的时间步(即ABM控制的每个时间步)应用ODE。首先,当你说时间步时,我认为你实际上指的是输出时间。ODE解算器(通常)会选择时间步,而您对它们一无所知,因为您只是在请求时得到了一个解决方案。记住这一点很重要。你所描述的听起来令人费解,但却是可能的。我将在deSolve
包中查看事件的帮助文件。这应该可以让您将ODE模型链接到ABM。
solve_sir_model <- function (times, parameters) {
sir_model <- function (times, states, parameters) {
with(as.list(c(states, parameters)), {
dSdt <- -beta*S*I
dIdt <- beta*S*I-gamma*I
dRdt <- gamma*I
dNdt <- dSdt + dIdt + dRdt
return(list(c(dSdt, dIdt, dRdt, dNdt)))
})
}
states <- c(S = 99, I = 1, R = 0, N = 100)
return(ode(y = states, times = times, func = sir_model, parms = parameters, method = "iteration"))
}
require(deSolve)
output <- as.data.frame(solve_sir_model(times = 1, parameters = c(beta = 400, gamma = 28)))
Error in iteration(y, times, func, parms, ...) :
times should be equally spaced In addition: Warning messages:
1: In min(x) : no non-missing arguments to min; returning Inf
2: In max(x) : no non-missing arguments to max; returning -Inf
# Library *not* require
library(deSolve)
# Parameters: number of polygons, beta, & gamma
n.polys <- 10
beta <- sample(c(100, 200, 400, 600), n.polys, replace = TRUE)
gamma <- sample(c(25, 26, 27, 28), n.polys, replace = TRUE)
# Model defintion
sir_model <- function (t, Y, pars) {
# Break up state variable into parts
S <- Y[1:n.polys]
I <- Y[(n.polys+1):(2 * n.polys)]
R <- Y[(2 * n.polys+1):(3 * n.polys)]
# Calculate rate of change
dSdt <- -beta * S * I
dIdt <- beta * S * I - gamma * I
dRdt <- gamma * I
# Return rates of change after concatenating them
return(list(c(dSdt, dIdt, dRdt)))
}
# Initial conditions
Y.ini <- c(S = rep(99, n.polys), I = rep(1, n.polys), R = rep(0, n.polys))
# Solve the model
ode(y = Y.ini, times = 0:5, func = sir_model, parms = NULL)