R - deSolve 包(ode 函数):根据时间改变 SIR 模型中的参数矩阵

2023-12-13

我正在尝试使用该函数模拟病毒在人群中的传播ode来自deSolve包裹。我的模型的基础是 SIR 模型,我在这里发布了一个更简单的模型演示,其中仅包含三个状态S(易感)、I(传染性)和R(康复)。每个状态由一个代表m*n 矩阵在我的代码中,因为我有年龄组 and n 个亚群在我的人口中。

问题是:在模拟期间,会有几次疫苗接种活动将人员转移到州内S陈述I。每个疫苗接种活动的特点是开始日期, an end date, its 覆盖率 and duration。我想做的是一旦time t落入区间开始日期 and end date对于一项疫苗接种活动,代码计算有效疫苗接种率(也m*n矩阵,基于覆盖率 and duration)并乘以S (m*n矩阵),得到过渡到状态的人员矩阵I。现在,我正在使用if()决定是否time t是介于一个开始日期 and a end date:

#initialize the matrix of effective vaccination rate 
irrate_matrix = matrix(data = rep(0, m*n), nrow = m, ncol = n) 

for (i in 1:length(tbegin)){
  if (t>=tbegin[i] & t<=tend[i]){
    for (j in 1:n){
      irrate_matrix[, j] = -log(1-covir[(j-1)*length(tbegin)+i])/duration[i]
    }
  }
}

Here, irrate_matrix is the m*n有效疫苗接种率矩阵, m = 2是数量年龄组, n = 2是数量亚群, tbegin = c(5, 20, 35) is the 开始日期3 项疫苗接种活动中,tend = c(8, 23, 38) is the end date3 项疫苗接种活动中,covir = c(0.35, 0.25, 0.25, 0.225, 0.18, 0.13) is the 覆盖率每个亚群的每次疫苗接种(例如,covir[1] = 0.35 is the 覆盖率第一次疫苗接种的亚群1, while covir[4] = 0.225 is the 覆盖率第一次疫苗接种的亚群2) and duration = c(4, 4, 4)是每次疫苗接种的持续时间(以天为单位)。

计算后irrate_matrix,我将其转化为导数,因此我有:

dS = as.matrix(b*N) - as.matrix(irrate_matrix*S) - as.matrix(mu*S)
dI = as.matrix(irrate_matrix*S) - as.matrix(gammaS*I) - as.matrix(mu*I)
dR = as.matrix(gammaS*I) - as.matrix(mu*R)

我想以 1 天为步长从第 0 天到第 50 天进行模拟,因此:

times = seq(0, 50, 1)

我的代码当前的问题是: 每次time t到达接近 a 的时间点tbegin[i] or tend[i],模拟变得慢得多,因为它在这个时间点迭代的轮次比任何其他时间点都要多得多。例如,一旦time t来到tbegin[1] = 5,模型在时间点 5 迭代多轮。我附上了打印这些迭代的屏幕截图(截图1 and 截图2)。我发现这就是为什么我的更大的模型现在需要很长的运行时间。

我尝试过使用“事件”功能deSolvetpetzoldt 在这个问题中提到stackoverflow:根据时间更改参数值。然而,我发现改变一个参数矩阵并在每次有疫苗接种活动时都改变它对我来说很不方便。

我正在寻找以下方面的解决方案:

  • 如何改变我的irrate_matrix当有疫苗接种活动时将其设为非零矩阵,而在没有疫苗接种活动时将其设为零矩阵? (必须为每次疫苗接种计算)

  • 同时,如何通过避免随时迭代来让代码运行得更快tbegin[i] or tend[i]多轮? (我认为我不应该使用if()但我不知道我应该如何处理我的案子)

  • 如果我需要使用“强制”或“事件”功能,您能否告诉我如何在模型中拥有多个“强制”/“事件”?现在,我在更大的模型中使用了一个“事件”来向人群引入病毒,如下所示:

virusevents = data.frame(var = "I1", time = 2, value = 1, method = "add")

欢迎任何好主意,并且非常感谢直接提供一些代码!先感谢您!

作为参考,我在这里发布了整个演示:

library(deSolve)

##################################
###(1) define the sir function####
##################################

sir_basic <- function (t, x, params) 
{ # retrieve initial states
  S = matrix(data = x[(0*m*n+1):(1*m*n)], nrow = m, ncol = n)
  I = matrix(data = x[(1*m*n+1):(2*m*n)], nrow = m, ncol = n)
  R = matrix(data = x[(2*m*n+1):(3*m*n)], nrow = m, ncol = n)
  
  with(as.list(params), {
    N = as.matrix(S + I + R) 
    
    # print out current iteration
    print(paste0("Total population at time ", t, " is ", sum(N)))
    
    # calculate irrate_matrix by checking time t
    irrate_matrix = matrix(data = rep(0, m*n), nrow = m, ncol = n)
    for (i in 1:length(tbegin)){
      if (t>=tbegin[i] & t<=tend[i]){
        for (j in 1:n){
          irrate_matrix[, j] = -log(1-covir[(j-1)*length(tbegin)+i])/duration[i]
        }
      }
    }
    
    # derivatives
    dS = as.matrix(b*N) - as.matrix(irrate_matrix*S) - as.matrix(mu*S)
    dI = as.matrix(irrate_matrix*S) - as.matrix(gammaS*I) - as.matrix(mu*I)
    dR = as.matrix(gammaS*I) - as.matrix(mu*R)
    derivatives <- c(dS, dI, dR)
    list(derivatives)
  })
}

