[R-sig-dyn-mod] deSolve::ode workaround for solutions with NaN

Thomas Petzoldt Thomas.Petzoldt at tu-dresden.de
Wed Jun 30 16:10:53 CEST 2010


On 30.06.2010 11:32, Maik Renner wrote:
> Dear all,
>
>
>
> thank you a lot for your help and suggestions.
>
> I tried Stephens approach with some success and it was the solution I
> was looking for.
>
> I still have to play around with the values I set for dy.
>
> Because setting it to zero, results in zeros for the remaining
> simulation. But this is problem specific.
>
> Maik


Dear Mike,

yes, you are right, this is strictly problem specific. Crossing zero is 
a problem of your model definition and its parametrization, and *not* an 
instability of the solver.

The solution of Stephen Ellner works as long as mass balances are not 
violated (e.g. if other states do not 'profit' from the negative 
derivative before it is zeroed).

If the scientific question allows, then it is better to adapt the model 
itself than tuning the tools. So I would prefer something like a 
Michaelis-Menten function instead of a constant loss, e.g. something 
like the following:


library(deSolve)

func1 <- function(t, y, p) {
   with(as.list(p), {
    dy <-  -a
    list(c(dy), c(a))
   })
}

func2 <- function(t, y, p) {
   with(as.list(p), {
    a  <- y * b / (k + y)
    dy <-  -a
    list(c(dy), c(a))
   })
}


times <- seq(0, 10, .1)
y <- 5

o1 <- ode(y, times, func1, c(a = 1))

o2 <- ode(y, times, func2, c(b = 1, k = 1e-6), atol=1e-8)

par(mfrow=c(1,2))

matplot(o1[,1], o1[,-1], type="l", ylim=c(-1,5))
abline(h=0, lty="dotted")

matplot(o2[,1], o2[,-1], type="l", ylim=c(-1,5))
abline(h=0, lty="dotted")


The half saturation parameter k is uncritical but it should
not be too low because of limited numerical precision. If you set it to 
a 'very' small number (e.g. 1e-6), you need to adjust atol accordingly 
(e.g. 1e-8). Instead of a MM you can also use a sigmoid function.



Thomas Petzoldt



More information about the R-sig-dynamic-models mailing list