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


68

我想知道如何在3维单位球面上生成均匀分布的点?同样在生成这些点之后,什么是可视化并检查它们在表面上是否真正均匀的最佳方法?x2+y2+z2=1


如果统一表示“常规”,那么在 = 2、4、6、8、12、20之外没有其他方法n
Marcos

1
来自MultiVariateGaussian的样本出了什么问题,而该矢量只是对其进行了归一化处理:v = MultivariateNormal(torch.zeros(10000), torch.eye(10000))然后 v = v/v.norm(10000)
Pinocchio

Answers:


72

一种标准方法是生成三个标准法线并从中构造一个单位向量。也就是说,当和,则是一致的分布在球体上。该方法也适用于维球体。XiN(0,1)λ2=X12+X22+X32(X1/λ,X2/λ,X3/λ)d

在3D中,您可以使用拒绝采样:从均匀的分布中提取,直到长度小于或等于1,然后-与前面的方法一样-将向量归一化为单位长度。每个球形点的预期试验次数等于 = 1.91。在更高的维度上,预期的试验数量如此之大,以至于迅速变得不切实际。Xi[1,1](X1,X2,X3)23/(4π/3)

有许多检查均匀性的方法。尽管有一定的计算量,但一种巧妙的方法是使用Ripley的K函数。(3D欧几里德)距离内的点的预期数量在球体上的任何位置的正比于距离内的球的面积,它等于。通过计算所有点间距离,您可以将数据与理想值进行比较。ρρπρ2

构造统计图形的一般原则建议进行比较的一种好方法是针对绘制方差稳定的残差,其中是相互距离中最小的,而。该图应接近零。(这种方法是非常规的。)ei(d[i]ei)i=1,2,,n(n1)/2=md[i]ithei=2i/m

这是用第一种方法从均匀球面分布中获得的100次独立绘制的图片:

100个均匀的球形点

这是距离的诊断图:

诊断图

y标度表明这些值都接近零。

这是100个这样的图的累积,以表明哪些尺寸偏差实际上可能是不均匀性的重要指标:

模拟值

(这些图看起来像布朗桥一样可怕……这里可能潜藏着一些有趣的理论发现。)

最后,这是一组100个均匀随机点和仅均匀分布在上半球的另外41个点的诊断图:

模拟非均匀值

相对于均匀分布,它显示出在一个半球范围内的平均点距显着减小。这本身是没有意义的,但是这里有用的信息是,某事物在一个半球的尺度上是不均匀的。实际上,此图很容易检测到一个半球的密度与另一半球的密度不同。(如果您事先知道要在无限多个可能的半球中进行测试,则更简单的卡方检验会以更大的能力执行此操作。)


@whuber:非常好!非常感谢您的帖子!“均匀分布在球体上。” 我在哪里可以找到有关其证明的参考,还是可以证明的?(X1/λ,X2/λ,X3/λ)
李强

23
@Qiang,这是证明的本质:让其中表示身份矩阵。然后,对于任何正交矩阵,。因此,的分布在旋转下是不变的。令并注意任何正交。由于不变于旋转,因此不变,并且由于几乎肯定,因此它必须均匀地分布在球体上。XN(0,In)Inn×nQQXN(0,In)XY=X/X2YQ=QX/QX2=QX/X2QXYY2=1
红衣主教

3
@迈克不,因为纬度的均匀分布不会在球体上给出均匀分布。(球体的大部分表面都位于赤道附近,远离波兰人的低纬度处。您需要均匀分布。)ϕcos(ϕ)
whuber

1
@Ahsan因为正交矩阵形成了球体的区域保持变换的传递组,所以在形式的球体子集中分布是均匀的:但这是整个球体。X/||X||2
ub

1
@Cesar“均匀分布”(在球体上)。
ub

19

这是一些相当简单的R代码

