Random 什么';我的Fortran 95随机数发生器有什么问题吗?
这是一个randon数字生成器模块,我使用它与主程序一起编译(此处未列出) 当我试图编译我的随机数生成器模块以查看它是否工作时,我得到以下消息: 在第61行:调用随机种子(put=seed) 错误:“random_seed”的“put”参数的大小太小 这是什么意思?我怎样才能修好它Random 什么';我的Fortran 95随机数发生器有什么问题吗?,random,fortran,gfortran,Random,Fortran,Gfortran,这是一个randon数字生成器模块,我使用它与主程序一起编译(此处未列出) 当我试图编译我的随机数生成器模块以查看它是否工作时,我得到以下消息: 在第61行:调用随机种子(put=seed) 错误:“random_seed”的“put”参数的大小太小 这是什么意思?我怎样才能修好它 module random_angle contains 0 integer Function random_integer (N) ! return a random integer b
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
当编译器说
错误:“random_seed”的“put”参数的大小太小
这意味着变量种子的大小太小
在本例中,您有大小为4的seed
(我猜编译器一定期望(至少)12)
数组的大小必须是特定的大小,这取决于编译器。您可以通过使用另一个参数调用random\u seed
来确定所需的大小
integer seed_size
integer, allocatable :: seed(:)
call random_seed(size=seed_size)
allocate(seed(seed_size))
seed = ...
call random_seed(put=seed)
正如Vladimir F在评论中指出的,gfortran记录了这种方法本身
如果您不关心便携性,您可以使用大小为12的数组来选择值
作为更高级的阅读,我要说另一件事。我上面给出的示例与您的代码不太相似。也就是说,种子设置子例程的输入保证至少为大小4,并且它可能包含也可能不包含要用作种子的值
正如我上面提到的,您可以将其更改为12,但这是不可移植的。如果你想随身携带,事情会变得更尴尬
integer, dimension(4), intent(inout):: seed
具有一个大小为4的显式形状数组作为伪参数。主程序中的实际参数是至少该大小的数组。然而,这个大小是一个规范表达式,唉,调用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
子程序设置种子(种子)
整数,可分配,意图(inout)::种子(:)
整数种子大小
! 确定种子的正确大小
调用随机种子(大小=种子大小)
! 如果我们的种子没有结实,或者太小,就把它杀死。
如果(分配(种子))那么
如果(大小(种子)在gfortran的手册中还有一个很好的例子说明如何使用random_seed