Probability & Statistics

Sampling the d-Ball

To sample a point in the unit d-ball, draw from the surrounding cube and keep it if it lands inside. How often does that succeed as the dimension grows?

solvedmedium1 min

A simple way to sample a point uniformly in the unit dd-ball {xRd:x1}\{x \in \mathbb{R}^d : \lVert x \rVert \le 1\} is to draw a point uniformly in the cube [1,1]d[-1,1]^d and accept it only if its norm is at most 11. Find the acceptance probability as a function of dd and describe how it behaves for d=1,,50d = 1, \dots, 50.

Reveal solutionHide solution

#The acceptance probability

A point drawn uniformly in the cube lands inside the ball with probability equal to the ratio of their volumes,

Pd=vol(ball)vol(cube)=πd/2/Γ(d2+1)2d.(1)P_d = \frac{\operatorname{vol}(\text{ball})}{\operatorname{vol}(\text{cube})} = \frac{\pi^{d/2}/\Gamma(\tfrac{d}{2}+1)}{2^d}. \tag{1}

#It collapses with dimension

The ball's volume eventually shrinks while the cube's volume keeps doubling, so PdP_d races to zero. A clean recursion is Pd=π2dPd2P_d = \tfrac{\pi}{2d}\,P_{d-2}, starting from P0=P1=1P_0 = P_1 = 1.

11e-101e-2011020304050dimension d
The ball fills less and less of the cube as the dimension climbs, so the acceptance probability falls off a cliff. By fifty dimensions it is around ten to the minus 28, which is why naive rejection sampling is hopeless in high dimension.

#In code

import numpy as np
from scipy.special import gammaln

d = np.arange(1, 51)
log_p = (d / 2) * np.log(np.pi) - gammaln(d / 2 + 1) - d * np.log(2)
accept = np.exp(log_p)

#Read it off

By d=10d = 10 the acceptance is already about 0.00250.0025, and by d=20d = 20 near 2.51082.5 \cdot 10^{-8}. Past a handful of dimensions, rejection from the cube is hopeless, the curse of dimensionality in miniature, and one reaches instead for a direct method like normalizing a Gaussian vector.