linear_congruential_engine.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H
  9. #define _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H
  10. #include <__config>
  11. #include <__random/is_seed_sequence.h>
  12. #include <__type_traits/enable_if.h>
  13. #include <__type_traits/integral_constant.h>
  14. #include <__type_traits/is_unsigned.h>
  15. #include <cstdint>
  16. #include <iosfwd>
  17. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  18. # pragma GCC system_header
  19. #endif
  20. _LIBCPP_PUSH_MACROS
  21. #include <__undef_macros>
  22. _LIBCPP_BEGIN_NAMESPACE_STD
  23. template <unsigned long long __a,
  24. unsigned long long __c,
  25. unsigned long long __m,
  26. unsigned long long _Mp,
  27. bool _MightOverflow = (__a != 0 && __m != 0 && __m - 1 > (_Mp - __c) / __a),
  28. bool _OverflowOK = ((__m & (__m - 1)) == 0ull), // m = 2^n
  29. bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q
  30. struct __lce_alg_picker {
  31. static_assert(!_MightOverflow || _OverflowOK || _SchrageOK,
  32. "The current values of a, c, and m cannot generate a number "
  33. "within bounds of linear_congruential_engine.");
  34. static _LIBCPP_CONSTEXPR const bool __use_schrage = _MightOverflow && !_OverflowOK && _SchrageOK;
  35. };
  36. template <unsigned long long __a,
  37. unsigned long long __c,
  38. unsigned long long __m,
  39. unsigned long long _Mp,
  40. bool _UseSchrage = __lce_alg_picker<__a, __c, __m, _Mp>::__use_schrage>
  41. struct __lce_ta;
  42. // 64
  43. template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
  44. struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true> {
  45. typedef unsigned long long result_type;
  46. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) {
  47. // Schrage's algorithm
  48. const result_type __q = __m / __a;
  49. const result_type __r = __m % __a;
  50. const result_type __t0 = __a * (__x % __q);
  51. const result_type __t1 = __r * (__x / __q);
  52. __x = __t0 + (__t0 < __t1) * __m - __t1;
  53. __x += __c - (__x >= __m - __c) * __m;
  54. return __x;
  55. }
  56. };
  57. template <unsigned long long __a, unsigned long long __m>
  58. struct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true> {
  59. typedef unsigned long long result_type;
  60. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) {
  61. // Schrage's algorithm
  62. const result_type __q = __m / __a;
  63. const result_type __r = __m % __a;
  64. const result_type __t0 = __a * (__x % __q);
  65. const result_type __t1 = __r * (__x / __q);
  66. __x = __t0 + (__t0 < __t1) * __m - __t1;
  67. return __x;
  68. }
  69. };
  70. template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
  71. struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), false> {
  72. typedef unsigned long long result_type;
  73. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { return (__a * __x + __c) % __m; }
  74. };
  75. template <unsigned long long __a, unsigned long long __c>
  76. struct __lce_ta<__a, __c, 0, (unsigned long long)(~0), false> {
  77. typedef unsigned long long result_type;
  78. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { return __a * __x + __c; }
  79. };
  80. // 32
  81. template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
  82. struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true> {
  83. typedef unsigned result_type;
  84. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) {
  85. const result_type __a = static_cast<result_type>(_Ap);
  86. const result_type __c = static_cast<result_type>(_Cp);
  87. const result_type __m = static_cast<result_type>(_Mp);
  88. // Schrage's algorithm
  89. const result_type __q = __m / __a;
  90. const result_type __r = __m % __a;
  91. const result_type __t0 = __a * (__x % __q);
  92. const result_type __t1 = __r * (__x / __q);
  93. __x = __t0 + (__t0 < __t1) * __m - __t1;
  94. __x += __c - (__x >= __m - __c) * __m;
  95. return __x;
  96. }
  97. };
  98. template <unsigned long long _Ap, unsigned long long _Mp>
  99. struct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true> {
  100. typedef unsigned result_type;
  101. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) {
  102. const result_type __a = static_cast<result_type>(_Ap);
  103. const result_type __m = static_cast<result_type>(_Mp);
  104. // Schrage's algorithm
  105. const result_type __q = __m / __a;
  106. const result_type __r = __m % __a;
  107. const result_type __t0 = __a * (__x % __q);
  108. const result_type __t1 = __r * (__x / __q);
  109. __x = __t0 + (__t0 < __t1) * __m - __t1;
  110. return __x;
  111. }
  112. };
  113. template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
  114. struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false> {
  115. typedef unsigned result_type;
  116. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) {
  117. const result_type __a = static_cast<result_type>(_Ap);
  118. const result_type __c = static_cast<result_type>(_Cp);
  119. const result_type __m = static_cast<result_type>(_Mp);
  120. return (__a * __x + __c) % __m;
  121. }
  122. };
  123. template <unsigned long long _Ap, unsigned long long _Cp>
  124. struct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false> {
  125. typedef unsigned result_type;
  126. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) {
  127. const result_type __a = static_cast<result_type>(_Ap);
  128. const result_type __c = static_cast<result_type>(_Cp);
  129. return __a * __x + __c;
  130. }
  131. };
  132. // 16
  133. template <unsigned long long __a, unsigned long long __c, unsigned long long __m, bool __b>
  134. struct __lce_ta<__a, __c, __m, (unsigned short)(~0), __b> {
  135. typedef unsigned short result_type;
  136. _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) {
  137. return static_cast<result_type>(__lce_ta<__a, __c, __m, unsigned(~0)>::next(__x));
  138. }
  139. };
  140. template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  141. class _LIBCPP_TEMPLATE_VIS linear_congruential_engine;
  142. template <class _CharT, class _Traits, class _Up, _Up _Ap, _Up _Cp, _Up _Np>
  143. _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  144. operator<<(basic_ostream<_CharT, _Traits>& __os, const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);
  145. template <class _CharT, class _Traits, class _Up, _Up _Ap, _Up _Cp, _Up _Np>
  146. _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  147. operator>>(basic_istream<_CharT, _Traits>& __is, linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
  148. template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  149. class _LIBCPP_TEMPLATE_VIS linear_congruential_engine {
  150. public:
  151. // types
  152. typedef _UIntType result_type;
  153. private:
  154. result_type __x_;
  155. static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(~0);
  156. static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters");
  157. static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters");
  158. static_assert(is_unsigned<_UIntType>::value, "_UIntType must be unsigned type");
  159. public:
  160. static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u : 0u;
  161. static _LIBCPP_CONSTEXPR const result_type _Max = __m - _UIntType(1u);
  162. static_assert(_Min < _Max, "linear_congruential_engine invalid parameters");
  163. // engine characteristics
  164. static _LIBCPP_CONSTEXPR const result_type multiplier = __a;
  165. static _LIBCPP_CONSTEXPR const result_type increment = __c;
  166. static _LIBCPP_CONSTEXPR const result_type modulus = __m;
  167. _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
  168. _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
  169. static _LIBCPP_CONSTEXPR const result_type default_seed = 1u;
  170. // constructors and seeding functions
  171. #ifndef _LIBCPP_CXX03_LANG
  172. _LIBCPP_HIDE_FROM_ABI linear_congruential_engine() : linear_congruential_engine(default_seed) {}
  173. _LIBCPP_HIDE_FROM_ABI explicit linear_congruential_engine(result_type __s) { seed(__s); }
  174. #else
  175. _LIBCPP_HIDE_FROM_ABI explicit linear_congruential_engine(result_type __s = default_seed) { seed(__s); }
  176. #endif
  177. template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, linear_congruential_engine>::value, int> = 0>
  178. _LIBCPP_HIDE_FROM_ABI explicit linear_congruential_engine(_Sseq& __q) {
  179. seed(__q);
  180. }
  181. _LIBCPP_HIDE_FROM_ABI void seed(result_type __s = default_seed) {
  182. seed(integral_constant<bool, __m == 0>(), integral_constant<bool, __c == 0>(), __s);
  183. }
  184. template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, linear_congruential_engine>::value, int> = 0>
  185. _LIBCPP_HIDE_FROM_ABI void seed(_Sseq& __q) {
  186. __seed(
  187. __q,
  188. integral_constant<unsigned,
  189. 1 + (__m == 0 ? (sizeof(result_type) * __CHAR_BIT__ - 1) / 32 : (__m > 0x100000000ull))>());
  190. }
  191. // generating functions
  192. _LIBCPP_HIDE_FROM_ABI result_type operator()() {
  193. return __x_ = static_cast<result_type>(__lce_ta<__a, __c, __m, _Mp>::next(__x_));
  194. }
  195. _LIBCPP_HIDE_FROM_ABI void discard(unsigned long long __z) {
  196. for (; __z; --__z)
  197. operator()();
  198. }
  199. friend _LIBCPP_HIDE_FROM_ABI bool
  200. operator==(const linear_congruential_engine& __x, const linear_congruential_engine& __y) {
  201. return __x.__x_ == __y.__x_;
  202. }
  203. friend _LIBCPP_HIDE_FROM_ABI bool
  204. operator!=(const linear_congruential_engine& __x, const linear_congruential_engine& __y) {
  205. return !(__x == __y);
  206. }
  207. private:
  208. _LIBCPP_HIDE_FROM_ABI void seed(true_type, true_type, result_type __s) { __x_ = __s == 0 ? 1 : __s; }
  209. _LIBCPP_HIDE_FROM_ABI void seed(true_type, false_type, result_type __s) { __x_ = __s; }
  210. _LIBCPP_HIDE_FROM_ABI void seed(false_type, true_type, result_type __s) { __x_ = __s % __m == 0 ? 1 : __s % __m; }
  211. _LIBCPP_HIDE_FROM_ABI void seed(false_type, false_type, result_type __s) { __x_ = __s % __m; }
  212. template <class _Sseq>
  213. _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
  214. template <class _Sseq>
  215. _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
  216. template <class _CharT, class _Traits, class _Up, _Up _Ap, _Up _Cp, _Up _Np>
  217. friend basic_ostream<_CharT, _Traits>&
  218. operator<<(basic_ostream<_CharT, _Traits>& __os, const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);
  219. template <class _CharT, class _Traits, class _Up, _Up _Ap, _Up _Cp, _Up _Np>
  220. friend basic_istream<_CharT, _Traits>&
  221. operator>>(basic_istream<_CharT, _Traits>& __is, linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
  222. };
  223. template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  224. _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
  225. linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;
  226. template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  227. _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
  228. linear_congruential_engine<_UIntType, __a, __c, __m>::increment;
  229. template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  230. _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
  231. linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;
  232. template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  233. _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
  234. linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
  235. template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  236. template <class _Sseq>
  237. void linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q, integral_constant<unsigned, 1>) {
  238. const unsigned __k = 1;
  239. uint32_t __ar[__k + 3];
  240. __q.generate(__ar, __ar + __k + 3);
  241. result_type __s = static_cast<result_type>(__ar[3] % __m);
  242. __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
  243. }
  244. template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  245. template <class _Sseq>
  246. void linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q, integral_constant<unsigned, 2>) {
  247. const unsigned __k = 2;
  248. uint32_t __ar[__k + 3];
  249. __q.generate(__ar, __ar + __k + 3);
  250. result_type __s = static_cast<result_type>((__ar[3] + ((uint64_t)__ar[4] << 32)) % __m);
  251. __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
  252. }
  253. template <class _CharT, class _Traits, class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  254. inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  255. operator<<(basic_ostream<_CharT, _Traits>& __os, const linear_congruential_engine<_UIntType, __a, __c, __m>& __x) {
  256. __save_flags<_CharT, _Traits> __lx(__os);
  257. typedef basic_ostream<_CharT, _Traits> _Ostream;
  258. __os.flags(_Ostream::dec | _Ostream::left);
  259. __os.fill(__os.widen(' '));
  260. return __os << __x.__x_;
  261. }
  262. template <class _CharT, class _Traits, class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
  263. _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  264. operator>>(basic_istream<_CharT, _Traits>& __is, linear_congruential_engine<_UIntType, __a, __c, __m>& __x) {
  265. __save_flags<_CharT, _Traits> __lx(__is);
  266. typedef basic_istream<_CharT, _Traits> _Istream;
  267. __is.flags(_Istream::dec | _Istream::skipws);
  268. _UIntType __t;
  269. __is >> __t;
  270. if (!__is.fail())
  271. __x.__x_ = __t;
  272. return __is;
  273. }
  274. typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;
  275. typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647> minstd_rand;
  276. _LIBCPP_END_NAMESPACE_STD
  277. _LIBCPP_POP_MACROS
  278. #endif // _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H