gKit2 light
Loading...
Searching...
No Matches
pcg.h
Go to the documentation of this file.
1
3
4#ifndef _PCG_H
5#define _PCG_H
6
7#include <cstdint>
8
9
10// reprise de http://www.pcg-random.org
11// periode 2^64 mais 2^63 sequences aleatoires
12struct PCG32
13{
14 PCG32( ) : x(), x0(), key() { seed(0x853c49e6748fea9b, b); }
15 PCG32( const uint64_t s, const uint64_t ss= b ) : x(), x0(), key() { seed(s, ss); }
16
17 void seed( const uint64_t s, const uint64_t ss= b )
18 {
19 key= (ss << 1) | 1;
20
21 x= key + s;
22 sample();
23 x0= x;
24 }
25
26 PCG32& index( const uint64_t i )
27 {
28 // advance to sample index
29 // http://www.pcg-random.org implementation
30 uint64_t tmul= a;
31 uint64_t tadd= key;
32 uint64_t mul= 1;
33 uint64_t add= 0;
34
35 uint64_t delta= i;
36 while(delta)
37 {
38 if(delta & 1)
39 {
40 mul= mul * tmul;
41 add= add * tmul + tadd;
42 }
43
44 tadd= tmul * tadd + tadd;
45 tmul= tmul * tmul;
46 delta= delta >> 1;
47 }
48
49 x= mul * x0 + add;
50 return *this;
51 }
52
53 unsigned sample( )
54 {
55 uint64_t xx= x;
56 x= a*x + key;
57
58 // hash(x)
59 uint32_t tmp= ((xx >> 18u) ^ xx) >> 27u;
60 uint32_t r= xx >> 59u;
61 return (tmp >> r) | (tmp << ((~r + 1u) & 31));
62 }
63
64 unsigned sample_range( const unsigned range )
65 {
66 // Efficiently Generating a Number in a Range
67 // cf http://www.pcg-random.org/posts/bounded-rands.html
68 unsigned divisor= ((-range) / range) + 1; // (2^32) / range
69 if(divisor == 0) return 0;
70
71 while(true)
72 {
73 unsigned x= sample() / divisor;
74 if(x < range) return x;
75 }
76 }
77
78 // c++ interface
79 unsigned operator() ( ) { return sample(); }
80 static constexpr unsigned min( ) { return 0; }
81 static constexpr unsigned max( ) { return ~unsigned(0); }
82 typedef unsigned result_type;
83
84 static constexpr uint64_t a= 0x5851f42d4c957f2d;
85 static constexpr uint64_t b= 0xda3e39cb94b95bdb;
86
87 uint64_t x;
88 uint64_t x0;
89 uint64_t key;
90};
91
92
93// reprise de https://github.com/imneme/pcg-c/blob/master/include/pcg_variants.h
94// version 32 bits, periode 2^32 mais 2^31 sequences aleatoires
95struct PCG32I
96{
97 PCG32I( ) : x(), key() { seed(0x46b56677u, 2891336453u); }
98 PCG32I( const unsigned s, const unsigned ss= 2891336453u ) : x(), key() { seed(s, ss); }
99
100 void seed( const unsigned s, const unsigned ss )
101 {
102 key= (ss << 1) | 1;
103 x= s + key;
104 sample();
105 }
106
107 // todo index()
108
109 unsigned sample( )
110 {
111 unsigned xx= x;
112 x= x * 747796405u + key;
113
114 unsigned tmp= ((x >> ((x >> 28u) + 4u)) ^ x) * 277803737u;
115 return (tmp >> 22u) ^ tmp;
116 }
117
118 unsigned sample_range( const unsigned range )
119 {
120 // Efficiently Generating a Number in a Range
121 // cf http://www.pcg-random.org/posts/bounded-rands.html
122 unsigned divisor= ((-range) / range) + 1; // (2^32) / range
123 if(divisor == 0) return 0;
124
125 while(true)
126 {
127 unsigned x= sample() / divisor;
128 if(x < range) return x;
129 }
130 }
131
132 // c++ interface, compatible avec la stl
133 unsigned operator() ( ) { return sample(); }
134 static constexpr unsigned min( ) { return 0; }
135 static constexpr unsigned max( ) { return ~unsigned(0); }
136 typedef unsigned result_type;
137
138 unsigned x;
139 unsigned key;
140};
141
142
143#endif