Differential Equations in Java

Sergei G picture Sergei G · Dec 5, 2010 · Viewed 15.2k times · Source

I am trying to create a simple simulation program of SIR-epidemics model in java.

Basically, SIR is defined by a system of three differential equations:
S'(t) = - l(t) * S(t)
I'(t) = l(t) * S(t) - g(t) * I(t)
R'(t) = g(t) * I(t)

S - susceptible people, I - infected people, R - recovered people.

l(t) = [c * x * I(t)] / N(T)

c - number of contacts, x - infectiveness (probability to get sick after contact with sick person), N(t) - total population (which is constant).

How can I solve such differential equations in Java? I don't think I know any useful way to do that, so my implementation produces rubbish.

public class Main {
public static void main(String[] args) {
    int tppl = 100;
    double sppl = 1;
    double hppl = 99;
    double rppl = 0;
    int numContacts = 50;
    double infectiveness = 0.5;
    double lamda = 0;
    double duration = 0.5;
    double gamma = 1 / duration;
    for (int i = 0; i < 40; i++) {
        lamda = (numContacts * infectiveness * sppl) / tppl;
        hppl = hppl - lamda * hppl;
        sppl = sppl + lamda * hppl - gamma * sppl;
        rppl = rppl + gamma * sppl;
        System.out.println (i + " " + tppl + " " + hppl + " " + sppl + " " + rppl); 
    }
}

}

I would greatly appreciate any help, many thanks in advance!

Answer

Jason S picture Jason S · Dec 5, 2010

Time-series differential equations can be simulated numerically by taking dt = a small number, and using one of several numerical integration techniques e.g. Euler's method, or Runge-Kutta. Euler's method may be primitive but it works OK for some equations and it's simple enough that you might give it a try. e.g.:

S'(t) = - l(t) * S(t)

I'(t) = l(t) * S(t) - g(t) * I(t)

R'(t) = g(t) * I(t)

int N = 100;
double[] S = new double[N+1];
double[] I = new double[N+1];
double[] R = new double[N+1];

S[0] = /* initial value */
I[0] = /* initial value */
R[0] = /* initial value */

double dt = total_time / N;

for (int i = 0; i < 100; ++i)
{
   double t = i*dt;
   double l = /* compute l here */
   double g = /* compute g here */

   /* calculate derivatives */
   double dSdt = - I[i] * S[i];
   double dIdt = I[i] * S[i] - g * I[i];
   double dRdt = g * I[i];

   /* now integrate using Euler */
   S[i+1] = S[i] + dSdt * dt;
   I[i+1] = I[i] + dIdt * dt;
   R[i+1] = R[i] + dRdt * dt;
}

The tough part is figuring out how many steps to use. You should read one of the articles I have linked to. More sophisticated differential equation solvers use variable step sizes that adapt to accuracy/stability for each step.

I would actually recommend using numerical software like R or Mathematica or MATLAB or Octave, as they include ODE solvers and you wouldn't need to go to all the trouble yourself. But if you need to do this as part of a larger Java application, at least try it out first with math software, then get a sense of what the step sizes are and what solvers work.

Good luck!