Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Random 在Fortran模块中生成随机数_Random_Fortran_Fortran90 - Fatal编程技术网

Random 在Fortran模块中生成随机数

Random 在Fortran模块中生成随机数,random,fortran,fortran90,Random,Fortran,Fortran90,现在我面临的问题是,在模块中,我使用种子生成随机数以用于函数的循环,但每次调用该函数时,都会生成相同的随机数(因为种子显然是相同的)但它必须继续这个系列,或者至少在调用之间必须有所不同。一个解决方案可能是主程序提供一个新的种子用于模块,但我认为可能还有另一个优雅的解决方案。 根据许多人的建议,我正在使用梅森捻线机发生器 增加 我模块中的函数(它是一个函数包)通常使用种子生成的随机数进行这样的大都会测试,出于某种原因,如果我将 module mymod uses mtmod

现在我面临的问题是,在模块中,我使用种子生成随机数以用于函数的循环,但每次调用该函数时,都会生成相同的随机数(因为种子显然是相同的)但它必须继续这个系列,或者至少在调用之间必须有所不同。一个解决方案可能是主程序提供一个新的种子用于模块,但我认为可能还有另一个优雅的解决方案。 根据许多人的建议,我正在使用梅森捻线机发生器

增加

我模块中的函数(它是一个函数包)通常使用种子生成的随机数进行这样的大都会测试,出于某种原因,如果我将

    module mymod
    uses mtmod
    call sgrnd(4357)!<-- this line causes compilation error
    contains
    myfunc(args)
    implicit none
    // declarations etc
    !call sgrnd(4357) <-- if I put this call here compilator says ok,
    !but re-start random number series each time this function is called :(
    ....
    !the following part is inside a loop
    if (prob < grnd()) then
    !grnd() is random number generated
    return
    else continue testing to the end of the loop cycle
    end myfunc
模块mymod
使用mtmod
致电sgrnd(4357) 您可以找到一个使用系统时间对随机数生成器重新设定种子的子例程。您不应该每次调用random_number()时都这样做,只要每次重新启动程序


老实说,我在Google上找到它不需要超过十分钟。

我总是使用这个子程序(我正在运行MonteCarlo模拟),在主程序开始时调用它,它应该可以完成以下工作:

(来源:)


为了恢复我的分数,我不得不找到我自己的答案,在这里(经过一个小时的尝试)

主程序是

    program callrtmod
    use mymod
    implicit none
    real::x
    x=1.0
    write(*,*) x+writerandnum()
    write(*,*) x+writerandnum()
    write(*,*) x+writerandnum()
    end program callrtmod
这是我的模块

    module mymod
    implicit none
    !-------------mt variables-------------
    ! Default seed
        integer, parameter :: defaultsd = 4357
    ! Period parameters
        integer, parameter :: N = 624, N1 = N + 1

    ! the array for the state vector
        integer, save, dimension(0:N-1) :: mt
        integer, save                   :: mti = N1
    !--------------------------------------

    contains
    function writerandnum
    implicit none
    real(8)::writerandnum

    writerandnum = grnd()
            !if you please, you could perform a Metropolis test here too
    end function writerandnum


    !Initialization subroutine
      subroutine sgrnd(seed)
        implicit none

        integer, intent(in) :: seed

        mt(0) = iand(seed,-1)
        do mti=1,N-1
          mt(mti) = iand(69069 * mt(mti-1),-1)
        enddo
    !
        return
      end subroutine sgrnd
    !---------------------------------------------------------------------------
    !the function grnd was here
    !---------------------------------------------------------------------------


      subroutine mtsavef( fname, forma )

        character(*), intent(in) :: fname
        character, intent(in)    :: forma

        select case (forma)
          case('u','U')
          open(unit=10,file=trim(fname),status='UNKNOWN',form='UNFORMATTED', &
            position='APPEND')
          write(10)mti
          write(10)mt

          case default
          open(unit=10,file=trim(fname),status='UNKNOWN',form='FORMATTED', &
            position='APPEND')
          write(10,*)mti
          write(10,*)mt

        end select
        close(10)

        return
      end subroutine mtsavef

      subroutine mtsaveu( unum, forma )

        integer, intent(in)    :: unum
        character, intent(in)  :: forma

        select case (forma)
          case('u','U')
          write(unum)mti
          write(unum)mt

          case default
          write(unum,*)mti
          write(unum,*)mt

          end select

        return
      end subroutine mtsaveu

      subroutine mtgetf( fname, forma )

        character(*), intent(in) :: fname
        character, intent(in)    :: forma

        select case (forma)
          case('u','U')
          open(unit=10,file=trim(fname),status='OLD',form='UNFORMATTED')
          read(10)mti
          read(10)mt

          case default
          open(unit=10,file=trim(fname),status='OLD',form='FORMATTED')
          read(10,*)mti
          read(10,*)mt

        end select
        close(10)

        return
      end subroutine mtgetf

      subroutine mtgetu( unum, forma )

        integer, intent(in)    :: unum
        character, intent(in)  :: forma

        select case (forma)
          case('u','U')
          read(unum)mti
          read(unum)mt

          case default
          read(unum,*)mti
          read(unum,*)mt

          end select

        return
      end subroutine mtgetu


    !===============================================

    !Random number generator
    !  real(8) function grnd()
      function grnd !agregue yo
        implicit integer(a-z)
        real(8) grnd    !agregue yo
    ! Period parameters
        integer, parameter :: M = 397, MATA  = -1727483681
    !                                    constant vector a
        integer, parameter :: LMASK =  2147483647
    !                                    least significant r bits
        integer, parameter :: UMASK = -LMASK - 1
    !                                    most significant w-r bits
    ! Tempering parameters
        integer, parameter :: TMASKB= -1658038656, TMASKC= -272236544

        dimension mag01(0:1)
        data mag01/0, MATA/
        save mag01
    !                        mag01(x) = x * MATA for x=0,1

        TSHFTU(y)=ishft(y,-11)
        TSHFTS(y)=ishft(y,7)
        TSHFTT(y)=ishft(y,15)
        TSHFTL(y)=ishft(y,-18)

        if(mti.ge.N) then
    !                       generate N words at one time
          if(mti.eq.N+1) then
    !                            if sgrnd() has not been called,
        call sgrnd( defaultsd )
    !                              a default initial seed is used
          endif

          do kk=0,N-M-1
          y=ior(iand(mt(kk),UMASK),iand(mt(kk+1),LMASK))
          mt(kk)=ieor(ieor(mt(kk+M),ishft(y,-1)),mag01(iand(y,1)))
          enddo
          do kk=N-M,N-2
          y=ior(iand(mt(kk),UMASK),iand(mt(kk+1),LMASK))
          mt(kk)=ieor(ieor(mt(kk+(M-N)),ishft(y,-1)),mag01(iand(y,1)))
          enddo
          y=ior(iand(mt(N-1),UMASK),iand(mt(0),LMASK))
          mt(N-1)=ieor(ieor(mt(M-1),ishft(y,-1)),mag01(iand(y,1)))
          mti = 0
        endif

        y=mt(mti)
        mti = mti + 1 
        y=ieor(y,TSHFTU(y))
        y=ieor(y,iand(TSHFTS(y),TMASKB))
        y=ieor(y,iand(TSHFTT(y),TMASKC))
        y=ieor(y,TSHFTL(y))

        if(y .lt. 0) then
          grnd=(dble(y)+2.0d0**32)/(2.0d0**32-1.0d0)
        else
          grnd=dble(y)/(2.0d0**32-1.0d0)
        endif

        return
      end function grnd


    end module mymod

测试我的解决方案并投票支持我;)[当然,正如您所看到的,我修改了mt.f90代码以便方便地包含在我的模块中,因此我可以将主程序与randon数字生成部分分开,这样我可以在主程序之外进行Metropolis测试。主程序只想知道是否接受了试验。我的解决方案确实让主程序更加清晰]

