模拟光盘上的均匀分布


24

我试图模拟在圆中随机点的注入,以使圆的任何部分都具有相同的出现缺陷的可能性。如果我将圆分成相等面积的矩形,我期望结果分布的每面积计数遵循泊松分布。

由于只需要在圆形区域内放置点,因此我在极坐标中注入了两个均匀的随机分布:(半径)和(极角)。θ[Rθ

但是在完成注入之后,与边缘相比,我显然在圆心得到了更多的点。

在此处输入图片说明

在圆上进行这种注入以使点随机分布在整个圆上的正确方法是什么?


这个问题在论坛上的几何精确的模拟:math.stackexchange.com/questions/87230/...
Aksakal

Answers:


35

您希望点的比例与面积成均匀比例,而不是与原点的距离成比例。由于面积与距离的平方成正比,因此生成均匀的随机半径并取其平方根。 结合一个均匀的极角。

这是快速,简单的代码,有效的执行(尤其是在并行平台上),并且精确地生成了规定数量的点。

这是R用于说明算法的工作代码。

n <- 1e4
rho <- sqrt(runif(n))
theta <- runif(n, 0, 2*pi)
x <- rho * cos(theta)
y <- rho * sin(theta)
plot(x, y, pch=19, cex=0.6, col="#00000020")

在此处输入图片说明


3

可以使用拒绝采样。这意味着我们可以从2D均匀分布中采样,然后选择满足光盘条件的采样。

这是一个例子。

x=runif(1e4,-1,1)
y=runif(1e4,-1,1)

d=data.frame(x=x,y=y)
disc_sample=d[d$x^2+d$y^2<1,]
plot(disc_sample)

在此处输入图片说明


3
这是OP采取的方法的一个很好的选择。简单高效。但是,它并没有真正解决这个问题,该问题涉及如何修改极坐标方法以产生均匀分布的变量。我们为什么要在乎呢?由于所涉问题:一旦你知道如何在极坐标生成均匀分布的点,你可以用拒绝抽样(和其他熟悉的方法)在极坐标到样品从可能被过于复杂的样品在直角坐标系的区域(认为内摆线的, 例如)。
ub

1
π/4

@whuber感谢您评论我的答案来教育我!
海涛杜

3

当然,我也将为您提供适用于二维情况的一般n维答案。在三个维度上,磁盘的类似物是实心球(球)的体积。

我将讨论两种方法。其中一个我称为“精确”,在R中您将获得一个完整的解决方案。第二个我称为启发式,这只是一个主意,没有提供完整的解决方案。

“精确”解决方案

我的解决方案基于Marsaglia和Muller的作品。基本上会发生这种情况,以便规范化到其范数的高斯向量将为您提供d维超球面上的均匀分布点:

在此处输入图片说明

d1个/d

n <- 1e4
rho <- sqrt(runif(n))
# d - # of dimensions of hyperdisk
d = 2
r = matrix(rnorm(n*d),nrow=n,ncol=d)
x = r/rep(sqrt(rowSums(r^2))/rho,1)
plot(x[,1], x[,2], pch=19, cex=0.6, col="#00000020")

在此处输入图片说明

这是3D外壳的代码片段,即实心球:

library(scatterplot3d)
n <- 1e3
# d - # of dimensions of hyperdisk

d=3
rho <- (runif(n))^(1/d)
r = matrix(rnorm(n*d),nrow=n,ncol=d)
x = r/rep(sqrt(rowSums(r^2))/rho,1)

scatterplot3d(x[,1], x[,2], x[,3])

在此处输入图片说明

启发式方法

Vñ[R=πñ2Γñ2+1个[Rñ
[Rñ

一世=1个dX一世2<[R2

我建议的解决方案是使用拒绝采样对中心附近的点进行过采样。事实证明,如果您从球内部观看随机均匀样本的笛卡尔坐标之一,则其分布将收敛为方差为的高斯1个d+2


@Silverfish,您是对的,我确定了语言
Aksakal)

@Silverfish,由于使用了高斯变量,所以速度较慢,但​​是在高维情况下可能比简单的拒绝采样要快,尽管这是一个不同的主题,但对许多人来说并不明显
Aksakal

1个/dd

@whuber,我正在复制粘贴,更正了多维数据集功能上的错字。如果我们使用高斯,则拒绝采样并不更好,因此我们必须使用比高斯更快的钟形时钟,您是正确的
阿克萨卡尔(Aksakal)

0

这是以下方面的替代解决方案R

n <- 1e4
## r <- seq(0, 1, by=1/1000)
r <- runif(n)
rho <- sample(r, size=n, replace=T, prob=r)
theta <- runif(n, 0, 2*pi)
x <- rho * cos(theta)
y <- rho * sin(theta)
plot(x, y, pch=19, cex=0.6, col="#00000020")

在此处输入图片说明


4
你能用简单的英语解释这个答案吗?我们并不是真正的代码帮助站点,不建议仅使用代码的答案。
gung-恢复莫妮卡

5
01个r <- seq(0, 1, by=1/10)

1
@whuber感谢您指出这一点。实际上,这是我对解决方案的主要想法。我的方法是生成许多具有不同半径的均匀圆,并且对于每个圆,点的数量与半径的长度成比例。因此,在半径不同的圆的单位长度上,点数相同。为了避免离散性,我们可以r从Uniform(0,1)中采样。
Q_Li
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.