import numpy as np
from scipy.stats import norm
n_mc = 1000
rng = np.random.default_rng(10 * 5 / 2021)
xy = rng.random.uniform(2 * n_mc)
xy = xy.reshape((2, n_mc))
d = np.power(xy[0, :], 2) + np.power(xy[1, :], 2)
p_hat = np.mean(d < 1)
pi_hat = 4 * p_hat
pi_hat
On the previous slide, $\sigma^2$ is the variance of the underlying distribution from which X is drawn.
Estimate the variance of a Monte Carlo estimate to construct confidence intervals around your estimates.
Choose the number of Monte Carlo replicates to attain the desired precision.
se = 4 * np.sqrt(p_hat * (1 - p_hat) / n_mc)
se2 = 4 * np.sqrt( np.var(d) / n_mc )
z = norm.ppf(.975)
lwr, upr = pi_hat - z * se, pi_hat + z * se
'{0:5.3f} ({1:4.2f}, {2:4.2f})'.format(pi_hat, lwr, upr)
lwr < np.pi < upr # Expect this to be True ~95% of the time with z = 1.96
z = norm.ppf(.995)
n_min = (1000 * z * 4 * np.sqrt(np.pi / 4 * (1 - np.pi / 4))) ** 2
n_min
n_mc = int(1.8e7)
xy = rng.uniform(size=2 * n_mc).reshape((2, n_mc))
d = np.power(xy[0, :], 2) + np.power(xy[1, :], 2)
eps = 4 * np.mean(d < 1) - np.pi
(eps, np.abs(eps) < 0.001)