简体   繁体   English

R 中 ODE 求解器的问题

[英]Problems with ODE solver in R

so let's say that we have an arbitrary system of ODEs in R, which we want to solve, for example a SIR model所以假设我们在 R 中有一个任意的 ODE 系统,我们想要解决这个问题,例如 SIR model

  dS <- -beta * I * S
  dI <-  beta * I * S - gamma * I
  dR <-  gamma * I

I want beta and gamma to have time varying parameters, for example我希望 beta 和 gamma 具有时变参数,例如

 beta_vector <- seq(0.05, 1, by=0.05)
 gamma_vector <- seq(0.05, 1, by=0.05)

User @Ben Bolker gave me the advice to use beta <- beta_vector[ceiling(time)] inside the gradient function用户@Ben Bolker 建议我在渐变 function 中使用 beta <- beta_vector[ceiling(time)]

    sir_1 <- function(beta, gamma, S0, I0, R0, times) {
    require(deSolve) # for the "ode" function
   
     # the differential equations:
     sir_equations <- function(time, variables, parameters) {
         beta <- beta_vector[ceiling(time)]
         gamma <- gamma_vector[ceiling(time)]
         with(as.list(c(variables, parameters)), {
             dS <- -beta * I * S
             dI <-  beta * I * S - gamma * I
             dR <-  gamma * I
             return(list(c(dS, dI, dR)))
           })
       }
     
       # the parameters values:
       parameters_values <- c(beta=beta, gamma = gamma)
       
         # the initial values of variables:
         initial_values <- c(S = S0, I = I0, R = R0)
         
           # solving
           out <- ode(initial_values, times, sir_equations, parameters_values)
           
             # returning the output:
             as.data.frame(out)
        }


sir_1(beta = beta, gamma = gamma, S0 = 99999, I0 = 1, R0 = 0, times = seq(0, 19))

When I execute it it gives me the following error当我执行它时,它给了我以下错误

Error in checkFunc(Func2, times, y, rho) : 
The number of derivatives returned by func() (1) must equal the length of the initial 
 conditions vector (3)

The problem must lay somewhere here:问题一定出在此处:

parameters_values <- c(beta=beta, gamma = gamma)

I have tried to change the paramters_values to a Matrix with two rows (beta in the first, gamma in the second) or two columns, it did not work.我试图将 paramters_values 更改为具有两行(第一行是 beta,第二行是 gamma)或两列的 Matrix,但它不起作用。 What do I have to do in order to make this work?我必须做什么才能完成这项工作?

Your code had several issues, one is that time starts with zero while ceiling needs to start with one, and there was also some confusion with parameter names.您的代码有几个问题,一个是时间从零开始,而上限需要从一开始,并且参数名称也存在一些混淆。 In the following, I show one (of several) possible ways that uses approxfun s instead of ceiling .在下文中,我展示了一种(几种)使用approxfun而不是ceiling的可能方式。 This is more robust, even if ceiling has also some advantages.这更稳健,即使ceiling也有一些优势。 The parameters are then functions that are passed to ode as a list.然后,参数是作为列表传递给ode的函数。 An even simpler approach would be to use global variables.更简单的方法是使用全局变量。

One additional consideration is whether the time dependent gamma and beta should be linearly interpolated or stepwise.另一个考虑因素是时间相关的gammabeta应该是线性插值还是逐步插值。 The approxfun function allows both, below I use linear interpolation. approxfun function 允许两者,下面我使用线性插值。

require(deSolve) # for the "ode" function

beta_vector <- seq(0.05, 1, by=0.05)
gamma_vector <- seq(0.05, 1, by=0.05)

sir_1 <- function(f_beta, f_gamma, S0, I0, R0, times) {

  # the differential equations
  sir_equations <- function(time, variables, parameters) {
    beta  <- f_beta(time)
    gamma <- f_gamma(time)
    with(as.list(variables), {
      dS <- -beta * I * S
      dI <-  beta * I * S - gamma * I
      dR <-  gamma * I
      # include beta and gamma as auxiliary variables for debugging
      return(list(c(dS, dI, dR), beta=beta, gamma=gamma))
    })
  }
  
  # time dependent parameter functions
  parameters_values <- list(
    f_beta  = f_beta,
    f_gamma = f_gamma
  )
  
  # the initial values of variables
  initial_values <- c(S = S0, I = I0, R = R0)
  
  # solving
  # return the deSolve object as is, not a data.frame to ake plotting easier
  out <- ode(initial_values, times, sir_equations, parameters)
}

times <- seq(0, 19)

# approxfun is a function that returns a function
f_gamma <- approxfun(x=times, y=seq(0.05, 1, by=0.05), rule=2)
f_beta <- approxfun(x=times, y=seq(0.05, 1, by=0.05), rule=2)

# check how the approxfun functions work
f_beta(5)

out <- sir_1(f_beta=f_beta, f_gamma=f_gamma, S0 = 99999, I0 = 1, R0 = 0, times = times)

# plot method of class "deSolve", plots states and auxilliary variables
plot(out)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM