3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
11 * DOUBLE PRECISION FUNCTION DLARAN( ISEED )
13 * .. Array Arguments ..
23 *> DLARAN returns a random real number from a uniform (0,1)
30 *> \param[in,out] ISEED
32 *> ISEED is INTEGER array, dimension (4)
33 *> On entry, the seed of the random number generator; the array
34 *> elements must be between 0 and 4095, and ISEED(4) must be
36 *> On exit, the seed is updated.
42 *> \author Univ. of Tennessee
43 *> \author Univ. of California Berkeley
44 *> \author Univ. of Colorado Denver
47 *> \date November 2011
51 *> \par Further Details:
52 * =====================
56 *> This routine uses a multiplicative congruential method with modulus
57 *> 2**48 and multiplier 33952834046453 (see G.S.Fishman,
58 *> 'Multiplicative congruential random number generators with modulus
59 *> 2**b: an exhaustive analysis for b = 32 and a partial analysis for
60 *> b = 48', Math. Comp. 189, pp 331-344, 1990).
62 *> 48-bit integers are stored in 4 integer array elements with 12 bits
63 *> per element. Hence the routine is portable across machines with
64 *> integers of 32 bits or more.
67 * =====================================================================
68 DOUBLE PRECISION FUNCTION DLARAN( ISEED )
70 * -- LAPACK auxiliary routine (version 3.4.0) --
71 * -- LAPACK is a software package provided by Univ. of Tennessee, --
72 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
75 * .. Array Arguments ..
79 * =====================================================================
82 INTEGER M1, M2, M3, M4
83 PARAMETER ( M1 = 494, M2 = 322, M3 = 2508, M4 = 2549 )
85 PARAMETER ( ONE = 1.0D+0 )
88 PARAMETER ( IPW2 = 4096, R = ONE / IPW2 )
91 INTEGER IT1, IT2, IT3, IT4
92 DOUBLE PRECISION RNDOUT
94 * .. Intrinsic Functions ..
97 * .. Executable Statements ..
100 * multiply the seed by the multiplier modulo 2**48
105 IT3 = IT3 + ISEED( 3 )*M4 + ISEED( 4 )*M3
108 IT2 = IT2 + ISEED( 2 )*M4 + ISEED( 3 )*M3 + ISEED( 4 )*M2
111 IT1 = IT1 + ISEED( 1 )*M4 + ISEED( 2 )*M3 + ISEED( 3 )*M2 +
113 IT1 = MOD( IT1, IPW2 )
115 * return updated seed
122 * convert 48-bit integer to a real number in the interval (0,1)
124 RNDOUT = R*( DBLE( IT1 )+R*( DBLE( IT2 )+R*( DBLE( IT3 )+R*
125 $ ( DBLE( IT4 ) ) ) ) )
127 IF (RNDOUT.EQ.1.0D+0) THEN
128 * If a real number has n bits of precision, and the first
129 * n bits of the 48-bit integer above happen to be all 1 (which
130 * will occur about once every 2**n calls), then DLARAN will
131 * be rounded to exactly 1.0.
132 * Since DLARAN is not supposed to return exactly 0.0 or 1.0
133 * (and some callers of DLARAN, such as CLARND, depend on that),
134 * the statistically correct thing to do in this situation is
135 * simply to iterate again.
136 * N.B. the case DLARAN = 0.0 should not be possible.