Modelling: Conway’s Game of Life Implemented in R

Figure 1. Several iterations of the algorithm, beginning from a randomly determined initial position.

Figure 1. Several iterations of the algorithm, beginning from a randomly determined initial position.

By Allan Roberts

The R script provided below implements J.H. Conway’s “Game of Life” algorithm on an 8 by 8 grid. In this model, cells persist and propagate according to how many neighbours they have (including perpendicular and diagonal neighbours). A cell persists if it has either  2 or 3 neighbours, and empty cells become occupied if they have exactly 3 neighbours. This set of rules might be thought of as mimicking a single species population with density-related effects. Note that, in the final stable distribution shown in Figure 1, each green square is adjacent to either 2 or 3 other green squares.

Reference

Game of Life. Wolfram Mathworld:  http://mathworld.wolfram.com/GameofLife.html

R Script

#An implementation of J.H. Conway’s ‘Game of Life’ algorithm.
#Implemented by A. Roberts, May 2013

Life.Example = function(){
neighbours = function(M){
if (!is.matrix(M)) return(NULL);
m = dim(M)[1];
n = dim(M)[2];
left = cbind( rep(0,m), M[ ,1:(n-1)]);
right = cbind(M[ ,2:n], rep(0,m));
up = rbind( rep(0,n), M[1:(m-1),]);
down = rbind( M[2:m,], rep(0,n));
upper.right = M[1:(m-1),2:n];
upper.right = rbind(rep(0,n-1),upper.right);
upper.right = cbind(upper.right,rep(0,m));
lower.right = M[2:m,2:n];
lower.right = rbind(lower.right, rep(0,n-1));
lower.right = cbind(lower.right, rep(0,m));
lower.left = M[2:m,1:(n-1)];
lower.left = cbind(rep(0,n-1),lower.left);
lower.left = rbind(lower.left, rep(0,m));
upper.left = M[1:(m-1),1:(n-1)];
upper.left = rbind(rep(0,n-1),upper.left);
upper.left = cbind(rep(0,m),upper.left);

N =up+down+right+left+upper.right+lower.right+lower.left+upper.left;return(N);
}

N2 = function(M){
m = dim(M)[1];
n = dim(M)[2];
N2 = (neighbours(M)==2);
N2 = as.numeric(N2);
dim(N2) = c(m,n);
return(N2);
}

N3 = function(M){
m = dim(M)[1];
n = dim(M)[2];
N3 = (neighbours(M)==3);
N3 = as.numeric(N3);
dim(N3) = c(m,n);
return(N3);
}

update = function(M){
return( N3(M) + N2(M)*M);
}

random.setup = function(n){
M = matrix(sample(c(0,1),n*n,replace=TRUE),n,n);
return(M);
}

M = random.setup(8);
plot.new();
par( mfrow=c(4,4),mar=c(1,1,2,2));
for (i in 1:16){
M=update(M);
image(M,col=c(rgb(1,1,1),rgb(0,0.5,0)),axes=FALSE,frame=TRUE);mtext(side=3,paste(quote(iteration),i-1));
}
}
Life.Example();

Advertisements

Logistic Growth Model with R

Figure 1. Example.

Figure 1. This graph was produced by the R script provided below.

Models like the discrete logistic growth model are famous for producing complex behaviour from simple equations. You can cut and paste the R script provided below onto the R command line, to produce a graph like the one given Figure 1. Try varying the parameter r to see what happens; for example, to set the parameter r to 1.5, enter the following:

> LogisticGrowthExample( r = 1.5 );

References

Logistic Equation. Wolfram Mathworld: mathworld.wolfram.com/LogisticEquation.html
Logistic Map. Wikipedia: en.wikipedia.org/wiki/Logistic_map

R Script

#NOTE: You will need to replace the right and left quotation marks with
#straight quotes before running this script in R.

LogisticGrowthExample <- function(r = 3.7, N0 = 0.1, steps = 100){
#Implemention by Allan Roberts, March 2013.

N <- numeric(steps);
N[1] <- N0; #the initial population

Next <- function(N) {N <-  N + (r-1)*N*(1-N)};
for (i in 2:(steps)) N[i] <- Next(N[i-1]);

plot(N~seq(0,(steps-1)),type=”l”,xlab=quote(time), ylim=c(0,1.5), las = 1 );
title(main=”Discrete Logistic Growth Model”, font.main=1, cex.main=2);
text(80,0.2,paste(“r =”,as.character(r) ), adj=c(0,0.5));
text(80,0.1, expression(“N”[0]), adj=c(0,0.5 ) );
text(84.14,0.1, paste(” =”,as.character(N[1])), adj=c(0,0.5) );
}

LogisticGrowthExample( );