forked from sysprog21/rv32emu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRandom.c
131 lines (101 loc) · 2.64 KB
/
Random.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <stdlib.h>
#include "Random.h"
/* static const int mdig = 32; */
#define MDIG 32
/* static const int one = 1; */
#define ONE 1
static const int m1 = (ONE << (MDIG - 2)) + ((ONE << (MDIG - 2)) - ONE);
static const int m2 = ONE << MDIG / 2;
/* For mdig = 32 : m1 = 2147483647, m2 = 65536
* For mdig = 64 : m1 = 9223372036854775807, m2 = 4294967296
*/
/* move to initialize() because compiler could not resolve as a constant. */
static /*const*/ double dm1; /* = 1.0 / (double) m1; */
/* private methods (defined below, but not in Random.h */
static void initialize(Random R, int seed);
Random new_Random_seed(int seed)
{
Random R = (Random) malloc(sizeof(Random_struct));
initialize(R, seed);
R->left = 0.0;
R->right = 1.0;
R->width = 1.0;
return R;
}
void Random_delete(Random R)
{
free(R);
}
/* Returns the next random number in the sequence. */
double Random_nextDouble(Random R)
{
int k;
int I = R->i;
int J = R->j;
int *m = R->m;
k = m[I] - m[J];
if (k < 0)
k += m1;
R->m[J] = k;
if (I == 0)
I = 16;
else
I--;
R->i = I;
if (J == 0)
J = 16;
else
J--;
R->j = J;
return dm1 * (double) k;
}
/*--------------------------------------------------------------------
PRIVATE METHODS
----------------------------------------------------------------- */
static void initialize(Random R, int seed)
{
int jseed, k0, k1, j0, j1, iloop;
dm1 = 1.0 / (double) m1;
R->seed = seed;
if (seed < 0)
seed = -seed; /* seed = abs(seed) */
jseed = (seed < m1 ? seed : m1); /* jseed = min(seed, m1) */
if (jseed % 2 == 0)
--jseed;
k0 = 9069 % m2;
k1 = 9069 / m2;
j0 = jseed % m2;
j1 = jseed / m2;
for (iloop = 0; iloop < 17; ++iloop) {
jseed = j0 * k0;
j1 = (jseed / m2 + j0 * k1 + j1 * k0) % (m2 / 2);
j0 = jseed % m2;
R->m[iloop] = j0 + m2 * j1;
}
R->i = 4;
R->j = 16;
}
double *RandomVector(int N, Random R)
{
double *x = (double *) malloc(sizeof(double) * N);
for (int i = 0; i < N; i++)
x[i] = Random_nextDouble(R);
return x;
}
double **RandomMatrix(int M, int N, Random R)
{
/* allocate matrix */
double **A = (double **) malloc(sizeof(double *) * M);
if (A == NULL)
return NULL;
for (int i = 0; i < M; i++) {
A[i] = (double *) malloc(sizeof(double) * N);
if (A[i] == NULL) {
free(A);
return NULL;
}
for (int j = 0; j < N; j++)
A[i][j] = Random_nextDouble(R);
}
return A;
}