Generalized Lotka-Volterra model

The model

\(\frac{dx_i}{dt}= ax_i+\sum_{j=1}^pb_{ij}x_ix_j\)

## library
library('deSolve')
## GLV function
lvm <- function(t, x, params){
  with(as.list(params, c(x)), {
    dx <- alpha * x + x * (beta %*% x)
    list(dx)
  })
}

## numerical integration
n.integrate <- function(time, init.x, model, params){
    as.data.frame(ode(init.x, time, model, params))
}
## normalizations
TSS <- function(x){
  apply(x, 1, function(x)x/sum(x))
}

GLV with 3 species

alpha <- c(0.1, 0.2, 0.3)
beta <- t(matrix(c(-0.5, -0.3 ,   0, 
                    0.1, -0.5 ,   0,
                     0 ,   0  , -0.5), 
                 3,3 ))

init.x <- c(0.6, 1, 0.4)

dat <- n.integrate(0:10, init.x, lvm, list(alpha=alpha, beta=beta))
dat.norm <- t(TSS(dat[,-1]))

par(mfrow=c(1,2))
matplot(x=dat$time, y=dat[,-1], typ='b', xlab='time', ylab='Absolute abundance') ## absolute abundance
matplot(x=dat$time, y=dat.norm, typ='b', xlab='time', ylab='Relative abundance') ## relative abundance

Scale parameters

init.x.scaled <- init.x/sum(init.x)
beta.scaled <- beta * sum(init.x)

dat.w_scaled_beta <- n.integrate(0:10, init.x.scaled, lvm, list(alpha=alpha, beta=beta.scaled))
dat.norm.w_scaled_beta <- t(TSS(dat.w_scaled_beta[,-1]))

par(mfrow=c(1,2))
matplot(x=dat.w_scaled_beta$time, y=dat.w_scaled_beta[,-1], typ='b', xlab='time', ylab='Absolute abundance') ## absolute abundance
matplot(x=dat.w_scaled_beta$time, y=dat.norm.w_scaled_beta, typ='b', xlab='time', ylab='Relative abundance') ## relative abundance

Compare

par(mfrow=c(1,2))
matplot(dat.w_scaled_beta[,-1]/dat[,-1], type='b', ylab='Ratio of abundance trajectories')
matplot(dat.norm.w_scaled_beta - dat.norm, type='b', ylab='Absolute Error in Relative Abundances')

Conclusion

It turned out that the GLV model could be scaled as long as the abundances and the interaction matrix were compatible (scale abundances by a factor of \(c\), then interaction matrix scaled by a factor of \(1/c\)).

Related

comments powered by Disqus