Lotka-Volterra equations
From JSXGraph Wiki
Warning
The following feature is not implemented in the current release of JSXGraph, but will be included in the next release.
This example doesn't work by now because it uses Runge-Kutta methods not implemented in the current release of jsxgraph. With the next release this example should work.
--Michael 18:12, 29 May 2009 (UTC)
The Lotka-Volterra equations, a.k.a. the predator-prey equations, are a pair of non-linear differential equations mainly used to describe interaction of two biological species, one a predator and one a prey. The equations were developed independently by Alfred J. Lotka and Vito Volterra.
Model
[math]\displaystyle{ \frac{dN_1}{dt} = N_1(\epsilon_1 - \gamma_1N_2), \quad \frac{dN_2}{dt} = -N_2(\epsilon_2 - \gamma_2N_1) }[/math]
Bedeutung der Variablen:
[math]\displaystyle{ N_1 = N_1(t) }[/math] Number of preys [math]\displaystyle{ \epsilon_1\gt 0 }[/math] Reproduction rate of prey without distortion and with enough food supply [math]\displaystyle{ N_2 = N_2(t) }[/math] Number of predators [math]\displaystyle{ \epsilon_2\gt 0 }[/math] Death rate of predators if no prey available [math]\displaystyle{ \gamma_1\gt 0 }[/math] Eating rate of predator per prey (equals death rate of prey per predator) [math]\displaystyle{ \gamma_2\gt 0 }[/math] Reproduction rate of predator per prey
Plot
Source code
// Initialise board
board = JXG.JSXGraph.initBoard('jxgbox', {originX: 40, originY: 560, unitX: 20, unitY: 20, axis: false, grid: false});
// Create axis
xax = board.createElement('axis', [[0,0],[1,0]]);
yax = board.createElement('axis', [[0,0],[0,1]]);
// Define sliders to dynamically change parameters of the equations and create text elements to describe them
s = board.createElement('slider', [[20.0,26.0],[25.0,26.0],[0.0,0.3,1.0]],{name:'ε1'});
st = board.createElement('text', [20,25, "Birth rate predators"]);
u = board.createElement('slider', [[20.0,24.0],[25.0,24.0],[0.0,0.7,1.0]],{name:'ε2'});
ut = board.createElement('text', [20,23, "Death rate predators"]);
o = board.createElement('slider', [[10.0,26.0],[15.0,26.0],[0.0,0.1,1.0]],{name:'γ1'});
ot = board.createElement('text', [10,25, "Death rate preys/per predator"]);
p = board.createElement('slider', [[10.0,24.0],[15.0,24.0],[0.0,0.3,1.0]],{name:'γ2'});
pt = board.createElement('text', [10,23, "Reproduction rate pred./per prey"]);
// Dynamic initial value as gliders on the y-axis
startpred = board.createElement('glider', [0, 10, yax], {name:'Preys'});
startprey = board.createElement('glider', [0, 5, yax], {name:'Predators'});
// Variables for the JXG.Curves
var g3 = null;
var g4 = null;
// Initialise ODE and solve it with JXG.Math.Numerics.rungeKutta()
function ode() {
// evaluation interval
var I = [0, 25];
// Number of steps. 1000 should be enough
var N = 1000;
// Right hand side of the ODE dx/dt = f(t, x)
var f = function(t, x) {
var bpred = s.Value();//0.3;
var bprey = u.Value();//0.7;
var dpred = o.Value();//0.1;
var dprey = p.Value();//0.3;
var y = [];
y[0] = x[0]*(bpred - dpred*x[1]);
y[1] = -x[1]*(bprey - dprey*x[0]);
return y;
}
// Initial value
var x0 = [startpred.Y(), startprey.Y()];
// Solve ode
var data = JXG.Math.Numerics.rungeKutta(JXG.Math.Numerics.predefinedButcher.Euler, x0, I, N, f);
// to plot the data against time we need the times where the equations were solved
var t = [];
var q = I[0];
var h = (I[1]-I[0])/N;
for(var i=0; i<data.length; i++) {
data[i].push(q);
q += h;
}
return data;
}
// get data points
var data = ode();
// copy data to arrays so we can plot it using JXG.Curve
var t = [];
var dataprey = [];
var datapred = [];
for(var i=0; i<data.length; i++) {
t[i] = data[i][2];
datapred[i] = data[i][0];
dataprey[i] = data[i][1];
}
// Plot Predator
g3 = board.createElement('curve', [t, datapred], {strokeColor:'red', strokeWidth:'2px'});
g3.updateDataArray = function() {
var data = ode();
this.dataX = [];
this.dataY = [];
for(var i=0; i<data.length; i++) {
this.dataX[i] = t[i];
this.dataY[i] = data[i][0];
}
}
// Plot Prey
g4 = board.createElement('curve', [t, dataprey], {strokeColor:'blue', strokeWidth:'2px'});
g4.updateDataArray = function() {
var data = ode();
this.dataX = [];
this.dataY = [];
for(var i=0; i<data.length; i++) {
this.dataX[i] = t[i];
this.dataY[i] = data[i][1];
}
}