回 帖 发 新 帖 刷新版面

主题:求助,球内均匀分布点

已知n个(0,1)内的随机数,要在半径r内对球均匀撒点,请问算法如何实现?

回复列表 (共16个回复)

11 楼

不是球心不应该有点,而是"产生(x,y,z),然后2.0*(x,y,z)-1.0,再然后将x^2+y^2+z^2>1的舍去" 
这种算法不会在(0,0,0)产生点,因为Fortran 产生的随机数是在[0,1)区间上分布的,左端是开区间,将这些随机数放大2倍,在向右平移1,则分布在,额,是[-1,1)区间,
我错了,不是(0,0,0)没点,而是x,y,z都不可能等于1,但有可能等于-1,所以,是在(0,0,1)(0,1,0),(1,0,0)这三个位置没点。
注:在那三个位置非常近非常近的附近,圆内还是有点的。只不过点不可能一点不差地正好落在那三个位置。

12 楼

先小声的问下,为什么回帖的时候界面是乱码呢?

这个问题的其实很简单的。
如果在笛卡尔做标下,那么概率密度函数就是g(x,y,z)=1/V. V 是球的体积
现在我们转换的球坐标下,有关系f(r,theta,phi)=g(x,y,z)*d(x,y,z)/d(r,theta,phi)
可以得到f(r,theta,phi)=r^2*sin(theta)/V. 积分得到对应的概率分布函数就是
F(r,theta,phi)=f1(r)*f2(theta)*f3(phi)
f1(r)=r^3/R^3;f2(theta)=(1-cos(theta))/2;f3(phi)=phi/(2*pi)
让我们产生三个(0,1)间均分布的函数,由此求反函数得到对应的r,theta,phi分别满足对应的分布。
你也可以进一步转化到笛卡尔坐标系。

13 楼

先小声的问下,为什么回帖的时候界面是乱码呢?

这个问题的其实很简单的。
如果在笛卡尔做标下,那么概率密度函数就是g(x,y,z)=1/V. V 是球的体积
现在我们转换的球坐标下,有关系f(r,theta,phi)=g(x,y,z)*d(x,y,z)/d(r,theta,phi)
可以得到f(r,theta,phi)=r^2*sin(theta)/V.(这个也可以直接写出来的) 积分得到对应的概率分布函数就是
F(r,theta,phi)=f1(r)*f2(theta)*f3(phi)
f1(r)=r^3/R^3;f2(theta)=(1-cos(theta))/2;f3(phi)=phi/(2*pi)
让我们产生三个(0,1)间均分布的函数,由此求反函数得到对应的r,theta,phi分别满足对应的分布。
r=R*(U(0,1))^(1/3);theta=arccos(1-2*U(0,1));phi=2*pi*U(0,1);
U(0,1)代表0到1的均匀分布.
你也可以进一步转化到笛卡尔坐标系。

14 楼

[quote]先小声的问下,为什么回帖的时候界面是乱码呢?

这个问题的其实很简单的。
如果在笛卡尔做标下,那么概率密度函数就是g(x,y,z)=1/V. V 是球的体积
现在我们转换的球坐标下,有关系f(r,theta,phi)=g(x,y,z)*d(x,y,z)/d(r,theta,phi)
可以得到f(r,theta,phi)=r^2*sin(theta)/V.(这个也可以直接写出来的) 积分得到对应的概率分布函数就是
F(r,theta,phi)=f1(r)*f2(theta)*f3(phi)
f1(r)=r^3/R^3;f2(theta)=(1-cos(theta))/2;f3(phi)=phi/(2*pi)
让我们产生三个(0,1)间均分布的函数,由此求反函数得到对应的r,theta,phi分别满足对应的分布。
r=R*(U(0,1))^(1/3);theta=arccos(1-2*U(0,1));phi=2*pi*U(0,1);
U(0,1)代表0到1的均匀分布.
你也可以进一步转化到笛卡尔坐标系。[/quote]

实际上这样撒出的点有一个很致命的问题:半径r范围内的点个数的误差不服从泊松分布。。。我也不知道为啥会这样,可能是我的程序错了;不过有一个很好玩的地方,就是如果画一张图,横坐标是点数,纵坐标是点数的中误差(方差),在n<总点数一半的时候,符合泊松分布(中误差,或者说标准差与根号下n成正比),而大于总点数一半的时候,就掉下去了。。。而实际上如果取对个数均匀取点的话,可以看到这俩是对称的。。。
我采用的方法是取一个密度与所求均匀球一样的球(或者box也可以),然后取一个半径为r的球在边缘实际上是由误差的,也就是r范围内的点个数实际上是N+or-dN,N是所需数目,我在边缘强制等于N。这样一来,得到的点,如果画log图的话,半径和半径内包含点的数目是3次方关系,符合均匀分布;中误差(标准差)与n的在误差允许的范围内(误差棒覆盖下)符合二分之一次方关系,也就是符合泊松分布。。

15 楼

[quote][quote]笨人想出的没有技术含量的算法:可以直接产生x,y,z三个随机数,再将x^2+y^2+z^2>1的扔掉,直到球内有n个随机点为止。

另,2楼说的没错,1楼的算法感觉是[0,1)上的随机数绕着圆心转一圈,半径小的地方点出现的几率与大半径处一样,就会产生中心聚度。
二楼的方法相当于产生了在[0,1)区间上按分布律f(x)=2x分布的随机数,再将这些数绕圆心转一圈。

那么,球内均匀分布是不是先产生按f(x)=3x^2分布的随机数,即半径开立方,然后
x=开立方a1 * sin(2*pi*b1)*cos(2*pi*c1)
y=开立方a1 * sin(2*pi*b1)*sin(2*pi*c1)
z=开立方a1 * cos(2*pi*b1)                     ?


beginner,望赐教![/quote]
经验证,第二种方法貌似有问题,产生出来的随机数会向z轴的两端聚集,
x=开立方a1 * sin(2*pi*b1)*cos(2*pi*c1)
y=开立方a1 * sin(2*pi*b1)*sin(2*pi*c1)
z=开立方a1 * cos(2*pi*b1)


第一种方法(产生(x,y,z),然后2.0*(x,y,z)-1.0,再然后将x^2+y^2+z^2>1的舍去)尽管很笨,但还算有效。但无论如何,球心肯定是不会有点的。[/quote]

我一开始也这么撒点,而且,看起来的确是很均匀,注意,只是“看起来”,所以。。。见楼上,还是算误差的时候出事儿了。不符合泊松分布,因此我觉得如果给定:要在半径r范围内均匀撒N个点,这样的话如果越靠近边缘,与N的偏差就越小,越靠近0,与0的偏差越小;这样定性的分析,得到一个推论,在n=N/2处会有边界效应。。。我不知道这么解释好不好。。。总之我换了个方法,就是用box往外扣球的方法。。

16 楼


我觉得这个没有什么问题。
不明白你的点的个数误差指什么。在给定半径内点的,点的个数是符合二项分布。当半径很小时,也服从泊松分布。你的误差是怎么算的,为什么服从泊松分布?

我来回复

您尚未登录,请登录后再回复。点此登录或注册