Answers:
一种标准方法是生成三个标准法线并从中构造一个单位向量。也就是说,当和,则是一致的分布在球体上。该方法也适用于维球体。
在3D中,您可以使用拒绝采样:从均匀的分布中提取,直到长度小于或等于1,然后-与前面的方法一样-将向量归一化为单位长度。每个球形点的预期试验次数等于 = 1.91。在更高的维度上,预期的试验数量如此之大,以至于迅速变得不切实际。
有许多检查均匀性的方法。尽管有一定的计算量,但一种巧妙的方法是使用Ripley的K函数。(3D欧几里德)距离内的点的预期数量在球体上的任何位置的正比于距离内的球的面积,它等于。通过计算所有点间距离,您可以将数据与理想值进行比较。
构造统计图形的一般原则建议进行比较的一种好方法是针对绘制方差稳定的残差,其中是相互距离中最小的,而。该图应接近零。(这种方法是非常规的。)
这是用第一种方法从均匀球面分布中获得的100次独立绘制的图片:
这是距离的诊断图:
y标度表明这些值都接近零。
这是100个这样的图的累积,以表明哪些尺寸偏差实际上可能是不均匀性的重要指标:
(这些图看起来像布朗桥一样可怕……这里可能潜藏着一些有趣的理论发现。)
最后,这是一组100个均匀随机点和仅均匀分布在上半球的另外41个点的诊断图:
相对于均匀分布,它显示出在一个半球范围内的平均点距显着减小。这本身是没有意义的,但是这里有用的信息是,某事物在一个半球的尺度上是不均匀的。实际上,此图很容易检测到一个半球的密度与另一半球的密度不同。(如果您事先知道要在无限多个可能的半球中进行测试,则更简单的卡方检验会以更大的能力执行此操作。)
这是一些相当简单的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)
这是非常简单的从建筑看到等,但如果需要将其然后测试
mean(x^2+y^2+z^2) # should be 1
var(x^2+y^2+z^2) # should be 0
并易于测试和分别均匀分布在(很明显是)上
plot.ecdf(x) # should be uniform on [-1, 1]
plot.ecdf(y)
plot.ecdf(z)
显然,给定的值,和均匀地分布在半径的圆周围,可以通过查看其比率的反正切分布来进行测试。但是由于具有与和相同的边际分布,因此类似的说法适用于任何一对,这也可以进行测试。
plot.ecdf(atan2(x,y)) # should be uniform on [-pi, pi]
plot.ecdf(atan2(y,z))
plot.ecdf(atan2(z,x))
如果仍然不能令人信服,那么下一步将是查看一些任意的3-D旋转或在给定的立体角内落了多少点,但这开始变得更加复杂,我认为这是不必要的。
如果要对均匀分布在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分布)。
v = MultivariateNormal(torch.zeros(10000), torch.eye(10000))
然后 v = v/v.norm(10000)
在攻读博士学位期间,我遇到了类似的问题(n球),当地的一位专家建议从n立方体中进行拒绝采样!当然,这就像我以hunderds的顺序查看n时所花的时间一样。
我最终使用的算法非常简单,并发布在:
WP Petersen和A. Bernasconic从n球面进行均匀采样:各向同性方法技术报告,TR-97-06,瑞士科学计算中心
我的书目中也有我没有看过的这篇论文。您可能会发现它很有用。
Harman,R.&Lacko,V.关于从球和球进行均匀采样的分解算法,《多元分析杂志》,2010年
我以前遇到过这个问题,这是我找到的替代方法,
至于分布本身,我发现比较有效的公式是使用极坐标(我实际上使用了已开发的极坐标的变体),然后转换为笛卡尔坐标。
半径当然是要绘制的球体的半径。然后,在平面上有第二个角度值,然后是第三个值,即该平面上方或下方的角度。
为了获得合理的分布,假设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脚本制作的,因此您可以直接在地图中构建公式,从而无需离开游戏就可以检查多个采样。也许这不是科学的方法,但是是一种直观地查看结果的好方法。
我最好的猜测是首先在二维空间中生成一组均匀分布的点,然后使用某种投影将这些点投影到球体的表面上。
您可能必须将生成点的方式与映射它们的方式混合并匹配。就二维点生成而言,我认为加扰的低差异序列是一个很好的起点(即加扰的Sobol序列),因为它通常会产生不“聚集在一起”的点。我不确定要使用哪种类型的映射,但是Woflram弹出了Gnonomic投影 ...所以也许可以奏效?
MATLAB可以很好地实现低差异序列,您可以使用生成q = sobolset(2)
和使用q = scramble(q)
。MATLAB中还有一个映射工具箱,其中包含许多不同的投影函数,如果您不想自己编写映射和图形代码,可以使用它们。