SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
dlaran.c
Go to the documentation of this file.
1/**
2 * @file dlaran.c
3 * @brief LAPACK-based random number generator.
4 *
5 * @details Translation of the LAPACK auxiliary routine `DLARAN` using the
6 * f2c tool. Generates uniform random numbers in the interval (0, 1) using
7 * a 48-bit seed stored across four 12-bit integers.
8 *
9 * @copyright
10 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
11 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
12 *
13 * @license
14 * This file is distributed subject to a Software License Agreement found in the file LICENSE
15 * that is included with this distribution.
16 *
17 * @author
18 * - Original LAPACK authors
19 * - SDDS maintainers
20 */
21
22#include "f2c.h"
23
24/* dlaran.f -- translated by f2c (version of 30 January 1990 16:02:04).
25 You must link the resulting object file with the libraries:
26 -lF77 -lI77 -lm -lc (in that order)
27*/
28
29/**
30 * @brief Generates a random number using the DLARAN algorithm.
31 * @param iseed Seed array of four integers. Updated in place.
32 * @return Uniform random number in the interval (0, 1).
33 */
34doublereal dlaran_(integer *iseed) {
35 /* System generated locals */
36 doublereal ret_val;
37
38 /* Local variables */
39 integer it1, it2, it3, it4;
40
41 /* Parameter adjustments */
42 /*--iseed;*/
43
44 /* Function Body */
45
46 /* -- LAPACK auxiliary routine (version 2.0) -- */
47 /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */
48 /* Courant Institute, Argonne National Lab, and Rice University */
49 /* February 29, 1992 */
50
51 /* .. Array Arguments .. */
52 /* .. */
53
54 /* Purpose */
55 /* ======= */
56
57 /* DLARAN returns a random real number from a uniform (0,1) */
58 /* distribution. */
59
60 /* Arguments */
61 /* ========= */
62
63 /* ISEED (input/output) INTEGER array, dimension (4) */
64 /* On entry, the seed of the random number generator; the array
65*/
66 /* elements must be between 0 and 4095, and ISEED(4) must be */
67 /* odd. */
68 /* On exit, the seed is updated. */
69
70 /* Further Details */
71 /* =============== */
72
73 /* This routine uses a multiplicative congruential method with modulus */
74
75 /* 2**48 and multiplier 33952834046453 (see G.S.Fishman, */
76 /* 'Multiplicative congruential random number generators with modulus */
77 /* 2**b: an exhaustive analysis for b = 32 and a partial analysis for */
78 /* b = 48', Math. Comp. 189, pp 331-344, 1990). */
79
80 /* 48-bit integers are stored in 4 integer array elements with 12 bits */
81
82 /* per element. Hence the routine is portable across machines with */
83 /* integers of 32 bits or more. */
84
85 /* =====================================================================
86*/
87
88 /* .. Parameters .. */
89 /* .. */
90 /* .. Local Scalars .. */
91 /* .. */
92 /* .. Intrinsic Functions .. */
93 /* .. */
94 /* .. Executable Statements .. */
95
96 /* multiply the seed by the multiplier modulo 2**48 */
97
98 it4 = iseed[3] * 2549;
99 it3 = it4 / 4096;
100 it4 -= it3 << 12;
101 it3 = it3 + iseed[2] * 2549 + iseed[3] * 2508;
102 it2 = it3 / 4096;
103 it3 -= it2 << 12;
104 it2 = it2 + iseed[1] * 2549 + iseed[2] * 2508 + iseed[3] * 322;
105 it1 = it2 / 4096;
106 it2 -= it1 << 12;
107 it1 = it1 + iseed[0] * 2549 + iseed[1] * 2508 + iseed[2] * 322 + iseed[3] * 494;
108 it1 %= 4096;
109
110 /* return updated seed */
111
112 iseed[0] = it1;
113 iseed[1] = it2;
114 iseed[2] = it3;
115 iseed[3] = it4;
116
117 /* convert 48-bit integer to a real number in the interval (0,1) */
118
119 ret_val = ((doublereal)it1 + ((doublereal)it2 + ((doublereal)it3 + (doublereal)it4 * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4;
120 return ret_val;
121
122 /* End of DLARAN */
123
124} /* dlaran_ */
125
126/**
127 * @brief Advance the DLARAN seed and return a random number.
128 * @param iseed Seed array of four integers. Updated in place.
129 * @param increment Number of times to update the seed before returning the
130 * new value.
131 * @return Uniform random number in the interval (0, 1).
132 */
133doublereal dlaran_oag(integer *iseed, long increment) {
134 doublereal ret_val;
135
136 integer it1, it2, it3, it4, i;
137
138 if (increment < 1)
139 increment = 1;
140 for (i = 0; i < increment; i++) {
141 it4 = iseed[3] * 2549;
142 it3 = it4 / 4096;
143 it4 -= it3 << 12;
144 it3 = it3 + iseed[2] * 2549 + iseed[3] * 2508;
145 it2 = it3 / 4096;
146 it3 -= it2 << 12;
147 it2 = it2 + iseed[1] * 2549 + iseed[2] * 2508 + iseed[3] * 322;
148 it1 = it2 / 4096;
149 it2 -= it1 << 12;
150 it1 = it1 + iseed[0] * 2549 + iseed[1] * 2508 + iseed[2] * 322 + iseed[3] * 494;
151 it1 %= 4096;
152
153 iseed[0] = it1;
154 iseed[1] = it2;
155 iseed[2] = it3;
156 iseed[3] = it4;
157 }
158
159 ret_val = ((doublereal)it1 + ((doublereal)it2 + ((doublereal)it3 + (doublereal)it4 * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4;
160 return ret_val;
161}
doublereal dlaran_oag(integer *iseed, long increment)
Advance the DLARAN seed and return a random number.
Definition dlaran.c:133
doublereal dlaran_(integer *iseed)
Generates a random number using the DLARAN algorithm.
Definition dlaran.c:34