此问题已在此处有答案:
How to generate uniform random points inside d-dimension ball / sphere?(1个答案)
两年前关闭。
我想从n维实心球体中生成随机均匀样本。
我现在的方法是这样的
def sample_sphere(d, npoints):
points = np.zeros((npoints, d))
for i in range(npoints):
r = np.random.rand() #random radius
v = np.random.uniform(low= -1, high=1, size=d) #random direction
v = v / np.linalg.norm(v)
points[i] = r * v
return points
但令人惊讶的是,这种方法给出了接近0的更高浓度的点,因为采样密度与体积不成比例:
如何统一采样?
1条答案
按热度按时间z8dt9xmd1#
球面分布有两种基本解释:
1.有界实心球
在给定半径处得到一个点的概率由在该半径处厚度为
dr
的壳的体积给出:p(r) ~ r^D
直到一个常数。因此,径向CDF是(r / R)^(D+1)
,其中R
是外半径,D
是维数。球体必须是有界的,除非你想从整个空间中进行选择。给定CDF生成样本的标准方法是将其反转:
顺便说一句,正确选择均匀方向的常用方法是使用高斯分布(see here):
你可以而且应该对你的函数进行向量化。不需要循环:
请注意
1 - np.random.uniform(...)
。这是因为函数的值域是[0, 1)
,而我们想要的是(0, 1]
。减法在不影响均匀性的情况下反转范围。2.无界衰减分布
在这种情况下,你要找的是具有球对称性的高斯分布。这种分布的径向CDF与
R^(D-1)
成比例。对于高斯分布,这在2D中称为瑞利分布,在3D中称为麦克斯韦分布,在一般情况下称为chi分布。它们可以分别通过scipy.stats.rayleigh
、scipy.stats.maxwell
和scipy.stats.chi
对象直接获得。在这种情况下,半径的意义不大,但它可以解释为分布的标准差。
函数的无界版本(也是矢量化的),然后变为: