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 PGI Fortran中的随机数生成器不太随机_Random_Fortran_Fortran90_Gfortran_Pgi - Fatal编程技术网

Random PGI Fortran中的随机数生成器不太随机

Random PGI Fortran中的随机数生成器不太随机,random,fortran,fortran90,gfortran,pgi,Random,Fortran,Fortran90,Gfortran,Pgi,以下代码仅生成一个简单的三重随机数: program testrand integer, parameter :: nz = 160, nf = 160, nlt = 90 real :: tmpidx(3) integer :: idxarr(3), idx1, idx2, idx3, seed_size, ticks integer, allocatable :: seed(:) call random_seed(size=seed_size) allocate(seed(seed_s

以下代码仅生成一个简单的三重随机数:

program testrand

integer, parameter :: nz = 160, nf = 160, nlt = 90

real :: tmpidx(3)
integer :: idxarr(3), idx1, idx2, idx3, seed_size, ticks
integer, allocatable :: seed(:)

call random_seed(size=seed_size)
allocate(seed(seed_size))

call system_clock(count=ticks)
seed = ticks+37*(/(i-1, i=1,seed_size)/)
call random_seed(put=seed)

deallocate(seed)

call random_number(tmpidx)
idxarr = tmpidx * (/nz, nf, nlt/)
idx1 = max(1,idxarr(1))
idx2 = max(1,idxarr(2))
idx3 = max(1,idxarr(3))
print *,idx1, idx2, idx3

end program
我用gfortran编译了这个,运行了几次,我得到:

> gfortran testrand.f90
> ./a.out
          74          98          86
> ./a.out
         113           3          10
> ./a.out
          44         104          27
看起来很随意。现在我使用PGI Fortran编译并运行了几次:

> pgf90 testrand.f90
> ./a.out
            1            1            1
> ./a.out
            1            1            1
> ./a.out
            1            1            1

当然,没有办法完全确定,但我怀疑这不是随机的有人知道这是怎么回事吗?有人知道使用PGI Fortran获取随机数的正确方法吗?

不知何故,PGI并不像GNU编译器那样实现系统时钟。我不知道为什么,我最近通过做类似于你的事情发现了它

要了解我在说什么,只需在调用
system\u clock
后打印
ticks
。很有可能,使用PGI和GNU编译器,您会一直得到
0
。为了解决您的问题,您可以修改下面的代码。这是一个稍加修改的代码版本,您可以在

程序测试
仅使用iso_fortran_env:int64
整数,参数::nz=160,nf=160,nlt=90
real::tmpidx(3)
整数::idxarr(3)、idx1、idx2、idx3、种子大小、刻度
整数,可分配::种子(:)
调用随机种子(大小=种子大小)
分配(种子(种子大小))
! 呼叫系统时钟(计数=滴答声)
! 种子=蜱+37*(/(i-1,i=1,种子大小)/)
! 调用随机种子(put=seed)
! 
! 解除分配(种子)
调用init_random_seed()
呼叫随机号码(tmpidx)
idxarr=tmpidx*(/nz,nf,nlt/)
idx1=最大值(1,idxarr(1))
idx2=最大值(1,idxarr(2))
idx3=最大值(1,idxarr(3))
打印*,idx1,idx2,idx3
包含
!
子例程init_random_seed()
隐式无
整数,可分配::种子(:)
整数::i,n,istat,dt(8),pid
整数(int64)::t
整数,参数::un=703
调用随机种子(大小=n)
分配(种子(n))
! 如果操作系统提供随机数生成器,请首先尝试
打开(unit=un,file=“/dev/uradom”,access=“stream”&
form=“未格式化”,action=“读取”,status=“旧”,iostat=istat)
如果(istat==0),则
读取(联合国)种子
关闭(联合国)
其他的
! PID是
! 在一个启动相同的多个实例时非常有用
! 并行编程。
呼叫系统时钟(t)
如果(t==0),则
调用日期和时间(值=dt)
t=(dt(1)-1970)*365*64*24*60*60*1000&
+dt(2)*31_int64*24*60*60*1000&
+dt(3)*24_int64*60*60*1000&
+dt(5)*60*60*1000&
+dt(6)*60*1000+dt(7)*1000&
+dt(8)
如果结束
pid=getpid()
t=ieor(t,int(pid,种类(t)))
i=1,n吗
种子(i)=lcg(t)
结束
如果结束
调用随机种子(put=seed)
!打印*,“最佳种子=”,种子
结束子例程init_random_seed
!
功能lcg(s)
整数::lcg
整数(int64),意图(输入输出)::s
如果(s==0),则
s=104729
其他的
s=mod(s,4294967296_int64)
如果结束
s=mod(s*279470273_int64,4294967291_int64)
lcg=int(mod(s,int(巨大的(0),8)),种类(0))
端功能液晶显示器
!
!此选项特别用于pgf90,以提供getpid()函数
!> @返回当前进程的进程ID
!! @todo编写实际代码,目前返回一个固定值
!<
函数getpid()结果(pid)
整数pid
pid=53!只是一个素数,没有特殊意义
结束函数getpid
结束程序

Ack!我已经看到了,我希望避免它!永远不要忘记日期和时间()似乎效果更好。谢谢
program testrand
use iso_fortran_env, only: int64

    integer, parameter :: nz = 160, nf = 160, nlt = 90
    real :: tmpidx(3)
    integer :: idxarr(3), idx1, idx2, idx3, seed_size, ticks
    integer, allocatable :: seed(:)

    call random_seed(size=seed_size)
    allocate(seed(seed_size))

    ! call system_clock(count=ticks)
    ! seed = ticks+37*(/(i-1, i=1,seed_size)/)
    ! call random_seed(put=seed)
    ! 
    ! deallocate(seed)

    call init_random_seed()

    call random_number(tmpidx)
    idxarr = tmpidx * (/nz, nf, nlt/)
    idx1 = max(1,idxarr(1))
    idx2 = max(1,idxarr(2))
    idx3 = max(1,idxarr(3))
    print *,idx1, idx2, idx3

contains
    !
    subroutine init_random_seed()
        implicit none
        integer, allocatable :: seed(:)
        integer :: i, n, istat, dt(8), pid
        integer(int64) :: t

        integer, parameter :: un=703

        call random_seed(size = n)
        allocate(seed(n))
        ! First try if the OS provides a random number generator
        open(unit=un, file="/dev/urandom", access="stream", &
            form="unformatted", action="read", status="old", iostat=istat)
        if (istat == 0) then
            read(un) seed
            close(un)
        else
            ! The PID is
            ! useful in case one launches multiple instances of the same
            ! program in parallel.
            call system_clock(t)
            if (t == 0) then
                call date_and_time(values=dt)
                t = (dt(1) - 1970) * 365_int64 * 24 * 60 * 60 * 1000 &
                + dt(2) * 31_int64 * 24 * 60 * 60 * 1000 &
                + dt(3) * 24_int64 * 60 * 60 * 1000 &
                + dt(5) * 60 * 60 * 1000 &
                + dt(6) * 60 * 1000 + dt(7) * 1000 &
                + dt(8)
            end if
            pid = getpid()
            t = ieor( t, int(pid, kind(t)) )
            do i = 1, n
                seed(i) = lcg(t)
            end do
        end if
        call random_seed(put=seed)
        !print*, "optimal seed = ", seed
    end subroutine init_random_seed
    !
    function lcg(s)
        integer :: lcg
        integer(int64), intent(in out) :: s
        if (s == 0) then
            s = 104729
        else
            s = mod(s, 4294967296_int64)
        end if
        s = mod(s * 279470273_int64, 4294967291_int64)
        lcg = int(mod(s, int(huge(0), 8)), kind(0))
    end function lcg
    !
    !this option is especially used for pgf90 to provide a getpid() function
    !> @brief Returns the process ID of the current process
    !! @todo write the actual code, for now returns a fixed value
    !<
    function getpid()result(pid)
        integer pid
        pid = 53 !just a prime number, no special meaning
    end function getpid
end program