Sampling uniformly distributed random points inside a spherical volume Sampling uniformly distributed random points inside a spherical volume python python

Sampling uniformly distributed random points inside a spherical volume


While I prefer the discarding method for spheres, for completeness I offer the exact solution.

In spherical coordinates, taking advantage of the sampling rule:

phi = random(0,2pi)costheta = random(-1,1)u = random(0,1)theta = arccos( costheta )r = R * cuberoot( u )

now you have a (r, theta, phi) group which can be transformed to (x, y, z) in the usual way

x = r * sin( theta) * cos( phi )y = r * sin( theta) * sin( phi )z = r * cos( theta )


There is a brilliant way to generate uniformly points on sphere in n-dimensional space, and you have pointed this in your question (I mean MATLAB code).

Why does it work? The answer is: let us look at the probability density of n-dimensional normal distribution. It is equal (up to constant)

exp(-x_1*x_1/2) *exp(-x_2*x_2/2)... = exp(-r*r/2),so it doesn't depend on the direction, only on the distance! This means, after you normalize vector, the resulting distribution's density will be constant across the sphere.

This method should be definitely preferred due to it's simplicity, generality and efficiency (and beauty).The code, which generates 1000 events on the sphere in three dimensions:

size = 1000n = 3 # or any positive integerx = numpy.random.normal(size=(size, n)) x /= numpy.linalg.norm(x, axis=1)[:, numpy.newaxis]

BTW, the good link to look at: http://www-alg.ist.hokudai.ac.jp/~jan/randsphere.pdf

As for having uniform distribution within a sphere, instead of normalizing a vector, you should multiply vercor by some f(r): f(r)*r is distributed with density proportional to r^n on [0,1], which was done in the code you posted


Generate a set of points uniformly distributed within a cube, then discard the ones whose distance from the center exceeds the radius of the desired sphere.