Aleph-w
3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ran_array.c
Go to the documentation of this file.
1
/* This program by D E Knuth is in the public domain and freely copyable
2
* AS LONG AS YOU MAKE ABSOLUTELY NO CHANGES!
3
* It is explained in Seminumerical Algorithms, 3rd edition, Section 3.6
4
* (or in the errata to the 2nd edition --- see
5
* http://www-cs-faculty.stanford.edu/~knuth/taocp.html
6
* in the changes to Volume 2 on pages 171 and following). */
7
8
/* N.B. The MODIFICATIONS introduced in the 9th printing (2002) are
9
included here; there's no backwards compatibility with the original. */
10
11
/* This version also adopts Brendan McKay's suggestion to
12
accommodate naive users who forget to call ran_start(seed). */
13
14
/* If you find any bugs, please report them immediately to
15
* taocp@cs.stanford.edu
16
* (and you will be rewarded if the bug is genuine). Thanks! */
17
18
/************ see the book for explanations and caveats! *******************/
19
/************ in particular, you need two's complement arithmetic **********/
20
21
# include "
ran_array.h
"
22
23
#define KK 100
/* the long lag */
24
#define LL 37
/* the short lag */
25
#define MM (1L<<30)
/* the modulus */
26
#define mod_diff(x,y) (((x)-(y))&(MM-1))
/* subtraction mod MM */
27
28
29
#define TT 70
/* guaranteed separation between streams */
30
#define is_odd(x) ((x)&1)
/* units bit of x */
31
#define evenize(x) ((x)&(MM-2))
/* make x even */
32
33
34
35
static
long
ran_x
[
KK
];
/* the generator state */
36
37
#ifdef __STDC__
38
static
void
ran_array
(
long
aa[],
int
n)
39
#else
40
static
void
ran_array
(aa,n)
/* put n new random numbers in aa */
41
long
*aa;
/* destination */
42
int
n;
/* array length (must be at least KK) */
43
#endif
44
{
45
register
int
i,j;
46
for
(j=0;j<
KK
;j++) aa[j]=
ran_x
[j];
47
for
(;j<n;j++) aa[j]=
mod_diff
(aa[j-
KK
],aa[j-
LL
]);
48
for
(i=0;i<
LL
;i++,j++)
ran_x
[i]=
mod_diff
(aa[j-
KK
],aa[j-
LL
]);
49
for
(;i<
KK
;i++,j++)
ran_x
[i]=
mod_diff
(aa[j-
KK
],
ran_x
[i-
LL
]);
50
}
51
52
/* the following routines are from exercise 3.6--15 */
53
/* after calling ran_start, get new randoms by, e.g., "x=ran_arr_next()" */
54
55
#define QUALITY 1009
/* recommended quality level for high-res use */
56
static
long
ran_arr_buf
[
QUALITY
];
57
static
long
ran_arr_dummy
=-1,
ran_arr_started
=-1;
58
long
*
ran_arr_ptr
=&
ran_arr_dummy
;
/* the next random number, or -1 */
59
60
#define TT 70
/* guaranteed separation between streams */
61
#define is_odd(x) ((x)&1)
/* units bit of x */
62
63
#ifdef __STDC__
64
void
ran_start
(
long
seed)
65
#else
66
void
ran_start
(seed)
/* do this before using ran_array */
67
long
seed;
/* selector for different streams */
68
#endif
69
{
70
register
int
t,j;
71
long
x[
KK
+
KK
-1];
/* the preparation buffer */
72
register
long
ss=(seed+2)&(
MM
-2);
73
for
(j=0;j<
KK
;j++) {
74
x[j]=ss;
/* bootstrap the buffer */
75
ss<<=1;
if
(ss>=
MM
) ss-=
MM
-2;
/* cyclic shift 29 bits */
76
}
77
x[1]++;
/* make x[1] (and only x[1]) odd */
78
for
(ss=seed&(
MM
-1),t=
TT
-1; t; ) {
79
for
(j=
KK
-1;j>0;j--) x[j+j]=x[j], x[j+j-1]=0;
/* "square" */
80
for
(j=
KK
+
KK
-2;j>=
KK
;j--)
81
x[j-(
KK
-
LL
)]=
mod_diff
(x[j-(
KK
-
LL
)],x[j]),
82
x[j-
KK
]=
mod_diff
(x[j-
KK
],x[j]);
83
if
(
is_odd
(ss)) {
/* "multiply by z" */
84
for
(j=
KK
;j>0;j--) x[j]=x[j-1];
85
x[0]=x[
KK
];
/* shift the buffer cyclically */
86
x[
LL
]=
mod_diff
(x[
LL
],x[
KK
]);
87
}
88
if
(ss) ss>>=1;
else
t--;
89
}
90
for
(j=0;j<
LL
;j++)
ran_x
[j+
KK
-
LL
]=x[j];
91
for
(;j<
KK
;j++)
ran_x
[j-
LL
]=x[j];
92
for
(j=0;j<10;j++)
ran_array
(x,
KK
+
KK
-1);
/* warm things up */
93
ran_arr_ptr
=&
ran_arr_started
;
94
}
95
96
97
long
ran_arr_cycle
(
void
)
98
{
99
if
(
ran_arr_ptr
==&
ran_arr_dummy
)
100
ran_start
(314159L);
/* the user forgot to initialize */
101
ran_array
(
ran_arr_buf
,
QUALITY
);
102
ran_arr_buf
[100]=-1;
103
ran_arr_ptr
=
ran_arr_buf
+1;
104
return
ran_arr_buf
[0];
105
}
TT
#define TT
Definition
ran_array.c:29
is_odd
#define is_odd(x)
Definition
ran_array.c:30
ran_start
void ran_start(long seed)
Definition
ran_array.c:66
ran_arr_dummy
static long ran_arr_dummy
Definition
ran_array.c:57
ran_arr_started
static long ran_arr_started
Definition
ran_array.c:57
LL
#define LL
Definition
ran_array.c:24
mod_diff
#define mod_diff(x, y)
Definition
ran_array.c:26
ran_arr_cycle
long ran_arr_cycle(void)
Definition
ran_array.c:97
ran_array
static void ran_array(long *aa, int n)
Definition
ran_array.c:40
QUALITY
#define QUALITY
Definition
ran_array.c:55
ran_arr_ptr
long * ran_arr_ptr
Definition
ran_array.c:58
ran_x
static long ran_x[100]
Definition
ran_array.c:35
KK
#define KK
Definition
ran_array.c:23
ran_arr_buf
static long ran_arr_buf[1009]
Definition
ran_array.c:56
MM
#define MM
Definition
ran_array.c:25
ran_array.h
ran_array.c
Generated by
1.9.8