MTH3007b Weekly Problems 2
Original Documents: Problem Sheet / Provided Solutions
Vibes: …
Used Techniques:
- …
2.1. Error Scaling for Forward Euler
Question
You run forward Euler with and find an error of in . What error would you expect if you halved the step size to ?
Forward (explicit) Euler is a first-order method, meaning its Global truncation error scales as . Halving therefore halves the error.
So if error at is :
2.2. Error Scaling for Ralston’s Method
Question
You run Ralston’s method with and find an error of . What error would you expect for ?
Ralston’s method is a second-order Runge-Kutta method, so its GTE scales as . Halving reduces the error by a factor of .
So if error at is :
2.3. Implementing Ralston’s Method and Verifying Second-Order Convergence
Question
Implement Ralston’s method for with , , , . Verify numerically that the method is second order by checking the error ratio as is halved.
Ralston’s method is a two-stage Runge-Kutta scheme with coefficients chosen to minimise the truncation error bound. The update is:
import numpy as np
forcing_coefficient = 1.0
decay_rate = 22.0
time_start = 0.0
time_end = 1.0
initial_value = 1.0
def g(t: float, y: float) -> float:
return forcing_coefficient * t - decay_rate * y
def y_exact(t: float) -> float:
return (
np.exp(-decay_rate * t) * (initial_value + forcing_coefficient / decay_rate ** 2)
+ forcing_coefficient * t / decay_rate
- forcing_coefficient / decay_rate ** 2
)
def ralston_step(g, t: float, y: float, time_step: float) -> float:
k1 = g(t, y)
k2 = g(t + 2 * time_step / 3, y + 2 * time_step * k1 / 3)
return y + time_step * (k1 / 4 + 3 * k2 / 4)
def run_ralston(time_step: float) -> float:
number_of_steps = int(round((time_end - time_start) / time_step))
current_t = time_start
current_y = initial_value
for _ in range(number_of_steps):
current_y = ralston_step(g, current_t, current_y, time_step)
current_t += time_step
return current_y
y_true = y_exact(time_end)
print(f"{'dt':>10} {'y(1)':>14} {'error':>14} {'ratio':>8}")
previous_error = None
for time_step in [0.1, 0.05, 0.025, 0.0125]:
y_numerical = run_ralston(time_step)
error = abs(y_numerical - y_true)
ratio = previous_error / error if previous_error is not None else float('nan')
print(f"{time_step:>10.4f} {y_numerical:>14.8f} {error:>14.6e} {ratio:>8.2f}")
previous_error = errorThe ratio column should converge to as decreases, confirming second-order convergence - each halving of reduces the error by a factor of .
Why second order? The Local truncation error of Ralston’s method is per step (it matches the Taylor series up to and including the term). With steps, the Global truncation error is .