Fall 2026
  • Discord
  • Gradescope
  • Syllabus
  • Spring 2026

Demo: Why Sums Become Bell-Shaped

A single fair die has a flat distribution. Adding independent dice concentrates the sum near its mean. We will use exact probabilities to answer three questions: How does the shape change as dice are added? Does a Gaussian predict the sum of ten dice? Does the pattern survive when the die is loaded?

Question 1: What Shape Does a Sum of Dice Have?

Start with one die, then add independent dice. np.convolve computes a sum distribution by adding the probabilities of all roll pairs with the same total. The short function below repeats that operation once per additional die. Before running the cell, sketch the shapes you expect for one, two, three, and ten dice.

import numpy as np
import matplotlib.pyplot as plt

plt.style.use("../figure_style.mplstyle")

fair_die = np.ones(6) / 6


def sum_distribution(single_die, number_of_dice):
    distribution = single_die.copy()
    for _ in range(number_of_dice - 1):
        distribution = np.convolve(distribution, single_die)
    return distribution

Apply the same calculation to one, two, three, and ten dice. Predict how the concentration around the center changes.

fig, axes = plt.subplots(1, 4, figsize=(9, 2.4))
for ax, number_of_dice in zip(axes, [1, 2, 3, 10]):
    probabilities = sum_distribution(fair_die, number_of_dice)
    possible_sums = np.arange(number_of_dice, 6 * number_of_dice + 1)
    ax.bar(possible_sums, probabilities, width=0.7)
    ax.set_xlabel(f"Sum of {number_of_dice} Dice")

axes[0].set_xticks(np.arange(1, 7))
axes[0].set_ylabel("Probability")
fig.tight_layout()
plt.show()

Answer. The distribution changes from flat to triangular and then becomes smooth and bell-shaped. Its center also moves: the expected sum of \(k\) dice is \(3.5k\).

Question 2: Does a Gaussian Predict the Sum?

One fair die has variance \(35/12\). Independence therefore gives

\[ \mathbb{E}[S_{10}] = 35, \qquad \operatorname{Var}(S_{10}) = \frac{350}{12}. \]

These two quantities determine the Gaussian curve below. We compare it with the exact probabilities of all possible totals.

number_of_dice = 10
probabilities = sum_distribution(fair_die, number_of_dice)
possible_sums = np.arange(number_of_dice, 6 * number_of_dice + 1)

mean = 3.5 * number_of_dice
variance = (35 / 12) * number_of_dice
grid = np.linspace(possible_sums[0], possible_sums[-1], 500)
gaussian = np.exp(-((grid - mean) ** 2) / (2 * variance))
gaussian /= np.sqrt(2 * np.pi * variance)

fig, ax = plt.subplots(figsize=(7, 3.2))
ax.bar(possible_sums, probabilities, width=0.8,
       label="Exact sum of 10 dice")
ax.plot(grid, gaussian, linewidth=1.6,
        label="Gaussian prediction")
ax.set_xlabel("Sum")
ax.set_ylabel("Probability")
ax.legend(frameon=False)
plt.show()

Answer. The Gaussian closely follows the exact probabilities. It cannot reproduce the discreteness of the sum, but it predicts the center, width, and overall shape from only the mean and variance.

Question 3: Must the Die Be Fair?

The next die is heavily loaded. Its mean and variance change, but its rolls are still independent and no single roll dominates the sum. We add thirty copies and compare the exact distribution with the Gaussian determined by the loaded die’s mean and variance.

loaded_die = np.array([0.40, 0.10, 0.05, 0.05, 0.10, 0.30])
faces = np.arange(1, 7)

single_mean = np.sum(faces * loaded_die)
single_variance = np.sum((faces - single_mean) ** 2 * loaded_die)

number_of_dice = 30
probabilities = sum_distribution(loaded_die, number_of_dice)
possible_sums = np.arange(number_of_dice, 6 * number_of_dice + 1)

mean = number_of_dice * single_mean
variance = number_of_dice * single_variance
grid = np.linspace(possible_sums[0], possible_sums[-1], 500)
gaussian = np.exp(-((grid - mean) ** 2) / (2 * variance))
gaussian /= np.sqrt(2 * np.pi * variance)

fig, (ax_die, ax_sum) = plt.subplots(1, 2, figsize=(9, 2.8))
ax_die.bar(faces, loaded_die, width=0.6)
ax_die.set_xlabel("Face")
ax_die.set_ylabel("Probability for One Die")

ax_sum.bar(possible_sums, probabilities, width=0.8,
           label=f"Exact sum of {number_of_dice} dice")
ax_sum.plot(grid, gaussian, linewidth=1.6,
            label="Gaussian prediction")
ax_sum.set_xlabel("Sum")
ax_sum.set_ylabel("Probability")
ax_sum.legend(frameon=False, loc="lower center", bbox_to_anchor=(0.5, 1.02))
fig.tight_layout()
plt.show()

Answer. The single-die distribution is far from bell-shaped, yet its sum is again close to a Gaussian. The central limit theorem applies to independent rolls of either die because each roll has finite variance.

This is why Gaussian noise models appear so often: a measurement can combine many small effects even when none of those effects is itself Gaussian.