Short answer
No, lsoda
does not create "fictional" values.
Detailed Answer
As @Ben Bolker stated, "floating point arithmetics is intrinsically imprecise". I want to add that all solvers including lsoda
compute approximations, and that nonlinear models can magnify errors.
You can check your model, if all derivatives are exactly zero by calling the model function separately, without the solver, see the following example of a Lorenz system, where all states are set to zero:
library(deSolve)
Lorenz <- function(t, state, parameters) {
with(as.list(c(state, parameters)), {
dX <- a * X + Y * Z
dY <- b * (Y - Z)
dZ <- -X * Y + c * Y - Z
list(c(dX, dY, dZ))
})
}
parameters <- c(a = -8/3, b = -10, c = 28)
state <- c(X = 0, Y = 0, Z = 0)
times <- seq(0, 500, by = 1)
range(Lorenz(0, state, parameters))
that gives
[1] 0 0
Counter example
If we modify the model, so that one derivative is slightly different from zero due to rounding error, e.g. by using Ben's example:
Fancy <- function(t, state, parameters) {
with(as.list(c(state, parameters)), {
dX <- a * X + Y * Z + 27 * (sqrt(X + Y + Z + 2)^2 - 2)
dY <- b * (Y - Z)
dZ <- -X * Y + c * Y - Z
list(c(dX, dY, dZ))
})
}
range(Fancy(0, state, parameters))
then it gives:
[1] 0.000000e+00 1.199041e-14
Depending on tolerances, such a model may then fluctuate or even blow up. Surprisingly, a smaller tolerance may sometimes be worse:
out1 <- ode(y = state, times = times, func = Lorenz, parms = parameters, atol=1e-6)
out2 <- ode(y = state, times = times, func = Fancy, parms = parameters, atol=1e-6)
out3 <- ode(y = state, times = times, func = Fancy, parms = parameters, atol=1e-8)
par(mfrow=c(3,1))
plot(out1[,1:2], type="l", main="Lorenz, derivatives = 0")
plot(out2[,1:2], type="l", main="Fancy, small error in derivatives, atol=1e-6")
plot(out3[,1:2], type="l", main="Fancy, small error in derivatives, atol=1e-8")

Conclusion
lsoda
works well within the limitations of floating point arithmetics.
- models should be carefully designed and tested.