gKit2 light
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
12 struct 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
95 struct 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
Definition: pcg.h:96
Definition: pcg.h:13