/[MITgcm]/MITgcm/model/src/port_rand.F
ViewVC logotype

Contents of /MITgcm/model/src/port_rand.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.8 - (show annotations) (download)
Fri Aug 9 15:00:46 2013 UTC (10 years, 9 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint65z, checkpoint65x, checkpoint65y, checkpoint65r, checkpoint65s, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint65j, checkpoint65k, checkpoint65h, checkpoint65i, checkpoint65n, checkpoint65l, checkpoint65m, checkpoint65b, checkpoint65c, checkpoint65a, checkpoint65f, checkpoint65g, checkpoint65d, checkpoint65e, checkpoint65, checkpoint66g, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, checkpoint66n, checkpoint66m, checkpoint66l, checkpoint66k, checkpoint66j, checkpoint66i, checkpoint66h, checkpoint65o, checkpoint64y, checkpoint64x, checkpoint64z, checkpoint64q, checkpoint64p, checkpoint64s, checkpoint64r, checkpoint64u, checkpoint64t, checkpoint64w, checkpoint64v, checkpoint64m, checkpoint64o, checkpoint64n, HEAD
Changes since 1.7: +4 -7 lines
cleaning (remove GOTO since there was already "DO WHILE")

1 C $Header: /u/gcmpack/MITgcm/model/src/port_rand.F,v 1.7 2009/12/08 21:50:35 jmc Exp $
2 C $Name: $
3
4 #undef _USE_INTEGERS
5
6 C-- File port_rand.F: Portable random number generator functions
7 C-- Contents
8 C-- o PORT_RAND
9 C-- o PORT_RANARR
10 C-- o PORT_RAND_NORM
11
12 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
13 CBOP
14 C !ROUTINE: PORT_RAND
15 C !INTERFACE:
16 real*8 FUNCTION PORT_RAND(seed)
17
18 C !DESCRIPTION:
19 C Portable random number generator
20 C seed >=0 :: initialise using this seed ; and return 0
21 C seed < 0 :: if first call then initialise using the default seed (=mseed)
22 C and always return a random number
23
24 C !USES:
25 IMPLICIT NONE
26
27 C !INPUT PARAMETERS:
28 #ifdef _USE_INTEGERS
29 INTEGER seed
30 #else
31 real*8 seed
32 #endif
33 CEOP
34
35 C !LOCAL VARIABLES:
36 INTEGER nff,idum
37 PARAMETER(nff=55)
38 PARAMETER(idum=-2)
39 real*8 fac
40 #ifdef _USE_INTEGERS
41 INTEGER mbig,mseed,mZ
42 PARAMETER (mbig=1000000000,mz=0,fac=1.d0/mbig)
43 INTEGER mj,mk,ma(nff)
44 DATA mseed/161803398/
45 #else
46 real*8 mbig,mseed,mz
47 PARAMETER (mbig=4000000.,mz=0.,fac=1.d0/mbig)
48 real*8 mj,mk,ma(nff)
49 DATA mseed/1618033./
50 #endif
51 LOGICAL firstCall
52 INTEGER i,ii,inext,inextp,k
53 DATA firstCall /.true./
54 SAVE firstCall,inext,inextp,ma
55
56 C- Initialise the random number generator
57 IF (firstCall .OR. seed.GE.mz) THEN
58 IF (seed.GE.mz) mseed = seed
59 firstCall=.false.
60 mj=mseed-iabs(idum)
61 mj=mod(mj,mbig)
62 ma(nff)=mj
63 mk=1
64 DO i=1,nff-1
65 ii=mod(21*i,nff)
66 ma(ii)=mk
67 mk=mj-mk
68 IF (mk.LT.mz) mk=mk+mbig
69 mj=ma(ii)
70 ENDDO
71 DO k=1,4
72 DO i=1,nff
73 ma(i)=ma(i)-ma(1+mod(i+30,nff))
74 IF (ma(i).LT.mz) ma(i)=ma(i)+mbig
75 ENDDO
76 ENDDO
77 inext=0
78 inextp=31
79 ENDIF
80
81 C- Compute a random number (only if seed < 0)
82 IF (seed.GE.mz) THEN
83 port_rand=0.d0
84 ELSE
85 inext=mod(inext,nff)+1
86 inextp=mod(inextp,nff)+1
87 mj=ma(inext)-ma(inextp)
88 IF (mj.LT.mz) mj=mj+mbig
89 ma(inext)=mj
90 port_rand=mj*fac
91 ENDIF
92
93 RETURN
94 END
95
96 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
97
98 CBOP
99 C !ROUTINE: PORT_RANARR
100 C !INTERFACE:
101 SUBROUTINE PORT_RANARR(n,arr)
102
103 C !DESCRIPTION:
104 C Portable random number array generator
105
106 C !USES:
107 IMPLICIT NONE
108
109 C !INPUT PARAMETERS:
110 INTEGER n
111 real*8 arr(n)
112 CEOP
113
114 C !LOCAL VARIABLES:
115 INTEGER i
116 real*8 port_rand
117 #ifdef _USE_INTEGERS
118 INTEGER seed
119 seed=-1
120 #else
121 real*8 seed
122 seed=-1.d0
123 #endif
124 c seed=1618033.0d0
125 DO i=1,n
126 arr(i)=port_rand(seed)
127 ENDDO
128
129 RETURN
130 END
131
132 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
133 CBOP
134 C !ROUTINE: PORT_RAND_NORM
135 C !INTERFACE:
136 real*8 FUNCTION PORT_RAND_NORM()
137
138 C !DESCRIPTION:
139 C This function generates a normally distributed random number with
140 C the so called polar algorithm. The algorithm actually generates 2
141 C numbers, but only 1 is returned for maximum compatibility with old
142 C code. The most obvious way to improve this function would be to
143 C make sure that the second number is not wasted.
144
145 C Changed: 2004.09.06 antti.westerlund@fimr.fi
146
147 C !USES:
148 IMPLICIT NONE
149 CEOP
150
151 C !LOCAL VARIABLES:
152 real*8 port_rand
153 real*8 x1, x2, xs, t
154
155 #ifdef _USE_INTEGERS
156 INTEGER seed
157 seed=-1
158 #else
159 real*8 seed
160 seed=-1.d0
161 #endif
162 c seed=1618033.0d0
163
164 C first generate 2 equally distributed random numbers (-1,1)
165 xs = 0.0
166 DO WHILE ( xs.GE.1.0 .OR. xs.EQ.0.0 )
167 x1=2.0*port_rand(seed)-1.0
168 x2=2.0*port_rand(seed)-1.0
169 xs=x1**2+x2**2
170 ENDDO
171
172 t = SQRT(-2.0*LOG(xs)/xs)
173 port_rand_norm = t*x1
174
175 C also t*x2 would be a gaussian random number and could be returned
176
177 RETURN
178 END

  ViewVC Help
Powered by ViewVC 1.1.22