我正在尝试模拟一个物理问题(布朗动力学),我需要为其生成随机数。
以前,我只是使用以下方法从高斯分布中选择随机数:
subroutine box_muller(l)
implicit none
real :: l, u1, u2
real, parameter :: pi = acos(-1.0)
call random_seed()
call random_number(u1)
call random_number(u2)
l = sqrt(-2*log(u1))*cos(2*pi*u2)
end subroutine
这是 Box-Muller 算法。
我在每个瞬间(时间步长)调用这个子例程。
但我想我还没有明白如何正确使用
call random_seed()
的东西。
例如,经过一些互联网搜索后,我尝试了以下方法:
program seeding
implicit none
integer:: n
INTEGER :: seed
REAL :: num
CALL RANDOM_SEED (size=seed)
seed = 123456789
DO n = 1, 5
CALL RANDOM_NUMBER(num)
PRINT *, num
END DO
end program
它给出以下输出:
4.80166674E-02
0.797537327
0.294925630
0.107502699
0.987043023
虽然我不知道我是否做对了。
我还在我的主要问题中尝试了以下方法:
subroutine box_muller(x)
implicit none
integer :: n
integer,allocatable :: seed(:)
real,intent(out) :: x
real,parameter :: pi=3.14159265
real :: u1,u2
call random_seed(size=n)
allocate(seed(n))
seed = 12 ! putting arbitrary seed to all elements
call random_number(u1)
call random_number(u2)
x = sqrt(-2*log(u1))*cos(2*pi*u2)
end subroutine
但是相信我,我对自己在做什么一无所知。
问题是 -
call random_seed()
,call random_number()
,您是否希望/需要随机数序列在每次运行中都可重复?如果不是,您根本不必致电
random_seed()
。如果是的话,你的最后一段代码几乎是正确的,但它错过了一个调用:
integer :: n
integer,allocatable :: seed(:)
call random_seed(size=n) ! n is processor-dependent
allocate(seed(n))
seed = 12 ! putting arbitrary seed to all elements
call random_seed(put=seed) ! effectively initializing the RNG with the seed