在deSolve中更改时间步的参数值

时间:2017-03-24 16:54:52

标签: r parameters ode differential-equations

我正在尝试使用deSolve来解决R中的ODE。使用以下代码,我期望参数gamma0在时间步0,1,2,3,4,5,6,7,8,9和10取值5,否则取0。但是,print(gamma0)表示gamma0保持为0.

这是我的ODE:

library(deSolve) 
param <- c(a = 0.1, b = 1) 
yini <- c(alpha0 = 6, beta0 = 2) 

mod <- function(times, yini, param) { 

  with(as.list(c(yini, param)), { 

    gamma0 <- ifelse(times %in% seq(0,10,1), 5, 0) 

    ## print(gamma0) 

    dalpha0 <- - a*alpha0 + gamma0 
    dbeta0 <- a*alpha0 - b*beta0 
    return(list(c(dalpha0, dbeta0))) 

  })} 

times <- seq(from = 0, to = 10, by = 1/24) 
out <- ode(func = mod, times = times, y = yini, parms = param) 
plot(out, lwd = 2, xlab = "day")

我做错了什么?

3 个答案:

答案 0 :(得分:4)

我得到的结果略有不同。如果我取消注释print(gamma0)它打印5次,然后输出513个零。尽管你可能想要的比我在这里提供的更多,但要用一种肤浅的方式来追踪它们并不难。

如果您有(注释掉)声明print(gamma0),请填写以下行:

cat("g:", gamma0, "  t:", times, "\n")

并运行代码。您将看到它显示的前两次是0.因为这些在您的列表中seq(0,10,1),gamma0是5.之后,显示的时间值会发生变化。请注意,打印的其中没有来自您原始的时间列表seq(from = 0, to = 10, by = 1/24),并且它们都不是整数,因此没有符合条件将gamma0设置为5. ode是用时间做某事(插值?)但它不是简单地使用你提供的值。实际上,它不会打印出gamma0和次数的241个值。它打印出515个这样的值。我注意到结果out确实有241个值。

我认为,根据您的问题,您认为ode实际上会评估您times的功能。它不是。它将times视为连续变量。但是你的情况

gamma0 <- ifelse(times %in% seq(0,10,1), 5, 0) 

仅测试11个特定值 - 而不是值范围。连续变量不太可能完全达到这些值。

答案 1 :(得分:4)

这是对您的功能的一个非常简单的修改。如果您对了解自己的错误感兴趣,可以查看以下内容。

mod <- function(times, yini, param) { 

  dt = times[2] - times[1]
  with(as.list(c(yini, param)), { 

    gamma0 <- ifelse(times <= 10*dt, 5, 0) 

    ## print(gamma0) 

    dalpha0 <- - a*alpha0 + gamma0 
    dbeta0 <- a*alpha0 - b*beta0 
    return(list(c(dalpha0, dbeta0))) 

  })} 

修改

与G5W的回答相同,问题在于您将timestimes %in% seq(0,10,1) 进行比较。

写作时

times

你不是指时间步骤。您只需引用dt

的值

因此,如果您想在前10个步骤中使用它,您只需要使用我的代码或任何考虑gamma0的内容。

但是这里有一个问题:

如果您不需要times根据times进行更改,并希望在前11(10)个时间步长为5,那么为什么要将其与{{1}}进行比较?为什么不简单地将它设置为5用于那些时间步骤?

答案 2 :(得分:1)

M--的答案对我不起作用,如果您只是尝试这样做呢?

mod <- function(times, yini, param) {
  with(as.list(c(yini, param)), {

    if (times < 10) {
      gamma0 = 5
    } else if (times >= 10) {
      gamma0 = 0
    }

    dalpha0 <- -a * alpha0 + gamma0
    dbeta0 <- a * alpha0 - b * beta0
    return(list(c(dalpha0, dbeta0)))

  })
}

这可以用作Headvise类型的功能