##################################
###(2) characterize parameters####
##################################

m = 2 # the number of age groups
n = 2 # the number of sub-populations

tbegin = c(5, 20, 35) # begin dates
tend = c(8, 23, 38) # end dates
duration = c(4, 4, 4) # duration
covir = c(0.35, 0.25, 0.25, 0.225, 0.18, 0.13) # coverage rates

b = 0.0006 # daily birth rate
mu = 0.0006 # daily death rate
gammaS = 0.05 # transition rate from I to R

parameters = c(m = m, n = n,
               tbegin = tbegin, tend = tend, duration = duration, covir = covir,
               b = b, mu = mu, gammaS = gammaS)

##################################
#######(3) initial states ########
##################################

inits = c(
  S = c(20000, 40000, 10000, 20000),
  I = rep(0, m*n),
  R = rep(0, m*n)
)

##################################
#######(4) run simulations########
##################################

times = seq(0, 50, 1)

traj <- ode(func  = sir_basic, 
            y = inits,
            parms = parameters,
            times = times)

plot(traj)

矩阵和向量的逐元素运算是相同的,因此as.matrix转换是多余的,因为没有true使用矩阵乘法。与rep:无论如何,零都会被回收。

实际上,CPU 时间已减少至 50%。相反,使用外部强迫approxTime而不是内在的if and for使模型变慢(未显示)。

简化代码

sir_basic2 <- function (t, x, params)
{ # retrieve initial states
  S = x[(0*m*n+1):(1*m*n)]
  I = x[(1*m*n+1):(2*m*n)]
  R = x[(2*m*n+1):(3*m*n)]

  with(as.list(params), {
    N = S + I + R

    # print out current iteration
    #print(paste0("Total population at time ", t, " is ", sum(N)))

    # calculate irrate_matrix by checking time t
    irrate_matrix = matrix(data = 0, nrow = m, ncol = n)
    for (i in 1:length(tbegin)){
      if (t >= tbegin[i] & t <= tend[i]){
        for (j in 1:n){
          irrate_matrix[, j] = -log(1-covir[(j-1) * length(tbegin)+i])/duration[i]
        }
      }
    }

    # derivatives
    dS = b*N - irrate_matrix*S - mu*S
    dI = irrate_matrix*S - gammaS*I - mu*I
    dR = gammaS*I - mu*R
    list(c(dS, dI, dR))
  })
}

基准

每个模型版本运行 10 次。模型sir_basic是原始实现,其中print为了公平比较,线路被禁用。

system.time(
  for(i in 1:10)
    traj <- ode(func  = sir_basic,
            y = inits,
            parms = parameters,
            times = times)
)

system.time(
  for(i in 1:10)
    traj2 <- ode(func  = sir_basic2,
            y = inits,
            parms = parameters,
            times = times)
)

plot(traj, traj2)
summary(traj - traj2)

当我使用时,我观察到另一个相当大的加速method="adams"而不是默认的lsoda解算器,但这对于您的完整模型可能有所不同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R - deSolve 包(ode 函数):根据时间改变 SIR 模型中的参数矩阵 的相关文章

