How fast does the central limit theorem work, and what decides it?
The race for Exponential(1). Left: histogram of 2,000 simulated values of
Version 2 of a small study of how fast the standardized sample mean
approaches the standard normal distribution for the ten population distributions of version 1. Speed is measured by
the Kolmogorov distance
-
Skewness sets the speed. For symmetric distributions with a finite fourth moment (Uniform, Laplace,
Student-t(5))
$D_n$ falls like$1/n$ ; for skewed ones (Chi-square(5), Exponential) only like$1/\sqrt n$ , with the constant given by the Edgeworth expansion.$D_n < 0.01$ is reached at$n = 3$ (Uniform), 7 (Laplace), 8 (Student-t(5)), 71 (Chi-square(5)) and 177 (Exponential). Laplace, which version 1 grouped with Exponential, is about ten times closer to normal at$n = 30$ . -
Infinite third moments slow convergence. Student-t(3) is symmetric but converges like
$0.110/\sqrt n$ and needs$n = 116$ . Pareto(2.5), the default of version 1, is still at a distance of 0.031 at$n = 10^4$ . -
The race of version 1 mostly showed simulation noise. With
$R = 2000$ replications the simulated distance averages about 0.017–0.019 even when$Z_n$ is exactly normal: version 1 reported 0.0151 for the Normal distribution at$n = 10^4$ . To resolve the exact distance of Uniform at$n = 1000$ would take about$10^9$ replications. -
Infinite variance. The interquartile range of the Cauchy mean stays at 2 for every
$n$ ; for Pareto(1.5) it shrinks like$n^{-0.30}$ (theory:$n^{-1/3}$ ), not like$n^{-1/2}$ .
All numbers are in figures/*.csv and in the project note.
| Setting | Value |
|---|---|
| Distribution | Exponential(1), standardized with |
| Replications |
2,000 independent paths, each extended from one |
| Sample sizes | 118 values of steps=120; rounding merges two) |
| Random seed | 42 (NumPy default_rng) |
| Simulated distance | exact |
| Exact distance | regularized incomplete gamma function (sum of |
| Noise level | mean of the exact Kolmogorov statistic of 2,000 draws (scipy.stats.kstwo), 0.0193 |
| Animation | 118 frames, 25 frames per second (40 ms each), 1135 × 361 px, about 4.7 s per loop |
To reproduce the animation, run from the repository root (about two minutes):
python -c "from cltspeed import Distribution, race; race.run(Distribution('Exponential'), R=2000, nmax=10_000, steps=120, seed=42, outdir='notebook/clt_renders/exponential', fmt='gif', fps=25, dpi=150)"
cp notebook/clt_renders/exponential/race_Exponential.gif figures/race_exponential.gifAny other distribution or setting works the same way, for example Distribution('Student-t', {'df': 3}) or R=20000.
The frames are written to notebook/clt_renders/, which .gitignore excludes. The interactive version is
notebook/clt_speed_race.ipynb.
| Path | What it is |
|---|---|
cltspeed/distributions.py |
The ten distributions of version 1: samplers (identical to version 1), moments, characteristic functions |
cltspeed/exact.py |
Exact |
cltspeed/montecarlo.py |
The simulation of version 1, reproduced draw for draw; exact empirical distance; noise level of a simulation |
cltspeed/race.py |
The animated race (frames, GIF, MP4), usable with or without Jupyter |
cltspeed/style.py |
Shared figure style (Latin Modern Roman, colours, English and Turkish versions of each figure) |
tests/run_tests.py |
Unit tests against SciPy, numerical Fourier integrals, exact rational arithmetic and the output of version 1 |
analysis/01_exact_speed.py |
Exact |
analysis/02_monte_carlo.py |
What the simulation of version 1 measures (Figure 2) |
analysis/03_heavy_tails.py |
Lognormal, F and Pareto by simulation; infinite variance (Figure 3) |
analysis/run_all.py |
Runs the three analyses in order |
notebook/clt_speed_race.ipynb |
The interactive race |
figures/ |
Figures as PNG (300 dpi) and PDF, every reported table as CSV; figures/tr/ holds the Turkish figures |
paper/clt_note.pdf, paper/clt_notu.pdf
|
Project note in English and in Turkish; make_paper.py writes all their numbers from figures/*.csv
|
legacy/clt_speed_race_v1.ipynb |
Version 1, unchanged |
fonts/ |
Latin Modern Roman (GUST Font License) |
pip install -r requirements.txt
python tests/run_tests.py
cd analysis
python run_all.py # about four minutes
cd ../paper
python make_paper.py
xelatex clt_note.tex && xelatex clt_note.tex # English; needs XeLaTeX
xelatex clt_notu.tex && xelatex clt_notu.tex # Turkish
Seeds are fixed, so every number is the same at every run.
For the interactive race: pip install ipywidgets jupyter, then open notebook/clt_speed_race.ipynb. MP4 recording
needs ffmpeg; without it the notebook writes a GIF.
from cltspeed import Distribution, kolmogorov_distance, leading_term
from cltspeed import race
d = Distribution("Exponential")
kolmogorov_distance(d, 30) # (D_30, point where it is attained, method)
leading_term(d, 30) # (|skewness| phi(0) / (6 sqrt n), order 0.5, "skewness")
rows, gif = race.run(d, R=2000, nmax=10_000, steps=30, seed=42, outdir="notebook/clt_renders/exponential", fmt="gif")See NEWS.md. In short: version 1 ranked the distributions from simulations whose distance was mostly
Monte Carlo noise, grouped Laplace with the skewed Exponential, drew the difference curve with fixed limits that cut off
large values, piled draws outside the histogram window onto its edge bins, replaced an invalid uniform range silently, and
created a render folder at every run. Its repository held nine such folders, nine GIFs, an RTF copy of the README and
HTML and PDF exports of the notebook.
The Kolmogorov distance measures the largest error in a probability, not the relative error in the tails. Lognormal, F and Pareto have no exact method here and are studied by simulation. Only the default parameters of version 1 are used.
- Gil-Pelaez, J. (1951). Note on the inversion theorem. Biometrika, 38(3–4), 481–482.
- Gnedenko, B. V., Kolmogorov, A. N. (1954). Limit Distributions for Sums of Independent Random Variables. Addison-Wesley.
- Hall, P. (1992). The Bootstrap and Edgeworth Expansion. Springer.
- Katz, M. L. (1963). Note on the Berry–Esseen theorem. Annals of Mathematical Statistics, 34(3), 1107–1108.
Citation metadata are in CITATION.cff; GitHub shows them under "Cite this repository".
MIT; see LICENSE. The fonts in fonts/ are distributed under the GUST Font License.
