Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ModRandom.F90
Go to the documentation of this file.
1 ! *********************************************************************
2 ! * Rocstar Simulation Suite *
3 ! * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4 ! * *
5 ! * Illinois Rocstar LLC *
6 ! * Champaign, IL *
7 ! * www.illinoisrocstar.com *
8 ! * sales@illinoisrocstar.com *
9 ! * *
10 ! * License: See LICENSE file in top level of distribution package or *
11 ! * http://opensource.org/licenses/NCSA *
12 ! *********************************************************************
13 ! *********************************************************************
14 ! * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15 ! * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16 ! * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17 ! * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18 ! * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19 ! * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20 ! * Arising FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21 ! * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22 ! *********************************************************************
23 !******************************************************************************
24 !
25 ! Purpose: Portable random number generator
26 !
27 ! Description: This module provides the following routines:
28 !
29 ! RandomSeed: seeds the random number generator
30 !
31 ! RandUniform: generates an array of uniformly distributed random numbers
32 ! on the interval [0,1)
33 !
34 ! RandNormal: generates an array of normally distributed random numbers
35 !
36 ! RandLogNormal: generates an array of log-normally distributed numbers
37 !
38 ! RandImposedPDF: generates an array of number distributed according to a dscrete PDF
39 !
40 ! Rand1Uniform: function form of RandUniform -- returns a single number
41 !
42 ! Rand1Normal: function form of RandNormal
43 !
44 ! Rand1LogNormal: function form of RandLogNormal
45 !
46 ! Rand1ImposedPDF: function form of RandImposedPDF
47 !
48 ! Notes:
49 !
50 ! This is an implementation of the Mersenne Twister random number
51 ! generator, MT19937, based on the Mersenne Prime 2^19937 - 1.
52 !
53 ! It is (somewhat painfully) coded such that it gives the same results
54 ! whether integers are 32- or 64-bit, and these results are identical
55 ! to the standard, C version of the Mersenne Twister.
56 !
57 ! It outputs random numbers with 53-bit precision.
58 !
59 !******************************************************************************
60 !
61 ! $Id: ModRandom.F90,v 1.6 2008/12/06 08:44:19 mtcampbe Exp $
62 !
63 ! Copyright: (c) 2003 by the University of Illinois
64 !
65 !******************************************************************************
66 
67 MODULE modrandom
68 
69  USE moddatatypes
70  IMPLICIT NONE
71 
72 ! Period parameter
73  INTEGER, PARAMETER :: RAND_BUFFER_SIZE = 624
74  INTEGER, PARAMETER :: RAND_MTI_INDEX = RAND_BUFFER_SIZE
75  INTEGER, PARAMETER :: RAND_SEED_INDEX = RAND_BUFFER_SIZE + 1
76  INTEGER, PARAMETER :: RAND_CALLS_INDEX = RAND_BUFFER_SIZE + 2
77  INTEGER, PARAMETER :: RAND_EXTRA_INTS = 3
78  INTEGER, PARAMETER :: RAND_TOTAL_SIZE = RAND_BUFFER_SIZE + RAND_EXTRA_INTS
79 
81  INTEGER :: mt(0:RAND_TOTAL_SIZE-1)
82  END TYPE t_rand_data
83 
84 CONTAINS
85 
86 ! ******************************************************************************
87 ! Initialization subroutine
88 ! ******************************************************************************
89 ! sets initial seeds to rdata%mt using the generator Line 25 of Table 1 in
90 ! [KNUTH 1981, The Art of Computer Programming Vol. 2 (2nd Ed.), pp102]
91 
92  SUBROUTINE randomseed(seed,rdata)
93 
94 ! ... parameters
95  INTEGER, INTENT(IN) :: seed
96  TYPE(t_rand_data), INTENT(OUT) :: rdata
97 
98 ! ... loop variables
99  INTEGER :: i
100 
101 ! ... local variables
102  INTEGER, PARAMETER :: one = 1
103  INTEGER, PARAMETER :: mult = 1812433253
104 
105  INTEGER :: mask32
106 
107  mask32 = ishft(one,32) - one
108 
109  rdata%mt(0) = iand(seed,mask32)
110 
111  DO i=1,rand_buffer_size-1
112 ! --- See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier
113 ! --- In the previous versions, MSBs of the seed affect
114 ! --- only MSBs of the array mt[].
115 ! --- 2002/01/09 modified by Makoto Matsumoto
116 
117  rdata%mt(i) = mult * (ieor(rdata%mt(i-1), &
118  ishft(rdata%mt(i-1),-30))) + i
119 
120 ! --- for >32 bit machines
121  rdata%mt(i) = iand(rdata%mt(i),mask32)
122 
123  END DO ! i
124 
125  rdata%mt(rand_mti_index) = rand_buffer_size
126  rdata%mt(rand_seed_index) = iand(seed,mask32)
127  rdata%mt(rand_calls_index) = 0
128 
129  END SUBROUTINE randomseed
130 
131 ! ******************************************************************************
132 ! Uniform random number generator on [0,1) with 53-bit precision
133 ! ******************************************************************************
134 
135  SUBROUTINE randuniform(a,rdata)
136 
137 ! ... parameters
138  REAL(RFREAL), INTENT(OUT) :: a(:)
139  TYPE(t_rand_data), INTENT(INOUT) :: rdata
140 
141 ! ... loop variables
142  INTEGER :: i,j,kk
143 
144 ! ... local variables
145 
146 ! - Period parameters
147  INTEGER, PARAMETER :: one = 1
148  INTEGER, PARAMETER :: m = 397
149  INTEGER, PARAMETER :: lmask = 2147483647 ! least significant r bits
150  INTEGER, PARAMETER :: pre_mata = -1727483681
151  INTEGER, PARAMETER :: pre_tmaskb = -1658038656
152  INTEGER, PARAMETER :: pre_tmaskc = -272236544
153 
154 ! - Normalization parameters
155  REAL(RFREAL), PARAMETER :: two32 = 4294967296.0_rfreal
156  REAL(RFREAL), PARAMETER :: nfac1 = 67108864.0_rfreal
157 
158 ! - These should be parameters, but cannot be initialized on all platforms
159  INTEGER :: mask32, mata, umask, tmaskb, tmaskc, mag01(0:1)
160  REAL(RFREAL) :: nfac2
161 
162  INTEGER :: y,mti,iamin,iamax
163  REAL(RFREAL) :: yr(2)
164 
165 ! - Set values of things that should, ideally, be parameters
166 
167  umask = ishft(one,31) ! most significant w-r bits
168  mask32 = ishft(one,32) - one ! mask to force 32-bit behavior
169  mata = iand(pre_mata, mask32) ! constant vector
170  tmaskb = iand(pre_tmaskb,mask32) ! tempering parameter
171  tmaskc = iand(pre_tmaskc,mask32) ! tempering parameter
172  mag01(0) = 0
173  mag01(1) = mata
174  nfac2 = 1.0_rfreal/9007199254740992.0_rfreal
175 
176 ! - Begin
177 
178  mti = rdata%mt(rand_mti_index)
179 
180  iamin = lbound(a,1)
181  iamax = ubound(a,1)
182 
183  DO i = iamin,iamax
184 
185  DO j = 1,2
186 
187  IF (mti >= rand_buffer_size) THEN ! make RAND_BUFFER_SIZE integers
188 
189  DO kk=0,rand_buffer_size-m-1
190  y = ior(iand(rdata%mt(kk),umask),iand(rdata%mt(kk+1),lmask))
191  rdata%mt(kk) = ieor(ieor(rdata%mt(kk+m),ishft(y,-1)), &
192  mag01(iand(y,one)))
193  END DO ! kk
194 
195  DO kk=rand_buffer_size-m,rand_buffer_size-2
196  y = ior(iand(rdata%mt(kk),umask),iand(rdata%mt(kk+1),lmask))
197  rdata%mt(kk) = ieor(ieor(rdata%mt(kk+(m-rand_buffer_size)), &
198  ishft(y,-1)), mag01(iand(y,one)))
199  END DO ! kk
200 
201  y = ior(iand(rdata%mt(rand_buffer_size-1),umask), &
202  iand(rdata%mt(0),lmask))
203  rdata%mt(rand_buffer_size-1) = &
204  ieor(ieor(rdata%mt(m-1), ishft(y,-1)), mag01(iand(y,one)))
205 
206  mti = 0
207 
208  END IF ! mti
209 
210  y = rdata%mt(mti)
211 
212 ! ----- Tempering
213 
214  y = ieor(y, ishft(y,-11))
215  y = ieor(y,iand(ishft(y, 7),tmaskb))
216  y = ieor(y,iand(ishft(y, 15),tmaskc))
217  y = ieor(y, ishft(y,-18))
218 
219  y = ishft(y,-4-j)
220 
221  IF (y < 0) THEN
222  yr(j) = REAL(y,KIND=RFREAL) + two32
223  ELSE
224  yr(j) = REAL(y,kind=rfreal)
225  END IF ! y
226 
227  mti = mti + 1
228 
229  END DO ! j
230 
231 ! --- Form random number from two 32-bit integers
232 
233  a(i) = (yr(1)*nfac1 + yr(2)) * nfac2
234 
235  END DO ! i
236 
237  rdata%mt(rand_mti_index) = mti
238  rdata%mt(rand_calls_index) = rdata%mt(rand_calls_index) + iamax - iamin + 1
239 
240  END SUBROUTINE randuniform
241 
242 ! ******************************************************************************
243 ! Normal distribution
244 ! ******************************************************************************
245 
246  SUBROUTINE randnormal(a,med,dev,rdata)
247 ! med = median
248 ! dev = standard deviation
249 
250  REAL(RFREAL), INTENT(OUT) :: a(:)
251  REAL(RFREAL), INTENT(IN) :: med,dev
252  TYPE(t_rand_data), INTENT(INOUT) :: rdata
253 
254  INTEGER :: i,iamin,iamax
255  REAL(RFREAL) :: r,th
256  REAL(RFREAL) :: twopi
257 
258  iamin = lbound(a,1)
259  iamax = ubound(a,1)
260  twopi = 8.0_rfreal*atan(1.0_rfreal)
261  CALL randuniform(a,rdata)
262 
263  DO i=iamin,iamax-1,2
264  th = twopi*a(i)
265  r = dev*sqrt(-2.0_rfreal*log(1.0_rfreal-a(i+1)))
266  a(i) = r*cos(th) + med
267  a(i+1) = r*sin(th) + med
268  END DO ! i
269 
270  IF (modulo(iamax-iamin+1,2)==1) THEN
271  th = twopi*a(iamax)
272  r = rand1uniform(rdata)
273  r = dev*sqrt(-2.0_rfreal*log(1.0_rfreal-r))
274  a(iamax) = r*cos(th) + med
275  END IF
276 
277  END SUBROUTINE randnormal
278 
279 ! ******************************************************************************
280 ! Log normal distribution
281 ! ******************************************************************************
282 
283  SUBROUTINE randlognormal(a,logmed,gdev,rdata)
284 ! logmed = log of median
285 ! gdev = standard deviation of corresponding Gaussian
286 
287  REAL(RFREAL), INTENT(OUT) :: a(:)
288  REAL(RFREAL), INTENT(IN) :: logmed,gdev
289  TYPE(t_rand_data), INTENT(INOUT) :: rdata
290 
291  CALL randnormal(a,logmed,gdev,rdata)
292  a = exp(a)
293 
294  END SUBROUTINE randlognormal
295 
296 ! ******************************************************************************
297 ! Discrete PDF distribution from file
298 ! ******************************************************************************
299 
300  SUBROUTINE randimposedpdf(a,pdfvalues,locMax,valmax,rdata)
301 
302  REAL(RFREAL), INTENT(IN) :: pdfvalues(:,:)
303  REAL(RFREAL), INTENT(OUT) :: a(:)
304  TYPE(t_rand_data), INTENT(INOUT) :: rdata
305  INTEGER, INTENT(IN) :: locmax
306  REAL(RFREAL), INTENT(IN) :: valmax
307 
308  INTEGER :: i,iamin,iamax,k1,k2
309 
310  iamin = lbound(a,1)
311  iamax = ubound(a,1)
312  CALL randuniform(a,rdata)
313 
314  DO i=iamin,iamax
315  call findpdf(a(i),pdfvalues(:,2),k1,k2)
316  a(i) = (a(i) - pdfvalues(k1,2))*(pdfvalues(k2,3)-pdfvalues(k1,3))&
317  /(pdfvalues(k2,2) - pdfvalues(k1,2)) + pdfvalues(k1,3)
318  END DO ! i
319 
320  RETURN
321 
322  CONTAINS
323  SUBROUTINE findpdf(datum,vec,k1,k2)
324  REAL(RFREAL), INTENT(IN) :: datum
325  REAL(RFREAL), INTENT(IN) :: vec(:)
326  INTEGER, INTENT(OUT) :: k1,k2
327  integer :: isgn
328 
329  isgn = sign(1.1_rfreal,datum-valmax)
330  k1 = locmax
331  k2 = k1+isgn
332  do while (int(sign(1.1_rfreal,datum-vec(k2)))*isgn > 0)
333  k1 = k2
334  k2 = k2+isgn
335  enddo
336  END SUBROUTINE findpdf
337 
338 
339  END SUBROUTINE randimposedpdf
340 
341 ! ******************************************************************************
342 ! Function form of RandUniform
343 ! ******************************************************************************
344 
345  REAL(RFREAL) FUNCTION rand1uniform(rdata)
346 
347 ! ... parameters
348  TYPE(t_rand_data), INTENT(INOUT) :: rdata
349 
350 ! ... local variables
351  REAL(RFREAL) :: a(1)
352 
353  CALL randuniform(a,rdata)
354  rand1uniform = a(1)
355 
356  END FUNCTION rand1uniform
357 
358 ! ******************************************************************************
359 ! Function form of RandNormal
360 ! ******************************************************************************
361 
362  REAL(RFREAL) FUNCTION rand1normal(med,dev,rdata)
363 
364 ! ... parameters
365  REAL(RFREAL), INTENT(IN) :: med,dev
366  TYPE(t_rand_data), INTENT(INOUT) :: rdata
367 
368 ! ... local variables
369  REAL(RFREAL) :: a(1)
370 
371  CALL randnormal(a,med,dev,rdata)
372  rand1normal = a(1)
373 
374  END FUNCTION rand1normal
375 
376 ! ******************************************************************************
377 ! Function form of RandLogNormal
378 ! ******************************************************************************
379 
380  REAL(RFREAL) FUNCTION rand1lognormal(logmed,gdev,rdata)
381 
382 ! ... parameters
383  REAL(RFREAL), INTENT(IN) :: logmed,gdev
384  TYPE(t_rand_data), INTENT(INOUT) :: rdata
385 
386 ! ... local variables
387  REAL(RFREAL) :: a(1)
388 
389  CALL randlognormal(a,logmed,gdev,rdata)
390  rand1lognormal = a(1)
391 
392  END FUNCTION rand1lognormal
393 
394 ! ******************************************************************************
395 ! Function form of RandUniform
396 ! ******************************************************************************
397 
398  REAL(RFREAL) FUNCTION rand1imposedpdf(rdata,pdfvalues,locMax,valmax)
399 
400 ! ... parameters
401  TYPE(t_rand_data), INTENT(INOUT) :: rdata
402  REAL(RFREAL), INTENT(IN) :: pdfvalues(:,:)
403  INTEGER, INTENT(IN) :: locmax
404  REAL(RFREAL), INTENT(IN) :: valmax
405 
406 ! ... local variables
407  REAL(RFREAL) :: a(1)
408 
409  CALL randimposedpdf(a,pdfvalues,locmax,valmax,rdata)
410  rand1imposedpdf = a(1)
411 
412  END FUNCTION rand1imposedpdf
413 END MODULE modrandom
414 
415 !******************************************************************************
416 !
417 ! RCS Revision history:
418 !
419 ! $Log: ModRandom.F90,v $
420 ! Revision 1.6 2008/12/06 08:44:19 mtcampbe
421 ! Updated license.
422 !
423 ! Revision 1.5 2008/11/19 22:17:30 mtcampbe
424 ! Added Illinois Open Source License/Copyright
425 !
426 ! Revision 1.4 2005/04/25 18:39:09 luca1
427 ! Imposed PDF from file option for random particle ejection
428 !
429 ! Revision 1.3 2003/12/08 16:39:47 jferry
430 ! Removed non-standard KIND intrinsic
431 !
432 ! Revision 1.2 2003/11/21 22:35:51 fnajjar
433 ! Update Random Number Generator
434 !
435 ! Revision 1.1 2003/02/17 19:31:11 jferry
436 ! Implemented portable random number generator ModRandom
437 !
438 !******************************************************************************
439 
440 
441 
442 
443 
444 
REAL(RFREAL) function rand1imposedpdf(rdata, pdfvalues, locMax, valmax)
Definition: ModRandom.F90:398
unsigned char r() const
Definition: Color.h:68
subroutine randnormal(a, med, dev, rdata)
Definition: ModRandom.F90:246
FT m(int i, int j) const
static SURF_BEGIN_NAMESPACE double sign(double x)
void int int REAL REAL * y
Definition: read.cpp:74
subroutine randomseed(seed, rdata)
Definition: ModRandom.F90:92
REAL(RFREAL) function rand1uniform(rdata)
Definition: ModRandom.F90:345
double sqrt(double d)
Definition: double.h:73
subroutine randlognormal(a, logmed, gdev, rdata)
Definition: ModRandom.F90:283
subroutine randimposedpdf(a, pdfvalues, locMax, valmax, rdata)
Definition: ModRandom.F90:300
NT & sin
blockLoc i
Definition: read.cpp:79
subroutine findpdf(datum, vec, k1, k2)
Definition: ModRandom.F90:323
subroutine randuniform(a, rdata)
Definition: ModRandom.F90:135
REAL(RFREAL) function rand1normal(med, dev, rdata)
Definition: ModRandom.F90:362
j indices j
Definition: Indexing.h:6
REAL(RFREAL) function rand1lognormal(logmed, gdev, rdata)
Definition: ModRandom.F90:380
NT & cos
RT a() const
Definition: Line_2.h:140