首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在deSolve中更改时间步长的参数值

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

Stack Overflow用户
提问于 2017-03-24 16:54:51
回答 3查看 2K关注 0票数 6

我正试图用deSolve解决R中的一个ODE问题。对于下面的代码,我期望参数gamma0在时间步骤0、1、2、3、4、5、6、7、8、9和10以及0时取值5。但是,print(gamma0)显示gamma0保持在0。

这是我的颂歌:

代码语言:javascript
运行
复制
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")

我做错了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-27 22:19:28

这是对您的函数的一个非常简单的修改。如果你有兴趣知道你做错了什么,你可以看看下面。

代码语言:javascript
运行
复制
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的答案一样,问题在于您将times与什么进行比较。

当你在写作时

代码语言:javascript
运行
复制
times %in% seq(0,10,1)

你指的不是时间步骤。您只需引用times的值。

因此,如果您想在最初的10个时间步骤中使用它,只需使用我的代码或任何考虑dt的内容即可。

但有个问题要问你:

如果您不需要gamma0根据times进行更改,并且希望在最初的11 (10)个时间步骤中为5,那么为什么要将它与times进行比较呢?为什么不简单地将这些时间步骤设置为5呢?

票数 5
EN

Stack Overflow用户

发布于 2017-03-26 19:59:36

我得到的结果和你略有不同。如果我取消注释print(gamma0),它会打印5次,然后打印出513个零。虽然你可能比我在这里提供的更多,但用一种表面的方式来寻找原因并不难。

如果您有(注释掉的)语句print(gamma0),则放置行:

代码语言:javascript
运行
复制
cat("g:", gamma0, "  t:", times, "\n")

并运行代码。您将看到它显示的前两次是0。因为这些都在您的列表中,所以seq(0,10,1) gamma0是5。在那之后,时间值显示了变化。注意,打印出来的没有一个是从原来的时间列表( seq(from = 0, to = 10, by = 1/24) )中打印出来的,也没有一个是整数,所以没有一个符合将gamma0设置为5的条件。ode正在用时间(内插吗?)但这并不是简单地使用您提供的值。实际上,它没有打印出241个gamma0值和时间。它打印出515个这样的值。我注意到结果out确实有241个值。

我认为,从您的问题中,您认为ode实际上将在您的times上评估该函数。事实并非如此。它将times视为一个连续变量。但你的情况

代码语言:javascript
运行
复制
gamma0 <- ifelse(times %in% seq(0,10,1), 5, 0) 

仅对11个特定值进行测试,而不是对值的范围进行测试。连续变量不太可能精确地命中这些值。

票数 4
EN

Stack Overflow用户

发布于 2020-03-28 15:52:36

M-的答案对我没用,如果你只是尝试一下呢?

代码语言:javascript
运行
复制
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)))

  })
}

这是作为works类型函数工作的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43005101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档