Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

 Open In Colab

We are now in a position to generalize the Runge-Kutta (RK) methods. Our goal is to use intermediate evaluations of the slope function ff called stages knk_n to better approximate the true integral (via cancelation of higher order corrections in the Taylor series):

yi+1≈yi+h∑n=1sankny_{i+1} \approx y_i + h \sum_{n=1}^s a_n k_n

For the explicit family of RK methods, each stage knk_n depends only on previously computed stages:

k1=f(ti,yi)k2=f(ti+p2h,yi+[q21k1]h)k3=f(ti+p3h,yi+[q31k1+q32k2]h)    ⋮ks=f(ti+psh,yi+[qs1k1+qs2k2+⋯+qs,s−1ks−1]h)\begin{aligned} k_1 &= f(t_i, y_i) \\ k_2 &= f(t_i + p_2 h, y_i + [q_{21}k_1] h) \\ k_3 &= f(t_i + p_3 h, y_i + [q_{31}k_1 + q_{32}k_2] h) \\ &\;\;\vdots \\ k_s &= f(t_i + p_s h, y_i + [q_{s1}k_1 + q_{s2}k_2 + \cdots + q_{s,s-1} k_{s-1}] h) \end{aligned}

RK methods are parameterized by:

  • nodes pnp_n - the fraction of the current timestep

  • coupling coefficients qnmq_{nm} that construct new stages

  • weights ana_n - the final combination for the full time step

These constant parameters are characteristic of the specific RK scheme. Note that RK1 is simply the Forward Euler method.

Butcher Tableaux

Noting that ana_n, pnp_n, and qnmq_{nm} form two vectors of dimension ss and an s×ss \times s matrix, RK schemes can be written compactly in a Butcher Tableau. For explicit methods, this takes the form:

p1p2q21p3q31q32⋮⋮⋱psqs1qs2⋯qs,s−1a1a2⋯as−1as\begin{array}{c|ccccc} p_1 & & & & & \\ p_2 & q_{21} & & & & \\ p_3 & q_{31} & q_{32} & & & \\ \vdots & \vdots & & \ddots & & \\ p_s & q_{s1} & q_{s2} & \cdots & q_{s,s-1} & \\ \hline & a_1 & a_2 & \cdots & a_{s-1} & a_s \end{array}

Notice that the qnmq_{nm} matrix is strictly lower triangular, allowing each stage to be evaluated sequentially. We will later introduce the implicit family of RK methods, where entries appear on and above the diagonal!

For a given order, the values of ana_n, pnp_n, and qnmq_{nm} are derived to match the Taylor series expansion.

Second-Order Runge-Kutta (RK2) Derivation

For RK2 methods:

yi+1=yi+[a1k1+a2k2]hwithk1=f(ti,yi)k2=f(ti+p2h,yi+q21k1h)\begin{align} y_{i+1} &= y_i + [a_1 k_1 + a_2 k_2] h \\ &with \\ k_1 &= f(t_i, y_i) \\ k_2 &= f(t_i + p_2 h, y_i + q_{21} k_1 h) \\ \end{align}

Performing a bivariate Taylor expansion of k2k_2 around (ti,yi)(t_i, y_i):

k2=f(ti,yi)+p2h∂f∂t+q21k1h∂f∂y+O(h2)k_2 = f(t_i, y_i) + p_2 h \frac{\partial f}{\partial t} + q_{21} k_1 h \frac{\partial f}{\partial y} + O(h^2)

Substituting k1k_1 and k2k_2 into the update for yi+1y_{i+1}:

yi+1=yi+[a1+a2]f(ti,yi)h+[a2p2∂f∂t+a2q21f(ti,yi)∂f∂y]h2+O(h3)y_{i+1} = y_i + [a_1 + a_2] f(t_i, y_i) h + \left[a_2 p_2 \frac{\partial f}{\partial t} + a_2 q_{21} f(t_i, y_i) \frac{\partial f}{\partial y}\right] h^2 + O(h^3)

