在封闭的时间间隔内生成统一的伪随机数

时间:2018-09-25 14:20:40

标签: random fortran

在闭区间[0,1]而不是通常的[0,1)中生成伪随机数的最佳方法是什么?我想到的一个想法是拒绝(1 / 2,1)中的值,然后将该数字加倍。我想知道是否有更好的方法。

real x
do
   call random_number(x)
   if (x <= 0.5) exit
end do
x = 2*x
print *, x
end

最重要的要求是该算法的分布(就均匀性和相关性而言)不应比random_number()生成的分布更差。我也赞成简单。 random_number()周围的包装将是非常好的,我不打算实现一个全新的生成器。


正如@francescalus在评论中指出的那样,通过上述算法,[0,1]中的许多数字将出现的可能性为零。以下代码实现了一种略有不同的方法:将间隔扩大一点,然后切出超过1的值。在这方面应该表现得更好。

real x
do
   call random_number(x)
   x = x*(1 + 1e-6)
   if (x <= 1.) exit
end do
print *, x
end

1 个答案:

答案 0 :(得分:3)

交换x和1-x怎么样?抱歉,我的Fortran生锈了

real function RNG()
real ::    x
logical, save :: swap = .TRUE.

call random_number(x)
if (swap .EQV. .TRUE.)
    RNG = x
    swap = .FALSE.
else
    RNG = 1.0 - x
    swap = .TRUE.
end if

end

如果您想使用Box-Muller,请在任何地方使用1-U,它应该可以工作

z0 = sqrt(-2.0*log(1.0-U1))*sin(TWOPI*U2)
z1 = sqrt(-2.0*log(1.0-U1))*cos(TWOPI*U2)

与Box-Muller的拒绝版本相同