physics · math
Lagrangian mechanics is just saying δS = 0 and seeing what falls out
The action principle in one line, then the derivation that shows why Euler-Lagrange is the only equation you need.
2026-05-14
The action is the integral of the Lagrangian over time:
The principle of least action says: the physical path is the one where — small variations around the true path produce no first-order change in .
The derivation
Let be the true path and be a variation, where (the endpoints are fixed). Then:
Differentiating under the integral:
Integrate the second term by parts (boundary terms vanish because is zero at endpoints):
Since this must hold for all , the integrand itself must vanish — the Euler-Lagrange equation:
A concrete example: the simple pendulum
For a pendulum of length and mass , take (the angle). Kinetic energy is , potential energy is (setting at the pivot). The Lagrangian:
Applying E-L:
The same equation you’d get from Newton’s second law, but without drawing a single free-body diagram.
Numerical integration
Here’s the small-angle pendulum integrated two ways — the Euler-Lagrange ODE and the equivalent Newtonian form — to confirm they agree:
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
def lagrangian_pendulum(t, y, g=9.81, L=1.0):
"""State: y = [theta, theta_dot]. Returns dy/dt via E-L."""
theta, theta_dot = y
return [theta_dot, -(g / L) * np.sin(theta)]
t_span = (0, 10)
y0 = [np.pi / 6, 0.0] # 30° initial angle, at rest
sol = solve_ivp(lagrangian_pendulum, t_span, y0,
max_step=0.01, dense_output=True)
t = np.linspace(*t_span, 1000)
theta = sol.sol(t)[0]
plt.plot(t, np.degrees(theta))
plt.xlabel("t (s)")
plt.ylabel("θ (°)")
plt.title("Pendulum: θ(t) from Euler-Lagrange")
plt.tight_layout()
plt.savefig("pendulum.png", dpi=150)
The same physics, in Rust with a hand-rolled RK4:
fn pendulum_rhs(theta: f64, omega: f64, g: f64, l: f64) -> (f64, f64) {
(omega, -(g / l) * theta.sin())
}
fn rk4_step(theta: f64, omega: f64, dt: f64, g: f64, l: f64) -> (f64, f64) {
let (k1t, k1o) = pendulum_rhs(theta, omega, g, l);
let (k2t, k2o) = pendulum_rhs(theta + 0.5*dt*k1t, omega + 0.5*dt*k1o, g, l);
let (k3t, k3o) = pendulum_rhs(theta + 0.5*dt*k2t, omega + 0.5*dt*k2o, g, l);
let (k4t, k4o) = pendulum_rhs(theta + dt*k3t, omega + dt*k3o, g, l);
let new_theta = theta + dt * (k1t + 2.0*k2t + 2.0*k3t + k4t) / 6.0;
let new_omega = omega + dt * (k1o + 2.0*k2o + 2.0*k3o + k4o) / 6.0;
(new_theta, new_omega)
}
fn main() {
let (mut theta, mut omega) = (std::f64::consts::PI / 6.0, 0.0_f64);
let dt = 0.01_f64;
for i in 0..1000 {
(theta, omega) = rk4_step(theta, omega, dt, 9.81, 1.0);
if i % 100 == 0 {
println!("t={:.2}s θ={:.4}°", i as f64 * dt, theta.to_degrees());
}
}
}
Both converge to the same trajectory for small angles. For , and the period is — independent of amplitude, which is the famous isochronous result Galileo observed.
Why this matters for ML
The path-integral formulation of quantum mechanics is a direct generalization: the probability amplitude for a particle to travel from to is a sum over all paths, weighted by . The Lagrangian framing unifies classical mechanics, field theory, and quantum theory in a single notation. Once you see the world through , the equations of motion for everything — electrodynamics, general relativity, the Standard Model — follow from the same one-line principle.