请不要只要求我们为您解决问题。向我们展示你是如何试图自己解决问题的,然后向我们展示结果是什么,并告诉我们为什么你觉得它不起作用。请参阅“”以获得一篇您真正需要阅读的优秀文章。您究竟为什么要在每次通话中重新设定RNG的种子?把它装上一次,然后让它撕裂。我同意凯尔的观点。此外,您是否在种子生成过程中使用了系统时间或任何其他变化量?请注意,如果您删除了其他“答案”,您可以重新获得这些丢失的点非常感谢。这对编写遗传算法非常有帮助。你应该始终确认代码的来源。在这种情况下是这样的
    module mymod
    implicit none
    !-------------mt variables-------------
    ! Default seed
        integer, parameter :: defaultsd = 4357
    ! Period parameters
        integer, parameter :: N = 624, N1 = N + 1

    ! the array for the state vector
        integer, save, dimension(0:N-1) :: mt
        integer, save                   :: mti = N1
    !--------------------------------------

    contains
    function writerandnum
    implicit none
    real(8)::writerandnum

    writerandnum = grnd()
            !if you please, you could perform a Metropolis test here too
    end function writerandnum


    !Initialization subroutine
      subroutine sgrnd(seed)
        implicit none

        integer, intent(in) :: seed

        mt(0) = iand(seed,-1)
        do mti=1,N-1
          mt(mti) = iand(69069 * mt(mti-1),-1)
        enddo
    !
        return
      end subroutine sgrnd
    !---------------------------------------------------------------------------
    !the function grnd was here
    !---------------------------------------------------------------------------


      subroutine mtsavef( fname, forma )

        character(*), intent(in) :: fname
        character, intent(in)    :: forma

        select case (forma)
          case('u','U')
          open(unit=10,file=trim(fname),status='UNKNOWN',form='UNFORMATTED', &
            position='APPEND')
          write(10)mti
          write(10)mt

          case default
          open(unit=10,file=trim(fname),status='UNKNOWN',form='FORMATTED', &
            position='APPEND')
          write(10,*)mti
          write(10,*)mt

        end select
        close(10)

        return
      end subroutine mtsavef

      subroutine mtsaveu( unum, forma )

        integer, intent(in)    :: unum
        character, intent(in)  :: forma

        select case (forma)
          case('u','U')
          write(unum)mti
          write(unum)mt

          case default
          write(unum,*)mti
          write(unum,*)mt

          end select

        return
      end subroutine mtsaveu

      subroutine mtgetf( fname, forma )

        character(*), intent(in) :: fname
        character, intent(in)    :: forma

        select case (forma)
          case('u','U')
          open(unit=10,file=trim(fname),status='OLD',form='UNFORMATTED')
          read(10)mti
          read(10)mt

          case default
          open(unit=10,file=trim(fname),status='OLD',form='FORMATTED')
          read(10,*)mti
          read(10,*)mt

        end select
        close(10)

        return
      end subroutine mtgetf

      subroutine mtgetu( unum, forma )

        integer, intent(in)    :: unum
        character, intent(in)  :: forma

        select case (forma)
          case('u','U')
          read(unum)mti
          read(unum)mt

          case default
          read(unum,*)mti
          read(unum,*)mt

          end select

        return
      end subroutine mtgetu


    !===============================================

    !Random number generator
    !  real(8) function grnd()
      function grnd !agregue yo
        implicit integer(a-z)
        real(8) grnd    !agregue yo
    ! Period parameters
        integer, parameter :: M = 397, MATA  = -1727483681
    !                                    constant vector a
        integer, parameter :: LMASK =  2147483647
    !                                    least significant r bits
        integer, parameter :: UMASK = -LMASK - 1
    !                                    most significant w-r bits
    ! Tempering parameters
        integer, parameter :: TMASKB= -1658038656, TMASKC= -272236544

        dimension mag01(0:1)
        data mag01/0, MATA/
        save mag01
    !                        mag01(x) = x * MATA for x=0,1

        TSHFTU(y)=ishft(y,-11)
        TSHFTS(y)=ishft(y,7)
        TSHFTT(y)=ishft(y,15)
        TSHFTL(y)=ishft(y,-18)

        if(mti.ge.N) then
    !                       generate N words at one time
          if(mti.eq.N+1) then
    !                            if sgrnd() has not been called,
        call sgrnd( defaultsd )
    !                              a default initial seed is used
          endif

          do kk=0,N-M-1
          y=ior(iand(mt(kk),UMASK),iand(mt(kk+1),LMASK))
          mt(kk)=ieor(ieor(mt(kk+M),ishft(y,-1)),mag01(iand(y,1)))
          enddo
          do kk=N-M,N-2
          y=ior(iand(mt(kk),UMASK),iand(mt(kk+1),LMASK))
          mt(kk)=ieor(ieor(mt(kk+(M-N)),ishft(y,-1)),mag01(iand(y,1)))
          enddo
          y=ior(iand(mt(N-1),UMASK),iand(mt(0),LMASK))
          mt(N-1)=ieor(ieor(mt(M-1),ishft(y,-1)),mag01(iand(y,1)))
          mti = 0
        endif

        y=mt(mti)
        mti = mti + 1 
        y=ieor(y,TSHFTU(y))
        y=ieor(y,iand(TSHFTS(y),TMASKB))
        y=ieor(y,iand(TSHFTT(y),TMASKC))
        y=ieor(y,TSHFTL(y))

        if(y .lt. 0) then
          grnd=(dble(y)+2.0d0**32)/(2.0d0**32-1.0d0)
        else
          grnd=dble(y)/(2.0d0**32-1.0d0)
        endif

        return
      end function grnd


    end module mymod