openGPMP
Open Source Mathematics Package
random.cpp
Go to the documentation of this file.
1 /*************************************************************************
2  *
3  * Project
4  * _____ _____ __ __ _____
5  * / ____| __ \| \/ | __ \
6  * ___ _ __ ___ _ __ | | __| |__) | \ / | |__) |
7  * / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/
8  *| (_) | |_) | __/ | | | |__| | | | | | | |
9  * \___/| .__/ \___|_| |_|\_____|_| |_| |_|_|
10  * | |
11  * |_|
12  *
13  * Copyright (C) Akiel Aries, <akiel@akiel.org>, et al.
14  *
15  * This software is licensed as described in the file LICENSE, which
16  * you should have received as part of this distribution. The terms
17  * among other details are referenced in the official documentation
18  * seen here : https://akielaries.github.io/openGPMP/ along with
19  * important files seen in this project.
20  *
21  * You may opt to use, copy, modify, merge, publish, distribute
22  * and/or sell copies of the Software, and permit persons to whom
23  * the Software is furnished to do so, under the terms of the
24  * LICENSE file. As this is an Open Source effort, all implementations
25  * must be of the same methodology.
26  *
27  *
28  *
29  * This software is distributed on an AS IS basis, WITHOUT
30  * WARRANTY OF ANY KIND, either express or implied.
31  *
32  ************************************************************************/
33 #include <chrono>
34 #include <cstdint>
35 #include <iostream>
36 #include <openGPMP/nt/random.hpp>
37 
38 // dfault constructor
40  : state(1), multiplier(6364136223846793005ULL),
41  increment(1442695040888963407ULL) {
42 }
43 
44 // constructor
45 gpmp::core::rndm::LCG::LCG(uint64_t seed, uint64_t a, uint64_t c)
46  : state(seed), multiplier(a), increment(c) {
47 }
48 
50  // Ensure the state is non-negative
51  state &= 0x7FFFFFFFFFFFFFFFULL;
52 
53  // Linear Congruential Generator algorithm
54  state = multiplier * state + increment;
55 
56  // Overflow handling
57  if (state < increment) {
58  // Overflow occurred, adjust the state
59  state += increment;
60  }
61 
62  return state;
63 }
64 
65 // set seed
66 void gpmp::core::rndm::LCG::seed(uint64_t new_seed) {
67  state = new_seed;
68 }
69 
70 // methods to retrieve parameters (optional)
72  return multiplier;
73 }
74 
76  return increment;
77 }
78 
80  return state;
81 }
82 
83 /*
84 uint32_t gpmp::core::rndm::LCG(uint32_t lower, uint32_t upper, uint32_t seed) {
85  uint32_t mod = __32MAX;
86  uint32_t mult = 1664525;
87  uint32_t incr = 1013904223;
88 
89  // set seed = current time
90  uint32_t time_seed =
91  std::chrono::system_clock::now().time_since_epoch().count();
92 
93  uint32_t final_seed = (seed == 0) ? time_seed : seed;
94 
95  // Linear Congruential Generator algorithm
96  uint32_t res = (mult * final_seed + incr) % mod;
97 
98  // trim to range
99  res = lower + (res % (upper - lower + 1));
100 
101  return res;
102 }
103 
104 uint64_t
105 gpmp::core::rndm::LCG_64(uint64_t lower, uint64_t upper, uint64_t seed) {
106  uint64_t mod = __64MAX;
107  uint64_t mult = 6364136223846793005ULL; // Large multiplier
108  uint64_t incr = 1442695040888963407ULL; // Large increment
109 
110  // set seed = current time
111  uint64_t time_seed =
112  std::chrono::system_clock::now().time_since_epoch().count();
113 
114  uint64_t final_seed = (seed == 0) ? time_seed : seed;
115 
116  // Linear Congruential Generator algorithm
117  uint64_t res = (mult * final_seed + incr) % mod;
118 
119  // Calculate the range size
120  uint64_t range_size = upper - lower + 1;
121 
122  // Avoid division by zero
123  if (range_size != 0) {
124  // Ensure res is non-negative
125  res = res & ((1ULL << 63) - 1);
126 
127  // trim to range
128  res = lower + (res % range_size);
129  }
130 
131  return res;
132 }*/
133 
134 uint32_t gpmp::core::rndm::rotr32(uint32_t x, unsigned r) {
135  return x >> r | x << (-r & 31);
136 }
137 
138 uint32_t gpmp::core::rndm::pcg32(void) {
139  uint64_t x = __PCG_STATE;
140  unsigned count = (unsigned)(x >> 59); // 59 = 64 - 5
141 
143  x ^= x >> 18; // 18 = (64 - 27)/2
144  return rotr32((uint32_t)(x >> 27), count); // 27 = 32 - 5
145 }
146 
147 void gpmp::core::rndm::pcg32_init(uint64_t seed) {
148  __PCG_STATE = seed + __PCG_INCR;
149  (void)pcg32();
150 }
uint64_t operator()()
Definition: random.cpp:49
uint64_t get_increment() const
Definition: random.cpp:75
void seed(uint64_t new_seed)
Definition: random.cpp:66
uint64_t get_seed() const
Definition: random.cpp:79
uint64_t get_multiplier() const
Definition: random.cpp:71
void pcg32_init(uint64_t seed)
Definition: random.cpp:147
uint32_t rotr32(uint32_t x, unsigned r)
Definition: random.cpp:134
uint32_t pcg32(void)
Definition: random.cpp:138
Pseudorandom Number Generators.
static uint64_t const __PCG_MULTPLR
Definition: random.hpp:62
static uint64_t __PCG_STATE
Definition: random.hpp:61
static uint64_t const __PCG_INCR
Definition: random.hpp:63