How well does the sum of 12 Uniform[0, 1] variates minus 6 approximate a Normal(0, 1) deviate?
import numpy as np
import matplotlib.pyplot as plt
def uniform_sums(size):
def sum_of_12():
return sum(np.random.uniform(size=12)) - 6
return [sum_of_12() for i in range(size)]
num_draws = 100000
uniforms = uniform_sums(size=num_draws)
normal = np.random.normal(size=num_draws)
bins = np.linspace(-6, 6)
plt.hist(uniforms, label='sums of 12', bins=bins, histtype='step')
plt.hist(normal, label='normal', bins=bins, histtype='step')
plt.legend()
<matplotlib.legend.Legend at 0xb15a7cc>
If $X_i \sim U[0, 1] \ \ $ and $Y_i = X_i - 1/2\ $, then $Y_i \sim U[-1/2, 1/2]\ \ $ and $$\varphi(Y) = \int_{-1/2}^{1/2} e^{i t y} dy = \int_{-1/2}^{1/2} \cos(ty) dy = \frac{2}{t} \sin\frac{t}{2}.$$
so if $Y = \sum_{i = 1}^{12} Y_i$ for independent $Y_i$, then $\varphi(Y) = \left( \frac{2}{t} \sin\frac{t}{2} \right)^{12}.$
Use the inversion formula to produce a way to numerically evaluate the p.d.f. of Y:
$$p_Y(y) = \int_{-\infty}^\infty e^{-ity} \left( \frac{2}{t} \sin\frac{t}{2} \right)^{12} dt = \int_{-\infty}^\infty \cos tx \left( \frac{2}{t} \sin\frac{t}{2} \right)^{12} dt$$import scipy.integrate
import scipy.stats
def inverse_transform(x):
def integrand(t):
return 1 / (2 * np.pi) * (2 * np.sin(t/2) / t)**12 * np.cos(t*x)
p, _ = scipy.integrate.quad(integrand, -np.infty, np.infty)
return p
sum_of_uniform_pdf = np.vectorize(inverse_transform)
norm_pdf = scipy.stats.norm().pdf
xs, step= np.linspace(-6, 6, 500, retstep=True)
ps_uniform = sum_of_uniform_pdf(xs)
ps_normal = norm_pdf(xs)
ps_uniform.sum() * step
0.99999999913984783
plt.plot(xs, ps_uniform, label="sum of uniforms")
plt.plot(xs, ps_normal, label="N(0, 1)")
plt.legend()
plt.title("Both pdfs")
<matplotlib.text.Text at 0xb4d976c>
plt.plot(xs, ps_uniform - ps_normal)
plt.title("difference")
<matplotlib.text.Text at 0xb56796c>
plt.plot(xs, (ps_uniform - ps_normal) / ps_normal)
plt.title("relative difference")
<matplotlib.text.Text at 0xb6e324c>
What is the expected number of independent Uniform[0, 1] deviates you need to sum to exceed 1? (I learned about this from http://nbviewer.ipython.org/4731599/.)
def how_many_to_exceed(threshold):
total = 0
count = 0
while total < threshold:
total += np.random.uniform()
count += 1
return count
num_draws = 100000
draws = [how_many_to_exceed(1) for i in range(num_draws)]
running_average = np.cumsum(draws) / (np.arange(num_draws) + 1.)
plt.plot(running_average, label='Average draws')
plt.axhline(np.e, color='red', linestyle='--', label='e = {:.8f}'.format(np.e))
plt.ylim(1, 4)
plt.legend()
plt.gca().set_xscale('log')