求解参数随间隔变化的微分方程

时间:2016-09-28 12:37:43

标签: r parameters differential-equations

我想解决一个微分方程组,其参数在intervlas上变化。

这是我的代码:

li

问题是函数rigidode仅适用于常量参数。我无法弄清楚如何在一段时间内(从0到2)改变我的参数。

感谢

2 个答案:

答案 0 :(得分:1)

这里(以我的意思)最佳解决方案和一些解释性说明:

  1. 要使函数中的参数可用,只需使用with(as.list(...))函数即可。
  2. 我很容易,并在功能中区分了案例:

    rigidode <- function(times, y, parms) {
      with(as.list(c(parms,y)), {
    
        if(times > 1.1 & times < 3.1){      
          mueDP <- 2.6
          mueHD <- 1.7 
          mueTX <- 3.3  
          tau12 <- 2.7 
          tau13 <- 1.3
          tau21 <- 1.8 
          tau23 <- 2.1  
          tau31 <- 3.6 
          tau32 <- 1.4      
        }
    
        if(times > 3.1){      
          mueDP <- 1.1
          mueHD <- 1.3 
          mueTX <- 1.3  
          tau12 <- 0.7 
          tau13 <- 2.3
          tau21 <- 2.8 
          tau23 <- 1.1  
          tau31 <- 1.6 
          tau32 <- 0.4      
        }
    
        #un-comment the line below, if you want to see, if this works as expected
        # print(c(times, mueDP, mueHD, mueTX, tau12, tau13, tau21,tau23,tau31, tau23))
    
        dert.comp_dp <- -(tau12)*comp_dp+(tau21)*comp_hd-(tau13)*comp_dp+(tau31)*comp_tx-(mueDP)*comp_dp
        dert.comp_hd <- -(tau21)*comp_hd+(tau12)*comp_dp-(tau23)*comp_hd+(tau32)*comp_tx-(mueHD)*comp_hd
        dert.comp_tx <- -(tau31)*comp_tx+(tau13)*comp_dp-(tau32)*comp_tx+(tau23)*comp_hd-(mueTX)*comp_tx
        dert.comp_dc <- (mueDP)*comp_dp+(mueHD)*comp_hd+(mueTX)*comp_tx
    
        return(list(c(dert.comp_dp, dert.comp_hd, dert.comp_tx, dert.comp_dc)))
      })
    }
    

    其余代码是标准的,请注意,parms的值为时间= 0。

    times <- seq(from = 0, to = 5, by = 0.1)
    
    yini <- c(comp_dp = 30, comp_hd = 60, comp_tx = 10, comp_dc = 0)
    parms <- c(mueDP = 3.1, mueHD = 2.6, mueTX = 1.9,  tau12 = 5.5, tau13 = 3.5,
           tau21 = 4.0, tau23 = 2.1,  tau31 = 3.9, tau32 = 5.1)
    
    out_lsoda <- lsoda (times = times, y = yini, func = rigidode, parms = parms, rtol = 1e-9, atol = 1e-9)
    out_lsoda
    

    所以最后,我来到这个解决方案。请检查我写的所有值是否正确,我只是让您的代码正常工作!

    enter image description here

答案 1 :(得分:0)

@Mily评论:是的,可以使用t1,这里是解决方案:

定义t1(在我看来,不需要Intervall)。

t1 <- data.frame(times=seq(from=0, to=5, by=0.1))
t1$mueDP=c(rep(3.1,10),rep(2.6,20),rep(1.1,21))
t1$mueHD=c(rep(2.6,10),rep(1.7,20),rep(1.3,21))
t1$mueTX=c(rep(1.9,10),rep(3.3,20),rep(1.3,21))
t1$tau12=c(rep(5.5,10),rep(2.7,20),rep(0.7,21))
t1$tau13=c(rep(3.5,10),rep(1.3,20),rep(2.3,21))
t1$tau21=c(rep(4,10),rep(1.8,20),rep(2.8,21))
t1$tau23=c(rep(2.1,10),rep(2.1,20),rep(1.1,21))
t1$tau31=c(rep(3.9,10),rep(3.6,20),rep(1.6,21))
t1$tau32=c(rep(5.1,10),rep(1.4,20),rep(0.4,21))

定义ODE功能:

rigidode <- function(times, y, parms,t1) {

  ## find out in which line of t1 `times` is
  id <- min(which(times < t1$times))-1
  parms <- t1[id,-1]

  with(as.list(c(parms,y)), {

    dert.comp_dp <- -(tau12)*comp_dp+(tau21)*comp_hd-(tau13)*comp_dp+(tau31)*comp_tx-(mueDP)*comp_dp
    dert.comp_hd <- -(tau21)*comp_hd+(tau12)*comp_dp-(tau23)*comp_hd+(tau32)*comp_tx-(mueHD)*comp_hd
    dert.comp_tx <- -(tau31)*comp_tx+(tau13)*comp_dp-(tau32)*comp_tx+(tau23)*comp_hd-(mueTX)*comp_tx
    dert.comp_dc <- (mueDP)*comp_dp+(mueHD)*comp_hd+(mueTX)*comp_tx

    return(list(c(dert.comp_dp, dert.comp_hd, dert.comp_tx, dert.comp_dc)))
  })
}


times <- seq(from = 0, to = 5, by = 0.1)


yini <- c(comp_dp = 30, comp_hd = 60, comp_tx = 10, comp_dc = 0)

parms <- t1[1,-1]

out_lsoda <- lsoda(times = times, y = yini, func = rigidode, parms = parms, rtol = 1e-9, atol = 1e-9, t1 = t1)
out_lsoda

请注意,在函数调用lsoda中,参数t1 = t1被提交给ODE函数。