Lotka-Volterra equations: Difference between revisions

From JSXGraph Wiki
(New page: 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. --~~~~ ---- <js...)
 
No edit summary
 
(12 intermediate revisions by 2 users not shown)
Line 1: Line 1:
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.
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.


--[[User:Michael|Michael]] 18:12, 29 May 2009 (UTC)
==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>


----
Meaning of the variables:
::{| border="1" ||
|-  
| <math>N_1 = N_1(t)</math> || Number of preys
|-
| <math>\epsilon_1>0</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>0</math> || Death rate of predators if no prey available
|-
| <math>\gamma_1>0</math> || Eating rate of predator per prey (equals death rate of prey per predator)
|-
| <math>\gamma_2>0</math> || Reproduction rate of predator per prey
|}


==Plot==


<jsxgraph width="600" height="600">
<jsxgraph width="600" height="600">
     board = JXG.JSXGraph.initBoard('jxgbox', {originX: 40, originY: 560, unitX: 20, unitY: 20, axis: false, grid: false});
     board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-1.5, 28.5, 28.5, -1.5], axis: true, grid: false});
    xax = board.createElement('axis', [[0,0],[1,0]]);
 
    yax = board.createElement('axis', [[0,0],[0,1]]);
     s = board.create('slider', [[20.0,26.0],[25.0,26.0],[0.0,0.3,1.0]],{name:'&epsilon;1',strokeColor:'black',fillColor:'black'});
     s = board.createElement('slider', [[20.0,26.0],[25.0,26.0],[0.0,0.3,1.0]],{name:'&epsilon;1'});
     st = board.create('text', [20,25, "Birth rate prey"], {fixed:true});
     st = board.createElement('text', [20,25, "Birth rate predators"]);
     u = board.create('slider', [[20.0,24.0],[25.0,24.0],[0.0,0.7,1.0]],{name:'&epsilon;2',strokeColor:'black',fillColor:'black'});
     u = board.createElement('slider', [[20.0,24.0],[25.0,24.0],[0.0,0.7,1.0]],{name:'&epsilon;2'});
     ut = board.create('text', [20,23, "Death rate predators"], {fixed:true});
     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:'&gamma;1'});
     o = board.create('slider', [[10.0,26.0],[15.0,26.0],[0.0,0.1,1.0]],{name:'&gamma;1',strokeColor:'black',fillColor:'black'});
     ot = board.createElement('text', [10,25, "Death rate preys/per predator"]);
     ot = board.create('text', [10,25, "Death rate preys/per predator"], {fixed:true});
     p = board.createElement('slider', [[10.0,24.0],[15.0,24.0],[0.0,0.3,1.0]],{name:'&gamma;2'});
     p = board.create('slider', [[10.0,24.0],[15.0,24.0],[0.0,0.3,1.0]],{name:'&gamma;2',strokeColor:'black',fillColor:'black'});
     pt = board.createElement('text', [10,23, "Reproduction rate pred./per prey"]);
     pt = board.create('text', [10,23, "Reproduction rate pred./per prey"], {fixed:true});


     startpred = board.createElement('glider', [0, 10, yax], {name:'Preys'});
     startpred = board.create('glider', [0, 10, board.defaultAxes.y], {name:'Preys',strokeColor:'red',fillColor:'red'});
     startprey = board.createElement('glider', [0, 5, yax], {name:'Predators'});
     startprey = board.create('glider', [0, 5, board.defaultAxes.y], {name:'Predators',strokeColor:'blue',fillColor:'blue'});


     var g3 = null;
     var g3 = null;
Line 44: Line 60:
         var x0 = [startpred.Y(), startprey.Y()];
         var x0 = [startpred.Y(), startprey.Y()];


         var data = JXG.Math.Numerics.rungeKutta(JXG.Math.Numerics.predefinedButcher.Euler, x0, I, N, f);
         var data = JXG.Math.Numerics.rungeKutta('euler', x0, I, N, f);


         var t = [];
         var t = [];
Line 57: Line 73:
     }
     }
      
      
     function createCurve() {
     var data = ode();
    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];
    }
       
    g3 = board.create('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];
        }
    }
    g4 = board.create('curve', [t, dataprey], {strokeColor:'blue', strokeWidth:'2px'});
    g4.updateDataArray = function() {
         var data = ode();
         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];
        }
    }
