Как решить систему ОДУ с параметрами, зависящими от времени в R?

Я пытаюсь решить эту систему ODE через deSolve, dX / dt = -X*a + (YX) b + c и dY / dt = -Ya + (XY)*b для времени [0,200], a= 0,30, b= 0,2, но c равно 1 для времени [50,70] и 0 в противном случае. Код, который я использовал,

      time <- seq(0, 200, by=1)
parameters <- c(a=0.33, b=0.2, c=1)
state <- c(X = 0, Y = 0)

    two_comp <- function(time, state, parameters){
      with(as.list(c(state, parameters)), {
        dX = -X*a + (Y-X)*b + c
        dY = -Y*a + (X-Y)*b
        return(list(c(dX, dY)))
      })
    }

out <- ode(y = state, times = time, func = two_comp, parms = parameters)
out.df = as.data.frame(out)

Я не учел изменяющуюся во времени часть параметра c, так как не могу найти способ включить ее и запустить ее плавно. Я попытался включить его в определения функций, но безуспешно. Пожалуйста помоги.

2 ответа

Стандартный способ - использовать approxfun, т.е. создать сигнал, зависящий от времени, который мы также называем переменной принуждения:

      library("deSolve")
time <- seq(0, 200, by=1)
parameters <- c(a=0.33, b=0.2, c=1)
state <- c(X = 0, Y = 0)

two_comp <- function(time, state, parameters, signal){
  cc <- signal(time)
  with(as.list(c(state, parameters)), {
    dX <- -X * a + (Y - X) * b + cc
    dY <- -Y * a + (X - Y) * b
    return(list(c(dX, dY), c = cc))
  })
}

signal <- approxfun(x = c(0, 50, 70, 200), 
                    y = c(0, 1,  0,  0), 
                    method = "constant", rule = 2)

out <- ode(y = state, times = time, func = two_comp, 
           parms = parameters, signal = signal)
plot(out)

Также обратите внимание на специфичный для deSolve plot функция и что зависящая от времени переменная cc используется как дополнительная выходная переменная.

Подробнее об этом можно узнать:

Пределы интервала, где равно 1, можно передать как parameters. Затем внутри дифференциальной функции используйте их для создания логического значения.

      time >= lower & time <= upper

С FALSE/TRUE кодируются как целые числа 0/1, каждый раз, когда это условие ложно, c умножается на ноль, и дело в шляпе.

      library(deSolve)

two_comp <- function(time, state, parameters){
  with(as.list(c(state, parameters)), {
    dX = -X*a + (Y-X)*b + c*(time >= lower & time <= upper)
    dY = -Y*a + (X-Y)*b
    return(list(c(dX, dY)))
  })
}

time <- seq(0, 200, by=1)
parameters <- c(a=0.33, b=0.2, c=1, lower = 50, upper = 70)
state <- c(X = 0, Y = 0)

out <- ode(
  y = state, 
  times = time, 
  func = two_comp, 
  parms = parameters
)

out.df <- as.data.frame(out)
head(out.df)

matplot(out.df$time, out.df[-1], type = "l", lty = "solid", ylim = c(0, 3))
legend("topright", legend = names(out.df)[-1], col = 1:2, lty = "solid")

Другие вопросы по тегам