n     <- 100000                  # large enough for meaningful tests
z     <- 2*runif(n) - 1          # uniform on [-1, 1]
theta <- 2*pi*runif(n) - pi      # uniform on [-pi, pi]
x     <- sin(theta)*sqrt(1-z^2)  # based on angle
y     <- cos(theta)*sqrt(1-z^2)     

这是非常简单的从建筑看到等,但如果需要将其然后测试x2+y2=1z2x2+y2+z2=1

mean(x^2+y^2+z^2)  # should be 1
var(x^2+y^2+z^2)   # should be 0

并易于测试和分别均匀分布在(很明显是)上xy[1,1]z

plot.ecdf(x)  # should be uniform on [-1, 1]
plot.ecdf(y)
plot.ecdf(z)

显然,给定的值,和均匀地分布在半径的圆周围,可以通过查看其比率的反正切分布来进行测试。但是由于具有与和相同的边际分布,因此类似的说法适用于任何一对,这也可以进行测试。 zxy1z2zxy

plot.ecdf(atan2(x,y)) # should be uniform on [-pi, pi]
plot.ecdf(atan2(y,z))
plot.ecdf(atan2(z,x))

如果仍然不能令人信服,那么下一步将是查看一些任意的3-D旋转或在给定的立体角内落了多少点,但这开始变得更加复杂,我认为这是不必要的。


我只是想知道您生成点(x,y,z)的方法是否与Whuber的方法相同?
李强

3
不,不是:wh使用三个随机数,而我使用两个。我的特例是“在以适当的密度[与成比例的点生成一个点,然后降低尺寸”。在这里很方便,因为它正式是2球[1,1](1z2)n/21n=2
亨利

3
或者,更一般而言,使用任何等面积投影(您是圆柱等面积投影)在地图上生成统一点,然后向后投影。(+1)
胡言乱语

@whuber:确实。题外话,但对于感兴趣的人,我可以在此处交互式选择世界地图的投影,其中一些是相等的区域
亨利

2
这几乎是计算机图形学中使用的标准方法,基于阿基米德的Hat-B​​ox定理:mathworld.wolfram.com/ArchimedesHat-B​​oxTheorem.html
Edward KMETT

10

如果要对均匀分布在3D球体(即3D球的表面)上的点进行采样,请使用简单的拒绝法或Marsaglia的方法(Ann。Math。Statist。,43(1972),第645页– 646)。对于小尺寸,废品率非常低。

如果要从高维球体和球中生成随机点,则取决于模拟的目的和规模。如果不想执行大型仿真,请使用Muller(Commun。ACM,2(1959),第19–20页)的方法或“球形”版本(请参见上面引用的Harman&Lacko的论文)。那是:

以获得均匀分布在n球(表面)上的样本1)从n维标准正态分布生成X 2)将X的每个分量除以X的欧几里得范数

以获得均匀分布在n球(内部)上的样本1)从(n + 2)维标准正态分布生成X 2)将X的每个分量除以X的欧几里得范数,仅取前n个分量

