When analytical solutions are impossible, we use numerical methods to approximate the physics.
Euler method — The simplest ODE integrator:
def euler(f, y0, t0, t_end, h):
t, y = t0, y0
trajectory = [(t, y)]
while t < t_end:
y = y + h * f(t, y)
t = t + h
trajectory.append((t, y))
return trajectory
Better integrators
- Midpoint (RK2): Evaluate slope at the midpoint for better accuracy.
- RK4 (Runge-Kutta 4): Four slope evaluations per step — the workhorse of physics simulations.
- Error scales as where is the method's order (Euler: , RK4: ).
Monte Carlo methods — Use random sampling to estimate quantities:
import random
inside = sum(1 for _ in range(N)
if random.random()**2 + random.random()**2 <= 1)
pi_estimate = 4 * inside / N
Convergence check — Run the simulation with step size and . If results agree to the desired precision, the solution is converged.
Tip: Always validate your simulation against a known analytical case before applying it to a new problem. If Euler's method can't match for exponential decay, it won't be reliable for anything more complex.
Common pitfall: A simulation that runs without errors is not a simulation that is right. Validate against a case with a known answer (analytic solution, conservation law) before trusting any new output.
Monte Carlo Simulation
Monte Carlo methods use random sampling to estimate numerical quantities.
To estimate : place random points in a unit square. The fraction that falls inside the inscribed quarter-circle () converges to :
Accuracy improves as — quadrupling points halves the error.
Monte Carlo methods are essential when analytical integration is intractable.