在FORTRAN 90中使用ran1 FORTRAN 77子例程

时间:2016-02-29 18:43:47

标签: random fortran fortran90 fortran77

我正在尝试在FORTRAN 90代码中使用Numerical Recipes中的ran1。我认为一种常见的方法是分别编译旧的子程序,然后使用目标文件。但在这里,我想知道在我的代码中直接使用它需要做哪些更改。

FUNCTION ran1(idum)
INTEGER idum,IA,IM,IQ,IR,NTAB,NDIV
REAL ran1,AM,EPS,RNMX
PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836,
! NTAB=32,NDIV=1+(IM-1)/NTAB,EPS=1.2e-7,RNMX=1.-EPS)
! “Minimal” random number generator of Park and Miller with Bays-Durham shuffle and
! added safeguards. Returns a uniform random deviate between 0.0 and 1.0 (exclusive of
! the endpoint values). Call with idum a negative integer to initialize; thereafter, do not
! alter idum between successive deviates in a sequence. RNMX should approximate the largest
! floating value that is less than 1.
INTEGER j,k,iv(NTAB),iy
SAVE iv,iy
DATA iv /NTAB*0/, iy /0/
iy = 0
if (idum.le.0.or.iy.eq.0) then !Initialize.
idum=max(-idum,1)
! Be sure to prevent idum = 0.
do 11 j=NTAB+8,1,-1
! Load the shuffle table (after 8 warm-ups).
k=idum/IQ
idum=IA*(idum-k*IQ)-IR*k
if (idum.lt.0) idum=idum+IM
if (j.le.NTAB) iv(j)=idum! Compute idum=mod(IA*idum,IM) without overflows by
enddo 11
iy=iv(1)
endif
k=idum/IQ
idum=IA*(idum-k*IQ)-IR*k
! Compute idum=mod(IA*idum,IM) without overflows by
if (idum.lt.0) idum=idum+IM      ! Schrage’s method.
j=1+iy/NDIV
iy=iv(j)                ! Output previously stored value and refill the shuffle table.

iv(j)=idum
ran1=min(AM*iy,RNMX)    ! Because users don’t expect endpoint values.
return
END 

1 个答案:

答案 0 :(得分:2)

您的代码格式错误。看起来你是从书中手动复制它,但不完全是。即使在书中也存在第二个问题。

首先,在第二行和第三行的参数语句中应该有一个行继续而不是注释

PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836, &
  NTAB=32,NDIV=1+(IM-1)/NTAB,EPS=1.2e-7,RNMX=1.-EPS)

(转换为自由格式,请参阅本书原件)

其次,循环是do循环与数字标签和带end do的do循环的奇怪组合:

do 11 j=NTAB+8,1,-1
...
enddo 11

应该是

do j=NTAB+8,1,-1
...
enddo

do 11 j=NTAB+8,1,-1
...
11 continue

可能存在更多问题。