Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
random.cpp
00001 ///\file 00002 00003 /****************************************************************************** 00004 The MIT License(MIT) 00005 00006 Embedded Template Library. 00007 https://github.com/ETLCPP/etl 00008 http://www.etlcpp.com 00009 00010 Copyright(c) 2017 jwellbelove 00011 00012 Permission is hereby granted, free of charge, to any person obtaining a copy 00013 of this software and associated documentation files(the "Software"), to deal 00014 in the Software without restriction, including without limitation the rights 00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00016 copies of the Software, and to permit persons to whom the Software is 00017 furnished to do so, subject to the following conditions : 00018 00019 The above copyright notice and this permission notice shall be included in all 00020 copies or substantial portions of the Software. 00021 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00028 SOFTWARE. 00029 ******************************************************************************/ 00030 00031 #include "platform.h " 00032 #include "random.h " 00033 00034 namespace etl 00035 { 00036 //*************************************************************************** 00037 // XOR Shift 00038 //*************************************************************************** 00039 00040 //*************************************************************************** 00041 /// Default constructor. 00042 /// Attempts to come up with a unique non-zero seed. 00043 //*************************************************************************** 00044 random_xorshift::random_xorshift() 00045 { 00046 // An attempt to come up with a unique non-zero seed, 00047 // based on the address of the instance. 00048 uintptr_t n = reinterpret_cast<uintptr_t>(this); 00049 uint32_t seed = static_cast<uint32_t>(n); 00050 initialise(seed); 00051 } 00052 00053 //*************************************************************************** 00054 /// Constructor with seed value. 00055 ///\param seed The new seed value. 00056 //*************************************************************************** 00057 random_xorshift::random_xorshift(uint32_t seed) 00058 { 00059 initialise(seed); 00060 } 00061 00062 //*************************************************************************** 00063 /// Initialises the sequence with a new seed value. 00064 ///\param seed The new seed value. 00065 //*************************************************************************** 00066 void random_xorshift::initialise(uint32_t seed) 00067 { 00068 // Add the first four primes to ensure that the seed isn't zero. 00069 state[0] = seed + 3; 00070 state[1] = seed + 5; 00071 state[2] = seed + 7; 00072 state[3] = seed + 11; 00073 } 00074 00075 //*************************************************************************** 00076 /// Get the next random_xorshift number. 00077 //*************************************************************************** 00078 uint32_t random_xorshift::operator()() 00079 { 00080 uint32_t n = state[3]; 00081 n ^= n << 11; 00082 n ^= n >> 8; 00083 state[3] = state[2]; 00084 state[2] = state[1]; 00085 state[1] = state[0]; 00086 n ^= state[0]; 00087 n ^= state[0] >> 19; 00088 state[0] = n; 00089 00090 return n; 00091 } 00092 00093 //*************************************************************************** 00094 /// Get the next random_xorshift number in a specified inclusive range. 00095 //*************************************************************************** 00096 uint32_t random_xorshift::range(uint32_t low, uint32_t high) 00097 { 00098 uint32_t r = high - low + 1; 00099 uint32_t n = operator()(); 00100 n %= r; 00101 n += low; 00102 00103 return n; 00104 } 00105 00106 //*************************************************************************** 00107 // Linear Congruential Generator 00108 //*************************************************************************** 00109 00110 //*************************************************************************** 00111 /// Default constructor. 00112 /// Attempts to come up with a unique non-zero seed. 00113 //*************************************************************************** 00114 random_lcg::random_lcg() 00115 { 00116 // An attempt to come up with a unique non-zero seed, 00117 // based on the address of the instance. 00118 uintptr_t n = reinterpret_cast<uintptr_t>(this); 00119 uint32_t seed = static_cast<uint32_t>(n); 00120 initialise(seed); 00121 } 00122 00123 //*************************************************************************** 00124 /// Constructor with seed value. 00125 ///\param seed The new seed value. 00126 //*************************************************************************** 00127 random_lcg::random_lcg(uint32_t seed) 00128 { 00129 initialise(seed); 00130 } 00131 00132 //*************************************************************************** 00133 /// Initialises the sequence with a new seed value. 00134 ///\param seed The new seed value. 00135 //*************************************************************************** 00136 void random_lcg::initialise(uint32_t seed) 00137 { 00138 seed = (seed == 0) ? 1 : seed; 00139 value = (seed > m) ? m : seed; 00140 } 00141 00142 //*************************************************************************** 00143 /// Get the next random_clcg number. 00144 //*************************************************************************** 00145 uint32_t random_lcg::operator()() 00146 { 00147 value = (a * value) % m; 00148 00149 return value; 00150 } 00151 00152 //*************************************************************************** 00153 /// Get the next random_clcg number in a specified inclusive range. 00154 //*************************************************************************** 00155 uint32_t random_lcg::range(uint32_t low, uint32_t high) 00156 { 00157 uint32_t r = high - low + 1; 00158 uint32_t n = operator()(); 00159 n %= r; 00160 n += low; 00161 00162 return n; 00163 } 00164 00165 //*************************************************************************** 00166 // Combined Linear Congruential Generator 00167 //*************************************************************************** 00168 00169 //*************************************************************************** 00170 /// Default constructor. 00171 /// Attempts to come up with a unique non-zero seed. 00172 //*************************************************************************** 00173 random_clcg::random_clcg() 00174 { 00175 // An attempt to come up with a unique non-zero seed, 00176 // based on the address of the instance. 00177 uintptr_t n = reinterpret_cast<uintptr_t>(this); 00178 uint32_t seed = static_cast<uint32_t>(n); 00179 initialise(seed); 00180 } 00181 00182 //*************************************************************************** 00183 /// Constructor with seed value. 00184 ///\param seed The new seed value. 00185 //*************************************************************************** 00186 random_clcg::random_clcg(uint32_t seed) 00187 { 00188 initialise(seed); 00189 } 00190 00191 //*************************************************************************** 00192 /// Initialises the sequence with a new seed value. 00193 ///\param seed The new seed value. 00194 //*************************************************************************** 00195 void random_clcg::initialise(uint32_t seed) 00196 { 00197 seed = (seed == 0) ? 1 : seed; 00198 value1 = (seed > m1) ? m1 : seed; 00199 value2 = (seed > m1) ? m1 : seed; 00200 } 00201 00202 //*************************************************************************** 00203 /// Get the next random_clcg number. 00204 //*************************************************************************** 00205 uint32_t random_clcg::operator()() 00206 { 00207 static const uint32_t m = ((m1 > m2) ? m1 : m2); 00208 00209 value1 = (a1 * value1) % m1; 00210 value2 = (a2 * value2) % m2; 00211 00212 return (value1 + value2) % m; 00213 } 00214 00215 //*************************************************************************** 00216 /// Get the next random_clcg number in a specified inclusive range. 00217 //*************************************************************************** 00218 uint32_t random_clcg::range(uint32_t low, uint32_t high) 00219 { 00220 uint32_t r = high - low + 1; 00221 uint32_t n = operator()(); 00222 n %= r; 00223 n += low; 00224 00225 return n; 00226 } 00227 00228 //*************************************************************************** 00229 // Linear Shift Feedback Register 00230 //*************************************************************************** 00231 00232 //*************************************************************************** 00233 /// Default constructor. 00234 /// Attempts to come up with a unique non-zero seed. 00235 //*************************************************************************** 00236 random_lsfr::random_lsfr() 00237 { 00238 // An attempt to come up with a unique non-zero seed, 00239 // based on the address of the instance. 00240 uintptr_t n = reinterpret_cast<uintptr_t>(this); 00241 uint32_t seed = static_cast<uint32_t>(n); 00242 initialise(seed); 00243 } 00244 00245 //*************************************************************************** 00246 /// Constructor with seed value. 00247 ///\param seed The new seed value. 00248 //*************************************************************************** 00249 random_lsfr::random_lsfr(uint32_t seed) 00250 { 00251 initialise(seed); 00252 } 00253 00254 //*************************************************************************** 00255 /// Initialises the sequence with a new seed value. 00256 ///\param seed The new seed value. 00257 //*************************************************************************** 00258 void random_lsfr::initialise(uint32_t seed) 00259 { 00260 value = seed; 00261 } 00262 00263 //*************************************************************************** 00264 /// Get the next random_lsfr number. 00265 //*************************************************************************** 00266 uint32_t random_lsfr::operator()() 00267 { 00268 static const uint32_t polynomial = 0x80200003; 00269 00270 value >>= 1; 00271 00272 if ((value & 1) == 1) 00273 { 00274 value ^= polynomial; 00275 } 00276 00277 return value; 00278 } 00279 00280 //*************************************************************************** 00281 /// Get the next random_lsfr number in a specified inclusive range. 00282 //*************************************************************************** 00283 uint32_t random_lsfr::range(uint32_t low, uint32_t high) 00284 { 00285 uint32_t r = high - low + 1; 00286 uint32_t n = operator()(); 00287 n %= r; 00288 n += low; 00289 00290 return n; 00291 } 00292 00293 //*************************************************************************** 00294 // Multiply with carry random number generator. 00295 //*************************************************************************** 00296 00297 //*************************************************************************** 00298 /// Default constructor. 00299 /// Attempts to come up with a unique non-zero seed. 00300 //*************************************************************************** 00301 random_mwc::random_mwc() 00302 { 00303 // An attempt to come up with a unique non-zero seed, 00304 // based on the address of the instance. 00305 uintptr_t n = reinterpret_cast<uintptr_t>(this); 00306 uint32_t seed = static_cast<uint32_t>(n); 00307 initialise(seed); 00308 } 00309 00310 //*************************************************************************** 00311 /// Constructor with seed value. 00312 ///\param seed The new seed value. 00313 //*************************************************************************** 00314 random_mwc::random_mwc(uint32_t seed) 00315 { 00316 initialise(seed); 00317 } 00318 00319 //*************************************************************************** 00320 /// Initialises the sequence with a new seed value. 00321 ///\param seed The new seed value. 00322 //*************************************************************************** 00323 void random_mwc::initialise(uint32_t seed) 00324 { 00325 value1 = seed; 00326 value2 = seed; 00327 } 00328 00329 //*************************************************************************** 00330 /// Get the next random_lsfr number. 00331 //*************************************************************************** 00332 uint32_t random_mwc::operator()() 00333 { 00334 value1 = 36969 * (value1 & 0xFFFF) + (value1 >> 16); 00335 value2 = 18000 * (value2 & 0xFFFF) + (value2 >> 16); 00336 00337 return (value1 << 16) + value2; 00338 } 00339 00340 //*************************************************************************** 00341 /// Get the next random_lsfr number in a specified inclusive range. 00342 //*************************************************************************** 00343 uint32_t random_mwc::range(uint32_t low, uint32_t high) 00344 { 00345 uint32_t r = high - low + 1; 00346 uint32_t n = operator()(); 00347 n %= r; 00348 n += low; 00349 00350 return n; 00351 } 00352 } 00353
Generated on Tue Jul 12 2022 14:05:43 by
