Differential equation by Runge Kutta and Heun


Carl Runge and Wilhelm Kutta developed a family of methods to solve an ordinary differential equation of the form:




Runge Kutta



The idea is to calculate y for a random x and therefore the basic formulation for an iterative approximation of y by Runge and Kutta is




Runge Kutta



With h = step size and




Runge Kutta
Runge Kutta
Runge Kutta
Runge Kutta

...

Runge Kutta



That looks quite complicate but fortunately not all formulations use all numbers of k.




Method of Heun

The method of Karl Heun is similar to the second order Runge Kutta algorithm. It integrates both sides of the above formula to



Runge Kutta


And as



Runge Kutta



Runge Kutta



Now the definite integral is solved by the trapezoidal rule



Runge Kutta



and as the linearization of Euler says



Runge Kutta

Runge Kutta



and due to that we can approximate y1 to y1*



Runge Kutta




Runge Kutta



That looks quite inaccurate but with a small step size it’s not too bad :-)



This inserted in the above formula gives:



Runge Kutta




With


Runge Kutta

Runge Kutta




That’s the formulation of the Heun algorithm.





Second order Runge Kutta

From a different view we can say



Runge Kutta



is an approximation with the trapezoidal integration rule that uses the trapezoidal



Runge Kutta



Instead of this we can as well use the function value on the half way from x0 to x1 multiplied by h like



Runge Kutta



with this we get the formulation of the second order Runge Kutta algorithm:



Runge Kutta

Runge Kutta



and



Runge Kutta



Implemented in a small loop the Heun algorithm looks like:



int i;
double h = 1.0 / (double)(datapoints-1);
double k1, k2;
xp[0] = 0;
yp[0] = 1; // initial value for y[0]
for (i = 1; i < datapoints; i++)
{
     xp[i] = i * h;
     k1 = f_xy(xp[i - 1], yp[i - 1]);
     yp[i] = yp[i - 1] + h/2 * (k1 + f_xy(xp[i], yp[i - 1] + h * k1));
}




For the implementation of the second order Runge Kutta algorithm the last line in the loop must be replaced by the 2 lines



k2 = f_xy(xp[i - 1] + h / 2, yp[i - 1] + h / 2 * k1);
    yp[i] = yp[i - 1] + h * k2;





In my sample project I implemented the equation



Runge Kutta



With the initial value y(0) = 1


Which has the exact solution



Runge Kutta



And so



double f_xy(double x, double y)
{
     return -2 * x * y * y;
}





With this the exact solution for x = 1 is y = 0.5 The algorithm by Heun returns 0.50000982 and the Runge Kutta approach returns 0.499998 with 100 supporting points.




Fourth order Runge Kutta

Similar to the Heun algorithm, the 4. Order Runge Kutta algorithm integrates the main formula



Runge Kutta



to


Runge Kutta



But the definite integral is not solved by the trapezoidal method but the Simpson integral (see Simpson integration for a detailed description)


Runge Kutta

Runge Kutta



For this approach y1 and y2 must be computed somehow. Therefore y1 is approximated according to Heun as y1* = y0 + h*f(x0). This will be used later on.

With 3 supporting points we can set up a 3. order polynomial to approximate the function f(x) within the interval x0 to x2. That leads to the following 4 equations:


Runge Kutta



whereas


Runge Kutta

Runge Kutta



Now the basic approach would be to solve this matrix equation. But that would end in a hell of a calculation.

A more suitable way to proceed is to do a parameter comparison:


At the end we need the solution for the approximation of y2:


Runge Kutta



which can be written as:


Runge Kutta



or expanded:


Runge Kutta



From this equation a, b, c and d should vanish as they are unknown.

Therefore I first try to get rid of the h3 term in the a part.


If we have a look on a term


Runge Kutta



If this is subtracted from the equation for y2*


Runge Kutta



Some parts already vanished. But there is still 5x03 in the a part. That’s 4 too much. So I subtract 5y0


Runge Kutta

Runge Kutta



Now it’s easy to see that there is only the subtraction of 2g0h that remains:


Runge Kutta



and with this


Runge Kutta



or


Runge Kutta



and according to Heun


Runge Kutta



If this is inserted in the above formula we get


Runge Kutta



Or simplified


Runge Kutta



with


Runge Kutta



Now everything can be put together in the Simpson formula


Runge Kutta



With the approximation for y2 we have


Runge Kutta



with


Runge Kutta



Or in the Runge Kutta form


Runge Kutta



with


Runge Kutta
Runge Kutta
Runge Kutta



Now there is only one thing the remains: With this formulation h = (x1 – x0)/2. But we need h = (x1 – x0). That means we have to divide every h from above by 2 and get


Runge Kutta



With


Runge Kutta
Runge Kutta



and with


Runge Kutta

Runge Kutta



and as


Runge Kutta

Runge Kutta



In a small c# sequence that looks like:



double h = 1.0 / (double)(datapoints - 1);
double k1, k2, k3, k4;
 
xp[0] = 0;
yp[0] = 1; // initial value for y[0]
for (i = 1; i < datapoints; i++)
{
     xp[i] = i * h;
     k1 = f_xy(xp[i - 1], yp[i - 1]);
     k2 = f_xy(xp[i - 1] + h / 2, yp[i - 1] + h * k1 / 2);
     k3 = f_xy(xp[i - 1] + h / 2, yp[i - 1] + h * (k1 + k2) / 4);
     k4 = f_xy(xp[i - 1] + h, yp[i - 1] + h * (-k2 + 2 * k3));
     yp[i] = yp[i - 1] + h / 6 * (k1 + 4 * k3 + k4);
}




That looks quite similar to the second order Runge Kutta algorithm. But a comparision of the two’s shows the difference:


Runge Kutta



With its polynomial approximation the fourth order Runge Kutta algorithm is already quite accurate with just a few data points or a rather big step width between two data points. That makes it quite attractive as it is not too much more complicate to be implemented than the other two’s :-)



C# Demo Project to Runge Kutta algorithm
  • RungeKutta4.zip