2016-06-06 5 views
2

У меня возникают проблемы с решателем ode в R от deSolve.deSolve in R дает неправильные промежуточные значения

Я обнаружил, что решатель дает ненулевые промежуточные значения для переменных, которые всегда должны быть равны нулю. Это не похоже на проблему, пока я не начну отлаживать тесты, например if (R> 0) {browser()}, которые запускаются.

Мой код ниже. Заранее спасибо!

Эллен

library(deSolve) 

simpleSIR <- function(t,states,par){ 
    with(as.list(c(states,par)),{ 

    S=states[1] 
    I=states[2] 
    R=states[3] 

    newinfections = beta*I*S 

    dS <- -newinfections 
    dI <- newinfections - gamma*I 
    dR <- gamma*I 

    if(R>0) 
    { 
     print(paste("why is this not zero?",R)) 
    } 

    return(list(c(dS,dI,dR))) 
})} 


par=list(beta=0.3,gamma=0.0) 

init=c(0.99,0.01,0) 

times <- seq(0,500,by = 1) 


out <- as.data.frame(ode(y = init, times = times, func = simpleSIR, parms = par,maxsteps=2000)) 


plot(out[,2],type="l") 
lines(out[,3],type="l",col="red") 
lines(out[,4],type="l",col="blue") 
+0

Почему вы проверяете 'R> 0' ** внутри ** функцию вместо проверки входов? Но в любом случае внимательно изучите оба ответа. –

+0

Это не мой код, над которым я работаю, но простой пример. Я считаю, что решение жесткой/не-жесткой решетки. – EBP

ответ

1

Я думаю, ваша проблема заключается в том, что метод по умолчанию для численного интегрирования в ode() является lsoda. Этот метод может переключаться между решателями для жестких и нежестких проблем. В случае, если вы переключаетесь на жесткие решатели, якобиан вычисляется численно, что может привести к появлению числовых ошибок. Вы можете видеть, что это может быть причиной, в следующем коде:

out <- deSolve::ode(y = init, times = times, func = simpleSIR, parms = par,maxsteps=2000) 
deSolve::diagnostics.deSolve(out) 

«[...] 14 Количество оценок якобиевыми и LU разбиений до сих пор: 23 [...]»

, который соответствует количеству печатных сообщений (23), которые производит ваш исходный код. Вы избавитесь от проблемы с помощью нежестких решателей как RK4:

out.rk4 <- deSolve::ode(y = init, times = times, func = simpleSIR,method = "rk4", parms = par,maxsteps=2000) 

, если вы настаиваете на использование lsoda, вы можете попробовать поставлять lsoda с якобианом Вы вычислили аналитически.

+0

Это не совсем понятно: если проблема на самом деле ** жесткая ** - или ** не жесткая **, согласно документации, 'lsoda' автоматически выбирает (не переключает) соответствующий решатель. Представляете ли вы, что исходное уравнение задает каким-то образом переключатели в зависимости от текущих значений? –

+1

Хотя я не мог найти подробного объяснения алгоритма, я понимаю, что метод действительно переключается во время выполнения. («Сначала он использует нестойкий метод и динамически контролирует данные, чтобы решить, какой метод использовать». Http://www.oecd-nea.org/tools/abstract/detail/uscd1227). Если у вас есть более подробная информация об алгоритме, я буду рад услышать их! –

+0

Отлично! Огромное спасибо. Переключение на rk4 останавливает это. Я не понимал, что lsoda переключает решатели. – EBP

0

Прежде всего, я не знаю, если вы понимаете различия между государственными-переменными и параметрами.

R (в вашем случае) является переменной состояния. Это означает, что в начале моделирования (при t = 0) R = 0. Но с развитием времени это может измениться. См. Переменную состояния S!

Ваши параметры бета и гамма, они не будут меняться во время вычислений.

Тогда вы можете упростить свой код. Используйте эти строки вместо вашего определения par и init:

par <- c(beta = 0.3, gamma = 0.0) 

init <- c(S = 0.99, I = 0.01, R = 0) 

И теперь вы можете удалить следующие строки, потому что с with(as.list(c(states, par)) имена параметров и государственных параметров доступны с их именами S, I и R .

S = states[1] 
I = states[2] 
R = states[3] 

И вы можете упростить сюжет, тоже:

matplot(out[,1], out[,2:4], type = "l", col = c("black", "red", "blue")) 

С уважением,

J_F

+0

Спасибо. Человек выше ответил на мой вопрос.«R» - это переменная состояния, но при моделировании она должна быть равна нулю, а gamma = 0. – EBP

Смежные вопросы