Runge-Kutta Methods and Adaptive Time-Stepping University of Massachusetts Amherst
Runge-Kutta methods achieve higher order accuracy by evaluating f f f at multiple
points within each step—no derivatives of f f f required. Embedded pairs
compute two approximations of different orders using (nearly) the same work,
enabling automatic error estimation. This powers adaptive time-stepping :
adjust h h h to maintain accuracy while minimizing computational cost.
Beyond Euler: The Need for Higher Order ¶ Euler’s method has local truncation error O ( h ) O(h) O ( h ) —first order. To achieve 10-6 accuracy might require millions of steps.
The challenge: Higher-order Taylor methods require derivatives of f f f :
u ( t + h ) = u ( t ) + h f + h 2 2 ( f t + f u f ) + ⋯ u(t+h) = u(t) + hf + \frac{h^2}{2}(f_t + f_u f) + \cdots u ( t + h ) = u ( t ) + h f + 2 h 2 ( f t + f u f ) + ⋯ Computing f t f_t f t , f u f_u f u , f u u f_{uu} f uu , etc. is tedious and error-prone.
The Runge-Kutta idea: Evaluate f f f at cleverly chosen intermediate points and combine to cancel error terms—no derivatives needed.
Second-Order Runge-Kutta (RK2) ¶ The Method ¶ Given the initial value problem u ′ ( t ) = f ( t , u ) u'(t) = f(t, u) u ′ ( t ) = f ( t , u ) , we proceed in two stages:
r 1 = f ( t n , u n ) r 2 = f ( t n + α h , u n + β h r 1 ) \begin{aligned}
r_1 &= f(t_n, u_n) \\
r_2 &= f(t_n + \alpha h, u_n + \beta h r_1)
\end{aligned} r 1 r 2 = f ( t n , u n ) = f ( t n + α h , u n + β h r 1 ) Here α , β ∈ [ 0 , 1 ] \alpha, \beta \in [0, 1] α , β ∈ [ 0 , 1 ] are fractional values to be determined. The update is:
u n + 1 = u n + h ( a r 1 + b r 2 ) u_{n+1} = u_n + h(a r_1 + b r_2) u n + 1 = u n + h ( a r 1 + b r 2 ) When a = 1 a = 1 a = 1 and b = 0 b = 0 b = 0 , this reduces to forward Euler. Our goal is to find a , b , α , β a, b, \alpha, \beta a , b , α , β that give second-order accuracy.
Derivation: Matching Taylor Series ¶ Goal: Choose parameters so the local truncation error is O ( h 2 ) O(h^2) O ( h 2 ) instead of O ( h ) O(h) O ( h ) .
Step 1: Taylor expand the exact solution.
u ( t n + 1 ) = u ( t n ) + h u ′ ( t n ) + h 2 2 u ′ ′ ( t n ) + O ( h 3 ) u(t_{n+1}) = u(t_n) + hu'(t_n) + \frac{h^2}{2}u''(t_n) + O(h^3) u ( t n + 1 ) = u ( t n ) + h u ′ ( t n ) + 2 h 2 u ′′ ( t n ) + O ( h 3 ) Using u ′ = f u' = f u ′ = f and the chain rule u ′ ′ = f t + f u f u'' = f_t + f_u f u ′′ = f t + f u f :
u ( t n + 1 ) = u n + h f + h 2 2 ( f t + f u f ) + O ( h 3 ) u(t_{n+1}) = u_n + hf + \frac{h^2}{2}(f_t + f_u f) + O(h^3) u ( t n + 1 ) = u n + h f + 2 h 2 ( f t + f u f ) + O ( h 3 ) Step 2: Taylor expand r 2 r_2 r 2 .
r 2 = f ( t n + α h , u n + β h r 1 ) = f + α h f t + β h f u r 1 + O ( h 2 ) r_2 = f(t_n + \alpha h, u_n + \beta h r_1) = f + \alpha h f_t + \beta h f_u r_1 + O(h^2) r 2 = f ( t n + α h , u n + β h r 1 ) = f + α h f t + β h f u r 1 + O ( h 2 ) Since r 1 = f r_1 = f r 1 = f :
r 2 = f + h ( α f t + β f u f ) + O ( h 2 ) r_2 = f + h(\alpha f_t + \beta f_u f) + O(h^2) r 2 = f + h ( α f t + β f u f ) + O ( h 2 ) Step 3: Expand the numerical method.
Substituting into the update formula:
u n + 1 = u n + h ( a r 1 + b r 2 ) = u n + h ( a + b ) f + h 2 b ( α f t + β f u f ) + O ( h 3 ) u_{n+1} = u_n + h(ar_1 + br_2) = u_n + h(a+b)f + h^2 b(\alpha f_t + \beta f_u f) + O(h^3) u n + 1 = u n + h ( a r 1 + b r 2 ) = u n + h ( a + b ) f + h 2 b ( α f t + β f u f ) + O ( h 3 ) Step 4: Match coefficients.
Equating terms of equal order in h h h on both sides:
Order Exact solution Numerical method Condition O ( h ) O(h) O ( h ) f f f ( a + b ) f (a+b)f ( a + b ) f a + b = 1 a + b = 1 a + b = 1 O ( h 2 ) O(h^2) O ( h 2 ) , f t f_t f t term1 2 f t \frac{1}{2}f_t 2 1 f t b α f t b\alpha f_t b α f t b α = 1 2 b\alpha = \frac{1}{2} b α = 2 1 O ( h 2 ) O(h^2) O ( h 2 ) , f u f f_u f f u f term1 2 f u f \frac{1}{2}f_u f 2 1 f u f b β f u f b\beta f_u f b β f u f b β = 1 2 b\beta = \frac{1}{2} b β = 2 1
Three equations, four unknowns — a one-parameter family of solutions!
Common RK2 Methods ¶ With a = 0 a = 0 a = 0 , b = 1 b = 1 b = 1 , and α = β = 1 / 2 \alpha = \beta = 1/2 α = β = 1/2 :
r 1 = f ( t n , u n ) r 2 = f ( t n + h 2 , u n + h 2 r 1 ) u n + 1 = u n + h r 2 \begin{aligned}
r_1 &= f(t_n, u_n) \\
r_2 &= f\left(t_n + \frac{h}{2}, u_n + \frac{h}{2}r_1\right) \\
u_{n+1} &= u_n + h r_2
\end{aligned} r 1 r 2 u n + 1 = f ( t n , u n ) = f ( t n + 2 h , u n + 2 h r 1 ) = u n + h r 2 Interpretation: Take half an Euler step, evaluate the slope there, use that slope for the full step.
Midpoint method (a = 0 , b = 1 , α = β = 1 / 2 a=0, b=1, \alpha=\beta=1/2 a = 0 , b = 1 , α = β = 1/2 ) solving u ′ = − 2 u u'=-2u u ′ = − 2 u with h = 0.2 h=0.2 h = 0.2 . Step 1: Compute slope r 1 r_1 r 1 at the current point. Step 2: Euler step with step-size h / 2 h/2 h /2 . Step 3: Compute slope r 2 r_2 r 2 at the intermediate point. Step 4: Full step uses slope r 2 r_2 r 2 . The diamond shows Euler’s result for comparison.
With a = b = 1 / 2 a = b = 1/2 a = b = 1/2 and α = β = 1 \alpha = \beta = 1 α = β = 1 :
r 1 = f ( t n , u n ) r 2 = f ( t n + h , u n + h r 1 ) u n + 1 = u n + h 2 ( r 1 + r 2 ) \begin{aligned}
r_1 &= f(t_n, u_n) \\
r_2 &= f(t_n + h, u_n + h r_1) \\
u_{n+1} &= u_n + \frac{h}{2}(r_1 + r_2)
\end{aligned} r 1 r 2 u n + 1 = f ( t n , u n ) = f ( t n + h , u n + h r 1 ) = u n + 2 h ( r 1 + r 2 ) Interpretation: Take a full Euler step, then average the initial and final slopes.
Heun’s method (a = b = 1 / 2 , α = β = 1 a=b=1/2, \alpha=\beta=1 a = b = 1/2 , α = β = 1 ) solving u ′ = − 5 u u'=-5u u ′ = − 5 u with h = 0.2 h=0.2 h = 0.2 . Step 1: Compute slope at initial point. Step 2: Full Euler step. Step 3: Compute slope at the new point. Step 4: Final step uses the average of the two slopes. The diamond shows Euler’s result for comparison.
Both methods have local truncation error O ( h 2 ) O(h^2) O ( h 2 ) , i.e. second order.
Embedded Pairs and Error Estimation ¶ Fixed step sizes are inefficient: too small wastes work, too large loses
accuracy. To adapt h h h locally, we need an estimate of the local
truncation error at each step. But τ n \tau_n τ n depends on the unknown exact
solution, so we cannot compute it directly. The key idea is to obtain a
cheap error estimate by comparing two methods of different order.
The Embedded Pair Idea ¶ Compute two approximations of different orders using the same f f f evaluations:
The difference estimates the local error of the lower-order method:
err ≈ ∣ u n + 1 − u ^ n + 1 ∣ = O ( h p ) \text{err} \approx |u_{n+1} - \hat{u}_{n+1}| = O(h^p) err ≈ ∣ u n + 1 − u ^ n + 1 ∣ = O ( h p ) RK12: Euler-Midpoint Pair ¶ Embed Euler (order 1) with RK2 midpoint (order 2):
Cost: 2 function evaluations per step (same as plain RK2), plus we get an error estimate!
Why This Works ¶ The difference between the methods is approximately:
u ^ n + 1 − u n + 1 = h ( r 1 − r 2 ) ≈ − h 2 2 ( f t + f u f ) = − h 2 2 u ′ ′ ( t n ) \hat{u}_{n+1} - u_{n+1} = h(r_1 - r_2) \approx -\frac{h^2}{2}(f_t + f_u f) = -\frac{h^2}{2}u''(t_n) u ^ n + 1 − u n + 1 = h ( r 1 − r 2 ) ≈ − 2 h 2 ( f t + f u f ) = − 2 h 2 u ′′ ( t n ) This is (up to sign) the leading error term in Euler’s method.
Adaptive Time-Stepping ¶ With an error estimate, we can adjust h h h automatically.
Input: Tolerance parameters atol, rtol; current step size h h h ; current state ( t n , u n ) (t_n, u_n) ( t n , u n )
Output: New state ( t n + 1 , u n + 1 ) (t_{n+1}, u_{n+1}) ( t n + 1 , u n + 1 ) and updated step size h new h_{\text{new}} h new
Compute the step using RK12:
r 1 = f ( t n , u n ) r_1 = f(t_n, u_n) r 1 = f ( t n , u n )
r 2 = f ( t n + h / 2 , u n + h r 1 / 2 ) r_2 = f(t_n + h/2, u_n + hr_1/2) r 2 = f ( t n + h /2 , u n + h r 1 /2 )
u ^ n + 1 = u n + h r 1 \hat{u}_{n+1} = u_n + hr_1 u ^ n + 1 = u n + h r 1 (Euler)
u n + 1 = u n + h r 2 u_{n+1} = u_n + hr_2 u n + 1 = u n + h r 2 (Midpoint)
Estimate scaled error:
s = atol + max ( ∣ u n ∣ , ∣ u n + 1 ∣ ) ⋅ rtol s = \text{atol} + \max(|u_n|, |u_{n+1}|) \cdot \text{rtol} s = atol + max ( ∣ u n ∣ , ∣ u n + 1 ∣ ) ⋅ rtol
err = ∥ u n + 1 − u ^ n + 1 s ∥ \text{err} = \left\|\frac{u_{n+1} - \hat{u}_{n+1}}{s}\right\| err = ∥ ∥ s u n + 1 − u ^ n + 1 ∥ ∥ Accept or reject:
If err ≤ 1 \text{err} \leq 1 err ≤ 1 : accept step, set t n + 1 ← t n + h t_{n+1} \leftarrow t_n + h t n + 1 ← t n + h
If err > 1 \text{err} > 1 err > 1 : reject step, keep ( t n , u n ) (t_n, u_n) ( t n , u n )
Update step size:
h new = h ⋅ min ( α max , max ( α min , α ⋅ err − 1 / ( p + 1 ) ) ) h_{\text{new}} = h \cdot \min\left(\alpha_{\max}, \max\left(\alpha_{\min}, \alpha \cdot \text{err}^{-1/(p+1)}\right)\right) h new = h ⋅ min ( α m a x , max ( α m i n , α ⋅ err − 1/ ( p + 1 ) ) ) where α ≈ 0.9 \alpha \approx 0.9 α ≈ 0.9 (safety factor), α min ≈ 0.2 \alpha_{\min} \approx 0.2 α m i n ≈ 0.2 , α max ≈ 5 \alpha_{\max} \approx 5 α m a x ≈ 5 .
Repeat from step 1 (with rejected step) or continue to next time step (if accepted).
Generalizations to Higher Order Methods ¶ The RK2 derivation extends to higher orders:
RK4 (Classical 4th-order): Uses 4 stages, local error O ( h 4 ) O(h^4) O ( h 4 ) . The most popular “hand-coded” method.
RK45 (Dormand-Prince): A 5th-order method with embedded 4th-order for error estimation. Used in scipy.integrate.solve_ivp with method='RK45'.
The derivation follows the same pattern: Taylor expand, match coefficients. But the algebra becomes increasingly complex; these methods are derived once and tabulated.