Exercises — Implementing ODE solvers from scratch — Euler, RK4
Level 1 — Recognition
(Can you name the pieces and plug into the formulas?)
Exercise L1.1
State, in words and in symbols, where Euler's method gets the single slope it uses, and write the Euler update.
Recall Solution
Euler evaluates the slope only at the left endpoint of the step, at the point , and then assumes that one slope stays constant across the whole interval . Picture a straight line leaving with that slope; you slide along it by a horizontal distance and read off the new height .
Exercise L1.2
For the IVP , with , take one Euler step and give .
Recall Solution
Slope at the start: . Here depends only on , and at the slope is genuinely , so Euler predicts no rise on the first step (the true solution is also flat at the origin). .
Exercise L1.3
List the four RK4 stages and the final update, labelling where in the interval each slope is sampled.
Recall Solution
k_1 &= f(t_n,\ y_n) && \text{slope at the start}\\ k_2 &= f\!\left(t_n+\tfrac h2,\ y_n+\tfrac h2 k_1\right) && \text{slope at the midpoint, using }k_1\\ k_3 &= f\!\left(t_n+\tfrac h2,\ y_n+\tfrac h2 k_2\right) && \text{midpoint again, using }k_2\\ k_4 &= f\!\left(t_n+h,\ y_n+h\,k_3\right) && \text{slope at the end, using }k_3\\ y_{n+1} &= y_n + \tfrac h6\big(k_1 + 2k_2 + 2k_3 + k_4\big) \end{aligned}$$ The weights $1,2,2,1$ sum to $6$, so $\tfrac h6(\dots)$ is a genuine **weighted average slope**.Level 2 — Application
(Run the machinery on real numbers.)
Exercise L2.1
IVP , (true solution ). Using , take two Euler steps to estimate . Give both intermediate values and the final error against .
Recall Solution
Step 1 (from ): slope . Step 2 (from ): slope . Error . The curve bends upward, so Euler — using the lower left-endpoint slope each time — undershoots.
Exercise L2.2
Same IVP , . Take one RK4 step with to estimate . Show every .
Recall Solution
k_1 &= f(0,1) = 1\\ k_2 &= f(0.5,\ 1 + 0.5\cdot 1) = f(0.5,\,1.5) = 1.5\\ k_3 &= f(0.5,\ 1 + 0.5\cdot 1.5) = f(0.5,\,1.75) = 1.75\\ k_4 &= f(1,\ 1 + 1\cdot 1.75) = f(1,\,2.75) = 2.75 \end{aligned}$$ $$y_1 = 1 + \tfrac16\big(1 + 2(1.5) + 2(1.75) + 2.75\big) = 1 + \tfrac{10.25}{6} \approx 2.70833$$ Error $\approx 2.71828 - 2.70833 = 0.00995$ — about **47× smaller** than the two-step Euler above, and RK4 used the *whole step in one shot*.Exercise L2.3
Non-autonomous IVP , . Take one RK4 step with . (True answer: .) Because does not depend on , only the -shifts matter — show them.
Recall Solution
Here , so each is just of a shifted time:
k_1 &= \sin(0) = 0\\ k_2 &= \sin(0+\tfrac{\pi}{2}) = 1\\ k_3 &= \sin(\tfrac{\pi}{2}) = 1\\ k_4 &= \sin(\pi) = 0 \end{aligned}$$ $$y_1 = 0 + \tfrac{\pi}{6}\big(0 + 2 + 2 + 0\big) = \tfrac{4\pi}{6} = \tfrac{2\pi}{3} \approx 2.0944$$ Error $\approx 0.0944$. Notice this is **exactly** Simpson's $1/3$ rule applied to $\int_0^\pi \sin t\,dt$: sample the integrand at the two ends and the middle with weights $1,4,1$ (RK4's $2+2=4$ in the middle). See [[Simpson's Rule]].Level 3 — Analysis
(Explain and predict the behaviour, don't just compute.)
The figure below sets up the geometry for this whole level. Read it before attempting the exercises.

Exercise L3.1
Euler applied to , to gives error at and at . What error do you predict at , and why? Which order does the ratio confirm?
Recall Solution
Euler's global error is — halving roughly halves the error (the ratio confirms this). Halving again from to : Why ? Each step throws away a Taylor term of size (the local truncation error). Over steps these accumulate: . See Taylor Series Expansion.
Exercise L3.2
RK4 on the same problem gives error at . Predict the error at and at . State the order that justifies your factor.
Recall Solution
RK4 has global error , so halving shrinks the error by : This is why RK4 dominates: the same effort per step buys a sixteenfold accuracy gain each halving, versus Euler's mere doubling.
Exercise L3.3
Look at the figure (s01). On an upward-bending curve like , does forward Euler over- or under-shoot? On a downward-bending curve like region where the solution is concave? Explain from the geometry of "one left slope".
Recall Solution
Euler follows the tangent line drawn at the left endpoint. For a curve that is concave up (bending upward, like ), the tangent lies below the curve, so Euler undershoots (as in L2.1: ). For a curve that is concave down, the tangent lies above the curve, so Euler overshoots. The sign of the error is set by the sign of — precisely the Taylor term Euler discards. RK4 largely cancels this because it peeks at the midpoint and end before committing.
Level 4 — Synthesis
(Combine ideas, weigh trade-offs, prove small facts.)
Exercise L4.1
A student needs a global error of on over . Using the scaling laws (Euler , RK4 ), roughly how many steps does each method need? Comment on the practical verdict.
Recall Solution
Number of steps , and error , so to reach we need , i.e. (ignoring the constant ).
- Euler : steps — a hundred million.
- RK4 : steps. Even though RK4 costs 4 function calls per step, its total work evaluations crushes Euler's . Verdict: at any demanding accuracy, RK4 wins by orders of magnitude — this is the whole reason it is the default workhorse.
Exercise L4.2
Prove that for the autonomous linear test problem , one RK4 step multiplies by a fixed factor Then evaluate for and compare to .
Recall Solution
With (write ):
k_1 &= \lambda y_n\\ k_2 &= \lambda\!\left(y_n + \tfrac h2 k_1\right) = \lambda y_n\left(1+\tfrac z2\right)\\ k_3 &= \lambda\!\left(y_n + \tfrac h2 k_2\right) = \lambda y_n\left(1+\tfrac z2+\tfrac{z^2}{4}\right)\\ k_4 &= \lambda\!\left(y_n + h k_3\right) = \lambda y_n\left(1+z+\tfrac{z^2}{2}+\tfrac{z^3}{4}\right) \end{aligned}$$ Insert into $y_{n+1}=y_n+\tfrac h6(k_1+2k_2+2k_3+k_4)$ and factor $y_n$. Collecting powers of $z$ gives exactly $$y_{n+1} = y_n\Big(1 + z + \tfrac{z^2}{2} + \tfrac{z^3}{6} + \tfrac{z^4}{24}\Big) = y_n\,R(z).$$ This is the Taylor series of $e^{z}$ truncated after the $z^4$ term — the algebraic fingerprint of RK4's order-4 accuracy. At $z=1$: $$R(1) = 1 + 1 + 0.5 + 0.1\overline{6} + 0.041\overline{6} = 2.708\overline{3}$$ versus $e^1 = 2.71828\dots$ — matching L2.2's $y_1\approx 2.70833$ exactly.Exercise L4.3
Using from L4.1/L4.2, explain the stability condition for RK4 on with (decaying solution). What must satisfy, and what does this imply about for very negative ?
Recall Solution
Each step multiplies by , so after steps . For the numerical solution to decay like the true solution ( when ), we need For real this holds only while (the real stability boundary of RK4, the most negative where ). So for a strongly negative you must keep — a very small step — or the numbers blow up despite the true answer shrinking. This is the door to Numerical Stability and Stiff ODEs: stiff problems have huge , forcing tiny and motivating implicit solvers.
Level 5 — Mastery
(Design, generalise, defend against edge cases.)
Exercise L5.1
Generalise your solvers to a system (vector-valued). What line(s) of the scalar rk4 change, and why does the formula survive unchanged?
Recall Solution
Treat and each as vectors; returns a vector. In Python with NumPy arrays the code is identical — the arithmetic y + h/2 * k1, the weighted sum, all broadcast componentwise:
def rk4_system(f, t0, y0, h, n): # y0 is a numpy array
t, y = t0, y0.copy()
ts, ys = [t], [y.copy()]
for _ in range(n):
k1 = f(t, y)
k2 = f(t + h/2, y + h/2 * k1)
k3 = f(t + h/2, y + h/2 * k2)
k4 = f(t + h, y + h * k3)
y = y + (h/6) * (k1 + 2*k2 + 2*k3 + k4)
t = t + h
ts.append(t); ys.append(y.copy())
return ts, ysThe update is linear in the , so it applies to each component independently — the same weighted average of slopes, now one slope per dimension. This is how a 2nd-order ODE is solved: rewrite as the system , .
Exercise L5.2
Test your understanding of the harmonic oscillator. Rewrite , , (true: ) as a first-order system, and take one RK4 step with for the position component. (True: .)
Recall Solution
Let with . Then , start , . Each stage is a vector; we track both components and read off the position at the end.
k_1 &= (v,\,-y)\big|_{(1,0)} = (0,\,-1)\\ \mathbf y + \tfrac h2 k_1 &= \big(1 + \tfrac h2\cdot 0,\ 0 + \tfrac h2(-1)\big) = (1,\,-0.7854)\\ k_2 &= (-0.7854,\,-1)\\ \mathbf y + \tfrac h2 k_2 &= \big(1 + \tfrac h2(-0.7854),\ 0 + \tfrac h2(-1)\big) = (0.3831,\,-0.7854)\\ k_3 &= (-0.7854,\,-0.3831)\\ \mathbf y + h\,k_3 &= \big(1 + h(-0.7854),\ 0 + h(-0.3831)\big) = (-0.2337,\,-0.6017)\\ k_4 &= (-0.6017,\,0.2337) \end{aligned}$$ Now apply the RK4 update to the **position** component (the first entry of each $k_i$): $$y_1 = 1 + \tfrac h6\big(0 + 2(-0.7854) + 2(-0.7854) + (-0.6017)\big) = 1 + \tfrac{1.5708}{6}(-3.7433) \approx 0.0198$$ True value is $\cos(\tfrac\pi2)=0$, so the error after one big step is only $\approx 0.02$ — remarkable for a step spanning a quarter period. (Verified numerically in `===VERIFY===`.)Exercise L5.3
Degenerate/edge cases. For each, state what your solver returns and whether it is correct: (a) ; (b) steps; (c) (constant solution); (d) a discontinuous that jumps inside a step.
Recall Solution
- (a) : every update is and never advances. The loop runs but produces a constant list at — mathematically vacuous (no time passes). Guard against it in code.
- (b) : the
forloop body never executes; you return just the initial point . Correct — asking for zero steps. - (c) : all , so forever — exactly the true constant solution. Both Euler and RK4 are exact here (zero error), because a constant is a degree-0 polynomial well within RK4's order-4 exactness.
- (d) discontinuous : RK4's order-4 accuracy assumes is smooth (it relies on the Taylor expansion of ). A jump inside breaks that assumption; you silently lose accuracy. Fix: place a grid point exactly at the discontinuity so no step straddles it — the same event-handling that scipy.integrate.solve_ivp provides.
Connections
- Implementing ODE solvers from scratch — Euler, RK4 — the parent note these drills test.
- Taylor Series Expansion — the source of both error orders and RK4's .
- Simpson's Rule — L2.3 shows RK4 is Simpson on .
- Numerical Stability and Stiff ODEs — L4.3's condition.
- Adaptive Step Size (RK45 / Dormand–Prince) — automates the order-gap and step control.
- scipy.integrate.solve_ivp — the production tool that handles L5.3's edge cases for you.