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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
# Random number generators
This describes the API of module **crandom**. Contains *pcg32* and a extremely fast *64-bit PRNG* inspired by *sfc64*.
The RNG's can generate uniform and normal distributions.
## Types
| crandom | Type definition | Used to represent... |
|:----------------------|:-----------------------------------------------------|:-------------------------------------|
| `crand_rng32_t` | `struct {uint64_t state[2];}` | The crandom type |
| `crand_uniform_i32_t` | `struct {int32_t offset; uint32_t range;}` | The crandom element type |
| `crand_uniform_f32_t` | `struct {float offset, range;}` | crandom iterator |
| `crand_rng64_t` | `struct {uint64_t state[4];}` | |
| `crand_uniform_i64_t` | `struct {int64_t offset; uint64_t range;}` | |
| `crand_uniform_f64_t` | `struct {double offset, range;}` | |
| `crand_normal_f64_t` | `struct {double mean, stddev, next; bool has_next;}` | |
## Header file
All cstr definitions and prototypes may be included in your C source file by including a single header file.
```c
#include "stc/crandom.h"
```
## Methods
### Interface for 32-bits random number generators
```c
(1) crand_rng32_t crand_rng32_init(uint64_t seed);
(2) crand_rng32_t crand_rng32_with_seq(uint64_t seed, uint64_t seq);
(3) uint32_t crand_i32(crand_rng32_t* rng);
(4) float crand_f32(crand_rng32_t* rng);
(5) crand_uniform_i32_t crand_uniform_i32_init(int32_t low, int32_t high);
(6) int32_t crand_uniform_i32(crand_rng32_t* rng, crand_uniform_i32_t* dist);
(7) uint32_t crand_unbiased_i32(crand_rng32_t* rng, crand_uniform_i32_t* dist);
(8) crand_uniform_f32_t crand_uniform_f32_init(float low, float high); /* */
(9) float crand_uniform_f32(crand_rng32_t* rng, crand_uniform_f32_t* dist);
```
(1-2) RNG engine initializers. (3) Integer random number generator with range \[0, 2^32). (5) Integer generator with range \[low, high].
(7) Unbiased version, see https://github.com/lemire/fastrange. (8) 32-bit float random number in range \[low, high), 23 bits resolution numbers.
### Interface for 64-bits random number generators
```c
(1) crand_rng64_t crand_rng64_with_seq(uint64_t seed, uint64_t seq);
(2) crand_rng64_t crand_rng64_init(uint64_t seed);
(3) uint64_t crand_i64(crand_rng64_t* rng);
(4) double crand_f64(crand_rng64_t* rng);
(5) crand_uniform_i64_t crand_uniform_i64_init(int64_t low, int64_t high);
(6) int64_t crand_uniform_i64(crand_rng64_t* rng, crand_uniform_i64_t* dist);
(7) crand_uniform_f64_t crand_uniform_f64_init(double low, double high);
(8) double crand_uniform_f64(crand_rng64_t* rng, crand_uniform_f64_t* dist);
(9) crand_normal_f64_t crand_normal_f64_init(double mean, double stddev);
(10) double crand_normal_f64(crand_rng64_t* rng, crand_normal_f64_t* dist);
```
(1-2) RNG engine initializers. (3) Integer generator, range \[0, 2^64): PRNG copyright Tyge Løvset, NORCE Research, 2020.
(4) Double random number in range \[low, high), 52 bit resolution. (5-8) Initializers and generators of uniform random numbers.
Integer generator has range \[low, high]. (9-10) Initializer and generator for normal distributed random numbers.
(9-10) Initializer and generator for normal-distributed random numbers.
## Example
```c
#include <stdio.h>
#include <time.h>
#include <math.h>
#include "stc/crandom.h"
#include "stc/cstr.h"
#include "stc/cmap.h"
#include "stc/cvec.h"
// Declare unordered map: int -> int with typetag 'i'.
using_cmap(i, int, size_t);
// Comparison of map keys.
static int compare(cmap_i_entry_t *a, cmap_i_entry_t *b) {
return c_default_compare(&a->first, &b->first);
}
// Declare vector of map entries, with comparison function.
using_cvec(e, cmap_i_entry_t, c_default_del, compare);
int main()
{
enum {N = 10000000};
const double Mean = -12.0, StdDev = 6.0, Scale = 74;
printf("Demo of gaussian / normal distribution of %d random samples\n", N);
// Setup random engine with normal distribution.
uint64_t seed = time(NULL);
crand_rng64_t rng = crand_rng64_init(seed);
crand_normal_f64_t dist = crand_normal_f64_init(Mean, StdDev);
// Create histogram map
cmap_i mhist = cmap_i_init();
for (size_t i = 0; i < N; ++i) {
int index = (int) round( crand_normal_f64(&rng, &dist) );
cmap_i_emplace(&mhist, index, 0).first->second += 1;
}
// Transfer map to vec and sort it by map entry keys.
cvec_e vhist = cvec_e_init();
c_foreach (i, cmap_i, mhist)
cvec_e_push_back(&vhist, *i.val);
cvec_e_sort(&vhist);
// Print the gaussian bar chart
cstr_t bar = cstr_init();
c_foreach (i, cvec_e, vhist) {
size_t n = (size_t) (i.val->second * StdDev * Scale * 2.5 / N);
if (n > 0) {
cstr_resize(&bar, n, '*');
printf("%4d %s\n", i.val->first, bar.str);
}
}
// Cleanup
cstr_del(&bar);
cmap_i_del(&mhist);
cvec_e_del(&vhist);
}
```
Output:
```
Demo of gaussian / normal distribution of 10000000 random samples
-29 *
-28 **
-27 ***
-26 ****
-25 *******
-24 *********
-23 *************
-22 ******************
-21 ***********************
-20 ******************************
-19 *************************************
-18 ********************************************
-17 ****************************************************
-16 ***********************************************************
-15 *****************************************************************
-14 *********************************************************************
-13 ************************************************************************
-12 *************************************************************************
-11 ************************************************************************
-10 *********************************************************************
-9 *****************************************************************
-8 ***********************************************************
-7 ****************************************************
-6 ********************************************
-5 *************************************
-4 ******************************
-3 ***********************
-2 ******************
-1 *************
0 *********
1 *******
2 ****
3 ***
4 **
5 *
```
|