2015-04-02 43 views
2

這是我用我的主要程序(此處未列出) 編譯沿着當我嘗試編譯我的隨機數發生器模塊,看看它的工作原理randon數發生器模塊,我得到以下信息:Fortran 95中的隨機數生成器有什麼問題?

at line 61: call random_seed(put = seed) Error: size of 'put' argument of 'random_seed' intrinsic too small <4/12>

這是什麼意思?我該如何解決它?

module random_angle 
contains 
0 
    integer Function random_integer (N)   ! return a random integer between 1 and N 
     integer, intent(in) :: N 
     real*8 :: x 

     call random_number(x) 
     random_integer = floor(real(N)*x)+1 

    end function random_integer 

    Real*8 Function gasdev()   ! ch7.pg.280:gaussian distribution function using ran1 as random # generator 

     implicit none 
!  integer, intent(inout) :: idum 
     integer, save::iset 
     real*8:: fac,rsq,v1,v2 
     real*8, dimension(2) :: x 
     real*8, save :: gset 

!  if (idum.lt.0) iset=0 
     if (iset.eq.0) then 
      rsq = 0.0 
      do while (rsq > 1.0.or.rsq==0) 
      call random_number(x) 
      v1=2.*x(1)-1 
      v2=2.*x(2)-1 
      rsq=v1**2+v2**2 
! print *, v1, v2,rsq 
      end do  

      fac=sqrt(-2.*log(rsq)/rsq) 
      gset=v1*fac 
      gasdev=v2*fac 
      iset=1 
     else 
      gasdev=gset 
      iset=0 
     endif 

     return 

    end Function gasdev 

    real*8 function NormalRandom (average, stddev) 
     implicit none 
     real*8, intent(in):: average, stddev 
     NormalRandom = average + stddev*gasdev() 

    end function NormalRandom 

    subroutine setSEED (seed) 
     implicit none 

     real*8:: x 
     integer, dimension(4), intent(inout):: seed 
     if (seed(1) == 0.0) & 
      seed = floor(1000*secnds(0.0)) +(/0, 37, 74, 111 /) 
     call random_seed(put=seed) 

    end subroutine setSEED 

end module random_angle 
+3

在gfortran的手冊https://gcc.gnu.org/onlinedocs/gfortran/RANDOM_005fSEED.html#RANDOM_005fSEED中,如何使用'random_seed'也是一個很好的例子 – 2015-04-02 22:02:56

回答

5

當編譯器說

Error: size of 'put' argument of 'random_seed' intrinsic too small <4/12>

就意味着你的變量seed的尺寸太小。

在這種情況下,你有seed的大小4(我猜編譯器必須期待(至少)12)。

數組的大小必須具有一定的大小,這取決於編譯器。您可以確定,便攜,通過調用所需要的尺寸,以random_seed有另一種說法

integer seed_size 
integer, allocatable :: seed(:) 

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

正如普京的F評論指出,gfortran文檔本身這種方法的has an example

如果你不關心便攜式,你可以使用大小爲12的數組來選擇值。


隨着更高級的閱讀,我會說另一件事。我上面給出的例子確實與您的代碼不太相似。也就是說,你說種子設置子例程的輸入至少保證大小爲4,它可以或不可以包含你想用作種子的值。

正如我上面提到的,您可以將其更改爲12,但這不是可移植的。如果你想成爲便攜式的東西會變得更加尷尬。

integer, dimension(4), intent(inout):: seed 

具有作爲虛擬參數的大小爲4的顯式形狀數組。主程序中的實際參數是一個至少具有該大小的數組。然而,這個大小是規範表達式,而唉,call random_seed(size=seed_size)沒有給我們我們可以在規範表達式中使用的東西。

也許類似

subroutine setSEED (seed) 
    integer, allocatable, intent(inout) :: seed(:) 
    integer seed_size 

    ! Determine the correct size for the seed 
    call random_seed(size=seed_size) 

    ! If our seed isn't set, or is too small, kill it. 
    if (ALLOCATED(seed)) then 
    if (SIZE(seed)<seed_size.or.seed(LBOUND(seed,1))==0.) deallocate(seed) 
    end if 

    ! If seed isn't allocated (perhaps we killed it because it was too small) 
    ! then allocate it to the correct size and initialize it. 
    if (.not.ALLOCATED(seed)) then 
    allocate(seed(seed_size)) 
    seed = ... ! Our fallback seed initialization 
    end if 

    ! Finally, put the seed. Using one we set, or the one originally given. 
    call random_seed(put=seed) 

end subroutine 

這當然需要實際的參數是allocatable,但如果你使用隨身結實,這是一個很好的事情。