随机推荐

  • 如何显示MySQL中未完成的事务

    我做了一些没有提交的查询 然后应用程序被停止 如何显示这些未结交易并提交或取消它们 如何显示这些未结交易并提交或取消它们 没有打开的事务 MySQL 将在断开连接时回滚事务 您无法提交事务 IFAIK 您使用显示线程 SHOW FULL P
  • C# 中根据空格分割字符串

    我有一个字符串 dexter 是好是坏 我想通过根据空格分割该字符串来创建一个列表 我使用以下代码实现了这一点 string ss dexter is good annd bad var s string IsNullOrEmpty ss
  • 从 Nunit 获取失败测试列表

    我有一个包含超过 8000 个测试的测试套件 并且很难看出哪些测试在代码更改之间中断 这些测试用例是从某些日志文件中自动提取的查询 有没有一种简单的方法来获取 NUnit 运行的失败测试列表 理想情况下 我想比较运行之间哪些测试受到影响 您
  • Protobuf-net 对 Dictionary/KeyValuePair 的支持是如何工作的?

    我试图了解 protobuf net 的 Dictionary KeyValuePair 支持 我们希望使用底层二进制流和从 java 生成的 proto 文件 但生成的 proto 文件包含看起来像名为 Pair String Int32
  • iOS 应用程序捆绑包 ID 错误和 iTunesConnect

    如本文所述SO entry 我在 iOS 应用程序应用程序上传器中遇到错误 这些是我的价值观 在钥匙串中我有这个证书 iPhone Distribution ExampleCompany DistCertificateID 在我的devel
  • 获取Linux中每个进程的堆和堆栈的大小

    我想知道Linux中每个进程的堆和堆栈的大小 有什么办法可以找到吗 我发现 sbrk 0 会给我堆的结尾 但是如何找到堆的起始位置来获取堆大小呢 另外 关于堆栈大小 是否有任何方法可以通过任何库调用或系统调用找到每个进程的堆栈开头和当前堆栈
  • Spring 4 i18n & l10n(无法更改 HTTP 接受标头)

    我需要帮助来解决此错误消息 我正在使用 spring 4 我想在我的项目中实现 i18n 和 l10n 当我尝试更改语言时 会出现此消息 下面是我的代码 请问 有人可以帮我解决这个问题吗 https i stack imgur com tK
  • didReceiveData 未获取所有数据

    我正在尝试使用 NSURLConnection 下载 JSON 但除非我强制应用程序暂停几秒钟 否则我获得的数据并不完整 它总是在 2600 字节左右 而我的响应应该在 70000 左右 任何线索为什么会发生这种情况 谢谢 void con
  • 未检测到文档的语法约束(DTD 或 XML 模式)

    我有这个 dtd http fast code sourceforge net template dtd但是当我包含在 xml 中时 我收到警告 未检测到文档的语法约束 DTD 或 XML 模式 xml 是
  • 使用正则表达式捕获 html 标签内的内容

    首先 我知道这是一种不好的做法 我已经回答了很多问题 甚至这么说 但需要澄清一下我被迫使用正则表达式 因为该应用程序将正则表达式存储在数据库中并且只能以这种方式运行 我绝对不能改变功能 现在我们已经解决了这个问题 因为我总是使用 DOM 方
  • 无法使 PubNub WebRTC 教程正常工作

    我正在尝试按照 PubNub 教程构建我的第一个 WebRTC 应用程序 https www pubnub com blog 2015 08 25 webrtc video chat app in 20 lines of javascrip
  • 使用 FluentFTP 以最大值同时从 FTP 下载多个文件

    我想从 FTP 目录递归下载多个下载文件 为此我使用 FluentFTP 库 我的代码是这样的 private async Task downloadRecursively string src string dest FtpClient
  • 在本地使用 mpi 安装 fftw-2.1.5

    我正在尝试使用 enable mpi 标志在带有 linux 的 IBM 集群上安装 fftw 2 1 5 库 但此后我一直未能这样做 我需要 fftw 版本 2 1 5 因为 GADGET2 代码需要该版本 并且具有 mpi 支持 首先
  • Python - BeautifulSoup html解析处理gbk编码不佳 - 中文网页抓取问题

    我一直在修改以下脚本 coding utf8 import codecs from BeautifulSoup import BeautifulSoup NavigableString UnicodeDammit import urllib
  • 字典、哈希集的访问时间

    访问时间是多少 在字典中查找值 检查HashSet是否有值 是像C 0x的unordered map那样O 1 吗 是的 当您使用 Contains 方法或字典的索引器时 来自文档 Dictionary Of TKey TValue 泛型类
  • 我可以在 JavaScript 中将新数组重新分配给数组变量吗?

    我对 JavaScript 中的数组以及在函数内操作它们有疑问 这是书上的练习雄辩的 JavaScript 它涉及两个功能 reverseArray 返回一个new与参数数组相反的数组 reverseArrayInPlace 只是反转参数数
  • Ruby:常量查找在instance_eval/class_eval 中如何工作?

    我正在研究 Pickaxe 1 9 并且对 instance class eval 块中的常量查找感到有点困惑 我用的是1 9 2 Ruby 似乎以与方法查找相同的方式处理 eval 块中的常量查找 在receiver singleton
  • Mac OS X:我可以在应用程序包中编写应用程序文件吗?

    该应用程序将位于 Applications 中 该应用程序将通过网络浏览器而不是通过 App Store 下载 使用的语言是 Tcl Tk 答 这适用于所有版本的 OS X 10 5 或更高版本吗 B 有没有更好的地方来存储应用程序文件 L
  • CMake如何将构建目录设置为与源目录不同

    我对 CMake 还很陌生 阅读了一些关于如何使用它的教程 并编写了一些复杂的 50 行 CMake 脚本 以便为 3 个不同的编译器制作一个程序 这可能总结了我对 CMake 的所有知识 现在我的问题是我有一些源代码 当我制作程序时我不想
  • R - deSolve 包(ode 函数):根据时间改变 SIR 模型中的参数矩阵

    我正在尝试使用该函数模拟病毒在人群中的传播ode来自deSolve包裹 我的模型的基础是 SIR 模型 我在这里发布了一个更简单的模型演示 其中仅包含三个状态S 易感 I 传染性 和R 康复 每个状态由一个代表m n 矩阵在我的代码中 因为