-
Notifications
You must be signed in to change notification settings - Fork 0
/
rand.cpp
135 lines (102 loc) · 2.97 KB
/
rand.cpp
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
132
133
134
//------------------------------------------------------------------------------
#include "rand.h"
#include <math.h>
#include <stdio.h>
//==============================================================================
RandInt::RandInt(long s)
// Uniform distribution assuming 32-bit long
{
randx = s;
}
//------------------------------------------------------------------------------
void RandInt::seed(long s)
{
randx = s;
}
//------------------------------------------------------------------------------
long RandInt::abs(long x)
{
return x & 0x7fffffff;
}
//------------------------------------------------------------------------------
double RandInt::max()
{
return 2147483648.0;
}
//------------------------------------------------------------------------------
long RandInt::draw()
{
return randx = randx * 1103515245 + 12345;
}
//------------------------------------------------------------------------------
double RandInt::fdraw()
// Return value in the interval [0,1]
{
return abs(draw())/max();
}
//------------------------------------------------------------------------------
long RandInt::operator()()
// Return value in the interval [0,2^31]
{
return abs(draw());
}
//==============================================================================
Urand::Urand()
{
n=0;
}
//------------------------------------------------------------------------------
Urand::Urand(long nn)
// Uniform distribution in the interval [0,n]
// Except it isn't. Measurements show 0..n-1.
// You HAVE to use this constructor OR Urand::Urand() followed by box(....)
// or it returns -1 all the time.
{
n = nn;
}
//------------------------------------------------------------------------------
void Urand::box(long nn)
{
n = nn;
}
//------------------------------------------------------------------------------
long Urand::operator()()
{
long r = long(double(n) * fdraw());
//printf("Urand returns %lu in [0,%lu]\n", (r==n) ? n-1 : r, n);
return (r==n) ? n-1 : r;
}
//==============================================================================
Erand::Erand(long m)
// Exponential distribution
{
mean = m;
}
//------------------------------------------------------------------------------
long Erand::operator()()
{
return -mean * long(log((max()-draw())/max() + 0.5));
}
//==============================================================================
bool P(double p)
// Return TRUE with a probability of p
{
static Urand RNG;
return RNG.fdraw() < p;
}
//------------------------------------------------------------------------------
void test()
// Test function for P(p) above. It all seems tickety-spong.
{
unsigned goes=10000;
unsigned bin[2] = {0,0};
for (double p=0.0;p<1.0;p+=0.1) {
for(unsigned i=0;i<goes;i++) {
if (P(p)) bin[0]++; else bin[1]++;;
printf("bin[0]=%3u bin[1]=%3u\n",bin[0],bin[1]);
}
printf("P(%10.2e) %%T = %10.2e\n",p,double(bin[0])/(double(bin[1])+double(bin[0])));
bin[0] = bin[1] = 0;
}
}
//==============================================================================