Share JSXGraph: example "Epidemiology: SIR model"

JSXGraph
Share JSXGraph: example "Epidemiology: SIR model"
This website is a beta version. The official release will be in **2023**.

Epidemiology: SIR model

Have also a look at "Epidemiology: SEIR model".
This is an example of simulation of differential equations with __turtle graphics__. ### SIR model without vital dynamics The SIR model measures the number of susceptible, infected, and recovered individuals in a host population. Given a fixed population, let $S(t)$ be the fraction that is susceptible to an infectious, but not deadly, disease at time $t$, let $I(t)$ be the fraction that is infected at time $t$ and let $R(t)$ be the fraction that has recovered. Let $\beta$ be the rate at which an infected person infects a susceptible person. Let $\gamma$ be the rate at which infected people recover from the disease. A single epidemic outbreak is usually far more rapid than the vital dynamics of a population, thus, if the aim is to study the immediate consequences of a single epidemic, one may neglect birth-death processes. In this case the SIR system can be expressed by the following set of differential equations: $$ \begin{aligned} \frac{dS}{dt} &= - \beta I S \\ \frac{dR}{dt} &= \gamma I \\ \frac{dI}{dt} &= -(\frac{dS}{dt}+\frac{dR}{dt}) \end{aligned} $$ ### Example Hong Kong flu - initially 7.9 million people, - 10 infected, - 0 recovered. - estimated average period of infection: 3 days, so $\gamma = 1/3$ - infection rate: one new person every other day, so $\beta = 1/2$ Thus $S(0) = 1$, $I(0) = 1.27E-6$, $R(0) = 0$, see [https://www.cs.princeton.edu/introcs/94diffeq/](https://www.cs.princeton.edu/introcs/94diffeq/). The lines in the JSXGraph-simulation below have the following meaning: - Blue: Rate of susceptible population - Red: Rate of infected population - Green: Rate of recovered population (which means: immune, isolated or dead)


<input type="button" value="clear and run a simulation of 100 days" onClick="clearTurtle(); run()"><br/>
<input type="button" value="stop" onClick="stop()"><br/>
<input type="button" value="continue" onClick="goOn()">
// Define the id of your board in BOARDID

const board = JXG.JSXGraph.initBoard(BOARDID, {
    axis: true,
    boundingbox: [-5, 1.2, 100, -1.2],
    showNavigation: false
});

// Turtles
var S = board.create('turtle', [], {
    strokeColor: 'blue',
    strokeWidth: 3
});
var I = board.create('turtle', [], {
    strokeColor: 'red',
    strokeWidth: 3
});
var R = board.create('turtle', [], {
    strokeColor: 'green',
    strokeWidth: 3
});

// Sliders
var s = board.create('slider', [
    [0, -0.6],
    [30, -0.6],
    [0, 1.27E-6, 1]
], {
    name: 's'
});
board.create('text', [10, -0.3, "initially infected population rate (on load: I(0)=1.27E-6)"]);
var beta = board.create('slider', [
    [0, -0.7],
    [30, -0.7],
    [0, 0.5, 1]
], {
    name: 'β'
});
board.create('text', [45, -0.7, "β: infection rate"]);
var gamma = board.create('slider', [
    [0, -0.8],
    [30, -0.8],
    [0, 0.3, 1]
], {
    name: 'γ'
});
board.create('text', [45, -0.8, "γ: recovery rate = 1/(days of infection)"]);

var t = 0; // global

board.create('text', [10, -0.2,
    function() {
        return "Day " + t + ": infected=" + (7900000 * I.Y()).toFixed(1) + " recovered=" + (7900000 * R.Y()).toFixed(1);
    }
]);

// Reset the turtles
var clearTurtle = function () {
  S.cs();
  I.cs();
  R.cs();

  S.hideTurtle();
  I.hideTurtle();
  R.hideTurtle();
};

// Start the animation
var run = function() {
    S.setPos(0, 1.0 - s.Value());
    R.setPos(0, 0);
    I.setPos(0, s.Value());

    delta = 1; // global
    t = 0; // global
    loop();
};

var turtleMove = function (turtle, dx, dy) {
    turtle.moveTo([dx + turtle.X(), dy + turtle.Y()]);
};

// Animation
var loop = function() {
    var dS = -beta.Value() * S.Y() * I.Y();
    var dR = gamma.Value() * I.Y();
    var dI = -(dS + dR);
    turtleMove(S, delta, dS);
    turtleMove(R, delta, dR);
    turtleMove(I, delta, dI);

    t += delta;
    if (t < 100.0) {
        active = setTimeout(loop, 10);
    }
};

// Stop animation
var stop = function() {
    if (active) clearTimeout(active);
    active = null;
};

// Continue
var goOn = function() {
    if (t > 0) {
        if (active === null) {
            active = setTimeout(loop, 10);
        }
    } else {
        run();
    }
};

clearTurtle();