Comparing this against the exact second-order Taylor expansion using the chain rule f′(ti,yi)=∂f∂t+∂f∂yf(ti,yi)f'(t_i, y_i) = \frac{\partial f}{\partial t} + \frac{\partial f}{\partial y} f(t_i, y_i):

yi+1=yi+f(ti,yi)h+[∂f∂t+∂f∂yf(ti,yi)]h22+O(h3)y_{i+1} = y_i + f(t_i, y_i) h + \left[\frac{\partial f}{\partial t} + \frac{\partial f}{\partial y} f(t_i, y_i)\right] \frac{h^2}{2} + O(h^3)

Matching terms yields three equations for four unknowns (1 degree of freedom):

a1+a2=1a2p2=12a2q21=12\begin{aligned} a_1 + a_2 &= 1 \\ a_2 p_2 &= \frac{1}{2} \\ a_2 q_{21} &= \frac{1}{2} \end{aligned}

RK2 Variants: Heun’s, Midpoint, and Ralston’s Methods

Any choice of a2a_2 satisfies the second-order conditions and integrates constant, linear, and quadratic trajectories exactly:

  • Heun’s Method (a2=12a_2 = \frac{1}{2}): Averages endpoint slopes k1=f(ti,yi)k_1 = f(t_i, y_i) and k2=f(ti+h,yi+k1h)k_2 = f(t_i + h, y_i + k_1 h).

  • Midpoint Method (a2=1a_2 = 1): Uses the midpoint slope k2=f(ti+12h,yi+12k1h)k_2 = f\left(t_i + \frac{1}{2}h, y_i + \frac{1}{2} k_1 h\right).

  • Ralston’s Method (a2=23a_2 = \frac{2}{3}): Provides a minimum bound on the leading local truncation error:

yi+1=yi+h3[k1+2k2],k1=f(ti,yi),k2=f(ti+34h,yi+34k1h)y_{i+1} = y_i + \frac{h}{3}[k_1 + 2 k_2], \quad k_1 = f(t_i, y_i), \quad k_2 = f\left(t_i + \frac{3}{4}h, y_i + \frac{3}{4} k_1 h\right)
Heun:0111212Midpoint:0121201Ralston:034341323\text{Heun:} \quad \begin{array}{c|cc} 0 & & \\ 1 & 1 & \\ \hline & \frac{1}{2} & \frac{1}{2} \end{array} \qquad \text{Midpoint:} \quad \begin{array}{c|cc} 0 & & \\ \frac{1}{2} & \frac{1}{2} & \\ \hline & 0 & 1 \end{array} \qquad \text{Ralston:} \quad \begin{array}{c|cc} 0 & & \\ \frac{3}{4} & \frac{3}{4} & \\ \hline & \frac{1}{3} & \frac{2}{3} \end{array}
differential_equations_module.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def ralston_method(f, t0, y0, t_end, h):
    t_points = np.arange(t0, t_end + h / 2, h)
    y_points = np.zeros_like(t_points, dtype=float)
    y_points[0] = y0

    for i in range(len(t_points) - 1):
        t_i, y_i = t_points[i], y_points[i]
        k1 = f(t_i, y_i)
        k2 = f(t_i + 0.75 * h, y_i + 0.75 * h * k1)
        y_points[i + 1] = y_points[i] + h * (k1 + 2.0 * k2) / 3.0

    return {
        "t_points": t_points,
        "y_points": y_points,
        "h": h,
        "method": "Ralston's Method (RK2)",
    }

Third-Order Runge-Kutta (RK3) Methods

A similar derivation follows for RK3 with additional degrees of freedom. Kutta’s classical third-order choice is:

yi+1=yi+h6[k1+4k2+k3]y_{i+1} = y_i + \frac{h}{6}[k_1 + 4 k_2 + k_3]

with

k1=f(ti,yi)k2=f(ti+12h,yi+12k1h)k3=f(ti+h,yi−k1h+2k2h)\begin{aligned} k_1 &= f(t_i, y_i) \\ k_2 &= f\left(t_i + \frac{1}{2}h, y_i + \frac{1}{2} k_1 h\right) \\ k_3 &= f(t_i + h, y_i - k_1 h + 2 k_2 h) \end{aligned}

