Millepede-II  V04-00-00
 All Classes Files Functions Variables Enumerator
randoms.f90
Go to the documentation of this file.
00001 
00002 ! Code converted using TO_F90 by Alan Miller
00003 ! Date: 2012-03-16  Time: 11:09:33
00004 
00012 
00020 
00021 SUBROUTINE gbrshi(n,a)
00022     IMPLICIT NONE
00023     INTEGER :: i
00024     INTEGER :: ian
00025     INTEGER :: iboost
00026     INTEGER :: ic
00027     INTEGER :: idum
00028     INTEGER :: irotor
00029     INTEGER :: iseed
00030     INTEGER :: it
00031     INTEGER :: iwarm
00032     INTEGER :: j
00033     INTEGER :: jseed
00034     INTEGER :: jwarm
00035     INTEGER :: k
00036     INTEGER :: m
00037     INTEGER :: mbuff
00038 
00039     INTEGER, INTENT(IN)                      :: n
00040     REAL, INTENT(OUT)                        :: a(*)
00041     INTEGER, PARAMETER :: nb=511
00042     INTEGER, PARAMETER :: ia=16807
00043     INTEGER, PARAMETER :: im=2147483647
00044     INTEGER, PARAMETER :: iq=127773
00045     INTEGER, PARAMETER :: ir=2836
00046     REAL, PARAMETER :: aeps=1.0E-10
00047     REAL, PARAMETER :: scalin=4.6566125E-10
00048     COMMON/ranbuf/mbuff(0:nb),ian,ic,iboost
00049 
00050     INTEGER :: istart
00051 
00052     irotor(m,n)=IEOR(ior(ishft(m,17),ishft(m,-15)),n)
00053     DATA istart/0/,iwarm/10/,iseed/4711/
00054     IF(istart /= 0) GO TO 20
00055     WRITE(*,*) ' Automatic GBRSHI initialization using:'
00056     !     initialize buffer
00057 10  idum=iseed+9876543          ! prevent damage, if iseed=0
00058     WRITE(*,*) '           ISEED=',iseed,'   IWARM=',iwarm
00059     DO j=0,nb+1                 ! fill buffer
00060         k=idum/iq                  ! minimal standard generator
00061         idum=ia*(idum-k*iq)-ir*k   !    with Schrages method
00062         IF(idum < 0) idum=idum+im !
00063         mbuff(j)=ishft(idum,1)     ! fill in leading bit
00064     END DO
00065     ian=IAND(ian,nb)            ! mask angle
00066     ic=1                        ! set pointer
00067     iboost=0
00068     DO j=1,iwarm*nb             ! warm up a few times
00069         it=mbuff(ian)              ! hit ball angle
00070         mbuff(ian)=irotor(it,ic)   ! new spin
00071         ic=it                      ! replace red spin
00072         ian=IAND(it+iboost,nb)     ! boost and mask angle
00073         iboost=iboost+1            ! increment boost
00074     END DO
00075     IF(istart < 0) RETURN      ! return for RBNVIN
00076     istart=1                    ! set done-flag
00077     !     generate array of r.n.
00078     20   DO i=1,n
00079         it=mbuff(ian)              ! hit ball angle
00080         mbuff(ian)=irotor(it,ic)   ! new spin
00081         ic=it                      ! replace red spin
00082         ian=IAND(it+iboost,nb)     ! boost and mask angle
00083         a(i)=FLOAT(ishft(it,-1))*scalin+aeps ! avoid zero output
00084         iboost=iboost+1            ! increment boost
00085     END DO
00086     iboost=IAND(iboost,nb)
00087     RETURN
00088 
00089     ENTRY gbrvin(jseed,jwarm)   ! initialize, but only once
00090     IF(istart == 0) THEN
00091         WRITE(*,*) ' Gbrshi initialization by GBRVIN-call using:'
00092         iseed=jseed              ! copy seed and
00093         iwarm=jwarm              ! warm-up parameter
00094         istart=-1                ! start flag
00095         GO TO 10
00096     END IF
00097 END SUBROUTINE gbrshi
00098 
00100 SUBROUTINE gbrtim
00101     IMPLICIT NONE
00102     INTEGER :: jseed
00103     REAL :: time
00104 
00105     LOGICAL :: done
00106     DATA    done/.FALSE./
00107     IF(done) RETURN
00108     jseed=time()
00109     WRITE(*,*) ' Gbrshi initialialization using Time()'
00110     CALL gbrvin(jseed,10)
00111     done=.TRUE.
00112 END SUBROUTINE gbrtim
00113 
00117 
00118 REAL FUNCTION uran()     ! U(0,1)
00119     IMPLICIT NONE
00120     INTEGER :: indx
00121     INTEGER :: ndim
00122 
00123     PARAMETER (ndim=100)
00124     REAL :: buffer(ndim)
00125     DATA indx/ndim/
00126     SAVE indx,buffer
00127     indx=MOD(indx,ndim)+1
00128     IF(indx == 1) CALL gbrshi(ndim,buffer)
00129     uran=buffer(indx)
00130 END FUNCTION uran
00131 
00135 
00136 REAL FUNCTION gran()     ! N(0,1)
00137     IMPLICIT NONE
00138     REAL :: al
00139     REAL :: cs
00140     INTEGER :: indx
00141     INTEGER :: kn
00142     INTEGER :: ndim
00143     REAL :: radsq
00144     REAL :: rn1
00145     REAL :: rn2
00146     REAL :: sn
00147 
00148     PARAMETER (ndim=100)
00149     REAL:: buffer(ndim)
00150     DATA indx/ndim/,kn/1/
00151     SAVE indx,buffer,kn,cs,al
00152     !     ...
00153     IF(kn <= 1) THEN
00154         !        two U(-1,+1) random numbers
00155 10      indx=MOD(indx,ndim)+2
00156         IF(indx == 2) CALL gbrshi(ndim,buffer)
00157         rn1=buffer(indx-1)-1.0+buffer(indx-1)
00158         rn2=buffer(indx  )-1.0+buffer(indx)
00159         radsq=rn1*rn1+rn2*rn2
00160         IF(radsq > 1.0) GO TO 10 ! test point inside circle?
00161         !        sine and cosine for random phi
00162         sn=rn1/SQRT(radsq)
00163         cs=rn2/SQRT(radsq)
00164         !        transform to gaussians
00165         al=SQRT(-2.0*ALOG(radsq))
00166         kn =2
00167         gran=sn*al
00168     ELSE
00169         kn =1
00170         gran=cs*al
00171     END IF
00172 END FUNCTION gran