pcg_random.hpp 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751
  1. /*
  2. * PCG Random Number Generation for C++
  3. *
  4. * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * For additional information about the PCG random number generation scheme,
  19. * including its license and other licensing options, visit
  20. *
  21. * http://www.pcg-random.org
  22. */
  23. /*
  24. * This code provides the reference implementation of the PCG family of
  25. * random number generators. The code is complex because it implements
  26. *
  27. * - several members of the PCG family, specifically members corresponding
  28. * to the output functions:
  29. * - XSH RR (good for 64-bit state, 32-bit output)
  30. * - XSH RS (good for 64-bit state, 32-bit output)
  31. * - XSL RR (good for 128-bit state, 64-bit output)
  32. * - RXS M XS (statistically most powerful generator)
  33. * - XSL RR RR (good for 128-bit state, 128-bit output)
  34. * - and RXS, RXS M, XSH, XSL (mostly for testing)
  35. * - at potentially *arbitrary* bit sizes
  36. * - with four different techniques for random streams (MCG, one-stream
  37. * LCG, settable-stream LCG, unique-stream LCG)
  38. * - and the extended generation schemes allowing arbitrary periods
  39. * - with all features of C++11 random number generation (and more),
  40. * some of which are somewhat painful, including
  41. * - initializing with a SeedSequence which writes 32-bit values
  42. * to memory, even though the state of the generator may not
  43. * use 32-bit values (it might use smaller or larger integers)
  44. * - I/O for RNGs and a prescribed format, which needs to handle
  45. * the issue that 8-bit and 128-bit integers don't have working
  46. * I/O routines (e.g., normally 8-bit = char, not integer)
  47. * - equality and inequality for RNGs
  48. * - and a number of convenience typedefs to mask all the complexity
  49. *
  50. * The code employes a fairly heavy level of abstraction, and has to deal
  51. * with various C++ minutia. If you're looking to learn about how the PCG
  52. * scheme works, you're probably best of starting with one of the other
  53. * codebases (see www.pcg-random.org). But if you're curious about the
  54. * constants for the various output functions used in those other, simpler,
  55. * codebases, this code shows how they are calculated.
  56. *
  57. * On the positive side, at least there are convenience typedefs so that you
  58. * can say
  59. *
  60. * pcg32 myRNG;
  61. *
  62. * rather than:
  63. *
  64. * pcg_detail::engine<
  65. * uint32_t, // Output Type
  66. * uint64_t, // State Type
  67. * pcg_detail::xsh_rr_mixin<uint32_t, uint64_t>, true, // Output Func
  68. * pcg_detail::specific_stream<uint64_t>, // Stream Kind
  69. * pcg_detail::default_multiplier<uint64_t> // LCG Mult
  70. * > myRNG;
  71. *
  72. */
  73. #ifndef PCG_RAND_HPP_INCLUDED
  74. #define PCG_RAND_HPP_INCLUDED 1
  75. #include <cinttypes>
  76. #include <cstddef>
  77. #include <cstdlib>
  78. #include <cstring>
  79. #include <cassert>
  80. #include <limits>
  81. #include <iostream>
  82. #include <type_traits>
  83. #include <utility>
  84. #include <locale>
  85. #include <new>
  86. #include <stdexcept>
  87. /*
  88. * The pcg_extras namespace contains some support code that is likley to
  89. * be useful for a variety of RNGs, including:
  90. * - 128-bit int support for platforms where it isn't available natively
  91. * - bit twiddling operations
  92. * - I/O of 128-bit and 8-bit integers
  93. * - Handling the evilness of SeedSeq
  94. * - Support for efficiently producing random numbers less than a given
  95. * bound
  96. */
  97. #include "pcg_extras.hpp"
  98. namespace pcg_detail {
  99. using namespace pcg_extras;
  100. /*
  101. * The LCG generators need some constants to function. This code lets you
  102. * look up the constant by *type*. For example
  103. *
  104. * default_multiplier<uint32_t>::multiplier()
  105. *
  106. * gives you the default multipler for 32-bit integers. We use the name
  107. * of the constant and not a generic word like value to allow these classes
  108. * to be used as mixins.
  109. */
  110. template <typename T>
  111. struct default_multiplier {
  112. // Not defined for an arbitrary type
  113. };
  114. template <typename T>
  115. struct default_increment {
  116. // Not defined for an arbitrary type
  117. };
  118. #define PCG_DEFINE_CONSTANT(type, what, kind, constant) \
  119. template <> \
  120. struct what ## _ ## kind<type> { \
  121. static constexpr type kind() { \
  122. return constant; \
  123. } \
  124. };
  125. PCG_DEFINE_CONSTANT(uint8_t, default, multiplier, 141U)
  126. PCG_DEFINE_CONSTANT(uint8_t, default, increment, 77U)
  127. PCG_DEFINE_CONSTANT(uint16_t, default, multiplier, 12829U)
  128. PCG_DEFINE_CONSTANT(uint16_t, default, increment, 47989U)
  129. PCG_DEFINE_CONSTANT(uint32_t, default, multiplier, 747796405U)
  130. PCG_DEFINE_CONSTANT(uint32_t, default, increment, 2891336453U)
  131. PCG_DEFINE_CONSTANT(uint64_t, default, multiplier, 6364136223846793005ULL)
  132. PCG_DEFINE_CONSTANT(uint64_t, default, increment, 1442695040888963407ULL)
  133. PCG_DEFINE_CONSTANT(pcg128_t, default, multiplier,
  134. PCG_128BIT_CONSTANT(2549297995355413924ULL,4865540595714422341ULL))
  135. PCG_DEFINE_CONSTANT(pcg128_t, default, increment,
  136. PCG_128BIT_CONSTANT(6364136223846793005ULL,1442695040888963407ULL))
  137. /*
  138. * Each PCG generator is available in four variants, based on how it applies
  139. * the additive constant for its underlying LCG; the variations are:
  140. *
  141. * single stream - all instances use the same fixed constant, thus
  142. * the RNG always somewhere in same sequence
  143. * mcg - adds zero, resulting in a single stream and reduced
  144. * period
  145. * specific stream - the constant can be changed at any time, selecting
  146. * a different random sequence
  147. * unique stream - the constant is based on the memory addresss of the
  148. * object, thus every RNG has its own unique sequence
  149. *
  150. * This variation is provided though mixin classes which define a function
  151. * value called increment() that returns the nesessary additive constant.
  152. */
  153. /*
  154. * unique stream
  155. */
  156. template <typename itype>
  157. class unique_stream {
  158. protected:
  159. static constexpr bool is_mcg = false;
  160. // Is never called, but is provided for symmetry with specific_stream
  161. void set_stream(...)
  162. {
  163. abort();
  164. }
  165. public:
  166. typedef itype state_type;
  167. constexpr itype increment() const {
  168. return itype(reinterpret_cast<unsigned long>(this) | 1);
  169. }
  170. constexpr itype stream() const
  171. {
  172. return increment() >> 1;
  173. }
  174. static constexpr bool can_specify_stream = false;
  175. static constexpr size_t streams_pow2()
  176. {
  177. return (sizeof(itype) < sizeof(size_t) ? sizeof(itype)
  178. : sizeof(size_t))*8 - 1u;
  179. }
  180. protected:
  181. constexpr unique_stream() = default;
  182. };
  183. /*
  184. * no stream (mcg)
  185. */
  186. template <typename itype>
  187. class no_stream {
  188. protected:
  189. static constexpr bool is_mcg = true;
  190. // Is never called, but is provided for symmetry with specific_stream
  191. void set_stream(...)
  192. {
  193. abort();
  194. }
  195. public:
  196. typedef itype state_type;
  197. static constexpr itype increment() {
  198. return 0;
  199. }
  200. static constexpr bool can_specify_stream = false;
  201. static constexpr size_t streams_pow2()
  202. {
  203. return 0u;
  204. }
  205. protected:
  206. constexpr no_stream() = default;
  207. };
  208. /*
  209. * single stream/sequence (oneseq)
  210. */
  211. template <typename itype>
  212. class oneseq_stream : public default_increment<itype> {
  213. protected:
  214. static constexpr bool is_mcg = false;
  215. // Is never called, but is provided for symmetry with specific_stream
  216. void set_stream(...)
  217. {
  218. abort();
  219. }
  220. public:
  221. typedef itype state_type;
  222. static constexpr itype stream()
  223. {
  224. return default_increment<itype>::increment() >> 1;
  225. }
  226. static constexpr bool can_specify_stream = false;
  227. static constexpr size_t streams_pow2()
  228. {
  229. return 0u;
  230. }
  231. protected:
  232. constexpr oneseq_stream() = default;
  233. };
  234. /*
  235. * specific stream
  236. */
  237. template <typename itype>
  238. class specific_stream {
  239. protected:
  240. static constexpr bool is_mcg = false;
  241. itype inc_ = default_increment<itype>::increment();
  242. public:
  243. typedef itype state_type;
  244. typedef itype stream_state;
  245. constexpr itype increment() const {
  246. return inc_;
  247. }
  248. itype stream()
  249. {
  250. return inc_ >> 1;
  251. }
  252. void set_stream(itype specific_seq)
  253. {
  254. inc_ = (specific_seq << 1) | 1;
  255. }
  256. static constexpr bool can_specify_stream = true;
  257. static constexpr size_t streams_pow2()
  258. {
  259. return (sizeof(itype)*8) - 1u;
  260. }
  261. protected:
  262. specific_stream() = default;
  263. specific_stream(itype specific_seq)
  264. : inc_((specific_seq << 1) | itype(1U))
  265. {
  266. // Nothing (else) to do.
  267. }
  268. };
  269. /*
  270. * This is where it all comes together. This function joins together three
  271. * mixin classes which define
  272. * - the LCG additive constant (the stream)
  273. * - the LCG multiplier
  274. * - the output function
  275. * in addition, we specify the type of the LCG state, and the result type,
  276. * and whether to use the pre-advance version of the state for the output
  277. * (increasing instruction-level parallelism) or the post-advance version
  278. * (reducing register pressure).
  279. *
  280. * Given the high level of parameterization, the code has to use some
  281. * template-metaprogramming tricks to handle some of the suble variations
  282. * involved.
  283. */
  284. template <typename xtype, typename itype,
  285. typename output_mixin,
  286. bool output_previous = true,
  287. typename stream_mixin = oneseq_stream<itype>,
  288. typename multiplier_mixin = default_multiplier<itype> >
  289. class engine : protected output_mixin,
  290. public stream_mixin,
  291. protected multiplier_mixin {
  292. protected:
  293. itype state_;
  294. struct can_specify_stream_tag {};
  295. struct no_specifiable_stream_tag {};
  296. using stream_mixin::increment;
  297. using multiplier_mixin::multiplier;
  298. public:
  299. typedef xtype result_type;
  300. typedef itype state_type;
  301. static constexpr size_t period_pow2()
  302. {
  303. return sizeof(state_type)*8 - 2*stream_mixin::is_mcg;
  304. }
  305. // It would be nice to use std::numeric_limits for these, but
  306. // we can't be sure that it'd be defined for the 128-bit types.
  307. static constexpr result_type min()
  308. {
  309. return result_type(0UL);
  310. }
  311. static constexpr result_type max()
  312. {
  313. return ~result_type(0UL);
  314. }
  315. protected:
  316. itype bump(itype state)
  317. {
  318. return state * multiplier() + increment();
  319. }
  320. itype base_generate()
  321. {
  322. return state_ = bump(state_);
  323. }
  324. itype base_generate0()
  325. {
  326. itype old_state = state_;
  327. state_ = bump(state_);
  328. return old_state;
  329. }
  330. public:
  331. result_type operator()()
  332. {
  333. if (output_previous)
  334. return this->output(base_generate0());
  335. else
  336. return this->output(base_generate());
  337. }
  338. result_type operator()(result_type upper_bound)
  339. {
  340. return bounded_rand(*this, upper_bound);
  341. }
  342. protected:
  343. static itype advance(itype state, itype delta,
  344. itype cur_mult, itype cur_plus);
  345. static itype distance(itype cur_state, itype newstate, itype cur_mult,
  346. itype cur_plus, itype mask = ~itype(0U));
  347. itype distance(itype newstate, itype mask = ~itype(0U)) const
  348. {
  349. return distance(state_, newstate, multiplier(), increment(), mask);
  350. }
  351. public:
  352. void advance(itype delta)
  353. {
  354. state_ = advance(state_, delta, this->multiplier(), this->increment());
  355. }
  356. void backstep(itype delta)
  357. {
  358. advance(-delta);
  359. }
  360. void discard(itype delta)
  361. {
  362. advance(delta);
  363. }
  364. bool wrapped()
  365. {
  366. if (stream_mixin::is_mcg) {
  367. // For MCGs, the low order two bits never change. In this
  368. // implementation, we keep them fixed at 3 to make this test
  369. // easier.
  370. return state_ == 3;
  371. } else {
  372. return state_ == 0;
  373. }
  374. }
  375. engine(itype state = itype(0xcafef00dd15ea5e5ULL))
  376. : state_(this->is_mcg ? state|state_type(3U)
  377. : bump(state + this->increment()))
  378. {
  379. // Nothing else to do.
  380. }
  381. // This function may or may not exist. It thus has to be a template
  382. // to use SFINAE; users don't have to worry about its template-ness.
  383. template <typename sm = stream_mixin>
  384. engine(itype state, typename sm::stream_state stream_seed)
  385. : stream_mixin(stream_seed),
  386. state_(this->is_mcg ? state|state_type(3U)
  387. : bump(state + this->increment()))
  388. {
  389. // Nothing else to do.
  390. }
  391. template<typename SeedSeq>
  392. engine(SeedSeq&& seedSeq, typename std::enable_if<
  393. !stream_mixin::can_specify_stream
  394. && !std::is_convertible<SeedSeq, itype>::value
  395. && !std::is_convertible<SeedSeq, engine>::value,
  396. no_specifiable_stream_tag>::type = {})
  397. : engine(generate_one<itype>(std::forward<SeedSeq>(seedSeq)))
  398. {
  399. // Nothing else to do.
  400. }
  401. template<typename SeedSeq>
  402. engine(SeedSeq&& seedSeq, typename std::enable_if<
  403. stream_mixin::can_specify_stream
  404. && !std::is_convertible<SeedSeq, itype>::value
  405. && !std::is_convertible<SeedSeq, engine>::value,
  406. can_specify_stream_tag>::type = {})
  407. : engine(generate_one<itype,1,2>(seedSeq),
  408. generate_one<itype,0,2>(seedSeq))
  409. {
  410. // Nothing else to do.
  411. }
  412. template<typename... Args>
  413. void seed(Args&&... args)
  414. {
  415. new (this) engine(std::forward<Args>(args)...);
  416. }
  417. template <typename xtype1, typename itype1,
  418. typename output_mixin1, bool output_previous1,
  419. typename stream_mixin_lhs, typename multiplier_mixin_lhs,
  420. typename stream_mixin_rhs, typename multiplier_mixin_rhs>
  421. friend bool operator==(const engine<xtype1,itype1,
  422. output_mixin1,output_previous1,
  423. stream_mixin_lhs, multiplier_mixin_lhs>&,
  424. const engine<xtype1,itype1,
  425. output_mixin1,output_previous1,
  426. stream_mixin_rhs, multiplier_mixin_rhs>&);
  427. template <typename xtype1, typename itype1,
  428. typename output_mixin1, bool output_previous1,
  429. typename stream_mixin_lhs, typename multiplier_mixin_lhs,
  430. typename stream_mixin_rhs, typename multiplier_mixin_rhs>
  431. friend itype1 operator-(const engine<xtype1,itype1,
  432. output_mixin1,output_previous1,
  433. stream_mixin_lhs, multiplier_mixin_lhs>&,
  434. const engine<xtype1,itype1,
  435. output_mixin1,output_previous1,
  436. stream_mixin_rhs, multiplier_mixin_rhs>&);
  437. template <typename CharT, typename Traits,
  438. typename xtype1, typename itype1,
  439. typename output_mixin1, bool output_previous1,
  440. typename stream_mixin1, typename multiplier_mixin1>
  441. friend std::basic_ostream<CharT,Traits>&
  442. operator<<(std::basic_ostream<CharT,Traits>& out,
  443. const engine<xtype1,itype1,
  444. output_mixin1,output_previous1,
  445. stream_mixin1, multiplier_mixin1>&);
  446. template <typename CharT, typename Traits,
  447. typename xtype1, typename itype1,
  448. typename output_mixin1, bool output_previous1,
  449. typename stream_mixin1, typename multiplier_mixin1>
  450. friend std::basic_istream<CharT,Traits>&
  451. operator>>(std::basic_istream<CharT,Traits>& in,
  452. engine<xtype1, itype1,
  453. output_mixin1, output_previous1,
  454. stream_mixin1, multiplier_mixin1>& rng);
  455. };
  456. template <typename CharT, typename Traits,
  457. typename xtype, typename itype,
  458. typename output_mixin, bool output_previous,
  459. typename stream_mixin, typename multiplier_mixin>
  460. std::basic_ostream<CharT,Traits>&
  461. operator<<(std::basic_ostream<CharT,Traits>& out,
  462. const engine<xtype,itype,
  463. output_mixin,output_previous,
  464. stream_mixin, multiplier_mixin>& rng)
  465. {
  466. auto orig_flags = out.flags(std::ios_base::dec | std::ios_base::left);
  467. auto space = out.widen(' ');
  468. auto orig_fill = out.fill();
  469. out << rng.multiplier() << space
  470. << rng.increment() << space
  471. << rng.state_;
  472. out.flags(orig_flags);
  473. out.fill(orig_fill);
  474. return out;
  475. }
  476. template <typename CharT, typename Traits,
  477. typename xtype, typename itype,
  478. typename output_mixin, bool output_previous,
  479. typename stream_mixin, typename multiplier_mixin>
  480. std::basic_istream<CharT,Traits>&
  481. operator>>(std::basic_istream<CharT,Traits>& in,
  482. engine<xtype,itype,
  483. output_mixin,output_previous,
  484. stream_mixin, multiplier_mixin>& rng)
  485. {
  486. auto orig_flags = in.flags(std::ios_base::dec | std::ios_base::skipws);
  487. itype multiplier, increment, state;
  488. in >> multiplier >> increment >> state;
  489. if (!in.fail()) {
  490. bool good = true;
  491. if (multiplier != rng.multiplier()) {
  492. good = false;
  493. } else if (rng.can_specify_stream) {
  494. rng.set_stream(increment >> 1);
  495. } else if (increment != rng.increment()) {
  496. good = false;
  497. }
  498. if (good) {
  499. rng.state_ = state;
  500. } else {
  501. in.clear(std::ios::failbit);
  502. }
  503. }
  504. in.flags(orig_flags);
  505. return in;
  506. }
  507. template <typename xtype, typename itype,
  508. typename output_mixin, bool output_previous,
  509. typename stream_mixin, typename multiplier_mixin>
  510. itype engine<xtype,itype,output_mixin,output_previous,stream_mixin,
  511. multiplier_mixin>::advance(
  512. itype state, itype delta, itype cur_mult, itype cur_plus)
  513. {
  514. // The method used here is based on Brown, "Random Number Generation
  515. // with Arbitrary Stride,", Transactions of the American Nuclear
  516. // Society (Nov. 1994). The algorithm is very similar to fast
  517. // exponentiation.
  518. //
  519. // Even though delta is an unsigned integer, we can pass a
  520. // signed integer to go backwards, it just goes "the long way round".
  521. constexpr itype ZERO = 0u; // itype may be a non-trivial types, so
  522. constexpr itype ONE = 1u; // we define some ugly constants.
  523. itype acc_mult = 1;
  524. itype acc_plus = 0;
  525. while (delta > ZERO) {
  526. if (delta & ONE) {
  527. acc_mult *= cur_mult;
  528. acc_plus = acc_plus*cur_mult + cur_plus;
  529. }
  530. cur_plus = (cur_mult+ONE)*cur_plus;
  531. cur_mult *= cur_mult;
  532. delta >>= 1;
  533. }
  534. return acc_mult * state + acc_plus;
  535. }
  536. template <typename xtype, typename itype,
  537. typename output_mixin, bool output_previous,
  538. typename stream_mixin, typename multiplier_mixin>
  539. itype engine<xtype,itype,output_mixin,output_previous,stream_mixin,
  540. multiplier_mixin>::distance(
  541. itype cur_state, itype newstate, itype cur_mult, itype cur_plus, itype mask)
  542. {
  543. constexpr itype ONE = 1u; // itype could be weird, so use constant
  544. itype the_bit = stream_mixin::is_mcg ? itype(4u) : itype(1u);
  545. itype distance = 0u;
  546. while ((cur_state & mask) != (newstate & mask)) {
  547. if ((cur_state & the_bit) != (newstate & the_bit)) {
  548. cur_state = cur_state * cur_mult + cur_plus;
  549. distance |= the_bit;
  550. }
  551. assert((cur_state & the_bit) == (newstate & the_bit));
  552. the_bit <<= 1;
  553. cur_plus = (cur_mult+ONE)*cur_plus;
  554. cur_mult *= cur_mult;
  555. }
  556. return stream_mixin::is_mcg ? distance >> 2 : distance;
  557. }
  558. template <typename xtype, typename itype,
  559. typename output_mixin, bool output_previous,
  560. typename stream_mixin_lhs, typename multiplier_mixin_lhs,
  561. typename stream_mixin_rhs, typename multiplier_mixin_rhs>
  562. itype operator-(const engine<xtype,itype,
  563. output_mixin,output_previous,
  564. stream_mixin_lhs, multiplier_mixin_lhs>& lhs,
  565. const engine<xtype,itype,
  566. output_mixin,output_previous,
  567. stream_mixin_rhs, multiplier_mixin_rhs>& rhs)
  568. {
  569. if (lhs.multiplier() != rhs.multiplier()
  570. || lhs.increment() != rhs.increment())
  571. throw std::logic_error("incomparable generators");
  572. return rhs.distance(lhs.state_);
  573. }
  574. template <typename xtype, typename itype,
  575. typename output_mixin, bool output_previous,
  576. typename stream_mixin_lhs, typename multiplier_mixin_lhs,
  577. typename stream_mixin_rhs, typename multiplier_mixin_rhs>
  578. bool operator==(const engine<xtype,itype,
  579. output_mixin,output_previous,
  580. stream_mixin_lhs, multiplier_mixin_lhs>& lhs,
  581. const engine<xtype,itype,
  582. output_mixin,output_previous,
  583. stream_mixin_rhs, multiplier_mixin_rhs>& rhs)
  584. {
  585. return (lhs.multiplier() == rhs.multiplier())
  586. && (lhs.increment() == rhs.increment())
  587. && (lhs.state_ == rhs.state_);
  588. }
  589. template <typename xtype, typename itype,
  590. typename output_mixin, bool output_previous,
  591. typename stream_mixin_lhs, typename multiplier_mixin_lhs,
  592. typename stream_mixin_rhs, typename multiplier_mixin_rhs>
  593. inline bool operator!=(const engine<xtype,itype,
  594. output_mixin,output_previous,
  595. stream_mixin_lhs, multiplier_mixin_lhs>& lhs,
  596. const engine<xtype,itype,
  597. output_mixin,output_previous,
  598. stream_mixin_rhs, multiplier_mixin_rhs>& rhs)
  599. {
  600. return !operator==(lhs,rhs);
  601. }
  602. template <typename xtype, typename itype,
  603. template<typename XT,typename IT> class output_mixin,
  604. bool output_previous = (sizeof(itype) <= 8)>
  605. using oneseq_base = engine<xtype, itype,
  606. output_mixin<xtype, itype>, output_previous,
  607. oneseq_stream<itype> >;
  608. template <typename xtype, typename itype,
  609. template<typename XT,typename IT> class output_mixin,
  610. bool output_previous = (sizeof(itype) <= 8)>
  611. using unique_base = engine<xtype, itype,
  612. output_mixin<xtype, itype>, output_previous,
  613. unique_stream<itype> >;
  614. template <typename xtype, typename itype,
  615. template<typename XT,typename IT> class output_mixin,
  616. bool output_previous = (sizeof(itype) <= 8)>
  617. using setseq_base = engine<xtype, itype,
  618. output_mixin<xtype, itype>, output_previous,
  619. specific_stream<itype> >;
  620. template <typename xtype, typename itype,
  621. template<typename XT,typename IT> class output_mixin,
  622. bool output_previous = (sizeof(itype) <= 8)>
  623. using mcg_base = engine<xtype, itype,
  624. output_mixin<xtype, itype>, output_previous,
  625. no_stream<itype> >;
  626. /*
  627. * OUTPUT FUNCTIONS.
  628. *
  629. * These are the core of the PCG generation scheme. They specify how to
  630. * turn the base LCG's internal state into the output value of the final
  631. * generator.
  632. *
  633. * They're implemented as mixin classes.
  634. *
  635. * All of the classes have code that is written to allow it to be applied
  636. * at *arbitrary* bit sizes, although in practice they'll only be used at
  637. * standard sizes supported by C++.
  638. */
  639. /*
  640. * XSH RS -- high xorshift, followed by a random shift
  641. *
  642. * Fast. A good performer.
  643. */
  644. template <typename xtype, typename itype>
  645. struct xsh_rs_mixin {
  646. static xtype output(itype internal)
  647. {
  648. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  649. constexpr bitcount_t xtypebits = bitcount_t(sizeof(xtype) * 8);
  650. constexpr bitcount_t sparebits = bits - xtypebits;
  651. constexpr bitcount_t opbits =
  652. sparebits-5 >= 64 ? 5
  653. : sparebits-4 >= 32 ? 4
  654. : sparebits-3 >= 16 ? 3
  655. : sparebits-2 >= 4 ? 2
  656. : sparebits-1 >= 1 ? 1
  657. : 0;
  658. constexpr bitcount_t mask = (1 << opbits) - 1;
  659. constexpr bitcount_t maxrandshift = mask;
  660. constexpr bitcount_t topspare = opbits;
  661. constexpr bitcount_t bottomspare = sparebits - topspare;
  662. constexpr bitcount_t xshift = topspare + (xtypebits+maxrandshift)/2;
  663. bitcount_t rshift =
  664. opbits ? bitcount_t(internal >> (bits - opbits)) & mask : 0;
  665. internal ^= internal >> xshift;
  666. xtype result = xtype(internal >> (bottomspare - maxrandshift + rshift));
  667. return result;
  668. }
  669. };
  670. /*
  671. * XSH RR -- high xorshift, followed by a random rotate
  672. *
  673. * Fast. A good performer. Slightly better statistically than XSH RS.
  674. */
  675. template <typename xtype, typename itype>
  676. struct xsh_rr_mixin {
  677. static xtype output(itype internal)
  678. {
  679. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  680. constexpr bitcount_t xtypebits = bitcount_t(sizeof(xtype)*8);
  681. constexpr bitcount_t sparebits = bits - xtypebits;
  682. constexpr bitcount_t wantedopbits =
  683. xtypebits >= 128 ? 7
  684. : xtypebits >= 64 ? 6
  685. : xtypebits >= 32 ? 5
  686. : xtypebits >= 16 ? 4
  687. : 3;
  688. constexpr bitcount_t opbits =
  689. sparebits >= wantedopbits ? wantedopbits
  690. : sparebits;
  691. constexpr bitcount_t amplifier = wantedopbits - opbits;
  692. constexpr bitcount_t mask = (1 << opbits) - 1;
  693. constexpr bitcount_t topspare = opbits;
  694. constexpr bitcount_t bottomspare = sparebits - topspare;
  695. constexpr bitcount_t xshift = (topspare + xtypebits)/2;
  696. bitcount_t rot = opbits ? bitcount_t(internal >> (bits - opbits)) & mask
  697. : 0;
  698. bitcount_t amprot = (rot << amplifier) & mask;
  699. internal ^= internal >> xshift;
  700. xtype result = xtype(internal >> bottomspare);
  701. result = rotr(result, amprot);
  702. return result;
  703. }
  704. };
  705. /*
  706. * RXS -- random xorshift
  707. */
  708. template <typename xtype, typename itype>
  709. struct rxs_mixin {
  710. static xtype output_rxs(itype internal)
  711. {
  712. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  713. constexpr bitcount_t xtypebits = bitcount_t(sizeof(xtype)*8);
  714. constexpr bitcount_t shift = bits - xtypebits;
  715. constexpr bitcount_t extrashift = (xtypebits - shift)/2;
  716. bitcount_t rshift = shift > 64+8 ? (internal >> (bits - 6)) & 63
  717. : shift > 32+4 ? (internal >> (bits - 5)) & 31
  718. : shift > 16+2 ? (internal >> (bits - 4)) & 15
  719. : shift > 8+1 ? (internal >> (bits - 3)) & 7
  720. : shift > 4+1 ? (internal >> (bits - 2)) & 3
  721. : shift > 2+1 ? (internal >> (bits - 1)) & 1
  722. : 0;
  723. internal ^= internal >> (shift + extrashift - rshift);
  724. xtype result = internal >> rshift;
  725. return result;
  726. }
  727. };
  728. /*
  729. * RXS M XS -- random xorshift, mcg multiply, fixed xorshift
  730. *
  731. * The most statistically powerful generator, but all those steps
  732. * make it slower than some of the others. We give it the rottenest jobs.
  733. *
  734. * Because it's usually used in contexts where the state type and the
  735. * result type are the same, it is a permutation and is thus invertable.
  736. * We thus provide a function to invert it. This function is used to
  737. * for the "inside out" generator used by the extended generator.
  738. */
  739. /* Defined type-based concepts for the multiplication step. They're actually
  740. * all derived by truncating the 128-bit, which was computed to be a good
  741. * "universal" constant.
  742. */
  743. template <typename T>
  744. struct mcg_multiplier {
  745. // Not defined for an arbitrary type
  746. };
  747. template <typename T>
  748. struct mcg_unmultiplier {
  749. // Not defined for an arbitrary type
  750. };
  751. PCG_DEFINE_CONSTANT(uint8_t, mcg, multiplier, 217U)
  752. PCG_DEFINE_CONSTANT(uint8_t, mcg, unmultiplier, 105U)
  753. PCG_DEFINE_CONSTANT(uint16_t, mcg, multiplier, 62169U)
  754. PCG_DEFINE_CONSTANT(uint16_t, mcg, unmultiplier, 28009U)
  755. PCG_DEFINE_CONSTANT(uint32_t, mcg, multiplier, 277803737U)
  756. PCG_DEFINE_CONSTANT(uint32_t, mcg, unmultiplier, 2897767785U)
  757. PCG_DEFINE_CONSTANT(uint64_t, mcg, multiplier, 12605985483714917081ULL)
  758. PCG_DEFINE_CONSTANT(uint64_t, mcg, unmultiplier, 15009553638781119849ULL)
  759. PCG_DEFINE_CONSTANT(pcg128_t, mcg, multiplier,
  760. PCG_128BIT_CONSTANT(17766728186571221404ULL, 12605985483714917081ULL))
  761. PCG_DEFINE_CONSTANT(pcg128_t, mcg, unmultiplier,
  762. PCG_128BIT_CONSTANT(14422606686972528997ULL, 15009553638781119849ULL))
  763. template <typename xtype, typename itype>
  764. struct rxs_m_xs_mixin {
  765. static xtype output(itype internal)
  766. {
  767. constexpr bitcount_t xtypebits = bitcount_t(sizeof(xtype) * 8);
  768. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  769. constexpr bitcount_t opbits = xtypebits >= 128 ? 6
  770. : xtypebits >= 64 ? 5
  771. : xtypebits >= 32 ? 4
  772. : xtypebits >= 16 ? 3
  773. : 2;
  774. constexpr bitcount_t shift = bits - xtypebits;
  775. constexpr bitcount_t mask = (1 << opbits) - 1;
  776. bitcount_t rshift =
  777. opbits ? bitcount_t(internal >> (bits - opbits)) & mask : 0;
  778. internal ^= internal >> (opbits + rshift);
  779. internal *= mcg_multiplier<itype>::multiplier();
  780. xtype result = internal >> shift;
  781. result ^= result >> ((2U*xtypebits+2U)/3U);
  782. return result;
  783. }
  784. static itype unoutput(itype internal)
  785. {
  786. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  787. constexpr bitcount_t opbits = bits >= 128 ? 6
  788. : bits >= 64 ? 5
  789. : bits >= 32 ? 4
  790. : bits >= 16 ? 3
  791. : 2;
  792. constexpr bitcount_t mask = (1 << opbits) - 1;
  793. internal = unxorshift(internal, bits, (2U*bits+2U)/3U);
  794. internal *= mcg_unmultiplier<itype>::unmultiplier();
  795. bitcount_t rshift = opbits ? (internal >> (bits - opbits)) & mask : 0;
  796. internal = unxorshift(internal, bits, opbits + rshift);
  797. return internal;
  798. }
  799. };
  800. /*
  801. * RXS M -- random xorshift, mcg multiply
  802. */
  803. template <typename xtype, typename itype>
  804. struct rxs_m_mixin {
  805. static xtype output(itype internal)
  806. {
  807. constexpr bitcount_t xtypebits = bitcount_t(sizeof(xtype) * 8);
  808. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  809. constexpr bitcount_t opbits = xtypebits >= 128 ? 6
  810. : xtypebits >= 64 ? 5
  811. : xtypebits >= 32 ? 4
  812. : xtypebits >= 16 ? 3
  813. : 2;
  814. constexpr bitcount_t shift = bits - xtypebits;
  815. constexpr bitcount_t mask = (1 << opbits) - 1;
  816. bitcount_t rshift = opbits ? (internal >> (bits - opbits)) & mask : 0;
  817. internal ^= internal >> (opbits + rshift);
  818. internal *= mcg_multiplier<itype>::multiplier();
  819. xtype result = internal >> shift;
  820. return result;
  821. }
  822. };
  823. /*
  824. * XSL RR -- fixed xorshift (to low bits), random rotate
  825. *
  826. * Useful for 128-bit types that are split across two CPU registers.
  827. */
  828. template <typename xtype, typename itype>
  829. struct xsl_rr_mixin {
  830. static xtype output(itype internal)
  831. {
  832. constexpr bitcount_t xtypebits = bitcount_t(sizeof(xtype) * 8);
  833. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  834. constexpr bitcount_t sparebits = bits - xtypebits;
  835. constexpr bitcount_t wantedopbits = xtypebits >= 128 ? 7
  836. : xtypebits >= 64 ? 6
  837. : xtypebits >= 32 ? 5
  838. : xtypebits >= 16 ? 4
  839. : 3;
  840. constexpr bitcount_t opbits = sparebits >= wantedopbits ? wantedopbits
  841. : sparebits;
  842. constexpr bitcount_t amplifier = wantedopbits - opbits;
  843. constexpr bitcount_t mask = (1 << opbits) - 1;
  844. constexpr bitcount_t topspare = sparebits;
  845. constexpr bitcount_t bottomspare = sparebits - topspare;
  846. constexpr bitcount_t xshift = (topspare + xtypebits) / 2;
  847. bitcount_t rot =
  848. opbits ? bitcount_t(internal >> (bits - opbits)) & mask : 0;
  849. bitcount_t amprot = (rot << amplifier) & mask;
  850. internal ^= internal >> xshift;
  851. xtype result = xtype(internal >> bottomspare);
  852. result = rotr(result, amprot);
  853. return result;
  854. }
  855. };
  856. /*
  857. * XSL RR RR -- fixed xorshift (to low bits), random rotate (both parts)
  858. *
  859. * Useful for 128-bit types that are split across two CPU registers.
  860. * If you really want an invertable 128-bit RNG, I guess this is the one.
  861. */
  862. template <typename T> struct halfsize_trait {};
  863. template <> struct halfsize_trait<pcg128_t> { typedef uint64_t type; };
  864. template <> struct halfsize_trait<uint64_t> { typedef uint32_t type; };
  865. template <> struct halfsize_trait<uint32_t> { typedef uint16_t type; };
  866. template <> struct halfsize_trait<uint16_t> { typedef uint8_t type; };
  867. template <typename xtype, typename itype>
  868. struct xsl_rr_rr_mixin {
  869. typedef typename halfsize_trait<itype>::type htype;
  870. static itype output(itype internal)
  871. {
  872. constexpr bitcount_t htypebits = bitcount_t(sizeof(htype) * 8);
  873. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  874. constexpr bitcount_t sparebits = bits - htypebits;
  875. constexpr bitcount_t wantedopbits = htypebits >= 128 ? 7
  876. : htypebits >= 64 ? 6
  877. : htypebits >= 32 ? 5
  878. : htypebits >= 16 ? 4
  879. : 3;
  880. constexpr bitcount_t opbits = sparebits >= wantedopbits ? wantedopbits
  881. : sparebits;
  882. constexpr bitcount_t amplifier = wantedopbits - opbits;
  883. constexpr bitcount_t mask = (1 << opbits) - 1;
  884. constexpr bitcount_t topspare = sparebits;
  885. constexpr bitcount_t xshift = (topspare + htypebits) / 2;
  886. bitcount_t rot =
  887. opbits ? bitcount_t(internal >> (bits - opbits)) & mask : 0;
  888. bitcount_t amprot = (rot << amplifier) & mask;
  889. internal ^= internal >> xshift;
  890. htype lowbits = htype(internal);
  891. lowbits = rotr(lowbits, amprot);
  892. htype highbits = htype(internal >> topspare);
  893. bitcount_t rot2 = lowbits & mask;
  894. bitcount_t amprot2 = (rot2 << amplifier) & mask;
  895. highbits = rotr(highbits, amprot2);
  896. return (itype(highbits) << topspare) ^ itype(lowbits);
  897. }
  898. };
  899. /*
  900. * XSH -- fixed xorshift (to high bits)
  901. *
  902. * You shouldn't use this at 64-bits or less.
  903. */
  904. template <typename xtype, typename itype>
  905. struct xsh_mixin {
  906. static xtype output(itype internal)
  907. {
  908. constexpr bitcount_t xtypebits = bitcount_t(sizeof(xtype) * 8);
  909. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  910. constexpr bitcount_t sparebits = bits - xtypebits;
  911. constexpr bitcount_t topspare = 0;
  912. constexpr bitcount_t bottomspare = sparebits - topspare;
  913. constexpr bitcount_t xshift = (topspare + xtypebits) / 2;
  914. internal ^= internal >> xshift;
  915. xtype result = internal >> bottomspare;
  916. return result;
  917. }
  918. };
  919. /*
  920. * XSL -- fixed xorshift (to low bits)
  921. *
  922. * You shouldn't use this at 64-bits or less.
  923. */
  924. template <typename xtype, typename itype>
  925. struct xsl_mixin {
  926. inline xtype output(itype internal)
  927. {
  928. constexpr bitcount_t xtypebits = bitcount_t(sizeof(xtype) * 8);
  929. constexpr bitcount_t bits = bitcount_t(sizeof(itype) * 8);
  930. constexpr bitcount_t sparebits = bits - xtypebits;
  931. constexpr bitcount_t topspare = sparebits;
  932. constexpr bitcount_t bottomspare = sparebits - topspare;
  933. constexpr bitcount_t xshift = (topspare + xtypebits) / 2;
  934. internal ^= internal >> xshift;
  935. xtype result = internal >> bottomspare;
  936. return result;
  937. }
  938. };
  939. /* ---- End of Output Functions ---- */
  940. template <typename baseclass>
  941. struct inside_out : private baseclass {
  942. inside_out() = delete;
  943. typedef typename baseclass::result_type result_type;
  944. typedef typename baseclass::state_type state_type;
  945. static_assert(sizeof(result_type) == sizeof(state_type),
  946. "Require a RNG whose output function is a permutation");
  947. static bool external_step(result_type& randval, size_t i)
  948. {
  949. state_type state = baseclass::unoutput(randval);
  950. state = state * baseclass::multiplier() + baseclass::increment()
  951. + state_type(i*2);
  952. result_type result = baseclass::output(state);
  953. randval = result;
  954. state_type zero =
  955. baseclass::is_mcg ? state & state_type(3U) : state_type(0U);
  956. return result == zero;
  957. }
  958. static bool external_advance(result_type& randval, size_t i,
  959. result_type delta, bool forwards = true)
  960. {
  961. state_type state = baseclass::unoutput(randval);
  962. state_type mult = baseclass::multiplier();
  963. state_type inc = baseclass::increment() + state_type(i*2);
  964. state_type zero =
  965. baseclass::is_mcg ? state & state_type(3U) : state_type(0U);
  966. state_type dist_to_zero = baseclass::distance(state, zero, mult, inc);
  967. bool crosses_zero =
  968. forwards ? dist_to_zero <= delta
  969. : (-dist_to_zero) <= delta;
  970. if (!forwards)
  971. delta = -delta;
  972. state = baseclass::advance(state, delta, mult, inc);
  973. randval = baseclass::output(state);
  974. return crosses_zero;
  975. }
  976. };
  977. template <bitcount_t table_pow2, bitcount_t advance_pow2, typename baseclass, typename extvalclass, bool kdd = true>
  978. class extended : public baseclass {
  979. public:
  980. typedef typename baseclass::state_type state_type;
  981. typedef typename baseclass::result_type result_type;
  982. typedef inside_out<extvalclass> insideout;
  983. private:
  984. static constexpr bitcount_t rtypebits = sizeof(result_type)*8;
  985. static constexpr bitcount_t stypebits = sizeof(state_type)*8;
  986. static constexpr bitcount_t tick_limit_pow2 = 64U;
  987. static constexpr size_t table_size = 1UL << table_pow2;
  988. static constexpr size_t table_shift = stypebits - table_pow2;
  989. static constexpr state_type table_mask =
  990. (state_type(1U) << table_pow2) - state_type(1U);
  991. static constexpr bool may_tick =
  992. (advance_pow2 < stypebits) && (advance_pow2 < tick_limit_pow2);
  993. static constexpr size_t tick_shift = stypebits - advance_pow2;
  994. static constexpr state_type tick_mask =
  995. may_tick ? state_type(
  996. (uint64_t(1) << (advance_pow2*may_tick)) - 1)
  997. // ^-- stupidity to appease GCC warnings
  998. : ~state_type(0U);
  999. static constexpr bool may_tock = stypebits < tick_limit_pow2;
  1000. result_type data_[table_size];
  1001. PCG_NOINLINE void advance_table();
  1002. PCG_NOINLINE void advance_table(state_type delta, bool isForwards = true);
  1003. result_type& get_extended_value()
  1004. {
  1005. state_type state = this->state_;
  1006. if (kdd && baseclass::is_mcg) {
  1007. // The low order bits of an MCG are constant, so drop them.
  1008. state >>= 2;
  1009. }
  1010. size_t index = kdd ? state & table_mask
  1011. : state >> table_shift;
  1012. if (may_tick) {
  1013. bool tick = kdd ? (state & tick_mask) == state_type(0u)
  1014. : (state >> tick_shift) == state_type(0u);
  1015. if (tick)
  1016. advance_table();
  1017. }
  1018. if (may_tock) {
  1019. bool tock = state == state_type(0u);
  1020. if (tock)
  1021. advance_table();
  1022. }
  1023. return data_[index];
  1024. }
  1025. public:
  1026. static constexpr size_t period_pow2()
  1027. {
  1028. return baseclass::period_pow2() + table_size*extvalclass::period_pow2();
  1029. }
  1030. __attribute__((always_inline)) result_type operator()()
  1031. {
  1032. result_type rhs = get_extended_value();
  1033. result_type lhs = this->baseclass::operator()();
  1034. return lhs ^ rhs;
  1035. }
  1036. result_type operator()(result_type upper_bound)
  1037. {
  1038. return bounded_rand(*this, upper_bound);
  1039. }
  1040. void set(result_type wanted)
  1041. {
  1042. result_type& rhs = get_extended_value();
  1043. result_type lhs = this->baseclass::operator()();
  1044. rhs = lhs ^ wanted;
  1045. }
  1046. void advance(state_type distance, bool forwards = true);
  1047. void backstep(state_type distance)
  1048. {
  1049. advance(distance, false);
  1050. }
  1051. extended(const result_type* data)
  1052. : baseclass()
  1053. {
  1054. datainit(data);
  1055. }
  1056. extended(const result_type* data, state_type seed)
  1057. : baseclass(seed)
  1058. {
  1059. datainit(data);
  1060. }
  1061. // This function may or may not exist. It thus has to be a template
  1062. // to use SFINAE; users don't have to worry about its template-ness.
  1063. template <typename bc = baseclass>
  1064. extended(const result_type* data, state_type seed,
  1065. typename bc::stream_state stream_seed)
  1066. : baseclass(seed, stream_seed)
  1067. {
  1068. datainit(data);
  1069. }
  1070. extended()
  1071. : baseclass()
  1072. {
  1073. selfinit();
  1074. }
  1075. extended(state_type seed)
  1076. : baseclass(seed)
  1077. {
  1078. selfinit();
  1079. }
  1080. // This function may or may not exist. It thus has to be a template
  1081. // to use SFINAE; users don't have to worry about its template-ness.
  1082. template <typename bc = baseclass>
  1083. extended(state_type seed, typename bc::stream_state stream_seed)
  1084. : baseclass(seed, stream_seed)
  1085. {
  1086. selfinit();
  1087. }
  1088. private:
  1089. void selfinit();
  1090. void datainit(const result_type* data);
  1091. public:
  1092. template<typename SeedSeq, typename = typename std::enable_if<
  1093. !std::is_convertible<SeedSeq, result_type>::value
  1094. && !std::is_convertible<SeedSeq, extended>::value>::type>
  1095. extended(SeedSeq&& seedSeq)
  1096. : baseclass(seedSeq)
  1097. {
  1098. generate_to<table_size>(seedSeq, data_);
  1099. }
  1100. template<typename... Args>
  1101. void seed(Args&&... args)
  1102. {
  1103. new (this) extended(std::forward<Args>(args)...);
  1104. }
  1105. template <bitcount_t table_pow2_, bitcount_t advance_pow2_,
  1106. typename baseclass_, typename extvalclass_, bool kdd_>
  1107. friend bool operator==(const extended<table_pow2_, advance_pow2_,
  1108. baseclass_, extvalclass_, kdd_>&,
  1109. const extended<table_pow2_, advance_pow2_,
  1110. baseclass_, extvalclass_, kdd_>&);
  1111. template <typename CharT, typename Traits,
  1112. bitcount_t table_pow2_, bitcount_t advance_pow2_,
  1113. typename baseclass_, typename extvalclass_, bool kdd_>
  1114. friend std::basic_ostream<CharT,Traits>&
  1115. operator<<(std::basic_ostream<CharT,Traits>& out,
  1116. const extended<table_pow2_, advance_pow2_,
  1117. baseclass_, extvalclass_, kdd_>&);
  1118. template <typename CharT, typename Traits,
  1119. bitcount_t table_pow2_, bitcount_t advance_pow2_,
  1120. typename baseclass_, typename extvalclass_, bool kdd_>
  1121. friend std::basic_istream<CharT,Traits>&
  1122. operator>>(std::basic_istream<CharT,Traits>& in,
  1123. extended<table_pow2_, advance_pow2_,
  1124. baseclass_, extvalclass_, kdd_>&);
  1125. };
  1126. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1127. typename baseclass, typename extvalclass, bool kdd>
  1128. void extended<table_pow2,advance_pow2,baseclass,extvalclass,kdd>::datainit(
  1129. const result_type* data)
  1130. {
  1131. for (size_t i = 0; i < table_size; ++i)
  1132. data_[i] = data[i];
  1133. }
  1134. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1135. typename baseclass, typename extvalclass, bool kdd>
  1136. void extended<table_pow2,advance_pow2,baseclass,extvalclass,kdd>::selfinit()
  1137. {
  1138. // We need to fill the extended table with something, and we have
  1139. // very little provided data, so we use the base generator to
  1140. // produce values. Although not ideal (use a seed sequence, folks!),
  1141. // unexpected correlations are mitigated by
  1142. // - using XOR differences rather than the number directly
  1143. // - the way the table is accessed, its values *won't* be accessed
  1144. // in the same order the were written.
  1145. // - any strange correlations would only be apparent if we
  1146. // were to backstep the generator so that the base generator
  1147. // was generating the same values again
  1148. result_type xdiff = baseclass::operator()() - baseclass::operator()();
  1149. for (size_t i = 0; i < table_size; ++i) {
  1150. data_[i] = baseclass::operator()() ^ xdiff;
  1151. }
  1152. }
  1153. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1154. typename baseclass, typename extvalclass, bool kdd>
  1155. bool operator==(const extended<table_pow2, advance_pow2,
  1156. baseclass, extvalclass, kdd>& lhs,
  1157. const extended<table_pow2, advance_pow2,
  1158. baseclass, extvalclass, kdd>& rhs)
  1159. {
  1160. auto& base_lhs = static_cast<const baseclass&>(lhs);
  1161. auto& base_rhs = static_cast<const baseclass&>(rhs);
  1162. return base_lhs == base_rhs
  1163. && !memcmp((void*) lhs.data_, (void*) rhs.data_, sizeof(lhs.data_));
  1164. }
  1165. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1166. typename baseclass, typename extvalclass, bool kdd>
  1167. inline bool operator!=(const extended<table_pow2, advance_pow2,
  1168. baseclass, extvalclass, kdd>& lhs,
  1169. const extended<table_pow2, advance_pow2,
  1170. baseclass, extvalclass, kdd>& rhs)
  1171. {
  1172. return lhs != rhs;
  1173. }
  1174. template <typename CharT, typename Traits,
  1175. bitcount_t table_pow2, bitcount_t advance_pow2,
  1176. typename baseclass, typename extvalclass, bool kdd>
  1177. std::basic_ostream<CharT,Traits>&
  1178. operator<<(std::basic_ostream<CharT,Traits>& out,
  1179. const extended<table_pow2, advance_pow2,
  1180. baseclass, extvalclass, kdd>& rng)
  1181. {
  1182. auto orig_flags = out.flags(std::ios_base::dec | std::ios_base::left);
  1183. auto space = out.widen(' ');
  1184. auto orig_fill = out.fill();
  1185. out << rng.multiplier() << space
  1186. << rng.increment() << space
  1187. << rng.state_;
  1188. for (const auto& datum : rng.data_)
  1189. out << space << datum;
  1190. out.flags(orig_flags);
  1191. out.fill(orig_fill);
  1192. return out;
  1193. }
  1194. template <typename CharT, typename Traits,
  1195. bitcount_t table_pow2, bitcount_t advance_pow2,
  1196. typename baseclass, typename extvalclass, bool kdd>
  1197. std::basic_istream<CharT,Traits>&
  1198. operator>>(std::basic_istream<CharT,Traits>& in,
  1199. extended<table_pow2, advance_pow2,
  1200. baseclass, extvalclass, kdd>& rng)
  1201. {
  1202. extended<table_pow2, advance_pow2, baseclass, extvalclass> new_rng;
  1203. auto& base_rng = static_cast<baseclass&>(new_rng);
  1204. in >> base_rng;
  1205. if (in.fail())
  1206. return in;
  1207. auto orig_flags = in.flags(std::ios_base::dec | std::ios_base::skipws);
  1208. for (auto& datum : new_rng.data_) {
  1209. in >> datum;
  1210. if (in.fail())
  1211. goto bail;
  1212. }
  1213. rng = new_rng;
  1214. bail:
  1215. in.flags(orig_flags);
  1216. return in;
  1217. }
  1218. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1219. typename baseclass, typename extvalclass, bool kdd>
  1220. void
  1221. extended<table_pow2,advance_pow2,baseclass,extvalclass,kdd>::advance_table()
  1222. {
  1223. bool carry = false;
  1224. for (size_t i = 0; i < table_size; ++i) {
  1225. if (carry) {
  1226. carry = insideout::external_step(data_[i],i+1);
  1227. }
  1228. bool carry2 = insideout::external_step(data_[i],i+1);
  1229. carry = carry || carry2;
  1230. }
  1231. }
  1232. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1233. typename baseclass, typename extvalclass, bool kdd>
  1234. void
  1235. extended<table_pow2,advance_pow2,baseclass,extvalclass,kdd>::advance_table(
  1236. state_type delta, bool isForwards)
  1237. {
  1238. typedef typename baseclass::state_type base_state_t;
  1239. typedef typename extvalclass::state_type ext_state_t;
  1240. constexpr bitcount_t basebits = sizeof(base_state_t)*8;
  1241. constexpr bitcount_t extbits = sizeof(ext_state_t)*8;
  1242. static_assert(basebits <= extbits || advance_pow2 > 0,
  1243. "Current implementation might overflow its carry");
  1244. base_state_t carry = 0;
  1245. for (size_t i = 0; i < table_size; ++i) {
  1246. base_state_t total_delta = carry + delta;
  1247. ext_state_t trunc_delta = ext_state_t(total_delta);
  1248. if (basebits > extbits) {
  1249. carry = total_delta >> extbits;
  1250. } else {
  1251. carry = 0;
  1252. }
  1253. carry +=
  1254. insideout::external_advance(data_[i],i+1, trunc_delta, isForwards);
  1255. }
  1256. }
  1257. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1258. typename baseclass, typename extvalclass, bool kdd>
  1259. void extended<table_pow2,advance_pow2,baseclass,extvalclass,kdd>::advance(
  1260. state_type distance, bool forwards)
  1261. {
  1262. static_assert(kdd,
  1263. "Efficient advance is too hard for non-kdd extension. "
  1264. "For a weak advance, cast to base class");
  1265. state_type zero =
  1266. baseclass::is_mcg ? this->state_ & state_type(3U) : state_type(0U);
  1267. if (may_tick) {
  1268. state_type ticks = distance >> (advance_pow2*may_tick);
  1269. // ^-- stupidity to appease GCC
  1270. // warnings
  1271. state_type adv_mask =
  1272. baseclass::is_mcg ? tick_mask << 2 : tick_mask;
  1273. state_type next_advance_distance = this->distance(zero, adv_mask);
  1274. if (!forwards)
  1275. next_advance_distance = (-next_advance_distance) & tick_mask;
  1276. if (next_advance_distance < (distance & tick_mask)) {
  1277. ++ticks;
  1278. }
  1279. if (ticks)
  1280. advance_table(ticks, forwards);
  1281. }
  1282. if (forwards) {
  1283. if (may_tock && this->distance(zero) <= distance)
  1284. advance_table();
  1285. baseclass::advance(distance);
  1286. } else {
  1287. if (may_tock && -(this->distance(zero)) <= distance)
  1288. advance_table(state_type(1U), false);
  1289. baseclass::advance(-distance);
  1290. }
  1291. }
  1292. } // namespace pcg_detail
  1293. namespace pcg_engines {
  1294. using namespace pcg_detail;
  1295. /* Predefined types for XSH RS */
  1296. typedef oneseq_base<uint8_t, uint16_t, xsh_rs_mixin> oneseq_xsh_rs_16_8;
  1297. typedef oneseq_base<uint16_t, uint32_t, xsh_rs_mixin> oneseq_xsh_rs_32_16;
  1298. typedef oneseq_base<uint32_t, uint64_t, xsh_rs_mixin> oneseq_xsh_rs_64_32;
  1299. typedef oneseq_base<uint64_t, pcg128_t, xsh_rs_mixin> oneseq_xsh_rs_128_64;
  1300. typedef unique_base<uint8_t, uint16_t, xsh_rs_mixin> unique_xsh_rs_16_8;
  1301. typedef unique_base<uint16_t, uint32_t, xsh_rs_mixin> unique_xsh_rs_32_16;
  1302. typedef unique_base<uint32_t, uint64_t, xsh_rs_mixin> unique_xsh_rs_64_32;
  1303. typedef unique_base<uint64_t, pcg128_t, xsh_rs_mixin> unique_xsh_rs_128_64;
  1304. typedef setseq_base<uint8_t, uint16_t, xsh_rs_mixin> setseq_xsh_rs_16_8;
  1305. typedef setseq_base<uint16_t, uint32_t, xsh_rs_mixin> setseq_xsh_rs_32_16;
  1306. typedef setseq_base<uint32_t, uint64_t, xsh_rs_mixin> setseq_xsh_rs_64_32;
  1307. typedef setseq_base<uint64_t, pcg128_t, xsh_rs_mixin> setseq_xsh_rs_128_64;
  1308. typedef mcg_base<uint8_t, uint16_t, xsh_rs_mixin> mcg_xsh_rs_16_8;
  1309. typedef mcg_base<uint16_t, uint32_t, xsh_rs_mixin> mcg_xsh_rs_32_16;
  1310. typedef mcg_base<uint32_t, uint64_t, xsh_rs_mixin> mcg_xsh_rs_64_32;
  1311. typedef mcg_base<uint64_t, pcg128_t, xsh_rs_mixin> mcg_xsh_rs_128_64;
  1312. /* Predefined types for XSH RR */
  1313. typedef oneseq_base<uint8_t, uint16_t, xsh_rr_mixin> oneseq_xsh_rr_16_8;
  1314. typedef oneseq_base<uint16_t, uint32_t, xsh_rr_mixin> oneseq_xsh_rr_32_16;
  1315. typedef oneseq_base<uint32_t, uint64_t, xsh_rr_mixin> oneseq_xsh_rr_64_32;
  1316. typedef oneseq_base<uint64_t, pcg128_t, xsh_rr_mixin> oneseq_xsh_rr_128_64;
  1317. typedef unique_base<uint8_t, uint16_t, xsh_rr_mixin> unique_xsh_rr_16_8;
  1318. typedef unique_base<uint16_t, uint32_t, xsh_rr_mixin> unique_xsh_rr_32_16;
  1319. typedef unique_base<uint32_t, uint64_t, xsh_rr_mixin> unique_xsh_rr_64_32;
  1320. typedef unique_base<uint64_t, pcg128_t, xsh_rr_mixin> unique_xsh_rr_128_64;
  1321. typedef setseq_base<uint8_t, uint16_t, xsh_rr_mixin> setseq_xsh_rr_16_8;
  1322. typedef setseq_base<uint16_t, uint32_t, xsh_rr_mixin> setseq_xsh_rr_32_16;
  1323. typedef setseq_base<uint32_t, uint64_t, xsh_rr_mixin> setseq_xsh_rr_64_32;
  1324. typedef setseq_base<uint64_t, pcg128_t, xsh_rr_mixin> setseq_xsh_rr_128_64;
  1325. typedef mcg_base<uint8_t, uint16_t, xsh_rr_mixin> mcg_xsh_rr_16_8;
  1326. typedef mcg_base<uint16_t, uint32_t, xsh_rr_mixin> mcg_xsh_rr_32_16;
  1327. typedef mcg_base<uint32_t, uint64_t, xsh_rr_mixin> mcg_xsh_rr_64_32;
  1328. typedef mcg_base<uint64_t, pcg128_t, xsh_rr_mixin> mcg_xsh_rr_128_64;
  1329. /* Predefined types for RXS M XS */
  1330. typedef oneseq_base<uint8_t, uint8_t, rxs_m_xs_mixin> oneseq_rxs_m_xs_8_8;
  1331. typedef oneseq_base<uint16_t, uint16_t, rxs_m_xs_mixin> oneseq_rxs_m_xs_16_16;
  1332. typedef oneseq_base<uint32_t, uint32_t, rxs_m_xs_mixin> oneseq_rxs_m_xs_32_32;
  1333. typedef oneseq_base<uint64_t, uint64_t, rxs_m_xs_mixin> oneseq_rxs_m_xs_64_64;
  1334. typedef oneseq_base<pcg128_t, pcg128_t, rxs_m_xs_mixin> oneseq_rxs_m_xs_128_128;
  1335. typedef unique_base<uint8_t, uint8_t, rxs_m_xs_mixin> unique_rxs_m_xs_8_8;
  1336. typedef unique_base<uint16_t, uint16_t, rxs_m_xs_mixin> unique_rxs_m_xs_16_16;
  1337. typedef unique_base<uint32_t, uint32_t, rxs_m_xs_mixin> unique_rxs_m_xs_32_32;
  1338. typedef unique_base<uint64_t, uint64_t, rxs_m_xs_mixin> unique_rxs_m_xs_64_64;
  1339. typedef unique_base<pcg128_t, pcg128_t, rxs_m_xs_mixin> unique_rxs_m_xs_128_128;
  1340. typedef setseq_base<uint8_t, uint8_t, rxs_m_xs_mixin> setseq_rxs_m_xs_8_8;
  1341. typedef setseq_base<uint16_t, uint16_t, rxs_m_xs_mixin> setseq_rxs_m_xs_16_16;
  1342. typedef setseq_base<uint32_t, uint32_t, rxs_m_xs_mixin> setseq_rxs_m_xs_32_32;
  1343. typedef setseq_base<uint64_t, uint64_t, rxs_m_xs_mixin> setseq_rxs_m_xs_64_64;
  1344. typedef setseq_base<pcg128_t, pcg128_t, rxs_m_xs_mixin> setseq_rxs_m_xs_128_128;
  1345. // MCG versions don't make sense here, so aren't defined.
  1346. /* Predefined types for XSL RR (only defined for "large" types) */
  1347. typedef oneseq_base<uint32_t, uint64_t, xsl_rr_mixin> oneseq_xsl_rr_64_32;
  1348. typedef oneseq_base<uint64_t, pcg128_t, xsl_rr_mixin> oneseq_xsl_rr_128_64;
  1349. typedef unique_base<uint32_t, uint64_t, xsl_rr_mixin> unique_xsl_rr_64_32;
  1350. typedef unique_base<uint64_t, pcg128_t, xsl_rr_mixin> unique_xsl_rr_128_64;
  1351. typedef setseq_base<uint32_t, uint64_t, xsl_rr_mixin> setseq_xsl_rr_64_32;
  1352. typedef setseq_base<uint64_t, pcg128_t, xsl_rr_mixin> setseq_xsl_rr_128_64;
  1353. typedef mcg_base<uint32_t, uint64_t, xsl_rr_mixin> mcg_xsl_rr_64_32;
  1354. typedef mcg_base<uint64_t, pcg128_t, xsl_rr_mixin> mcg_xsl_rr_128_64;
  1355. /* Predefined types for XSL RR RR (only defined for "large" types) */
  1356. typedef oneseq_base<uint64_t, uint64_t, xsl_rr_rr_mixin>
  1357. oneseq_xsl_rr_rr_64_64;
  1358. typedef oneseq_base<pcg128_t, pcg128_t, xsl_rr_rr_mixin>
  1359. oneseq_xsl_rr_rr_128_128;
  1360. typedef unique_base<uint64_t, uint64_t, xsl_rr_rr_mixin>
  1361. unique_xsl_rr_rr_64_64;
  1362. typedef unique_base<pcg128_t, pcg128_t, xsl_rr_rr_mixin>
  1363. unique_xsl_rr_rr_128_128;
  1364. typedef setseq_base<uint64_t, uint64_t, xsl_rr_rr_mixin>
  1365. setseq_xsl_rr_rr_64_64;
  1366. typedef setseq_base<pcg128_t, pcg128_t, xsl_rr_rr_mixin>
  1367. setseq_xsl_rr_rr_128_128;
  1368. // MCG versions don't make sense here, so aren't defined.
  1369. /* Extended generators */
  1370. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1371. typename BaseRNG, bool kdd = true>
  1372. using ext_std8 = extended<table_pow2, advance_pow2, BaseRNG,
  1373. oneseq_rxs_m_xs_8_8, kdd>;
  1374. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1375. typename BaseRNG, bool kdd = true>
  1376. using ext_std16 = extended<table_pow2, advance_pow2, BaseRNG,
  1377. oneseq_rxs_m_xs_16_16, kdd>;
  1378. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1379. typename BaseRNG, bool kdd = true>
  1380. using ext_std32 = extended<table_pow2, advance_pow2, BaseRNG,
  1381. oneseq_rxs_m_xs_32_32, kdd>;
  1382. template <bitcount_t table_pow2, bitcount_t advance_pow2,
  1383. typename BaseRNG, bool kdd = true>
  1384. using ext_std64 = extended<table_pow2, advance_pow2, BaseRNG,
  1385. oneseq_rxs_m_xs_64_64, kdd>;
  1386. template <bitcount_t table_pow2, bitcount_t advance_pow2, bool kdd = true>
  1387. using ext_oneseq_rxs_m_xs_32_32 =
  1388. ext_std32<table_pow2, advance_pow2, oneseq_rxs_m_xs_32_32, kdd>;
  1389. template <bitcount_t table_pow2, bitcount_t advance_pow2, bool kdd = true>
  1390. using ext_mcg_xsh_rs_64_32 =
  1391. ext_std32<table_pow2, advance_pow2, mcg_xsh_rs_64_32, kdd>;
  1392. template <bitcount_t table_pow2, bitcount_t advance_pow2, bool kdd = true>
  1393. using ext_oneseq_xsh_rs_64_32 =
  1394. ext_std32<table_pow2, advance_pow2, oneseq_xsh_rs_64_32, kdd>;
  1395. template <bitcount_t table_pow2, bitcount_t advance_pow2, bool kdd = true>
  1396. using ext_setseq_xsh_rr_64_32 =
  1397. ext_std32<table_pow2, advance_pow2, setseq_xsh_rr_64_32, kdd>;
  1398. template <bitcount_t table_pow2, bitcount_t advance_pow2, bool kdd = true>
  1399. using ext_mcg_xsl_rr_128_64 =
  1400. ext_std64<table_pow2, advance_pow2, mcg_xsl_rr_128_64, kdd>;
  1401. template <bitcount_t table_pow2, bitcount_t advance_pow2, bool kdd = true>
  1402. using ext_oneseq_xsl_rr_128_64 =
  1403. ext_std64<table_pow2, advance_pow2, oneseq_xsl_rr_128_64, kdd>;
  1404. template <bitcount_t table_pow2, bitcount_t advance_pow2, bool kdd = true>
  1405. using ext_setseq_xsl_rr_128_64 =
  1406. ext_std64<table_pow2, advance_pow2, setseq_xsl_rr_128_64, kdd>;
  1407. } // namespace pcg_engines
  1408. typedef pcg_engines::setseq_xsh_rr_64_32 pcg32;
  1409. typedef pcg_engines::oneseq_xsh_rr_64_32 pcg32_oneseq;
  1410. typedef pcg_engines::unique_xsh_rr_64_32 pcg32_unique;
  1411. typedef pcg_engines::mcg_xsh_rs_64_32 pcg32_fast;
  1412. typedef pcg_engines::setseq_xsl_rr_128_64 pcg64;
  1413. typedef pcg_engines::oneseq_xsl_rr_128_64 pcg64_oneseq;
  1414. typedef pcg_engines::unique_xsl_rr_128_64 pcg64_unique;
  1415. typedef pcg_engines::mcg_xsl_rr_128_64 pcg64_fast;
  1416. typedef pcg_engines::setseq_rxs_m_xs_8_8 pcg8_once_insecure;
  1417. typedef pcg_engines::setseq_rxs_m_xs_16_16 pcg16_once_insecure;
  1418. typedef pcg_engines::setseq_rxs_m_xs_32_32 pcg32_once_insecure;
  1419. typedef pcg_engines::setseq_rxs_m_xs_64_64 pcg64_once_insecure;
  1420. typedef pcg_engines::setseq_xsl_rr_rr_128_128 pcg128_once_insecure;
  1421. typedef pcg_engines::oneseq_rxs_m_xs_8_8 pcg8_oneseq_once_insecure;
  1422. typedef pcg_engines::oneseq_rxs_m_xs_16_16 pcg16_oneseq_once_insecure;
  1423. typedef pcg_engines::oneseq_rxs_m_xs_32_32 pcg32_oneseq_once_insecure;
  1424. typedef pcg_engines::oneseq_rxs_m_xs_64_64 pcg64_oneseq_once_insecure;
  1425. typedef pcg_engines::oneseq_xsl_rr_rr_128_128 pcg128_oneseq_once_insecure;
  1426. // These two extended RNGs provide two-dimensionally equidistributed
  1427. // 32-bit generators. pcg32_k2_fast occupies the same space as pcg64,
  1428. // and can be called twice to generate 64 bits, but does not required
  1429. // 128-bit math; on 32-bit systems, it's faster than pcg64 as well.
  1430. typedef pcg_engines::ext_setseq_xsh_rr_64_32<6,16,true> pcg32_k2;
  1431. typedef pcg_engines::ext_oneseq_xsh_rs_64_32<6,32,true> pcg32_k2_fast;
  1432. // These eight extended RNGs have about as much state as arc4random
  1433. //
  1434. // - the k variants are k-dimensionally equidistributed
  1435. // - the c variants offer better crypographic security
  1436. //
  1437. // (just how good the cryptographic security is is an open question)
  1438. typedef pcg_engines::ext_setseq_xsh_rr_64_32<6,16,true> pcg32_k64;
  1439. typedef pcg_engines::ext_mcg_xsh_rs_64_32<6,32,true> pcg32_k64_oneseq;
  1440. typedef pcg_engines::ext_oneseq_xsh_rs_64_32<6,32,true> pcg32_k64_fast;
  1441. typedef pcg_engines::ext_setseq_xsh_rr_64_32<6,16,false> pcg32_c64;
  1442. typedef pcg_engines::ext_oneseq_xsh_rs_64_32<6,32,false> pcg32_c64_oneseq;
  1443. typedef pcg_engines::ext_mcg_xsh_rs_64_32<6,32,false> pcg32_c64_fast;
  1444. typedef pcg_engines::ext_setseq_xsl_rr_128_64<5,16,true> pcg64_k32;
  1445. typedef pcg_engines::ext_oneseq_xsl_rr_128_64<5,128,true> pcg64_k32_oneseq;
  1446. typedef pcg_engines::ext_mcg_xsl_rr_128_64<5,128,true> pcg64_k32_fast;
  1447. typedef pcg_engines::ext_setseq_xsl_rr_128_64<5,16,false> pcg64_c32;
  1448. typedef pcg_engines::ext_oneseq_xsl_rr_128_64<5,128,false> pcg64_c32_oneseq;
  1449. typedef pcg_engines::ext_mcg_xsl_rr_128_64<5,128,false> pcg64_c32_fast;
  1450. // These eight extended RNGs have more state than the Mersenne twister
  1451. //
  1452. // - the k variants are k-dimensionally equidistributed
  1453. // - the c variants offer better crypographic security
  1454. //
  1455. // (just how good the cryptographic security is is an open question)
  1456. typedef pcg_engines::ext_setseq_xsh_rr_64_32<10,16,true> pcg32_k1024;
  1457. typedef pcg_engines::ext_oneseq_xsh_rs_64_32<10,32,true> pcg32_k1024_fast;
  1458. typedef pcg_engines::ext_setseq_xsh_rr_64_32<10,16,false> pcg32_c1024;
  1459. typedef pcg_engines::ext_oneseq_xsh_rs_64_32<10,32,false> pcg32_c1024_fast;
  1460. typedef pcg_engines::ext_setseq_xsl_rr_128_64<10,16,true> pcg64_k1024;
  1461. typedef pcg_engines::ext_oneseq_xsl_rr_128_64<10,128,true> pcg64_k1024_fast;
  1462. typedef pcg_engines::ext_setseq_xsl_rr_128_64<10,16,false> pcg64_c1024;
  1463. typedef pcg_engines::ext_oneseq_xsl_rr_128_64<10,128,false> pcg64_c1024_fast;
  1464. // These generators have an insanely huge period (2^524352), and is suitable
  1465. // for silly party tricks, such as dumping out 64 KB ZIP files at an arbitrary
  1466. // point in the future. [Actually, over the full period of the generator, it
  1467. // will produce every 64 KB ZIP file 2^64 times!]
  1468. typedef pcg_engines::ext_setseq_xsh_rr_64_32<14,16,true> pcg32_k16384;
  1469. typedef pcg_engines::ext_oneseq_xsh_rs_64_32<14,32,true> pcg32_k16384_fast;
  1470. #endif // PCG_RAND_HPP_INCLUDED