如何在 3-d 单位球中生成均匀分布的点?

机器算法验证 随机生成
2022-03-26 22:10:08

我已经发布了一个先前的问题,这是相关的,但我认为最好开始另一个线程。这一次,我想知道如何在 3-d 单位球体内生成均匀分布的点,以及如何在视觉和统计上检查分布?我看不到那里发布的策略可以直接转移到这种情况。

3个回答

最简单的方法是在相应的超立方体中均匀地采样点,并丢弃那些不在球体内的点。在 3D 中,这种情况不应该经常发生,大约 50% 的时间。(超立方体的体积为 1,球体的体积为43πr3=0.523....)

您也可以在球坐标中执行此操作,在这种情况下不会拒绝。首先随机生成半径和两个角度,然后使用过渡公式恢复x,yz(x=rsinθcosϕ,y=rsinθsinϕ,z=rcosθ)。

你生成ϕ统一在02π. 半径r和倾向θ虽然不统一。一个点在半径球内的概率rr3所以概率密度函数r3r2. 您可以轻松检查统一变量的三次根是否具有完全相同的分布,因此您可以通过以下方式生成r. 点位于由倾角定义的球锥内的概率θ(1cosθ)/2或者1(1cos(θ))/2如果θ>π/2. 所以密度θsin(θ)/2. 您可以检查减去统一变量的反余弦是否具有适当的密度。

或者更简单地说,我们可以模拟θ均匀地11.

在 R 中,这将如下所示。

n <- 10000 # For example n = 10,000.
phi <- runif(n, max=2*pi)
r <- runif(n)^(1/3)
cos_theta <- runif(n, min=-1, max=1)
x <- r * sqrt(1-cos_theta^2) * cos(phi)
y <- r * sqrt(1-cos_theta^2) * sin(phi)
z <- r * cos_theta

在编写和编辑此答案的过程中,我意识到解决方案没有我想象的那么简单。

我认为最简单和计算最有效的方法是按照@whuber的方法生成(x,y,z)在单位球体上,如这篇文章所示,并用r.

xyz <- matrix(rnorm(3*n), ncol=3)
lambda <- runif(n)^(1/3) / sqrt(rowSums(xyz^2))
xyz <- xyz*lambda

在我看来,也可以推广到更高维球的最简单的选择(这不是球坐标的情况,更不用说拒绝采样的情况)是生成随机点P是两个随机变量的乘积 P=N/||N||U1/n在哪里N是归一化的高斯随机变量(即各向同性,即均匀指向任何方向),使其位于球体上并且U这是一个均匀随机变量[0,1]对权力1/n,n作为数据的维度,注意半径。

瞧!