YAP
7.1.0
prandom.yap
Go to the documentation of this file.
1
/*************************************************************************
2
* *
3
* YAP Prolog *
4
* *
5
* Yap Prolog was developed at NCCUP - Universidade do Porto *
6
* *
7
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8
* *
9
**************************************************************************
10
* *
11
* File: regexp.yap *
12
* Last rev: 5/15/2000 *
13
* mods: *
14
* comments: pseudo random numbers in YAP (from code by Van Gelder) *
15
* *
16
*************************************************************************/
17
18
/**
19
* @file prandom.yap
20
* @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
21
* @date Tue Nov 17 23:43:18 2015
22
*
23
* @brief Van Gelder Random Number Generator
24
*
25
*
26
*/
27
28
:- module(
prandom
, [
29
ranstart/0,
30
ranstart/1
,
31
rannum/1
,
32
ranunif/2
]).
33
34
35
%%
36
%% @groupdef prandom Van Gelder Random Number Generator
37
%% @ingroup YAPLibrary
38
%% @{
39
%
40
%
41
% The following code produces the same random numbers as my previous
42
% ranpkg.pl, but is more accurately documented and slightly more
43
% efficient.
44
%
45
% ranpkg.pl random number package Allen Van Gelder, Stanford
46
%
47
% rannum produces a random non-negative integer whose low bits are not
48
% all that random, so it should be scaled to a smaller range in general.
49
% The integer is in the range 0 .. 2^(w-1) - 1,
50
% where w is the word size available for integers, e.g., 18 for DEC-10,
51
% and 16 or 32 for VAX and most IBM.
52
%
53
% ranunif produces a uniformly distributed non-negative random integer over
54
% a caller-specified range. If range is R, the result is in 0 .. R-1.
55
%
56
% ranstart must be called before the first use of rannum or ranunif,
57
% and may be called later to redefine the seed.
58
% ranstart/0 causes a built-in seed to be used.
59
% ranstart(N), N an integer, varies this, but the same N always
60
% produces the same sequence of numbers.
61
%
62
% According to my reading of Knuth, Vol. 2, this generator has period
63
% 2^(w-1) and potency w/2, i.e., 8, 9, or 16 in practice. Knuth says
64
% potency should be at least 5, so this looks more than adequate.
65
% Its drawback is the lack of randomness of low-order bits.
66
67
68
/** @pred rannum(- _I_)
69
70
71
Produces a random non-negative integer _I_ whose low bits are not
72
all that random, so it should be scaled to a smaller range in general.
73
The integer _I_ is in the range 0 .. 2^(w-1) - 1. You can use:
74
75
```
76
rannum(X) :- yap_flag(max_integer,MI), rannum(R), X is R/MI.
77
```
78
to obtain a floating point number uniformly distributed between 0 and 1.
79
80
81
*/
82
/** @pred ranstart
83
84
85
Initialize the random number generator using a built-in seed. The
86
ranstart/0 built-in is always called by the system when loading
87
the package.
88
89
90
*/
91
/** @pred ranstart(+ _Seed_)
92
93
Initialize the random number generator with user-defined _Seed_. The
94
same _Seed_ always produces the same sequence of numbers.
95
96
97
*/
98
/** @pred ranunif(+ _Range_,- _I_)
99
100
101
ranunif/2 produces a uniformly distributed non-negative random
102
integer _I_ over a caller-specified range _R_. If range is _R_,
103
the result is in 0 .. _R_-1.
104
105
106
107
108
*/
109
:-
initialization
(ranstart).
110
111
:-
dynamic
ranState/5.
112
113
%
114
% vsc: dangerous code, to change.
115
%
116
%
117
wsize(
32
)
:-
118
yap_flag
(max_tagged_integer,
I
),
I
>>
32
=:=
0
,
yap_flag.
119
wsize(
64
).
120
121
wsize
:-
ranstart
(
8
'
365
). %
122
123
ranstart
(
N
)
:-
124
wsize(
Wsize
),
% bits available for int.
125
MaxInt
is
\
(
1
<<
(
Wsize
-
1
)),
% all bits but sign bit are 1.
126
Incr
is
(
8
'
154
<<
(
Wsize
-
9
))
+
1
,
% per Knuth, v.2 p.78
127
Mult
is
8
'
3655
,
% OK for 16-18 Wsize
128
Prev
is
Mult
*
(
8
*
N
+
5
)
+
Incr
,
129
assert
(ranState(
Mult
,
Prev
,
Wsize
,
MaxInt
,
Incr
) ).
130
131
rannum
(
Raw
)
:-
132
retract
(ranState(
Mult
,
Prev
,
Wsize
,
MaxInt
,
Incr
)),
133
Curr
is
Mult
*
Prev
+
Incr
,
134
assert
(ranState(
Mult
,
Curr
,
Wsize
,
MaxInt
,
Incr
)),
135
(
Curr
>
0
,
136
Raw
is
Curr
137
;
138
Curr
<
0
,
139
Raw
is
Curr
/\
MaxInt
% force positive sign bit
140
).
141
142
ranunif
(
Range
,
Unif
)
:-
143
Range
>
0
,
144
retract
( ranState(
Mult
,
Prev
,
Wsize
,
MaxInt
,
Incr
) ),
145
Curr
is
Mult
*
Prev
+
Incr
,
146
assert
(ranState(
Mult
,
Curr
,
Wsize
,
MaxInt
,
Incr
)),
147
(
Curr
>
0
,
148
Raw
is
Curr
149
;
150
Curr
<
0
,
151
Raw
is
Curr
/\
MaxInt
% force positive sign bit
152
),
153
Unif
is
(
Raw
*
Range
)
>>
(
Wsize
-
1
).
154
155
156
/** @} */
157
ranstart/1
ranstart(+ Seed)
ranunif/2
ranunif(+ Range,- I)
yap_flag/2
yap_flag( ?Param, ?Value)
assert/1
assert(+ C)
retract/1
retract(+ C)
initialization/1
initialization(+ G)
rannum/1
@groupdef prandom Van Gelder Random Number Generator% % The following code produces the same random n...
library
prandom.yap
Generated by
1.9.3