-
Notifications
You must be signed in to change notification settings - Fork 414
/
randomNumbers.chpl
124 lines (101 loc) · 3.51 KB
/
randomNumbers.chpl
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
// Random
/*
This primer demonstrates usage of the standard module Random.chpl.
*/
use Random;
//
// This primer shows two ways to generate a sequence of random numbers:
// The first is by creating an array of random numbers using the
// :proc:`Random.fillRandom` function. The second way is to use
// a :class:`RandomStream` instance.
//
// Using fillRandom
// ----------------
// Call :proc:`Random.fillRandom` with an array argument. The array
// will be filled with random numbers.
var rands: [1..10] real;
fillRandom(rands);
// Now ``writeln(rands)`` would output these random values, but
// then this program's output would not be deterministic.
//
// To produce deterministic output, specify the starting seed to use when
// filling the array.
//
var randsSeeded: [1..10] real;
var seed = 17;
fillRandom(randsSeeded, seed);
writeln("randsSeeded = ", randsSeeded); // Here the output is deterministic
writeln();
// Other numeric types are supported:
var rand16s: [1..10] uint(16);
fillRandom(rand16s, seed);
writeln("rand16s = ", rand16s); // Here the output is deterministic
writeln();
// Using RandomStream
// ------------------
//
// The second way to generate a sequence of random numbers is by creating a
// :class:`RandomStream` class instance. If one is desired, the seed must be
// specified upon creation of this instance.
//
var randStream: RandomStream(real) = new RandomStream();
var randStreamSeeded: RandomStream(real) = new RandomStream(seed);
//
// Then the instance can be used to obtain the numbers. This can be done in a
// large chunk by calling :proc:`RandomStream.fillRandom`:
//
var randsFromStream: [1..10] real;
randStream.fillRandom(randsFromStream);
//
// Or random numbers can be requested one at a a time.
//
var nextRand = randStreamSeeded.getNext();
writeln(nextRand == randsSeeded[1]);
// Note that since since we are using the same seed, the numbers generated will
// match those generated earlier by ``fillRandom(randsSeeded, seed)``.
//
// The next random number generated will follow the most
// recent...
//
var secondRand = randStreamSeeded.getNext();
writeln(secondRand == randsSeeded[2]);
// ...unless the position to look at has been changed.
randStreamSeeded.skipToNth(7);
var seventhRand = randStreamSeeded.getNext();
writeln(seventhRand == randsSeeded[7]);
//
// A specific random number in the stream can be obtained by
// specifying the position. This argument must be greater
// than ``0``.
//
var secondRand2 = randStreamSeeded.getNth(2);
writeln(secondRand2 == secondRand);
//
// This position can be earlier or later than the most recent.
//
var fourthRand = randStreamSeeded.getNth(4);
writeln(fourthRand == randsSeeded[4]);
//
// The stream can be used to iterate over a specified set of positions.
//
for i in randStreamSeeded.iterate({5..10}, real) {
writeln(i);
}
//
// By default, access using the :class:`RandomStream` instance will be safe in
// the presence of parallelism. This can be changed for the entire stream during
// class creation. As a result, two parallel accesses or updates to the
// position from which reading is intended may conflict.
//
var parallelUnsafe = new RandomStream(parSafe=false);
var parallelSeededUnsafe = new RandomStream(seed, false);
// Now :class:`RandomStream` functions, such as ``parallelUnsafe.getNext()``
// and ``parallelSeededUnsafe.getNext()`` can be called.
//
// At present, RandomStream instances are classes and so they must be
// deleted.
//
delete parallelSeededUnsafe;
delete parallelUnsafe;
delete randStreamSeeded;
delete randStream;