which reduces to Simpson’s 1/31/3 Rule when ff is solely a function of tt, achieving O(h4)O(h^4) local and O(h3)O(h^3) global accuracy:

012121−12162316\begin{array}{c|ccc} 0 & & & \\ \frac{1}{2} & \frac{1}{2} & & \\ 1 & -1 & 2 & \\ \hline & \frac{1}{6} & \frac{2}{3} & \frac{1}{6} \end{array}
differential_equations_module.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def rk3_method(f, t0, y0, t_end, h):
    t_points = np.arange(t0, t_end + h / 2, h)
    y_points = np.zeros_like(t_points, dtype=float)
    y_points[0] = y0

    for i in range(len(t_points) - 1):
        t_i, y_i = t_points[i], y_points[i]
        k1 = f(t_i, y_i)
        k2 = f(t_i + 0.5 * h, y_i + 0.5 * h * k1)
        k3 = f(t_i + h, y_i - h * k1 + 2.0 * h * k2)
        y_points[i + 1] = y_points[i] + h * (k1 + 4.0 * k2 + k3) / 6.0

    return {
        "t_points": t_points,
        "y_points": y_points,
        "h": h,
        "method": "Classical RK3",
    }

Fourth-Order Runge-Kutta (Classical RK4)

Classical RK4 is the workhorse of fixed-step explicit integration:

yi+1=yi+h6[k1+2k2+2k3+k4]y_{i+1} = y_i + \frac{h}{6}[k_1 + 2 k_2 + 2 k_3 + k_4]

with

k1=f(ti,yi)k2=f(ti+12h,yi+12k1h)k3=f(ti+12h,yi+12k2h)k4=f(ti+h,yi+k3h)\begin{aligned} k_1 &= f(t_i, y_i) \\ k_2 &= f\left(t_i + \frac{1}{2}h, y_i + \frac{1}{2} k_1 h\right) \\ k_3 &= f\left(t_i + \frac{1}{2}h, y_i + \frac{1}{2} k_2 h\right) \\ k_4 &= f(t_i + h, y_i + k_3 h) \end{aligned}

achieving O(h5)O(h^5) local and O(h4)O(h^4) global truncation error:

0121212012100116131316\begin{array}{c|cccc} 0 & & & & \\ \frac{1}{2} & \frac{1}{2} & & & \\ \frac{1}{2} & 0 & \frac{1}{2} & & \\ 1 & 0 & 0 & 1 & \\ \hline & \frac{1}{6} & \frac{1}{3} & \frac{1}{3} & \frac{1}{6} \end{array}
differential_equations_module.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def rk4_method(f, t0, y0, t_end, h):
    t_points = np.arange(t0, t_end + h / 2, h)
    y_points = np.zeros_like(t_points, dtype=float)
    y_points[0] = y0

    for i in range(len(t_points) - 1):
        t_i, y_i = t_points[i], y_points[i]
        k1 = f(t_i, y_i)
        k2 = f(t_i + 0.5 * h, y_i + 0.5 * h * k1)
        k3 = f(t_i + 0.5 * h, y_i + 0.5 * h * k2)
        k4 = f(t_i + h, y_i + h * k3)
        y_points[i + 1] = y_points[i] + h * (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0

    return {
        "t_points": t_points,
        "y_points": y_points,
        "h": h,
        "method": "Classical RK4",
    }

Example: Geometric Anatomy of RK4 Stages

Notice how the RK4 algorithm walks its way forward across the interval: partial trial steps k1,k2,k3,k4k_1, k_2, k_3, k_4 inform subsequent slope evaluations, culminating in a highly accurate weighted step.

Runge-Kutta slopes

Because internal stages systematically cancel higher-order Taylor derivatives, a single RK4 step achieves far better accuracy than two RK2 half-steps using the same number of function evaluations. However, this assumes the solution is smooth over the step hh—when rapid transients occur, we need adaptive time stepping.