ODE Integration Methods
Marching forward in time: from Euler's simple step to adaptive Runge-Kutta, implicit methods for stiff systems, and symplectic integrators that conserve energy for Hamiltonian dynamics.
The Initial Value Problem
Given \(\frac{dy}{dt} = f(t, y)\) with \(y(t_0) = y_0\), compute \(y(t)\) for\(t > t_0\). This is the core problem of dynamics: planetary orbits, chemical kinetics, neural networks, population models, circuit simulation.
Key questions: How small must \(h = \Delta t\) be? Is the method stable? Does it conserve physical invariants (energy, symplectic structure)?
1. Euler's Method
The simplest ODE integrator: step along the tangent line at the current point.
\(y_{n+1} = y_n + h \, f(t_n, y_n)\)
First-order method: local error \(O(h^2)\), global error \(O(h)\)
Error Analysis
Taylor expand: \(y(t+h) = y(t) + h y'(t) + \frac{h^2}{2} y''(t) + \cdots\)Euler keeps only the first two terms, so the local truncation error is\(\tau = \frac{h^2}{2} y''(\xi) = O(h^2)\). Over \(N = T/h\) steps, errors accumulate to give global error \(O(h)\).
Euler Method: Simple but Instructive
PythonClick Run to execute the Python code
Code will be executed with Python 3 on the server
2. The Classic Runge-Kutta 4 (RK4)
The workhorse of ODE integration. Four function evaluations per step yield fourth-order accuracy:
\(k_1 = h \, f(t_n, y_n)\)
\(k_2 = h \, f(t_n + h/2, \; y_n + k_1/2)\)
\(k_3 = h \, f(t_n + h/2, \; y_n + k_2/2)\)
\(k_4 = h \, f(t_n + h, \; y_n + k_3)\)
\(y_{n+1} = y_n + \frac{1}{6}(k_1 + 2k_2 + 2k_3 + k_4)\)
Local error \(O(h^5)\), global error \(O(h^4)\). The most popular fixed-step ODE solver.
RK4 Implementation and Convergence Test
PythonClick Run to execute the Python code
Code will be executed with Python 3 on the server
3. Adaptive Step Size: RK45
Fixed step sizes waste effort in smooth regions and miss features in rapidly changing regions. Embedded Runge-Kutta pairs (like Dormand-Prince RK45) compute two solutions of different order to estimate the local error, then adjust \(h\) automatically.
Step Size Control
Estimate error \(\hat{e} = |y_5 - y_4|\) (difference between 5th and 4th order solutions). If \(\hat{e} > \text{tol}\), reject step and shrink \(h\). If \(\hat{e} \ll \text{tol}\), accept and grow \(h\). Optimal step factor: \(h_{\text{new}} = h \cdot 0.9 \cdot (\text{tol}/\hat{e})^{1/5}\).
Adaptive ODE Solving with scipy.integrate
PythonClick Run to execute the Python code
Code will be executed with Python 3 on the server
4. Stiff Systems and Implicit Methods
A system is stiff when it contains both fast and slow timescales. Explicit methods must use tiny steps (dictated by the fast scale) even when tracking the slow dynamics. Implicit methods like backward Euler and BDF (backward differentiation formulas) remain stable with large steps.
Backward Euler (implicit)
\(y_{n+1} = y_n + h \, f(t_{n+1}, y_{n+1})\)
A-stable: stable for any \(h > 0\) on \(y' = \lambda y\) with Re(\(\lambda\)) < 0
Forward Euler (explicit)
\(y_{n+1} = y_n + h \, f(t_n, y_n)\)
Stable only if \(|1 + h\lambda| < 1\), requires \(h < 2/|\lambda|\)
Stiff System: Explicit vs Implicit
PythonClick Run to execute the Python code
Code will be executed with Python 3 on the server
5. Symplectic Integrators
For Hamiltonian systems \(H(q,p) = T(p) + V(q)\), standard integrators cause energy to drift over long times. Symplectic integrators preserve the symplectic structure of phase space, keeping energy bounded (oscillating, not drifting) forever.
Stormer-Verlet (Leapfrog)
\(p_{n+1/2} = p_n - \frac{h}{2} \nabla V(q_n)\) (half-kick)
\(q_{n+1} = q_n + h \, p_{n+1/2} / m\) (drift)
\(p_{n+1} = p_{n+1/2} - \frac{h}{2} \nabla V(q_{n+1})\) (half-kick)
Second-order, time-reversible, symplectic. Used in molecular dynamics, celestial mechanics, particle physics.
Symplectic vs Non-Symplectic: Energy Conservation
PythonClick Run to execute the Python code
Code will be executed with Python 3 on the server
6. Stability Regions
For the test equation \(y' = \lambda y\), a method is stable if the numerical solution does not blow up. The stability region is the set of\(h\lambda \in \mathbb{C}\) for which \(|y_{n+1}/y_n| \leq 1\).
Forward Euler
\(y_{n+1} = (1 + h\lambda) y_n\), stable when \(|1 + h\lambda| \leq 1\): a disk of radius 1 centered at \(-1\).
Backward Euler
\(y_{n+1} = \frac{y_n}{1 - h\lambda}\), stable when \(|1 - h\lambda| \geq 1\): the complement of a disk. A-stable!
Stability Region Computation
PythonClick Run to execute the Python code
Code will be executed with Python 3 on the server