Random 在闭合区间内生成均匀伪随机数

Random 在闭合区间内生成均匀伪随机数,random,fortran,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 交换x和1-x怎么样?对不起,我的Fortran已经生锈了 real function RNG() real :: x logical, save ::

在闭区间[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

交换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

“Best”将过于宽泛,因此也许您可以解释在这个新分布中需要什么属性。例如,在这个问题中,区间[0,1]中的许多数字现在出现的概率为零。@francescalus最重要的要求是它不应“毁坏”由
random\u number()
生成的发行版。我不想实现一个全新的生成器,只是想包装一下
random\u number()
in。我希望它简洁。从第一个要求来看,如果我正确理解第一个算法的问题,我添加的第二个算法应该更好。@ArchStanton wiki页面提到了根据U(0,1)生成的随机数,这并不意味着必须包含1。我还认为该页面的限制有点混乱。如果你查看数字配方,它会得到很好的解释。简言之,你可以使用
随机数
进行Box-Muller变换,没有任何问题。你会得到一个非常好的高斯分布E4均匀分布U((0,1))、U([0,1])、U((0,1])和U([0,1])是相同的,因此您担心的是实际上什么都不是。@kvantour包含1(代价是在[0,1]中排除一些其他可表示的实数)并没有坏处,但是任何代码都明确使用了它(例如,通过显式测试与1相等)可能是错误代码(IMHO)。这种方法只是将问题从半开区间[0,1]切换到半开区间(0,1)。OP请求关闭区间[0,1]@kvantour否,有时采样0时返回0,有时采样0时返回1,因此此方法的总间隔为[0…1]啊,是的,您是正确的,但随后数字0和1的采样概率为所有其他数字的一半,这将使您的装箱发生偏差(非常轻微)@是的,我们用一半的零来交换ones@kvantour谢谢,这是C++中已知的东西,当标准说我们将有十二个RNG,但是它们都在[0…1的间隔]中。你是正确的WRT <代码> 1.0d0~u1 < /代码>,我为我的Fortran SkLLL变形而道歉。
z0 = sqrt(-2.0*log(1.0-U1))*sin(TWOPI*U2)
z1 = sqrt(-2.0*log(1.0-U1))*cos(TWOPI*U2)