</jsxgraph>
==Source code==
<source lang="javascript">
    // Initialise board
    board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-1.5, 28.5, 28.5, -1.5], axis: true, grid: false});
    // Define sliders to dynamically change parameters of the equations and create text elements to describe them
    s = board.create('slider', [[20.0,26.0],[25.0,26.0],[0.0,0.3,1.0]],{name:'&epsilon;1',strokeColor:'black',fillColor:'black'});
    st = board.create('text', [20,25, "Birth rate predators"], {fixed:true});
    u = board.create('slider', [[20.0,24.0],[25.0,24.0],[0.0,0.7,1.0]],{name:'&epsilon;2',strokeColor:'black',fillColor:'black'});
    ut = board.create('text', [20,23, "Death rate predators"], {fixed:true});
    o = board.create('slider', [[10.0,26.0],[15.0,26.0],[0.0,0.1,1.0]],{name:'&gamma;1',strokeColor:'black',fillColor:'black'});
    ot = board.create('text', [10,25, "Death rate preys/per predator"], {fixed:true});
    p = board.create('slider', [[10.0,24.0],[15.0,24.0],[0.0,0.3,1.0]],{name:'&gamma;2',strokeColor:'black',fillColor:'black'});
    pt = board.create('text', [10,23, "Reproduction rate pred./per prey"], {fixed:true});
    // Dynamic initial value as gliders on the y-axis
    startpred = board.create('glider', [0, 10, board.defaultAxes.y], {name:'Preys',strokeColor:'red',fillColor:'red'});
    startprey = board.create('glider', [0, 5, board.defaultAxes.y], {name:'Predators',strokeColor:'blue',fillColor:'blue'});
    // 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('euler', x0, I, N, f);
        // to plot the data against time we need the times where the equations were solved
         var t = [];
         var t = [];
         var dataprey = [];
         var q = I[0];
         var datapred = [];
         var h = (I[1]-I[0])/N;
         for(var i=0; i<data.length; i++) {
         for(var i=0; i<data.length; i++) {
             t[i] = data[i][2];
             data[i].push(q);
            datapred[i] = data[i][0];
             q += h;
             dataprey[i] = data[i][1];
         }
         }
          
 
         g3 = board.createElement('curve', [t, datapred], {strokeColor:'red', strokeWidth:'2px'});
        return data;
        g3.updateDataArray = function() {
    }
            var data = ode();
   
            this.dataX = [];
    // get data points
            this.dataY = [];
    var data = ode();
            for(var i=0; i<data.length; i++) {
 
                this.dataX[i] = t[i];
    // copy data to arrays so we can plot it using JXG.Curve
                this.dataY[i] = data[i][0];
    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.create('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];
         }
         }
        g4 = board.createElement('curve', [t, dataprey], {strokeColor:'blue', strokeWidth:'2px'});
    }
        g4.updateDataArray = function() {
 
            var data = ode();
    // Plot Prey
            this.dataX = [];
    g4 = board.create('curve', [t, dataprey], {strokeColor:'blue', strokeWidth:'2px'});
            this.dataY = [];
    g4.updateDataArray = function() {
            for(var i=0; i<data.length; i++) {
        var data = ode();
                this.dataX[i] = t[i];
        this.dataX = [];
                this.dataY[i] = data[i][1];
        this.dataY = [];
            }
        for(var i=0; i<data.length; i++) {
            this.dataX[i] = t[i];
            this.dataY[i] = data[i][1];
         }
         }
     }
     }
   
</source>
    createCurve();
 
</jsxgraph>
 
[[Category:Examples]]
[[Category:Calculus]]

Latest revision as of 13:08, 3 March 2021

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]

Meaning of the variables:

[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', {boundingbox: [-1.5, 28.5, 28.5, -1.5], axis: true, grid: false});

    // Define sliders to dynamically change parameters of the equations and create text elements to describe them
    s = board.create('slider', [[20.0,26.0],[25.0,26.0],[0.0,0.3,1.0]],{name:'&epsilon;1',strokeColor:'black',fillColor:'black'});
    st = board.create('text', [20,25, "Birth rate predators"], {fixed:true});
    u = board.create('slider', [[20.0,24.0],[25.0,24.0],[0.0,0.7,1.0]],{name:'&epsilon;2',strokeColor:'black',fillColor:'black'});
    ut = board.create('text', [20,23, "Death rate predators"], {fixed:true});

    o = board.create('slider', [[10.0,26.0],[15.0,26.0],[0.0,0.1,1.0]],{name:'&gamma;1',strokeColor:'black',fillColor:'black'});
    ot = board.create('text', [10,25, "Death rate preys/per predator"], {fixed:true});
    p = board.create('slider', [[10.0,24.0],[15.0,24.0],[0.0,0.3,1.0]],{name:'&gamma;2',strokeColor:'black',fillColor:'black'});
    pt = board.create('text', [10,23, "Reproduction rate pred./per prey"], {fixed:true});

    // Dynamic initial value as gliders on the y-axis
    startpred = board.create('glider', [0, 10, board.defaultAxes.y], {name:'Preys',strokeColor:'red',fillColor:'red'});
    startprey = board.create('glider', [0, 5, board.defaultAxes.y], {name:'Predators',strokeColor:'blue',fillColor:'blue'});


    // 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('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.create('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.create('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];
        }
    }