I just made a spatial predator-prey model but it runs a little slow and I am seeking some advice on how to compile it to optimise it for speed.
I first define matrix with 0 for an empty site, 1 for a predator and 2 for a prey present:
e = 0;r = 1;y = 2;
initSpace[n_] := RandomInteger[{0, 2} , {n, n}];
space = initSpace[10];
I then defined a getCell
function which looks for a neighbour at cell position $(i,j)$ in a matrix sp
with a certain value x
, and returns the coordinates of that cell; if it doesn't find a cell with that value it returns coordinates $(i,j)$.
getCell =
Compile[{{sp, _Integer,
2}, {i, _Integer}, {j, _Integer}, {x, _Integer}},
Block[{n, m, k2, l2, cells}, {n, m} = Dimensions[sp];
cells = {{i, j}};
Do[k2 = Mod[i + k, n, 1]; (* This is the neighborhood *)
l2 = Mod[j + l, m, 1];
If[(k2 != i || l2 != j) && sp[[k2, l2]] == x,
AppendTo[cells, {k2, l2}]], {l, -1, 1}, {k, -1, 1}];
If[Length[cells] == 1, {i, j}, RandomChoice[Rest[cells]]]],
CompilationTarget -> "C", Parallelization -> True,
RuntimeOptions -> "Speed"]
I then define a module step which calculates the space matrix in the next time step based on a given birth rate b
and death rate mu
after one event at a random location in the space.
step[b_, mu_] := Block[{i, j, k, l, dim},
dim = Dimensions[space];
i = Random[Integer, {1, dim[[1]]}];
j = Random[Integer, {1, dim[[2]]}];
Which[
(* Predator *)
space[[i, j]] == r,
If[Random[Real] < mu,
(* Predator dying *)
space[[i, j]] = e,
(* Predator eating *)
{k, l} = getCell[space, i, j, y];
space[[k, l]] = r;
],
(* Prey *)
space[[i, j]] == y,
If[Random[Real] < b,
(* Prey reproducing *)
{k, l} = getCell[space, i, j, e];
space[[k, l]] = y
]
]
]
Finally, I do many iterations
gridsize = 200;
space = initSpace[gridsize];
nrsteps = 100;
stepsize = 5000;
b = 0.9; mu = 0.4;
population = Table[0, {nrsteps}];
Do[Do[step[b, mu];, {stepsize}];
population[[i]] = space;
, {i, 1, nrsteps}];
Animate[
ArrayPlot[population[[i]], ColorRules -> {e -> Black, r -> Red, y -> Blue}],
{i, 1, nrsteps/stepsize, 1}, AnimationRepetitions -> 1,
AnimationRunning -> False]
Ideally I would like to have the latter two modules compiled as well, but when I tried to put Compile[]
around them I got a bunch of errors. Does anyone know what I might be doing wrong? Or have any other advice on how I should optimise my code for speed? Or should I try to put everything in a single compiled Module
?
{}
button inside the text box on this site), then it gets formatted as code with pretty syntax highlighting. $\endgroup$