Генерация равномерных псевдослучайных чисел в замкнутом интервале - PullRequest
0 голосов
/ 25 сентября 2018

Какой лучший способ генерировать псевдослучайные числа в замкнутом интервале [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 голосов
/ 25 сентября 2018

Как насчет замены x и 1-x?Извините, мой Фортран ржавый

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-Мюллер

...