## =======================================================================
## Example from the book of Soetaert and Herman(2009)
## A practical guide to ecological modelling -
## using R as a simulation platform. Springer
## implemented by Karline Soetaert
## =======================================================================
library(rootSolve) #uniroot.all, gradient
r <- 0.05
K <- 10
bet <- 0.1
alf <- 1
# the model : density-dependent growth and sigmoid-type mortality rate
rate <- function(x, r = 0.05) r*x*(1-x/K) - bet*x^2/(x^2+alf^2)
# uniroot.all finds all roots within an interval, her [0,10]
Eq <- uniroot.all(rate, c(0, 10))
# jacobian evaluated at all roots:
# This is just one value - and therefore jacobian = eigenvalue
# the sign of eigenvalue: stability of the root: neg=stable, 0=saddle, pos=unstable
eig <- vector()
for (i in 1:length(Eq))
eig[i] <- sign (gradient(rate, Eq[i]))
curve(rate(x), ylab = "dx/dt", from = 0, to = 10,
main = "Budworm model, roots",
sub = "Example from Soetaert and Herman, 2009")
abline(h = 0)
points(x = Eq, y = rep(0, length(Eq)), pch = 21, cex = 2,
bg = c("grey", "black", "white")[eig+2] )
legend("topleft", pch = 21, pt.cex = 2,
c("stable", "saddle", "unstable"),
pt.bg = c("grey", "black", "white"))
Budworm model, bifurcation
## =======================================================================
## use of function 'gradient' and uniroot.all
## Stability of the budworm model, as a function of its
## rate of increase.
##
## Example from the book of Soetaert and Herman(2009)
## A practical guide to ecological modelling,
## using R as a simulation platform. Springer
## code and theory are explained in this book
## implemented by Karline Soetaert
## =======================================================================
require(rootSolve) # uniroot.all and gradient
# parameters
r <- 0.05
K <- 10
bet <- 0.1
alf <- 1
# density-dependent growth and sigmoid-type mortality rate
rate <- function(x, r = 0.05)
r*x*(1-x/K) - bet*x^2/(x^2+alf^2)
# Stability of the roots ~ sign of eigenvalue of Jacobian
stability <- function (r) {
Eq <- uniroot.all(rate, c(0, 10), r = r) # finds all roots
eig <- vector()
for (i in 1:length(Eq))
eig[i] <- sign (gradient(f = rate, x = Eq[i], r = r))
return(list(Eq = Eq, Eigen = eig))
}
# bifurcation diagram for a range of r-values
rseq <- seq(0.01, 0.07, by = 0.0001)
plot(0, xlim = range(rseq), ylim = c(0, 10), type = "n",
xlab = "r", ylab = "B*", main = "Budworm model, bifurcation",
sub = "Example from Soetaert and Herman, 2009")
for (r in rseq) {
st <- stability(r)
points(rep(r, length(st$Eq)), st$Eq, pch = 15,
col = c("darkblue", "black", "lightblue")[st$Eigen+2])
}
legend("topleft", pch = 15, pt.cex = 2, c("stable", "unstable"),
col = c("darkblue", "lightblue"))
equi <- uniroot.all(rate, c(0, 10), r = 0.05)
arrows(0.05, 10 , 0.05, equi[4]+0.2, length = 0.1)
arrows(0.05, equi[3]+0.2, 0.05, equi[4]-0.2, length = 0.1)
arrows(0.05, equi[3]-0.2, 0.05, equi[2]+0.2, length = 0.1)
arrows(0.05, equi[1]+0.2, 0.05, equi[2]-0.2, length = 0.1)
equi <- uniroot.all(rate, c(0, 10), r = 0.038)
arrows(0.038, 10 , 0.038, equi[2]+0.1, length = 0.1)
arrows(0.038, equi[1]+0.1, 0.038, equi[2]-0.1, length = 0.1)
equi <- uniroot.all(rate, c(0, 10), r = 0.07)
arrows(0.07, 10 , 0.07, equi[2]+0.2, length = 0.1)
arrows(0.07, equi[1]+0.2, 0.07, equi[2]-0.2, length = 0.1)