Statistics
| Branch: | Revision:

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