![]() |
Millepede-II
V04-00-00
|
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