如果要执行大型仿真,则应研究更专业的方法。根据要求,我可以向您发送有关条件分布方法的Harman和Lacko的论文,其中提供了本次讨论中提到的某些算法的分类和概括。该联系人可以在我的网站上找到(http://www.iam.fmph.uniba.sk/ospm/Lacko)

如果要检查球的表面或内部的点是否真正均匀,请查看边界(由于旋转不变性,所有边界应相同,投影样本的平方范数是beta分布)。


来自MultiVariateGaussian的样本有什么问题,而该向量只是将其标准化:v = MultivariateNormal(torch.zeros(10000), torch.eye(10000))然后 v = v/v.norm(10000)
Pinocchio

8

在攻读博士学位期间,我遇到了类似的问题(n球),当地的一位专家建议从n立方体中进行拒绝采样!当然,这就像我以hunderds的顺序查看n时所花的时间一样。

我最终使用的算法非常简单,并发布在:

WP Petersen和A. Bernasconic从n球面进行均匀采样:各向同性方法技术报告,TR-97-06,瑞士科学计算中心

我的书目中也有我没有看过的这篇论文。您可能会发现它很有用。

Harman,R.&Lacko,V.关于从球和球进行均匀采样的分解算法,《多元分析杂志》,2010年nn


是否可以在我可以找到这些参考文献全文的链接上发布链接?谢谢。
李强

我没有关于我的论文,但是此页面似乎描述了算法(以及其他一些算法)mlahanas.de/Math/nsphere.htm
emakalic 2011年

3
据我了解,(从Petersen和Bernasconic的论文中)对于d维球,可以通过将U(0,1)变量提高为(1 / d)幂,最后一个角度作为a来生成半径。 U(0,2)变量。中间角可以作为,其中是。对我来说,这听起来很简单。我想知道的是:如果我对我的制服使用准随机序列,那么我也会在球上得到漂亮吗?πC.asin(uk)C1
πΓ(k2+0.5)Γ(k2+1)
Mohit

3

我以前遇到过这个问题,这是我找到的替代方法,

至于分布本身,我发现比较有效的公式是使用极坐标(我实际上使用了已开发的极坐标的变体),然后转换为笛卡尔坐标。

半径当然是要绘制的球体的半径。然后,在平面上有第二个角度值,然后是第三个值,即该平面上方或下方的角度。

为了获得合理的分布,假设U是均匀分布的随机数,r是半径,a是第二极坐标,b是第三极坐标,

a = U * 360 b = U + U-1然后通过x = r * sin(b)sin(a)z = r sin(b)cos(a)y = r sin(b)转换为笛卡尔

我最近发现以下数学上更好的表达式:a = 2(pi)* U b = cos ^ -1(2U-1)

实际上,我的原始公式与我的原始公式没有太大差异,尽管我的是度与弧度。

据称该最新版本可用于超球面,尽管未提及如何实现。

尽管我通过相当便宜的方法为Homeworld 2制作地图,然后“播放”这些地图,从视觉上检查了一致性。实际上,由于地图是使用lua脚本制作的,因此您可以直接在地图中构建公式,从而无需离开游戏就可以检查多个采样。也许这不是科学的方法,但是是一种直观地查看结果的好方法。


2

这是伪代码:

  1. vMultiVariateGaussian(μ,σI)
  2. v=vv

在pytorch中:

v = MultivariateNormal(torch.zeros(10000), torch.eye(10000))
v = v/v.norm(2)

我对此不太了解,但胡布告诉我:

v = torch.normal(torch.zeros(10000), torch.eye(10000))
v = v/v.norm(2)

也是正确的,即从每个坐标的单变量法线采样。


0

我最好的猜测是首先在二维空间中生成一组均匀分布的点,然后使用某种投影将这些点投影到球体的表面上。

您可能必须将生成点的方式与映射它们的方式混合并匹配。就二维点生成而言,我认为加扰的低差异序列是一个很好的起点(即加扰的Sobol序列),因为它通常会产生不“聚集在一起”的点。我不确定要使用哪种类型的映射,但是Woflram弹出了Gnonomic投影 ...所以也许可以奏效?

MATLAB可以很好地实现低差异序列,您可以使用生成q = sobolset(2)和使用q = scramble(q)。MATLAB中还有一个映射工具箱,其中包含许多不同的投影函数,如果您不想自己编写映射和图形代码,可以使用它们。


1
这些预测中的任何一个还能保持随机性的一致性吗?再次,我如何检查这些点的最终分布在球体表面上是否真正均匀地分布?谢谢。
李强

抱歉,我只是假设...我认为MATLAB上的映射函数将允许您检查它们,因为其中嵌入了一些可视化效果。如果不是,我还找到了一个不错的网站,该网站讨论了如何使用随机角度等方法在3D球体上生成均匀分布的点。它们上面也有一些C代码。看看
Berk U.

3
侏儒投影上均匀的随机点在球体上将不均匀,因为侏儒的面积不相等。由亨利提出的投影, - >(从经纬度到在矩形),等面积。(λ,ϕ)(λ,sin(ϕ))R2
ub
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.