SpectMorph
smpcg32rng.hh
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2 // Author: 2014, Tim Janik, see http://testbit.org/keccak
3 
4 #include <glib.h>
5 #include <stdint.h>
6 
7 namespace SpectMorph
8 {
9 
21 class Pcg32Rng {
22  uint64_t increment_; // must be odd, allows for 2^63 distinct random sequences
23  uint64_t accu_; // can contain all 2^64 possible values
24  static constexpr const uint64_t A = 6364136223846793005ULL; // from C. E. Hayness, see TAOCP by D. E. Knuth, 3.3.4, table 1, line 26.
25  static inline constexpr uint32_t
26  ror32 (const uint32_t bits, const uint32_t offset)
27  {
28  // bitwise rotate-right pattern recognized by gcc & clang iff 32==sizeof (bits)
29  return (bits >> offset) | (bits << (32 - offset));
30  }
31  static inline constexpr uint32_t
32  pcg_xsh_rr (const uint64_t input)
33  {
34  // Section 6.3.1. 32-bit Output, 64-bit State: PCG-XSH-RR
35  // http://www.pcg-random.org/pdf/toms-oneill-pcg-family-v1.02.pdf
36  return ror32 ((input ^ (input >> 18)) >> 27, input >> 59);
37  }
38 public:
40  template<class SeedSeq>
41  explicit Pcg32Rng (SeedSeq &seed_sequence) : increment_ (0), accu_ (0) { seed (seed_sequence); }
43  explicit Pcg32Rng (uint64_t offset, uint64_t sequence) :
44  increment_ (0), accu_ (0)
45  {
46  seed (offset, sequence);
47  }
49  explicit Pcg32Rng () :
50  increment_ (0), accu_ (0)
51  {
52  auto_seed();
53  }
54 
56  void auto_seed ()
57  {
58  //AutoSeeder seeder;
59  //seed (seeder);
60  seed (g_random_int(), g_random_int());
61  }
63  void seed (uint64_t offset, uint64_t sequence)
64  {
65  accu_ = sequence;
66  increment_ = (sequence << 1) | 1; // force increment_ to be odd
67  accu_ += offset;
68  accu_ = A * accu_ + increment_;
69  }
71  template<class SeedSeq> void
72  seed (SeedSeq &seed_sequence)
73  {
74  uint64_t seeds[2];
75  seed_sequence.generate (&seeds[0], &seeds[2]);
76  seed (seeds[0], seeds[1]);
77  }
79  uint32_t
80  random ()
81  {
82  const uint64_t lcgout = accu_; // using the *last* state as ouput helps with CPU pipelining
83  accu_ = A * accu_ + increment_;
84  return pcg_xsh_rr (lcgout); // PCG XOR-shift + random rotation
85  }
86 };
87 
88 }
uint32_t random()
Generate uniformly distributed 32 bit pseudo random number.
Definition: smpcg32rng.hh:80
void seed(uint64_t offset, uint64_t sequence)
Seed by seeking to position offset within stream sequence.
Definition: smpcg32rng.hh:63
Definition: smpcg32rng.hh:21
Pcg32Rng(SeedSeq &seed_sequence)
Initialize and seed from seed_sequence.
Definition: smpcg32rng.hh:41
void seed(SeedSeq &seed_sequence)
Seed the generator state from a seed_sequence.
Definition: smpcg32rng.hh:72
Definition: smalignedarray.cc:7
void auto_seed()
Seed the generator from a system specific nondeterministic random source.
Definition: smpcg32rng.hh:56
Pcg32Rng(uint64_t offset, uint64_t sequence)
Initialize and seed by seeking to position offset within stream sequence.
Definition: smpcg32rng.hh:43
Pcg32Rng()
Initialize and seed the generator from a system specific nondeterministic random source.
Definition: smpcg32rng.hh:49