Random Fortran随机模拟程序中种子数的改变
我正在运行一个Fortran代码,它对一个有标记的泊松聚类过程进行随机模拟。实际上,事件属性(如发生时间)是通过反演方法生成的,即通过累积分布函数的随机抽样。 由于泊松随机性,我希望每个生成的序列都是不同的,但事实并非如此。我猜原因是伪随机数生成器的种子在每次模拟时都是相同的。 我不懂Fortran,所以我不知道如何解决这个问题。这是伪随机数生成器的部分代码,你知道吗Random Fortran随机模拟程序中种子数的改变,random,fortran,simulation,random-seed,stochastic-process,Random,Fortran,Simulation,Random Seed,Stochastic Process,我正在运行一个Fortran代码,它对一个有标记的泊松聚类过程进行随机模拟。实际上,事件属性(如发生时间)是通过反演方法生成的,即通过累积分布函数的随机抽样。 由于泊松随机性,我希望每个生成的序列都是不同的,但事实并非如此。我猜原因是伪随机数生成器的种子在每次模拟时都是相同的。 我不懂Fortran,所以我不知道如何解决这个问题。这是伪随机数生成器的部分代码,你知道吗 subroutine pseud0(r) c generation of pseudo-random numbers c
subroutine pseud0(r)
c generation of pseudo-random numbers
c data ir/584287/
data ir/574289/
ir=ir*48828125
if(ir) 10,20,20
10 ir=(ir+2147483647)+1
20 r=float(ir)*0.4656613e-9
return
end
subroutine pseudo(random)
c wichmann+hill (1982) Appl. Statist 31
data ix,iy,iz /1992,1111,1151/
ix=171*mod(ix,177)-2*(ix/177)
iy=172*mod(iy,176)-35*(iy/176)
iz=170*mod(iz,178)-63*(iz/178)
if (ix.lt.0) ix=ix+30269
if (iy.lt.0) iy=iy+30307
if (iz.lt.0) iz=iz+30323
random=mod(float(ix)/30269.0+float(iy)/30307.0+
& float(iz)/30323.0,1.0)
return
end
首先,我将回顾PRNG的现代文献,并选择一个现代实现。其次,我将用现代Fortran重写代码 您需要遵循@francescalus的建议,并有更新种子的方法。在不尝试使代码现代化的情况下,以下是一种用于
pseud0
prng的方法
subroutine init0(i)
integer, intent(in) :: i
common /myseed0/iseed
iseed = i
end subroutine init0
subroutine pseud0(r)
common /myseed0/ir
ir = ir * 48828125
if (ir) 10,20,20
10 ir = (ir+2147483647)+1
20 r = ir*0.4656613e-9
end subroutine pseud0
program foo
integer i
real r1
call init0(574289) ! Original seed
do i = 1, 10
call pseud0(r1)
print *, r1
end do
print *
call init0(289574) ! New seed
do i = 1, 10
call pseud0(r1)
print *, r1
end do
print *
end program foo
首先,我将回顾PRNG的现代文献,并选择一个现代实现。其次,我将用现代Fortran重写代码 您需要遵循@francescalus的建议,并有更新种子的方法。在不尝试使代码现代化的情况下,以下是一种用于
pseud0
prng的方法
subroutine init0(i)
integer, intent(in) :: i
common /myseed0/iseed
iseed = i
end subroutine init0
subroutine pseud0(r)
common /myseed0/ir
ir = ir * 48828125
if (ir) 10,20,20
10 ir = (ir+2147483647)+1
20 r = ir*0.4656613e-9
end subroutine pseud0
program foo
integer i
real r1
call init0(574289) ! Original seed
do i = 1, 10
call pseud0(r1)
print *, r1
end do
print *
call init0(289574) ! New seed
do i = 1, 10
call pseud0(r1)
print *, r1
end do
print *
end program foo
种子被硬编码到源中。您可以在那里简单地更改值(在
data
语句中),但是如果您想做一些更奇特的事情,那么这将需要重新设计。问题是我需要运行此代码至少100次,这将使每次手动编辑种子都很麻烦。一种方法是从命令行传递种子,这样您的代码就不需要更改和重新编译。另一种方法是从/dev/uradom
(posix系统)中读取“随机性”。谢谢@pierredebyl,我是否应该编辑代码以使其接受来自命令行的输入?种子已硬编码到源代码中。您可以在那里简单地更改值(在data
语句中),但是如果您想做一些更奇特的事情,那么这将需要重新设计。问题是我需要运行此代码至少100次,这将使每次手动编辑种子都很麻烦。一种方法是从命令行传递种子,这样您的代码就不需要更改和重新编译。另一种方法是从/dev/uradom
(posix系统)中读取“随机性”。谢谢@Pierredebyl,我是否应该编辑代码以接受命令行的输入?谢谢@steve。事实上,这是一个非常古老的代码,这就是为什么对于那些不懂Fortran的人来说,它更加困难的原因。你知道为什么会有pseud0
prng和pseudo(random)
prng吗?有什么区别?据我所知,在整个代码中,只有pseud0
prng被称为@francescalus,当然,为了避免common
的一些方法,“现代”。我并没有试图变得现代,只是展示了OP one方法来满足OP的需求。希望OP遵循我的第一个建议,并寻找一个现代的PRNG。@Angela在生成器方面,您可能比Wichmann Hill做得更差,但您可以研究的FORTRAN实现。“它在标准测试套件中运行良好,速度非常快。”francescalus,我更新了我的答案,注意到我没有尝试使代码现代化。仅仅阅读旧代码就让我的眼睛受伤。@steve,问题是我不明白为什么会有Wichmann-Hill生成器,伪(随机)子程序从未被程序调用。谢谢@steve。事实上,这是一个非常古老的代码,这就是为什么对于那些不懂Fortran的人来说,它更加困难的原因。你知道为什么会有pseud0
prng和pseudo(random)
prng吗?有什么区别?据我所知,在整个代码中,只有pseud0
prng被称为@francescalus,当然,为了避免common
的一些方法,“现代”。我并没有试图变得现代,只是展示了OP one方法来满足OP的需求。希望OP遵循我的第一个建议,并寻找一个现代的PRNG。@Angela在生成器方面,您可能比Wichmann Hill做得更差,但您可以研究的FORTRAN实现。“它在标准测试套件中运行良好,速度非常快。”francescalus,我更新了我的答案,注意到我没有尝试使代码现代化。仅仅阅读旧代码就让我的眼睛受伤。@steve,问题是我不明白为什么会有Wichmann-Hill生成器,伪(随机)子例程从未被程序调用。