root / synthbench / euroben-dm / mod2b / ran1.f @ 0:839f52ef7657
History | View | Annotate | Download (3.2 kB)
1 | 0:839f52ef7657 | louridas | Function ran1(idum) Result( ran_out ) |
---|---|---|---|
2 | 0:839f52ef7657 | louridas | Use numerics |
3 | 0:839f52ef7657 | louridas | Implicit None |
4 | 0:839f52ef7657 | louridas | |
5 | 0:839f52ef7657 | louridas | Integer idum |
6 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
7 | 0:839f52ef7657 | louridas | ! --- ran1 returns a uniform deviate in (0,1). |
8 | 0:839f52ef7657 | louridas | |
9 | 0:839f52ef7657 | louridas | ! --- The algorithm is taken from Press & Teukolsky et.al. and |
10 | 0:839f52ef7657 | louridas | ! based on the linear congruential method with choices for |
11 | 0:839f52ef7657 | louridas | ! M, IA, and IC that are given by D. Knuth in "Semi-numerical |
12 | 0:839f52ef7657 | louridas | ! algorithms. |
13 | 0:839f52ef7657 | louridas | |
14 | 0:839f52ef7657 | louridas | ! --- Input-parameters: |
15 | 0:839f52ef7657 | louridas | ! Integer - idum. When idum < 0 the sequence of random values |
16 | 0:839f52ef7657 | louridas | ! When idum >= 0, ran1 returns the next value |
17 | 0:839f52ef7657 | louridas | ! in the sequence. When ran1 is called for |
18 | 0:839f52ef7657 | louridas | ! the first time it is also initialised. |
19 | 0:839f52ef7657 | louridas | |
20 | 0:839f52ef7657 | louridas | ! --- Output-parameters: |
21 | 0:839f52ef7657 | louridas | ! Integer - idum : Next value of seed produced by ran1. |
22 | 0:839f52ef7657 | louridas | ! Real(l_) - ran_out: the random number returned. |
23 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
24 | 0:839f52ef7657 | louridas | Real(l_) :: r(97), ran_out |
25 | 0:839f52ef7657 | louridas | Integer :: iff, x1, x2, x3, j |
26 | 0:839f52ef7657 | louridas | ! |
27 | 0:839f52ef7657 | louridas | ! --- Definitions of the three linear congruences used in generating |
28 | 0:839f52ef7657 | louridas | ! the random number. |
29 | 0:839f52ef7657 | louridas | ! |
30 | 0:839f52ef7657 | louridas | Integer, Parameter :: m1 = 259200, m2 = 134456, m3 = 243000, |
31 | 0:839f52ef7657 | louridas | & a1 = 7141, a2 = 8121, a3 = 4561, |
32 | 0:839f52ef7657 | louridas | & c1 = 54773, c2 = 28411, c3 = 51349 |
33 | 0:839f52ef7657 | louridas | Real(l_), Parameter :: one = 1.0, rm1 = one/m1, rm2 = one/m2 |
34 | 0:839f52ef7657 | louridas | ! |
35 | 0:839f52ef7657 | louridas | Save iff, r, x1, x2, x3 |
36 | 0:839f52ef7657 | louridas | Data iff/0/ |
37 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
38 | 0:839f52ef7657 | louridas | ! --- (Re)initialise if required. |
39 | 0:839f52ef7657 | louridas | |
40 | 0:839f52ef7657 | louridas | If ( idum < 0 .OR. iff == 0 ) Then |
41 | 0:839f52ef7657 | louridas | iff = 1 |
42 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
43 | 0:839f52ef7657 | louridas | ! --- Seed first generator. |
44 | 0:839f52ef7657 | louridas | |
45 | 0:839f52ef7657 | louridas | x1 = Mod( c1 - idum, m1 ) |
46 | 0:839f52ef7657 | louridas | x1 = Mod( a1*x1 + c1, m1 ) |
47 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
48 | 0:839f52ef7657 | louridas | ! --- Use it to seed the second generator. |
49 | 0:839f52ef7657 | louridas | |
50 | 0:839f52ef7657 | louridas | x2 = Mod( x1, m2 ) |
51 | 0:839f52ef7657 | louridas | x1 = Mod( a1*x1 + c1, m1 ) |
52 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
53 | 0:839f52ef7657 | louridas | ! --- Use generator 1 again to seed generator 3. |
54 | 0:839f52ef7657 | louridas | |
55 | 0:839f52ef7657 | louridas | x3 = Mod( a1*x1, m3 ) |
56 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
57 | 0:839f52ef7657 | louridas | ! --- Now fill array with random values, using gen. 2 for the high |
58 | 0:839f52ef7657 | louridas | ! order bits and gen. 1 for the low order bits. |
59 | 0:839f52ef7657 | louridas | |
60 | 0:839f52ef7657 | louridas | Do j = 1,97 |
61 | 0:839f52ef7657 | louridas | x1 = Mod( a1*x1 + c1, m1 ) |
62 | 0:839f52ef7657 | louridas | x2 = Mod( a2*x2 + c2, m2 ) |
63 | 0:839f52ef7657 | louridas | r(j) = ( Real( x1, Kind = l_ ) + |
64 | 0:839f52ef7657 | louridas | & Real( x2, Kind = l_ ) * rm2 ) * rm1 |
65 | 0:839f52ef7657 | louridas | End Do |
66 | 0:839f52ef7657 | louridas | idum = 1 |
67 | 0:839f52ef7657 | louridas | End If |
68 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
69 | 0:839f52ef7657 | louridas | ! --- This section is only reached when no (re)initialisation takes |
70 | 0:839f52ef7657 | louridas | ! place. A new random number is generated to fill the place of |
71 | 0:839f52ef7657 | louridas | ! a randomly picked element from array 'r' (the selection of the |
72 | 0:839f52ef7657 | louridas | ! index is done by gen. 3). |
73 | 0:839f52ef7657 | louridas | |
74 | 0:839f52ef7657 | louridas | x1 = Mod( a1*x1 + c1, m1 ) |
75 | 0:839f52ef7657 | louridas | x2 = Mod( a2*x2 + c2, m2 ) |
76 | 0:839f52ef7657 | louridas | x3 = Mod( a3*x3 + c3, m3 ) |
77 | 0:839f52ef7657 | louridas | j = 1 + ( 97 + x3 )/m3 |
78 | 0:839f52ef7657 | louridas | ran_out = r(j) |
79 | 0:839f52ef7657 | louridas | r(j) = ( Real( x1, l_ ) + Real( x2, l_ ) * rm2 ) * rm1 |
80 | 0:839f52ef7657 | louridas | ! ---------------------------------------------------------------------- |
81 | 0:839f52ef7657 | louridas | End Function ran1 |