/[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.5 - (show annotations) (download)
Tue Sep 7 15:16:58 2004 UTC (19 years, 9 months ago) by edhill
Branch: MAIN
CVS Tags: checkpoint57b_post, checkpoint56b_post, checkpoint57d_post, checkpoint55, checkpoint57, checkpoint56, checkpoint54f_post, checkpoint55i_post, checkpoint55c_post, checkpoint57a_post, checkpoint55g_post, checkpoint57c_post, checkpoint55d_post, checkpoint55d_pre, checkpoint57c_pre, checkpoint55j_post, checkpoint55h_post, checkpoint57e_post, checkpoint55b_post, checkpoint55f_post, eckpoint57e_pre, checkpoint56a_post, checkpoint56c_post, checkpoint57a_pre, checkpoint55a_post, checkpoint55e_post
Changes since 1.4: +55 -13 lines
 o add Antti Westerlund's port_rand_norm() which is a straight-forward
   Box-Muller method for generating normal deviates

1 C $Header: /u/gcmpack/MITgcm/model/src/port_rand.F,v 1.4 2004/07/19 15:13:07 molod Exp $
2 C $Name: $
3
4 C Portable random number generator
5
6 #undef _USE_INTEGERS
7
8 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
9 CBOP
10 C !ROUTINE: port_rand
11 C !INTERFACE:
12 real*8 function port_rand(seed)
13
14 C !DESCRIPTION:
15 C Portable random number generator
16
17 C !USES:
18 implicit none
19 CEOP
20
21 C !LOCAL VARIABLES:
22 integer nff
23 parameter(nff=55)
24 #ifdef _USE_INTEGERS
25 integer mbig,mseed,mZ,seed
26 #else
27 real*8 mbig,mseed,mz,seed
28 #endif
29 real*8 fac
30 #ifdef _USE_INTEGERS
31 parameter (mbig=1000000000,mz=0,fac=1./mbig)
32 data mseed/161803398/
33 #else
34 parameter (mbig=4000000.,mz=0.,fac=1./mbig)
35 data mseed/1618033./
36 #endif
37 integer i,ii,inext,inextp,k,idum
38 parameter(idum=-2)
39 #ifdef _USE_INTEGERS
40 integer mj,mk,ma(nff)
41 #else
42 real*8 mj,mk,ma(nff)
43 #endif
44 logical firstCall
45 save firstCall,inext,inextp,ma
46 data firstCall /.true./
47
48 mseed = seed
49 if(firstCall)then
50 firstCall=.false.
51 mj=mseed-iabs(idum)
52 mj=mod(mj,mbig)
53 ma(nff)=mj
54 mk=1
55 do i=1,nff-1
56 ii=mod(21*i,nff)
57 ma(ii)=mk
58 mk=mj-mk
59 if(mk.lt.mz)mk=mk+mbig
60 mj=ma(ii)
61 enddo
62 do k=1,4
63 do i=1,nff
64 ma(i)=ma(i)-ma(1+mod(i+30,nff))
65 if(ma(i).lt.MZ)ma(i)=ma(i)+mbig
66 enddo
67 enddo
68 inext=0
69 inextp=31
70 endif
71 inext=mod(inext,nff)+1
72 inextp=mod(inextp,nff)+1
73 mj=ma(inext)-ma(inextp)
74 if(mj.lt.MZ)mj=mj+mbig
75 ma(inext)=mj
76 port_rand=mj*fac
77 return
78
79 end
80
81 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
82
83 subroutine port_ranarr(n,arr)
84 implicit none
85 integer n,i
86 real arr(n)
87 real*8 port_rand,seed
88 seed=1618033.0d0
89 do i=1,n
90 arr(i)=port_rand(seed)
91 enddo
92
93 return
94 end
95
96 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
97 CBOP
98 C !ROUTINE: port_rand_norm
99 C !INTERFACE:
100 real*8 function port_rand_norm()
101
102 C !DESCRIPTION:
103 C This function generates a normally distributed random number with
104 C the so called polar algorithm. The algorithm actually generates 2
105 C numbers, but only 1 is returned for maximum compatibility with old
106 C code. The most obvious way to improve this function would be to
107 C make sure that the second number is not wasted.
108
109 C Changed: 2004.09.06 antti.westerlund@fimr.fi
110
111 C !USES:
112 implicit none
113 CEOP
114
115 C !LOCAL VARIABLES:
116 real*8 port_rand,seed
117 real*8 x1, x2, xs, t
118 integer i
119
120 seed=1618033.0d0
121 C first generate 2 equally distributed random numbers (-1,1)
122 DO WHILE (1 .eq. 1)
123 x1=2.0*port_rand(seed)-1.0
124 x2=2.0*port_rand(seed)-1.0
125 xs=x1**2+x2**2
126 if(xs .lt. 1.0 .and. xs .ne. 0.0) then
127 goto 100
128 end if
129 END DO
130 100 continue
131
132 t = sqrt(-2.0*log(xs)/xs)
133 port_rand_norm = t*x1
134 C
135 C also t*x2 would be a gaussian random number and could be returned
136
137 return
138 end

  ViewVC Help
Powered by ViewVC 1.1.22