Lotka-Volterra equations

From JSXGraph Wiki
Revision as of 17:57, 4 June 2009 by Michael (talk | contribs)
Jump to navigationJump to search

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]\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]N_1 = N_1(t)[/math] Number of preys
[math]\epsilon_1\gt0[/math] Reproduction rate of prey without distortion and with enough food supply
[math]N_2 = N_2(t)[/math] Number of predators
[math]\epsilon_2\gt0[/math] Death rate of predators if no prey available
[math]\gamma_1\gt0[/math] Eating rate of predator per prey (equals death rate of prey per predator)
[math]\gamma_2\gt0[/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];
        }
    }