Random 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

我正在运行一个Fortran代码,它对一个有标记的泊松聚类过程进行随机模拟。实际上,事件属性(如发生时间)是通过反演方法生成的,即通过累积分布函数的随机抽样。 由于泊松随机性,我希望每个生成的序列都是不同的,但事实并非如此。我猜原因是伪随机数生成器的种子在每次模拟时都是相同的。 我不懂Fortran,所以我不知道如何解决这个问题。这是伪随机数生成器的部分代码,你知道吗

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生成器,伪(随机)子例程从未被程序调用。