You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3883 lines
111KB

  1. // Random number extensions -*- C++ -*-
  2. // Copyright (C) 2012-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file ext/random
  21. * This file is a GNU extension to the Standard C++ Library.
  22. */
  23. #ifndef _EXT_RANDOM
  24. #define _EXT_RANDOM 1
  25. #pragma GCC system_header
  26. #if __cplusplus < 201103L
  27. # include <bits/c++0x_warning.h>
  28. #else
  29. #include <random>
  30. #include <algorithm>
  31. #include <array>
  32. #include <ext/cmath>
  33. #ifdef __SSE2__
  34. # include <emmintrin.h>
  35. #endif
  36. #if defined(_GLIBCXX_USE_C99_STDINT_TR1) && defined(UINT32_C)
  37. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  38. {
  39. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  40. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  41. /* Mersenne twister implementation optimized for vector operations.
  42. *
  43. * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
  44. */
  45. template<typename _UIntType, size_t __m,
  46. size_t __pos1, size_t __sl1, size_t __sl2,
  47. size_t __sr1, size_t __sr2,
  48. uint32_t __msk1, uint32_t __msk2,
  49. uint32_t __msk3, uint32_t __msk4,
  50. uint32_t __parity1, uint32_t __parity2,
  51. uint32_t __parity3, uint32_t __parity4>
  52. class simd_fast_mersenne_twister_engine
  53. {
  54. static_assert(std::is_unsigned<_UIntType>::value, "template argument "
  55. "substituting _UIntType not an unsigned integral type");
  56. static_assert(__sr1 < 32, "first right shift too large");
  57. static_assert(__sr2 < 16, "second right shift too large");
  58. static_assert(__sl1 < 32, "first left shift too large");
  59. static_assert(__sl2 < 16, "second left shift too large");
  60. public:
  61. typedef _UIntType result_type;
  62. private:
  63. static constexpr size_t m_w = sizeof(result_type) * 8;
  64. static constexpr size_t _M_nstate = __m / 128 + 1;
  65. static constexpr size_t _M_nstate32 = _M_nstate * 4;
  66. static_assert(std::is_unsigned<_UIntType>::value, "template argument "
  67. "substituting _UIntType not an unsigned integral type");
  68. static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size");
  69. static_assert(16 % sizeof(_UIntType) == 0,
  70. "UIntType size must divide 16");
  71. template<typename _Sseq>
  72. using _If_seed_seq
  73. = typename std::enable_if<std::__detail::__is_seed_seq<
  74. _Sseq, simd_fast_mersenne_twister_engine, result_type>::value
  75. >::type;
  76. public:
  77. static constexpr size_t state_size = _M_nstate * (16
  78. / sizeof(result_type));
  79. static constexpr result_type default_seed = 5489u;
  80. // constructors and member functions
  81. simd_fast_mersenne_twister_engine()
  82. : simd_fast_mersenne_twister_engine(default_seed)
  83. { }
  84. explicit
  85. simd_fast_mersenne_twister_engine(result_type __sd)
  86. { seed(__sd); }
  87. template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
  88. explicit
  89. simd_fast_mersenne_twister_engine(_Sseq& __q)
  90. { seed(__q); }
  91. void
  92. seed(result_type __sd = default_seed);
  93. template<typename _Sseq>
  94. _If_seed_seq<_Sseq>
  95. seed(_Sseq& __q);
  96. static constexpr result_type
  97. min()
  98. { return 0; }
  99. static constexpr result_type
  100. max()
  101. { return std::numeric_limits<result_type>::max(); }
  102. void
  103. discard(unsigned long long __z);
  104. result_type
  105. operator()()
  106. {
  107. if (__builtin_expect(_M_pos >= state_size, 0))
  108. _M_gen_rand();
  109. return _M_stateT[_M_pos++];
  110. }
  111. template<typename _UIntType_2, size_t __m_2,
  112. size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
  113. size_t __sr1_2, size_t __sr2_2,
  114. uint32_t __msk1_2, uint32_t __msk2_2,
  115. uint32_t __msk3_2, uint32_t __msk4_2,
  116. uint32_t __parity1_2, uint32_t __parity2_2,
  117. uint32_t __parity3_2, uint32_t __parity4_2>
  118. friend bool
  119. operator==(const simd_fast_mersenne_twister_engine<_UIntType_2,
  120. __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
  121. __msk1_2, __msk2_2, __msk3_2, __msk4_2,
  122. __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs,
  123. const simd_fast_mersenne_twister_engine<_UIntType_2,
  124. __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
  125. __msk1_2, __msk2_2, __msk3_2, __msk4_2,
  126. __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs);
  127. template<typename _UIntType_2, size_t __m_2,
  128. size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
  129. size_t __sr1_2, size_t __sr2_2,
  130. uint32_t __msk1_2, uint32_t __msk2_2,
  131. uint32_t __msk3_2, uint32_t __msk4_2,
  132. uint32_t __parity1_2, uint32_t __parity2_2,
  133. uint32_t __parity3_2, uint32_t __parity4_2,
  134. typename _CharT, typename _Traits>
  135. friend std::basic_ostream<_CharT, _Traits>&
  136. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  137. const __gnu_cxx::simd_fast_mersenne_twister_engine
  138. <_UIntType_2,
  139. __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
  140. __msk1_2, __msk2_2, __msk3_2, __msk4_2,
  141. __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
  142. template<typename _UIntType_2, size_t __m_2,
  143. size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
  144. size_t __sr1_2, size_t __sr2_2,
  145. uint32_t __msk1_2, uint32_t __msk2_2,
  146. uint32_t __msk3_2, uint32_t __msk4_2,
  147. uint32_t __parity1_2, uint32_t __parity2_2,
  148. uint32_t __parity3_2, uint32_t __parity4_2,
  149. typename _CharT, typename _Traits>
  150. friend std::basic_istream<_CharT, _Traits>&
  151. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  152. __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2,
  153. __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
  154. __msk1_2, __msk2_2, __msk3_2, __msk4_2,
  155. __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
  156. private:
  157. union
  158. {
  159. #ifdef __SSE2__
  160. __m128i _M_state[_M_nstate];
  161. #endif
  162. #ifdef __ARM_NEON
  163. #ifdef __aarch64__
  164. __Uint32x4_t _M_state[_M_nstate];
  165. #endif
  166. #endif
  167. uint32_t _M_state32[_M_nstate32];
  168. result_type _M_stateT[state_size];
  169. } __attribute__ ((__aligned__ (16)));
  170. size_t _M_pos;
  171. void _M_gen_rand(void);
  172. void _M_period_certification();
  173. };
  174. template<typename _UIntType, size_t __m,
  175. size_t __pos1, size_t __sl1, size_t __sl2,
  176. size_t __sr1, size_t __sr2,
  177. uint32_t __msk1, uint32_t __msk2,
  178. uint32_t __msk3, uint32_t __msk4,
  179. uint32_t __parity1, uint32_t __parity2,
  180. uint32_t __parity3, uint32_t __parity4>
  181. inline bool
  182. operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
  183. __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
  184. __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs,
  185. const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
  186. __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
  187. __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs)
  188. { return !(__lhs == __rhs); }
  189. /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined
  190. * in the C implementation by Daito and Matsumoto, as both a 32-bit
  191. * and 64-bit version.
  192. */
  193. typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2,
  194. 15, 3, 13, 3,
  195. 0xfdff37ffU, 0xef7f3f7dU,
  196. 0xff777b7dU, 0x7ff7fb2fU,
  197. 0x00000001U, 0x00000000U,
  198. 0x00000000U, 0x5986f054U>
  199. sfmt607;
  200. typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2,
  201. 15, 3, 13, 3,
  202. 0xfdff37ffU, 0xef7f3f7dU,
  203. 0xff777b7dU, 0x7ff7fb2fU,
  204. 0x00000001U, 0x00000000U,
  205. 0x00000000U, 0x5986f054U>
  206. sfmt607_64;
  207. typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7,
  208. 14, 3, 5, 1,
  209. 0xf7fefffdU, 0x7fefcfffU,
  210. 0xaff3ef3fU, 0xb5ffff7fU,
  211. 0x00000001U, 0x00000000U,
  212. 0x00000000U, 0x20000000U>
  213. sfmt1279;
  214. typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7,
  215. 14, 3, 5, 1,
  216. 0xf7fefffdU, 0x7fefcfffU,
  217. 0xaff3ef3fU, 0xb5ffff7fU,
  218. 0x00000001U, 0x00000000U,
  219. 0x00000000U, 0x20000000U>
  220. sfmt1279_64;
  221. typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12,
  222. 19, 1, 5, 1,
  223. 0xbff7ffbfU, 0xfdfffffeU,
  224. 0xf7ffef7fU, 0xf2f7cbbfU,
  225. 0x00000001U, 0x00000000U,
  226. 0x00000000U, 0x41dfa600U>
  227. sfmt2281;
  228. typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12,
  229. 19, 1, 5, 1,
  230. 0xbff7ffbfU, 0xfdfffffeU,
  231. 0xf7ffef7fU, 0xf2f7cbbfU,
  232. 0x00000001U, 0x00000000U,
  233. 0x00000000U, 0x41dfa600U>
  234. sfmt2281_64;
  235. typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17,
  236. 20, 1, 7, 1,
  237. 0x9f7bffffU, 0x9fffff5fU,
  238. 0x3efffffbU, 0xfffff7bbU,
  239. 0xa8000001U, 0xaf5390a3U,
  240. 0xb740b3f8U, 0x6c11486dU>
  241. sfmt4253;
  242. typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17,
  243. 20, 1, 7, 1,
  244. 0x9f7bffffU, 0x9fffff5fU,
  245. 0x3efffffbU, 0xfffff7bbU,
  246. 0xa8000001U, 0xaf5390a3U,
  247. 0xb740b3f8U, 0x6c11486dU>
  248. sfmt4253_64;
  249. typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68,
  250. 14, 3, 7, 3,
  251. 0xeffff7fbU, 0xffffffefU,
  252. 0xdfdfbfffU, 0x7fffdbfdU,
  253. 0x00000001U, 0x00000000U,
  254. 0xe8148000U, 0xd0c7afa3U>
  255. sfmt11213;
  256. typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68,
  257. 14, 3, 7, 3,
  258. 0xeffff7fbU, 0xffffffefU,
  259. 0xdfdfbfffU, 0x7fffdbfdU,
  260. 0x00000001U, 0x00000000U,
  261. 0xe8148000U, 0xd0c7afa3U>
  262. sfmt11213_64;
  263. typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122,
  264. 18, 1, 11, 1,
  265. 0xdfffffefU, 0xddfecb7fU,
  266. 0xbffaffffU, 0xbffffff6U,
  267. 0x00000001U, 0x00000000U,
  268. 0x00000000U, 0x13c9e684U>
  269. sfmt19937;
  270. typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122,
  271. 18, 1, 11, 1,
  272. 0xdfffffefU, 0xddfecb7fU,
  273. 0xbffaffffU, 0xbffffff6U,
  274. 0x00000001U, 0x00000000U,
  275. 0x00000000U, 0x13c9e684U>
  276. sfmt19937_64;
  277. typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330,
  278. 5, 3, 9, 3,
  279. 0xeffffffbU, 0xdfbebfffU,
  280. 0xbfbf7befU, 0x9ffd7bffU,
  281. 0x00000001U, 0x00000000U,
  282. 0xa3ac4000U, 0xecc1327aU>
  283. sfmt44497;
  284. typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330,
  285. 5, 3, 9, 3,
  286. 0xeffffffbU, 0xdfbebfffU,
  287. 0xbfbf7befU, 0x9ffd7bffU,
  288. 0x00000001U, 0x00000000U,
  289. 0xa3ac4000U, 0xecc1327aU>
  290. sfmt44497_64;
  291. typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366,
  292. 6, 7, 19, 1,
  293. 0xfdbffbffU, 0xbff7ff3fU,
  294. 0xfd77efffU, 0xbf9ff3ffU,
  295. 0x00000001U, 0x00000000U,
  296. 0x00000000U, 0xe9528d85U>
  297. sfmt86243;
  298. typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366,
  299. 6, 7, 19, 1,
  300. 0xfdbffbffU, 0xbff7ff3fU,
  301. 0xfd77efffU, 0xbf9ff3ffU,
  302. 0x00000001U, 0x00000000U,
  303. 0x00000000U, 0xe9528d85U>
  304. sfmt86243_64;
  305. typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110,
  306. 19, 1, 21, 1,
  307. 0xffffbb5fU, 0xfb6ebf95U,
  308. 0xfffefffaU, 0xcff77fffU,
  309. 0x00000001U, 0x00000000U,
  310. 0xcb520000U, 0xc7e91c7dU>
  311. sfmt132049;
  312. typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110,
  313. 19, 1, 21, 1,
  314. 0xffffbb5fU, 0xfb6ebf95U,
  315. 0xfffefffaU, 0xcff77fffU,
  316. 0x00000001U, 0x00000000U,
  317. 0xcb520000U, 0xc7e91c7dU>
  318. sfmt132049_64;
  319. typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627,
  320. 11, 3, 10, 1,
  321. 0xbff7bff7U, 0xbfffffffU,
  322. 0xbffffa7fU, 0xffddfbfbU,
  323. 0xf8000001U, 0x89e80709U,
  324. 0x3bd2b64bU, 0x0c64b1e4U>
  325. sfmt216091;
  326. typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627,
  327. 11, 3, 10, 1,
  328. 0xbff7bff7U, 0xbfffffffU,
  329. 0xbffffa7fU, 0xffddfbfbU,
  330. 0xf8000001U, 0x89e80709U,
  331. 0x3bd2b64bU, 0x0c64b1e4U>
  332. sfmt216091_64;
  333. #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  334. /**
  335. * @brief A beta continuous distribution for random numbers.
  336. *
  337. * The formula for the beta probability density function is:
  338. * @f[
  339. * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)}
  340. * x^{\alpha - 1} (1 - x)^{\beta - 1}
  341. * @f]
  342. */
  343. template<typename _RealType = double>
  344. class beta_distribution
  345. {
  346. static_assert(std::is_floating_point<_RealType>::value,
  347. "template argument not a floating point type");
  348. public:
  349. /** The type of the range of the distribution. */
  350. typedef _RealType result_type;
  351. /** Parameter type. */
  352. struct param_type
  353. {
  354. typedef beta_distribution<_RealType> distribution_type;
  355. friend class beta_distribution<_RealType>;
  356. param_type() : param_type(1) { }
  357. explicit
  358. param_type(_RealType __alpha_val, _RealType __beta_val = _RealType(1))
  359. : _M_alpha(__alpha_val), _M_beta(__beta_val)
  360. {
  361. __glibcxx_assert(_M_alpha > _RealType(0));
  362. __glibcxx_assert(_M_beta > _RealType(0));
  363. }
  364. _RealType
  365. alpha() const
  366. { return _M_alpha; }
  367. _RealType
  368. beta() const
  369. { return _M_beta; }
  370. friend bool
  371. operator==(const param_type& __p1, const param_type& __p2)
  372. { return (__p1._M_alpha == __p2._M_alpha
  373. && __p1._M_beta == __p2._M_beta); }
  374. friend bool
  375. operator!=(const param_type& __p1, const param_type& __p2)
  376. { return !(__p1 == __p2); }
  377. private:
  378. void
  379. _M_initialize();
  380. _RealType _M_alpha;
  381. _RealType _M_beta;
  382. };
  383. public:
  384. beta_distribution() : beta_distribution(1.0) { }
  385. /**
  386. * @brief Constructs a beta distribution with parameters
  387. * @f$\alpha@f$ and @f$\beta@f$.
  388. */
  389. explicit
  390. beta_distribution(_RealType __alpha_val,
  391. _RealType __beta_val = _RealType(1))
  392. : _M_param(__alpha_val, __beta_val)
  393. { }
  394. explicit
  395. beta_distribution(const param_type& __p)
  396. : _M_param(__p)
  397. { }
  398. /**
  399. * @brief Resets the distribution state.
  400. */
  401. void
  402. reset()
  403. { }
  404. /**
  405. * @brief Returns the @f$\alpha@f$ of the distribution.
  406. */
  407. _RealType
  408. alpha() const
  409. { return _M_param.alpha(); }
  410. /**
  411. * @brief Returns the @f$\beta@f$ of the distribution.
  412. */
  413. _RealType
  414. beta() const
  415. { return _M_param.beta(); }
  416. /**
  417. * @brief Returns the parameter set of the distribution.
  418. */
  419. param_type
  420. param() const
  421. { return _M_param; }
  422. /**
  423. * @brief Sets the parameter set of the distribution.
  424. * @param __param The new parameter set of the distribution.
  425. */
  426. void
  427. param(const param_type& __param)
  428. { _M_param = __param; }
  429. /**
  430. * @brief Returns the greatest lower bound value of the distribution.
  431. */
  432. result_type
  433. min() const
  434. { return result_type(0); }
  435. /**
  436. * @brief Returns the least upper bound value of the distribution.
  437. */
  438. result_type
  439. max() const
  440. { return result_type(1); }
  441. /**
  442. * @brief Generating functions.
  443. */
  444. template<typename _UniformRandomNumberGenerator>
  445. result_type
  446. operator()(_UniformRandomNumberGenerator& __urng)
  447. { return this->operator()(__urng, _M_param); }
  448. template<typename _UniformRandomNumberGenerator>
  449. result_type
  450. operator()(_UniformRandomNumberGenerator& __urng,
  451. const param_type& __p);
  452. template<typename _ForwardIterator,
  453. typename _UniformRandomNumberGenerator>
  454. void
  455. __generate(_ForwardIterator __f, _ForwardIterator __t,
  456. _UniformRandomNumberGenerator& __urng)
  457. { this->__generate(__f, __t, __urng, _M_param); }
  458. template<typename _ForwardIterator,
  459. typename _UniformRandomNumberGenerator>
  460. void
  461. __generate(_ForwardIterator __f, _ForwardIterator __t,
  462. _UniformRandomNumberGenerator& __urng,
  463. const param_type& __p)
  464. { this->__generate_impl(__f, __t, __urng, __p); }
  465. template<typename _UniformRandomNumberGenerator>
  466. void
  467. __generate(result_type* __f, result_type* __t,
  468. _UniformRandomNumberGenerator& __urng,
  469. const param_type& __p)
  470. { this->__generate_impl(__f, __t, __urng, __p); }
  471. /**
  472. * @brief Return true if two beta distributions have the same
  473. * parameters and the sequences that would be generated
  474. * are equal.
  475. */
  476. friend bool
  477. operator==(const beta_distribution& __d1,
  478. const beta_distribution& __d2)
  479. { return __d1._M_param == __d2._M_param; }
  480. /**
  481. * @brief Inserts a %beta_distribution random number distribution
  482. * @p __x into the output stream @p __os.
  483. *
  484. * @param __os An output stream.
  485. * @param __x A %beta_distribution random number distribution.
  486. *
  487. * @returns The output stream with the state of @p __x inserted or in
  488. * an error state.
  489. */
  490. template<typename _RealType1, typename _CharT, typename _Traits>
  491. friend std::basic_ostream<_CharT, _Traits>&
  492. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  493. const __gnu_cxx::beta_distribution<_RealType1>& __x);
  494. /**
  495. * @brief Extracts a %beta_distribution random number distribution
  496. * @p __x from the input stream @p __is.
  497. *
  498. * @param __is An input stream.
  499. * @param __x A %beta_distribution random number generator engine.
  500. *
  501. * @returns The input stream with @p __x extracted or in an error state.
  502. */
  503. template<typename _RealType1, typename _CharT, typename _Traits>
  504. friend std::basic_istream<_CharT, _Traits>&
  505. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  506. __gnu_cxx::beta_distribution<_RealType1>& __x);
  507. private:
  508. template<typename _ForwardIterator,
  509. typename _UniformRandomNumberGenerator>
  510. void
  511. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  512. _UniformRandomNumberGenerator& __urng,
  513. const param_type& __p);
  514. param_type _M_param;
  515. };
  516. /**
  517. * @brief Return true if two beta distributions are different.
  518. */
  519. template<typename _RealType>
  520. inline bool
  521. operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1,
  522. const __gnu_cxx::beta_distribution<_RealType>& __d2)
  523. { return !(__d1 == __d2); }
  524. /**
  525. * @brief A multi-variate normal continuous distribution for random numbers.
  526. *
  527. * The formula for the normal probability density function is
  528. * @f[
  529. * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) =
  530. * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}}
  531. * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T}
  532. * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})}
  533. * @f]
  534. *
  535. * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are
  536. * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance
  537. * matrix (which must be positive-definite).
  538. */
  539. template<std::size_t _Dimen, typename _RealType = double>
  540. class normal_mv_distribution
  541. {
  542. static_assert(std::is_floating_point<_RealType>::value,
  543. "template argument not a floating point type");
  544. static_assert(_Dimen != 0, "dimension is zero");
  545. public:
  546. /** The type of the range of the distribution. */
  547. typedef std::array<_RealType, _Dimen> result_type;
  548. /** Parameter type. */
  549. class param_type
  550. {
  551. static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2;
  552. public:
  553. typedef normal_mv_distribution<_Dimen, _RealType> distribution_type;
  554. friend class normal_mv_distribution<_Dimen, _RealType>;
  555. param_type()
  556. {
  557. std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0));
  558. auto __it = _M_t.begin();
  559. for (size_t __i = 0; __i < _Dimen; ++__i)
  560. {
  561. std::fill_n(__it, __i, _RealType(0));
  562. __it += __i;
  563. *__it++ = _RealType(1);
  564. }
  565. }
  566. template<typename _ForwardIterator1, typename _ForwardIterator2>
  567. param_type(_ForwardIterator1 __meanbegin,
  568. _ForwardIterator1 __meanend,
  569. _ForwardIterator2 __varcovbegin,
  570. _ForwardIterator2 __varcovend)
  571. {
  572. __glibcxx_function_requires(_ForwardIteratorConcept<
  573. _ForwardIterator1>)
  574. __glibcxx_function_requires(_ForwardIteratorConcept<
  575. _ForwardIterator2>)
  576. _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend)
  577. <= _Dimen);
  578. const auto __dist = std::distance(__varcovbegin, __varcovend);
  579. _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen
  580. || __dist == _Dimen * (_Dimen + 1) / 2
  581. || __dist == _Dimen);
  582. if (__dist == _Dimen * _Dimen)
  583. _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend);
  584. else if (__dist == _Dimen * (_Dimen + 1) / 2)
  585. _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend);
  586. else
  587. {
  588. __glibcxx_assert(__dist == _Dimen);
  589. _M_init_diagonal(__meanbegin, __meanend,
  590. __varcovbegin, __varcovend);
  591. }
  592. }
  593. param_type(std::initializer_list<_RealType> __mean,
  594. std::initializer_list<_RealType> __varcov)
  595. {
  596. _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen);
  597. _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen
  598. || __varcov.size() == _Dimen * (_Dimen + 1) / 2
  599. || __varcov.size() == _Dimen);
  600. if (__varcov.size() == _Dimen * _Dimen)
  601. _M_init_full(__mean.begin(), __mean.end(),
  602. __varcov.begin(), __varcov.end());
  603. else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2)
  604. _M_init_lower(__mean.begin(), __mean.end(),
  605. __varcov.begin(), __varcov.end());
  606. else
  607. {
  608. __glibcxx_assert(__varcov.size() == _Dimen);
  609. _M_init_diagonal(__mean.begin(), __mean.end(),
  610. __varcov.begin(), __varcov.end());
  611. }
  612. }
  613. std::array<_RealType, _Dimen>
  614. mean() const
  615. { return _M_mean; }
  616. std::array<_RealType, _M_t_size>
  617. varcov() const
  618. { return _M_t; }
  619. friend bool
  620. operator==(const param_type& __p1, const param_type& __p2)
  621. { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; }
  622. friend bool
  623. operator!=(const param_type& __p1, const param_type& __p2)
  624. { return !(__p1 == __p2); }
  625. private:
  626. template <typename _InputIterator1, typename _InputIterator2>
  627. void _M_init_full(_InputIterator1 __meanbegin,
  628. _InputIterator1 __meanend,
  629. _InputIterator2 __varcovbegin,
  630. _InputIterator2 __varcovend);
  631. template <typename _InputIterator1, typename _InputIterator2>
  632. void _M_init_lower(_InputIterator1 __meanbegin,
  633. _InputIterator1 __meanend,
  634. _InputIterator2 __varcovbegin,
  635. _InputIterator2 __varcovend);
  636. template <typename _InputIterator1, typename _InputIterator2>
  637. void _M_init_diagonal(_InputIterator1 __meanbegin,
  638. _InputIterator1 __meanend,
  639. _InputIterator2 __varbegin,
  640. _InputIterator2 __varend);
  641. // param_type constructors apply Cholesky decomposition to the
  642. // varcov matrix in _M_init_full and _M_init_lower, but the
  643. // varcov matrix output ot a stream is already decomposed, so
  644. // we need means to restore it as-is when reading it back in.
  645. template<size_t _Dimen1, typename _RealType1,
  646. typename _CharT, typename _Traits>
  647. friend std::basic_istream<_CharT, _Traits>&
  648. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  649. __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
  650. __x);
  651. param_type(std::array<_RealType, _Dimen> const &__mean,
  652. std::array<_RealType, _M_t_size> const &__varcov)
  653. : _M_mean (__mean), _M_t (__varcov)
  654. {}
  655. std::array<_RealType, _Dimen> _M_mean;
  656. std::array<_RealType, _M_t_size> _M_t;
  657. };
  658. public:
  659. normal_mv_distribution()
  660. : _M_param(), _M_nd()
  661. { }
  662. template<typename _ForwardIterator1, typename _ForwardIterator2>
  663. normal_mv_distribution(_ForwardIterator1 __meanbegin,
  664. _ForwardIterator1 __meanend,
  665. _ForwardIterator2 __varcovbegin,
  666. _ForwardIterator2 __varcovend)
  667. : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend),
  668. _M_nd()
  669. { }
  670. normal_mv_distribution(std::initializer_list<_RealType> __mean,
  671. std::initializer_list<_RealType> __varcov)
  672. : _M_param(__mean, __varcov), _M_nd()
  673. { }
  674. explicit
  675. normal_mv_distribution(const param_type& __p)
  676. : _M_param(__p), _M_nd()
  677. { }
  678. /**
  679. * @brief Resets the distribution state.
  680. */
  681. void
  682. reset()
  683. { _M_nd.reset(); }
  684. /**
  685. * @brief Returns the mean of the distribution.
  686. */
  687. result_type
  688. mean() const
  689. { return _M_param.mean(); }
  690. /**
  691. * @brief Returns the compact form of the variance/covariance
  692. * matrix of the distribution.
  693. */
  694. std::array<_RealType, _Dimen * (_Dimen + 1) / 2>
  695. varcov() const
  696. { return _M_param.varcov(); }
  697. /**
  698. * @brief Returns the parameter set of the distribution.
  699. */
  700. param_type
  701. param() const
  702. { return _M_param; }
  703. /**
  704. * @brief Sets the parameter set of the distribution.
  705. * @param __param The new parameter set of the distribution.
  706. */
  707. void
  708. param(const param_type& __param)
  709. { _M_param = __param; }
  710. /**
  711. * @brief Returns the greatest lower bound value of the distribution.
  712. */
  713. result_type
  714. min() const
  715. { result_type __res;
  716. __res.fill(std::numeric_limits<_RealType>::lowest());
  717. return __res; }
  718. /**
  719. * @brief Returns the least upper bound value of the distribution.
  720. */
  721. result_type
  722. max() const
  723. { result_type __res;
  724. __res.fill(std::numeric_limits<_RealType>::max());
  725. return __res; }
  726. /**
  727. * @brief Generating functions.
  728. */
  729. template<typename _UniformRandomNumberGenerator>
  730. result_type
  731. operator()(_UniformRandomNumberGenerator& __urng)
  732. { return this->operator()(__urng, _M_param); }
  733. template<typename _UniformRandomNumberGenerator>
  734. result_type
  735. operator()(_UniformRandomNumberGenerator& __urng,
  736. const param_type& __p);
  737. template<typename _ForwardIterator,
  738. typename _UniformRandomNumberGenerator>
  739. void
  740. __generate(_ForwardIterator __f, _ForwardIterator __t,
  741. _UniformRandomNumberGenerator& __urng)
  742. { return this->__generate_impl(__f, __t, __urng, _M_param); }
  743. template<typename _ForwardIterator,
  744. typename _UniformRandomNumberGenerator>
  745. void
  746. __generate(_ForwardIterator __f, _ForwardIterator __t,
  747. _UniformRandomNumberGenerator& __urng,
  748. const param_type& __p)
  749. { return this->__generate_impl(__f, __t, __urng, __p); }
  750. /**
  751. * @brief Return true if two multi-variant normal distributions have
  752. * the same parameters and the sequences that would
  753. * be generated are equal.
  754. */
  755. template<size_t _Dimen1, typename _RealType1>
  756. friend bool
  757. operator==(const
  758. __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
  759. __d1,
  760. const
  761. __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
  762. __d2);
  763. /**
  764. * @brief Inserts a %normal_mv_distribution random number distribution
  765. * @p __x into the output stream @p __os.
  766. *
  767. * @param __os An output stream.
  768. * @param __x A %normal_mv_distribution random number distribution.
  769. *
  770. * @returns The output stream with the state of @p __x inserted or in
  771. * an error state.
  772. */
  773. template<size_t _Dimen1, typename _RealType1,
  774. typename _CharT, typename _Traits>
  775. friend std::basic_ostream<_CharT, _Traits>&
  776. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  777. const
  778. __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
  779. __x);
  780. /**
  781. * @brief Extracts a %normal_mv_distribution random number distribution
  782. * @p __x from the input stream @p __is.
  783. *
  784. * @param __is An input stream.
  785. * @param __x A %normal_mv_distribution random number generator engine.
  786. *
  787. * @returns The input stream with @p __x extracted or in an error
  788. * state.
  789. */
  790. template<size_t _Dimen1, typename _RealType1,
  791. typename _CharT, typename _Traits>
  792. friend std::basic_istream<_CharT, _Traits>&
  793. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  794. __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
  795. __x);
  796. private:
  797. template<typename _ForwardIterator,
  798. typename _UniformRandomNumberGenerator>
  799. void
  800. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  801. _UniformRandomNumberGenerator& __urng,
  802. const param_type& __p);
  803. param_type _M_param;
  804. std::normal_distribution<_RealType> _M_nd;
  805. };
  806. /**
  807. * @brief Return true if two multi-variate normal distributions are
  808. * different.
  809. */
  810. template<size_t _Dimen, typename _RealType>
  811. inline bool
  812. operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
  813. __d1,
  814. const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
  815. __d2)
  816. { return !(__d1 == __d2); }
  817. /**
  818. * @brief A Rice continuous distribution for random numbers.
  819. *
  820. * The formula for the Rice probability density function is
  821. * @f[
  822. * p(x|\nu,\sigma) = \frac{x}{\sigma^2}
  823. * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right)
  824. * I_0\left(\frac{x \nu}{\sigma^2}\right)
  825. * @f]
  826. * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
  827. * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$.
  828. *
  829. * <table border=1 cellpadding=10 cellspacing=0>
  830. * <caption align=top>Distribution Statistics</caption>
  831. * <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
  832. * <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2
  833. * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
  834. * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
  835. * </table>
  836. * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2.
  837. */
  838. template<typename _RealType = double>
  839. class
  840. rice_distribution
  841. {
  842. static_assert(std::is_floating_point<_RealType>::value,
  843. "template argument not a floating point type");
  844. public:
  845. /** The type of the range of the distribution. */
  846. typedef _RealType result_type;
  847. /** Parameter type. */
  848. struct param_type
  849. {
  850. typedef rice_distribution<result_type> distribution_type;
  851. param_type() : param_type(0) { }
  852. param_type(result_type __nu_val,
  853. result_type __sigma_val = result_type(1))
  854. : _M_nu(__nu_val), _M_sigma(__sigma_val)
  855. {
  856. __glibcxx_assert(_M_nu >= result_type(0));
  857. __glibcxx_assert(_M_sigma > result_type(0));
  858. }
  859. result_type
  860. nu() const
  861. { return _M_nu; }
  862. result_type
  863. sigma() const
  864. { return _M_sigma; }
  865. friend bool
  866. operator==(const param_type& __p1, const param_type& __p2)
  867. { return __p1._M_nu == __p2._M_nu && __p1._M_sigma == __p2._M_sigma; }
  868. friend bool
  869. operator!=(const param_type& __p1, const param_type& __p2)
  870. { return !(__p1 == __p2); }
  871. private:
  872. void _M_initialize();
  873. result_type _M_nu;
  874. result_type _M_sigma;
  875. };
  876. /**
  877. * @brief Constructors.
  878. * @{
  879. */
  880. rice_distribution() : rice_distribution(0) { }
  881. explicit
  882. rice_distribution(result_type __nu_val,
  883. result_type __sigma_val = result_type(1))
  884. : _M_param(__nu_val, __sigma_val),
  885. _M_ndx(__nu_val, __sigma_val),
  886. _M_ndy(result_type(0), __sigma_val)
  887. { }
  888. explicit
  889. rice_distribution(const param_type& __p)
  890. : _M_param(__p),
  891. _M_ndx(__p.nu(), __p.sigma()),
  892. _M_ndy(result_type(0), __p.sigma())
  893. { }
  894. // @}
  895. /**
  896. * @brief Resets the distribution state.
  897. */
  898. void
  899. reset()
  900. {
  901. _M_ndx.reset();
  902. _M_ndy.reset();
  903. }
  904. /**
  905. * @brief Return the parameters of the distribution.
  906. */
  907. result_type
  908. nu() const
  909. { return _M_param.nu(); }
  910. result_type
  911. sigma() const
  912. { return _M_param.sigma(); }
  913. /**
  914. * @brief Returns the parameter set of the distribution.
  915. */
  916. param_type
  917. param() const
  918. { return _M_param; }
  919. /**
  920. * @brief Sets the parameter set of the distribution.
  921. * @param __param The new parameter set of the distribution.
  922. */
  923. void
  924. param(const param_type& __param)
  925. { _M_param = __param; }
  926. /**
  927. * @brief Returns the greatest lower bound value of the distribution.
  928. */
  929. result_type
  930. min() const
  931. { return result_type(0); }
  932. /**
  933. * @brief Returns the least upper bound value of the distribution.
  934. */
  935. result_type
  936. max() const
  937. { return std::numeric_limits<result_type>::max(); }
  938. /**
  939. * @brief Generating functions.
  940. */
  941. template<typename _UniformRandomNumberGenerator>
  942. result_type
  943. operator()(_UniformRandomNumberGenerator& __urng)
  944. {
  945. result_type __x = this->_M_ndx(__urng);
  946. result_type __y = this->_M_ndy(__urng);
  947. #if _GLIBCXX_USE_C99_MATH_TR1
  948. return std::hypot(__x, __y);
  949. #else
  950. return std::sqrt(__x * __x + __y * __y);
  951. #endif
  952. }
  953. template<typename _UniformRandomNumberGenerator>
  954. result_type
  955. operator()(_UniformRandomNumberGenerator& __urng,
  956. const param_type& __p)
  957. {
  958. typename std::normal_distribution<result_type>::param_type
  959. __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma());
  960. result_type __x = this->_M_ndx(__px, __urng);
  961. result_type __y = this->_M_ndy(__py, __urng);
  962. #if _GLIBCXX_USE_C99_MATH_TR1
  963. return std::hypot(__x, __y);
  964. #else
  965. return std::sqrt(__x * __x + __y * __y);
  966. #endif
  967. }
  968. template<typename _ForwardIterator,
  969. typename _UniformRandomNumberGenerator>
  970. void
  971. __generate(_ForwardIterator __f, _ForwardIterator __t,
  972. _UniformRandomNumberGenerator& __urng)
  973. { this->__generate(__f, __t, __urng, _M_param); }
  974. template<typename _ForwardIterator,
  975. typename _UniformRandomNumberGenerator>
  976. void
  977. __generate(_ForwardIterator __f, _ForwardIterator __t,
  978. _UniformRandomNumberGenerator& __urng,
  979. const param_type& __p)
  980. { this->__generate_impl(__f, __t, __urng, __p); }
  981. template<typename _UniformRandomNumberGenerator>
  982. void
  983. __generate(result_type* __f, result_type* __t,
  984. _UniformRandomNumberGenerator& __urng,
  985. const param_type& __p)
  986. { this->__generate_impl(__f, __t, __urng, __p); }
  987. /**
  988. * @brief Return true if two Rice distributions have
  989. * the same parameters and the sequences that would
  990. * be generated are equal.
  991. */
  992. friend bool
  993. operator==(const rice_distribution& __d1,
  994. const rice_distribution& __d2)
  995. { return (__d1._M_param == __d2._M_param
  996. && __d1._M_ndx == __d2._M_ndx
  997. && __d1._M_ndy == __d2._M_ndy); }
  998. /**
  999. * @brief Inserts a %rice_distribution random number distribution
  1000. * @p __x into the output stream @p __os.
  1001. *
  1002. * @param __os An output stream.
  1003. * @param __x A %rice_distribution random number distribution.
  1004. *
  1005. * @returns The output stream with the state of @p __x inserted or in
  1006. * an error state.
  1007. */
  1008. template<typename _RealType1, typename _CharT, typename _Traits>
  1009. friend std::basic_ostream<_CharT, _Traits>&
  1010. operator<<(std::basic_ostream<_CharT, _Traits>&,
  1011. const rice_distribution<_RealType1>&);
  1012. /**
  1013. * @brief Extracts a %rice_distribution random number distribution
  1014. * @p __x from the input stream @p __is.
  1015. *
  1016. * @param __is An input stream.
  1017. * @param __x A %rice_distribution random number
  1018. * generator engine.
  1019. *
  1020. * @returns The input stream with @p __x extracted or in an error state.
  1021. */
  1022. template<typename _RealType1, typename _CharT, typename _Traits>
  1023. friend std::basic_istream<_CharT, _Traits>&
  1024. operator>>(std::basic_istream<_CharT, _Traits>&,
  1025. rice_distribution<_RealType1>&);
  1026. private:
  1027. template<typename _ForwardIterator,
  1028. typename _UniformRandomNumberGenerator>
  1029. void
  1030. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  1031. _UniformRandomNumberGenerator& __urng,
  1032. const param_type& __p);
  1033. param_type _M_param;
  1034. std::normal_distribution<result_type> _M_ndx;
  1035. std::normal_distribution<result_type> _M_ndy;
  1036. };
  1037. /**
  1038. * @brief Return true if two Rice distributions are not equal.
  1039. */
  1040. template<typename _RealType1>
  1041. inline bool
  1042. operator!=(const rice_distribution<_RealType1>& __d1,
  1043. const rice_distribution<_RealType1>& __d2)
  1044. { return !(__d1 == __d2); }
  1045. /**
  1046. * @brief A Nakagami continuous distribution for random numbers.
  1047. *
  1048. * The formula for the Nakagami probability density function is
  1049. * @f[
  1050. * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu}
  1051. * x^{2\mu-1}e^{-\mu x / \omega}
  1052. * @f]
  1053. * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$
  1054. * and @f$\omega > 0@f$.
  1055. */
  1056. template<typename _RealType = double>
  1057. class
  1058. nakagami_distribution
  1059. {
  1060. static_assert(std::is_floating_point<_RealType>::value,
  1061. "template argument not a floating point type");
  1062. public:
  1063. /** The type of the range of the distribution. */
  1064. typedef _RealType result_type;
  1065. /** Parameter type. */
  1066. struct param_type
  1067. {
  1068. typedef nakagami_distribution<result_type> distribution_type;
  1069. param_type() : param_type(1) { }
  1070. param_type(result_type __mu_val,
  1071. result_type __omega_val = result_type(1))
  1072. : _M_mu(__mu_val), _M_omega(__omega_val)
  1073. {
  1074. __glibcxx_assert(_M_mu >= result_type(0.5L));
  1075. __glibcxx_assert(_M_omega > result_type(0));
  1076. }
  1077. result_type
  1078. mu() const
  1079. { return _M_mu; }
  1080. result_type
  1081. omega() const
  1082. { return _M_omega; }
  1083. friend bool
  1084. operator==(const param_type& __p1, const param_type& __p2)
  1085. { return __p1._M_mu == __p2._M_mu && __p1._M_omega == __p2._M_omega; }
  1086. friend bool
  1087. operator!=(const param_type& __p1, const param_type& __p2)
  1088. { return !(__p1 == __p2); }
  1089. private:
  1090. void _M_initialize();
  1091. result_type _M_mu;
  1092. result_type _M_omega;
  1093. };
  1094. /**
  1095. * @brief Constructors.
  1096. * @{
  1097. */
  1098. nakagami_distribution() : nakagami_distribution(1) { }
  1099. explicit
  1100. nakagami_distribution(result_type __mu_val,
  1101. result_type __omega_val = result_type(1))
  1102. : _M_param(__mu_val, __omega_val),
  1103. _M_gd(__mu_val, __omega_val / __mu_val)
  1104. { }
  1105. explicit
  1106. nakagami_distribution(const param_type& __p)
  1107. : _M_param(__p),
  1108. _M_gd(__p.mu(), __p.omega() / __p.mu())
  1109. { }
  1110. // @}
  1111. /**
  1112. * @brief Resets the distribution state.
  1113. */
  1114. void
  1115. reset()
  1116. { _M_gd.reset(); }
  1117. /**
  1118. * @brief Return the parameters of the distribution.
  1119. */
  1120. result_type
  1121. mu() const
  1122. { return _M_param.mu(); }
  1123. result_type
  1124. omega() const
  1125. { return _M_param.omega(); }
  1126. /**
  1127. * @brief Returns the parameter set of the distribution.
  1128. */
  1129. param_type
  1130. param() const
  1131. { return _M_param; }
  1132. /**
  1133. * @brief Sets the parameter set of the distribution.
  1134. * @param __param The new parameter set of the distribution.
  1135. */
  1136. void
  1137. param(const param_type& __param)
  1138. { _M_param = __param; }
  1139. /**
  1140. * @brief Returns the greatest lower bound value of the distribution.
  1141. */
  1142. result_type
  1143. min() const
  1144. { return result_type(0); }
  1145. /**
  1146. * @brief Returns the least upper bound value of the distribution.
  1147. */
  1148. result_type
  1149. max() const
  1150. { return std::numeric_limits<result_type>::max(); }
  1151. /**
  1152. * @brief Generating functions.
  1153. */
  1154. template<typename _UniformRandomNumberGenerator>
  1155. result_type
  1156. operator()(_UniformRandomNumberGenerator& __urng)
  1157. { return std::sqrt(this->_M_gd(__urng)); }
  1158. template<typename _UniformRandomNumberGenerator>
  1159. result_type
  1160. operator()(_UniformRandomNumberGenerator& __urng,
  1161. const param_type& __p)
  1162. {
  1163. typename std::gamma_distribution<result_type>::param_type
  1164. __pg(__p.mu(), __p.omega() / __p.mu());
  1165. return std::sqrt(this->_M_gd(__pg, __urng));
  1166. }
  1167. template<typename _ForwardIterator,
  1168. typename _UniformRandomNumberGenerator>
  1169. void
  1170. __generate(_ForwardIterator __f, _ForwardIterator __t,
  1171. _UniformRandomNumberGenerator& __urng)
  1172. { this->__generate(__f, __t, __urng, _M_param); }
  1173. template<typename _ForwardIterator,
  1174. typename _UniformRandomNumberGenerator>
  1175. void
  1176. __generate(_ForwardIterator __f, _ForwardIterator __t,
  1177. _UniformRandomNumberGenerator& __urng,
  1178. const param_type& __p)
  1179. { this->__generate_impl(__f, __t, __urng, __p); }
  1180. template<typename _UniformRandomNumberGenerator>
  1181. void
  1182. __generate(result_type* __f, result_type* __t,
  1183. _UniformRandomNumberGenerator& __urng,
  1184. const param_type& __p)
  1185. { this->__generate_impl(__f, __t, __urng, __p); }
  1186. /**
  1187. * @brief Return true if two Nakagami distributions have
  1188. * the same parameters and the sequences that would
  1189. * be generated are equal.
  1190. */
  1191. friend bool
  1192. operator==(const nakagami_distribution& __d1,
  1193. const nakagami_distribution& __d2)
  1194. { return (__d1._M_param == __d2._M_param
  1195. && __d1._M_gd == __d2._M_gd); }
  1196. /**
  1197. * @brief Inserts a %nakagami_distribution random number distribution
  1198. * @p __x into the output stream @p __os.
  1199. *
  1200. * @param __os An output stream.
  1201. * @param __x A %nakagami_distribution random number distribution.
  1202. *
  1203. * @returns The output stream with the state of @p __x inserted or in
  1204. * an error state.
  1205. */
  1206. template<typename _RealType1, typename _CharT, typename _Traits>
  1207. friend std::basic_ostream<_CharT, _Traits>&
  1208. operator<<(std::basic_ostream<_CharT, _Traits>&,
  1209. const nakagami_distribution<_RealType1>&);
  1210. /**
  1211. * @brief Extracts a %nakagami_distribution random number distribution
  1212. * @p __x from the input stream @p __is.
  1213. *
  1214. * @param __is An input stream.
  1215. * @param __x A %nakagami_distribution random number
  1216. * generator engine.
  1217. *
  1218. * @returns The input stream with @p __x extracted or in an error state.
  1219. */
  1220. template<typename _RealType1, typename _CharT, typename _Traits>
  1221. friend std::basic_istream<_CharT, _Traits>&
  1222. operator>>(std::basic_istream<_CharT, _Traits>&,
  1223. nakagami_distribution<_RealType1>&);
  1224. private:
  1225. template<typename _ForwardIterator,
  1226. typename _UniformRandomNumberGenerator>
  1227. void
  1228. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  1229. _UniformRandomNumberGenerator& __urng,
  1230. const param_type& __p);
  1231. param_type _M_param;
  1232. std::gamma_distribution<result_type> _M_gd;
  1233. };
  1234. /**
  1235. * @brief Return true if two Nakagami distributions are not equal.
  1236. */
  1237. template<typename _RealType>
  1238. inline bool
  1239. operator!=(const nakagami_distribution<_RealType>& __d1,
  1240. const nakagami_distribution<_RealType>& __d2)
  1241. { return !(__d1 == __d2); }
  1242. /**
  1243. * @brief A Pareto continuous distribution for random numbers.
  1244. *
  1245. * The formula for the Pareto cumulative probability function is
  1246. * @f[
  1247. * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha
  1248. * @f]
  1249. * The formula for the Pareto probability density function is
  1250. * @f[
  1251. * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu}
  1252. * \left(\frac{\mu}{x}\right)^{\alpha + 1}
  1253. * @f]
  1254. * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$.
  1255. *
  1256. * <table border=1 cellpadding=10 cellspacing=0>
  1257. * <caption align=top>Distribution Statistics</caption>
  1258. * <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$
  1259. * for @f$\alpha > 1@f$</td></tr>
  1260. * <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$
  1261. * for @f$\alpha > 2@f$</td></tr>
  1262. * <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr>
  1263. * </table>
  1264. */
  1265. template<typename _RealType = double>
  1266. class
  1267. pareto_distribution
  1268. {
  1269. static_assert(std::is_floating_point<_RealType>::value,
  1270. "template argument not a floating point type");
  1271. public:
  1272. /** The type of the range of the distribution. */
  1273. typedef _RealType result_type;
  1274. /** Parameter type. */
  1275. struct param_type
  1276. {
  1277. typedef pareto_distribution<result_type> distribution_type;
  1278. param_type() : param_type(1) { }
  1279. param_type(result_type __alpha_val,
  1280. result_type __mu_val = result_type(1))
  1281. : _M_alpha(__alpha_val), _M_mu(__mu_val)
  1282. {
  1283. __glibcxx_assert(_M_alpha > result_type(0));
  1284. __glibcxx_assert(_M_mu > result_type(0));
  1285. }
  1286. result_type
  1287. alpha() const
  1288. { return _M_alpha; }
  1289. result_type
  1290. mu() const
  1291. { return _M_mu; }
  1292. friend bool
  1293. operator==(const param_type& __p1, const param_type& __p2)
  1294. { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; }
  1295. friend bool
  1296. operator!=(const param_type& __p1, const param_type& __p2)
  1297. { return !(__p1 == __p2); }
  1298. private:
  1299. void _M_initialize();
  1300. result_type _M_alpha;
  1301. result_type _M_mu;
  1302. };
  1303. /**
  1304. * @brief Constructors.
  1305. * @{
  1306. */
  1307. pareto_distribution() : pareto_distribution(1) { }
  1308. explicit
  1309. pareto_distribution(result_type __alpha_val,
  1310. result_type __mu_val = result_type(1))
  1311. : _M_param(__alpha_val, __mu_val),
  1312. _M_ud()
  1313. { }
  1314. explicit
  1315. pareto_distribution(const param_type& __p)
  1316. : _M_param(__p),
  1317. _M_ud()
  1318. { }
  1319. // @}
  1320. /**
  1321. * @brief Resets the distribution state.
  1322. */
  1323. void
  1324. reset()
  1325. {
  1326. _M_ud.reset();
  1327. }
  1328. /**
  1329. * @brief Return the parameters of the distribution.
  1330. */
  1331. result_type
  1332. alpha() const
  1333. { return _M_param.alpha(); }
  1334. result_type
  1335. mu() const
  1336. { return _M_param.mu(); }
  1337. /**
  1338. * @brief Returns the parameter set of the distribution.
  1339. */
  1340. param_type
  1341. param() const
  1342. { return _M_param; }
  1343. /**
  1344. * @brief Sets the parameter set of the distribution.
  1345. * @param __param The new parameter set of the distribution.
  1346. */
  1347. void
  1348. param(const param_type& __param)
  1349. { _M_param = __param; }
  1350. /**
  1351. * @brief Returns the greatest lower bound value of the distribution.
  1352. */
  1353. result_type
  1354. min() const
  1355. { return this->mu(); }
  1356. /**
  1357. * @brief Returns the least upper bound value of the distribution.
  1358. */
  1359. result_type
  1360. max() const
  1361. { return std::numeric_limits<result_type>::max(); }
  1362. /**
  1363. * @brief Generating functions.
  1364. */
  1365. template<typename _UniformRandomNumberGenerator>
  1366. result_type
  1367. operator()(_UniformRandomNumberGenerator& __urng)
  1368. {
  1369. return this->mu() * std::pow(this->_M_ud(__urng),
  1370. -result_type(1) / this->alpha());
  1371. }
  1372. template<typename _UniformRandomNumberGenerator>
  1373. result_type
  1374. operator()(_UniformRandomNumberGenerator& __urng,
  1375. const param_type& __p)
  1376. {
  1377. return __p.mu() * std::pow(this->_M_ud(__urng),
  1378. -result_type(1) / __p.alpha());
  1379. }
  1380. template<typename _ForwardIterator,
  1381. typename _UniformRandomNumberGenerator>
  1382. void
  1383. __generate(_ForwardIterator __f, _ForwardIterator __t,
  1384. _UniformRandomNumberGenerator& __urng)
  1385. { this->__generate(__f, __t, __urng, _M_param); }
  1386. template<typename _ForwardIterator,
  1387. typename _UniformRandomNumberGenerator>
  1388. void
  1389. __generate(_ForwardIterator __f, _ForwardIterator __t,
  1390. _UniformRandomNumberGenerator& __urng,
  1391. const param_type& __p)
  1392. { this->__generate_impl(__f, __t, __urng, __p); }
  1393. template<typename _UniformRandomNumberGenerator>
  1394. void
  1395. __generate(result_type* __f, result_type* __t,
  1396. _UniformRandomNumberGenerator& __urng,
  1397. const param_type& __p)
  1398. { this->__generate_impl(__f, __t, __urng, __p); }
  1399. /**
  1400. * @brief Return true if two Pareto distributions have
  1401. * the same parameters and the sequences that would
  1402. * be generated are equal.
  1403. */
  1404. friend bool
  1405. operator==(const pareto_distribution& __d1,
  1406. const pareto_distribution& __d2)
  1407. { return (__d1._M_param == __d2._M_param
  1408. && __d1._M_ud == __d2._M_ud); }
  1409. /**
  1410. * @brief Inserts a %pareto_distribution random number distribution
  1411. * @p __x into the output stream @p __os.
  1412. *
  1413. * @param __os An output stream.
  1414. * @param __x A %pareto_distribution random number distribution.
  1415. *
  1416. * @returns The output stream with the state of @p __x inserted or in
  1417. * an error state.
  1418. */
  1419. template<typename _RealType1, typename _CharT, typename _Traits>
  1420. friend std::basic_ostream<_CharT, _Traits>&
  1421. operator<<(std::basic_ostream<_CharT, _Traits>&,
  1422. const pareto_distribution<_RealType1>&);
  1423. /**
  1424. * @brief Extracts a %pareto_distribution random number distribution
  1425. * @p __x from the input stream @p __is.
  1426. *
  1427. * @param __is An input stream.
  1428. * @param __x A %pareto_distribution random number
  1429. * generator engine.
  1430. *
  1431. * @returns The input stream with @p __x extracted or in an error state.
  1432. */
  1433. template<typename _RealType1, typename _CharT, typename _Traits>
  1434. friend std::basic_istream<_CharT, _Traits>&
  1435. operator>>(std::basic_istream<_CharT, _Traits>&,
  1436. pareto_distribution<_RealType1>&);
  1437. private:
  1438. template<typename _ForwardIterator,
  1439. typename _UniformRandomNumberGenerator>
  1440. void
  1441. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  1442. _UniformRandomNumberGenerator& __urng,
  1443. const param_type& __p);
  1444. param_type _M_param;
  1445. std::uniform_real_distribution<result_type> _M_ud;
  1446. };
  1447. /**
  1448. * @brief Return true if two Pareto distributions are not equal.
  1449. */
  1450. template<typename _RealType>
  1451. inline bool
  1452. operator!=(const pareto_distribution<_RealType>& __d1,
  1453. const pareto_distribution<_RealType>& __d2)
  1454. { return !(__d1 == __d2); }
  1455. /**
  1456. * @brief A K continuous distribution for random numbers.
  1457. *
  1458. * The formula for the K probability density function is
  1459. * @f[
  1460. * p(x|\lambda, \mu, \nu) = \frac{2}{x}
  1461. * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}}
  1462. * \frac{1}{\Gamma(\lambda)\Gamma(\nu)}
  1463. * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right)
  1464. * @f]
  1465. * where @f$I_0(z)@f$ is the modified Bessel function of the second kind
  1466. * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$
  1467. * and @f$\nu > 0@f$.
  1468. *
  1469. * <table border=1 cellpadding=10 cellspacing=0>
  1470. * <caption align=top>Distribution Statistics</caption>
  1471. * <tr><td>Mean</td><td>@f$\mu@f$</td></tr>
  1472. * <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr>
  1473. * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
  1474. * </table>
  1475. */
  1476. template<typename _RealType = double>
  1477. class
  1478. k_distribution
  1479. {
  1480. static_assert(std::is_floating_point<_RealType>::value,
  1481. "template argument not a floating point type");
  1482. public:
  1483. /** The type of the range of the distribution. */
  1484. typedef _RealType result_type;
  1485. /** Parameter type. */
  1486. struct param_type
  1487. {
  1488. typedef k_distribution<result_type> distribution_type;
  1489. param_type() : param_type(1) { }
  1490. param_type(result_type __lambda_val,
  1491. result_type __mu_val = result_type(1),
  1492. result_type __nu_val = result_type(1))
  1493. : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val)
  1494. {
  1495. __glibcxx_assert(_M_lambda > result_type(0));
  1496. __glibcxx_assert(_M_mu > result_type(0));
  1497. __glibcxx_assert(_M_nu > result_type(0));
  1498. }
  1499. result_type
  1500. lambda() const
  1501. { return _M_lambda; }
  1502. result_type
  1503. mu() const
  1504. { return _M_mu; }
  1505. result_type
  1506. nu() const
  1507. { return _M_nu; }
  1508. friend bool
  1509. operator==(const param_type& __p1, const param_type& __p2)
  1510. {
  1511. return __p1._M_lambda == __p2._M_lambda
  1512. && __p1._M_mu == __p2._M_mu
  1513. && __p1._M_nu == __p2._M_nu;
  1514. }
  1515. friend bool
  1516. operator!=(const param_type& __p1, const param_type& __p2)
  1517. { return !(__p1 == __p2); }
  1518. private:
  1519. void _M_initialize();
  1520. result_type _M_lambda;
  1521. result_type _M_mu;
  1522. result_type _M_nu;
  1523. };
  1524. /**
  1525. * @brief Constructors.
  1526. * @{
  1527. */
  1528. k_distribution() : k_distribution(1) { }
  1529. explicit
  1530. k_distribution(result_type __lambda_val,
  1531. result_type __mu_val = result_type(1),
  1532. result_type __nu_val = result_type(1))
  1533. : _M_param(__lambda_val, __mu_val, __nu_val),
  1534. _M_gd1(__lambda_val, result_type(1) / __lambda_val),
  1535. _M_gd2(__nu_val, __mu_val / __nu_val)
  1536. { }
  1537. explicit
  1538. k_distribution(const param_type& __p)
  1539. : _M_param(__p),
  1540. _M_gd1(__p.lambda(), result_type(1) / __p.lambda()),
  1541. _M_gd2(__p.nu(), __p.mu() / __p.nu())
  1542. { }
  1543. // @}
  1544. /**
  1545. * @brief Resets the distribution state.
  1546. */
  1547. void
  1548. reset()
  1549. {
  1550. _M_gd1.reset();
  1551. _M_gd2.reset();
  1552. }
  1553. /**
  1554. * @brief Return the parameters of the distribution.
  1555. */
  1556. result_type
  1557. lambda() const
  1558. { return _M_param.lambda(); }
  1559. result_type
  1560. mu() const
  1561. { return _M_param.mu(); }
  1562. result_type
  1563. nu() const
  1564. { return _M_param.nu(); }
  1565. /**
  1566. * @brief Returns the parameter set of the distribution.
  1567. */
  1568. param_type
  1569. param() const
  1570. { return _M_param; }
  1571. /**
  1572. * @brief Sets the parameter set of the distribution.
  1573. * @param __param The new parameter set of the distribution.
  1574. */
  1575. void
  1576. param(const param_type& __param)
  1577. { _M_param = __param; }
  1578. /**
  1579. * @brief Returns the greatest lower bound value of the distribution.
  1580. */
  1581. result_type
  1582. min() const
  1583. { return result_type(0); }
  1584. /**
  1585. * @brief Returns the least upper bound value of the distribution.
  1586. */
  1587. result_type
  1588. max() const
  1589. { return std::numeric_limits<result_type>::max(); }
  1590. /**
  1591. * @brief Generating functions.
  1592. */
  1593. template<typename _UniformRandomNumberGenerator>
  1594. result_type
  1595. operator()(_UniformRandomNumberGenerator&);
  1596. template<typename _UniformRandomNumberGenerator>
  1597. result_type
  1598. operator()(_UniformRandomNumberGenerator&, const param_type&);
  1599. template<typename _ForwardIterator,
  1600. typename _UniformRandomNumberGenerator>
  1601. void
  1602. __generate(_ForwardIterator __f, _ForwardIterator __t,
  1603. _UniformRandomNumberGenerator& __urng)
  1604. { this->__generate(__f, __t, __urng, _M_param); }
  1605. template<typename _ForwardIterator,
  1606. typename _UniformRandomNumberGenerator>
  1607. void
  1608. __generate(_ForwardIterator __f, _ForwardIterator __t,
  1609. _UniformRandomNumberGenerator& __urng,
  1610. const param_type& __p)
  1611. { this->__generate_impl(__f, __t, __urng, __p); }
  1612. template<typename _UniformRandomNumberGenerator>
  1613. void
  1614. __generate(result_type* __f, result_type* __t,
  1615. _UniformRandomNumberGenerator& __urng,
  1616. const param_type& __p)
  1617. { this->__generate_impl(__f, __t, __urng, __p); }
  1618. /**
  1619. * @brief Return true if two K distributions have
  1620. * the same parameters and the sequences that would
  1621. * be generated are equal.
  1622. */
  1623. friend bool
  1624. operator==(const k_distribution& __d1,
  1625. const k_distribution& __d2)
  1626. { return (__d1._M_param == __d2._M_param
  1627. && __d1._M_gd1 == __d2._M_gd1
  1628. && __d1._M_gd2 == __d2._M_gd2); }
  1629. /**
  1630. * @brief Inserts a %k_distribution random number distribution
  1631. * @p __x into the output stream @p __os.
  1632. *
  1633. * @param __os An output stream.
  1634. * @param __x A %k_distribution random number distribution.
  1635. *
  1636. * @returns The output stream with the state of @p __x inserted or in
  1637. * an error state.
  1638. */
  1639. template<typename _RealType1, typename _CharT, typename _Traits>
  1640. friend std::basic_ostream<_CharT, _Traits>&
  1641. operator<<(std::basic_ostream<_CharT, _Traits>&,
  1642. const k_distribution<_RealType1>&);
  1643. /**
  1644. * @brief Extracts a %k_distribution random number distribution
  1645. * @p __x from the input stream @p __is.
  1646. *
  1647. * @param __is An input stream.
  1648. * @param __x A %k_distribution random number
  1649. * generator engine.
  1650. *
  1651. * @returns The input stream with @p __x extracted or in an error state.
  1652. */
  1653. template<typename _RealType1, typename _CharT, typename _Traits>
  1654. friend std::basic_istream<_CharT, _Traits>&
  1655. operator>>(std::basic_istream<_CharT, _Traits>&,
  1656. k_distribution<_RealType1>&);
  1657. private:
  1658. template<typename _ForwardIterator,
  1659. typename _UniformRandomNumberGenerator>
  1660. void
  1661. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  1662. _UniformRandomNumberGenerator& __urng,
  1663. const param_type& __p);
  1664. param_type _M_param;
  1665. std::gamma_distribution<result_type> _M_gd1;
  1666. std::gamma_distribution<result_type> _M_gd2;
  1667. };
  1668. /**
  1669. * @brief Return true if two K distributions are not equal.
  1670. */
  1671. template<typename _RealType>
  1672. inline bool
  1673. operator!=(const k_distribution<_RealType>& __d1,
  1674. const k_distribution<_RealType>& __d2)
  1675. { return !(__d1 == __d2); }
  1676. /**
  1677. * @brief An arcsine continuous distribution for random numbers.
  1678. *
  1679. * The formula for the arcsine probability density function is
  1680. * @f[
  1681. * p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}}
  1682. * @f]
  1683. * where @f$x >= a@f$ and @f$x <= b@f$.
  1684. *
  1685. * <table border=1 cellpadding=10 cellspacing=0>
  1686. * <caption align=top>Distribution Statistics</caption>
  1687. * <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr>
  1688. * <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr>
  1689. * <tr><td>Range</td><td>@f$[a, b]@f$</td></tr>
  1690. * </table>
  1691. */
  1692. template<typename _RealType = double>
  1693. class
  1694. arcsine_distribution
  1695. {
  1696. static_assert(std::is_floating_point<_RealType>::value,
  1697. "template argument not a floating point type");
  1698. public:
  1699. /** The type of the range of the distribution. */
  1700. typedef _RealType result_type;
  1701. /** Parameter type. */
  1702. struct param_type
  1703. {
  1704. typedef arcsine_distribution<result_type> distribution_type;
  1705. param_type() : param_type(0) { }
  1706. param_type(result_type __a, result_type __b = result_type(1))
  1707. : _M_a(__a), _M_b(__b)
  1708. {
  1709. __glibcxx_assert(_M_a <= _M_b);
  1710. }
  1711. result_type
  1712. a() const
  1713. { return _M_a; }
  1714. result_type
  1715. b() const
  1716. { return _M_b; }
  1717. friend bool
  1718. operator==(const param_type& __p1, const param_type& __p2)
  1719. { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
  1720. friend bool
  1721. operator!=(const param_type& __p1, const param_type& __p2)
  1722. { return !(__p1 == __p2); }
  1723. private:
  1724. void _M_initialize();
  1725. result_type _M_a;
  1726. result_type _M_b;
  1727. };
  1728. /**
  1729. * @brief Constructors.
  1730. * :{
  1731. */
  1732. arcsine_distribution() : arcsine_distribution(0) { }
  1733. explicit
  1734. arcsine_distribution(result_type __a, result_type __b = result_type(1))
  1735. : _M_param(__a, __b),
  1736. _M_ud(-1.5707963267948966192313216916397514L,
  1737. +1.5707963267948966192313216916397514L)
  1738. { }
  1739. explicit
  1740. arcsine_distribution(const param_type& __p)
  1741. : _M_param(__p),
  1742. _M_ud(-1.5707963267948966192313216916397514L,
  1743. +1.5707963267948966192313216916397514L)
  1744. { }
  1745. // @}
  1746. /**
  1747. * @brief Resets the distribution state.
  1748. */
  1749. void
  1750. reset()
  1751. { _M_ud.reset(); }
  1752. /**
  1753. * @brief Return the parameters of the distribution.
  1754. */
  1755. result_type
  1756. a() const
  1757. { return _M_param.a(); }
  1758. result_type
  1759. b() const
  1760. { return _M_param.b(); }
  1761. /**
  1762. * @brief Returns the parameter set of the distribution.
  1763. */
  1764. param_type
  1765. param() const
  1766. { return _M_param; }
  1767. /**
  1768. * @brief Sets the parameter set of the distribution.
  1769. * @param __param The new parameter set of the distribution.
  1770. */
  1771. void
  1772. param(const param_type& __param)
  1773. { _M_param = __param; }
  1774. /**
  1775. * @brief Returns the greatest lower bound value of the distribution.
  1776. */
  1777. result_type
  1778. min() const
  1779. { return this->a(); }
  1780. /**
  1781. * @brief Returns the least upper bound value of the distribution.
  1782. */
  1783. result_type
  1784. max() const
  1785. { return this->b(); }
  1786. /**
  1787. * @brief Generating functions.
  1788. */
  1789. template<typename _UniformRandomNumberGenerator>
  1790. result_type
  1791. operator()(_UniformRandomNumberGenerator& __urng)
  1792. {
  1793. result_type __x = std::sin(this->_M_ud(__urng));
  1794. return (__x * (this->b() - this->a())
  1795. + this->a() + this->b()) / result_type(2);
  1796. }
  1797. template<typename _UniformRandomNumberGenerator>
  1798. result_type
  1799. operator()(_UniformRandomNumberGenerator& __urng,
  1800. const param_type& __p)
  1801. {
  1802. result_type __x = std::sin(this->_M_ud(__urng));
  1803. return (__x * (__p.b() - __p.a())
  1804. + __p.a() + __p.b()) / result_type(2);
  1805. }
  1806. template<typename _ForwardIterator,
  1807. typename _UniformRandomNumberGenerator>
  1808. void
  1809. __generate(_ForwardIterator __f, _ForwardIterator __t,
  1810. _UniformRandomNumberGenerator& __urng)
  1811. { this->__generate(__f, __t, __urng, _M_param); }
  1812. template<typename _ForwardIterator,
  1813. typename _UniformRandomNumberGenerator>
  1814. void
  1815. __generate(_ForwardIterator __f, _ForwardIterator __t,
  1816. _UniformRandomNumberGenerator& __urng,
  1817. const param_type& __p)
  1818. { this->__generate_impl(__f, __t, __urng, __p); }
  1819. template<typename _UniformRandomNumberGenerator>
  1820. void
  1821. __generate(result_type* __f, result_type* __t,
  1822. _UniformRandomNumberGenerator& __urng,
  1823. const param_type& __p)
  1824. { this->__generate_impl(__f, __t, __urng, __p); }
  1825. /**
  1826. * @brief Return true if two arcsine distributions have
  1827. * the same parameters and the sequences that would
  1828. * be generated are equal.
  1829. */
  1830. friend bool
  1831. operator==(const arcsine_distribution& __d1,
  1832. const arcsine_distribution& __d2)
  1833. { return (__d1._M_param == __d2._M_param
  1834. && __d1._M_ud == __d2._M_ud); }
  1835. /**
  1836. * @brief Inserts a %arcsine_distribution random number distribution
  1837. * @p __x into the output stream @p __os.
  1838. *
  1839. * @param __os An output stream.
  1840. * @param __x A %arcsine_distribution random number distribution.
  1841. *
  1842. * @returns The output stream with the state of @p __x inserted or in
  1843. * an error state.
  1844. */
  1845. template<typename _RealType1, typename _CharT, typename _Traits>
  1846. friend std::basic_ostream<_CharT, _Traits>&
  1847. operator<<(std::basic_ostream<_CharT, _Traits>&,
  1848. const arcsine_distribution<_RealType1>&);
  1849. /**
  1850. * @brief Extracts a %arcsine_distribution random number distribution
  1851. * @p __x from the input stream @p __is.
  1852. *
  1853. * @param __is An input stream.
  1854. * @param __x A %arcsine_distribution random number
  1855. * generator engine.
  1856. *
  1857. * @returns The input stream with @p __x extracted or in an error state.
  1858. */
  1859. template<typename _RealType1, typename _CharT, typename _Traits>
  1860. friend std::basic_istream<_CharT, _Traits>&
  1861. operator>>(std::basic_istream<_CharT, _Traits>&,
  1862. arcsine_distribution<_RealType1>&);
  1863. private:
  1864. template<typename _ForwardIterator,
  1865. typename _UniformRandomNumberGenerator>
  1866. void
  1867. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  1868. _UniformRandomNumberGenerator& __urng,
  1869. const param_type& __p);
  1870. param_type _M_param;
  1871. std::uniform_real_distribution<result_type> _M_ud;
  1872. };
  1873. /**
  1874. * @brief Return true if two arcsine distributions are not equal.
  1875. */
  1876. template<typename _RealType>
  1877. inline bool
  1878. operator!=(const arcsine_distribution<_RealType>& __d1,
  1879. const arcsine_distribution<_RealType>& __d2)
  1880. { return !(__d1 == __d2); }
  1881. /**
  1882. * @brief A Hoyt continuous distribution for random numbers.
  1883. *
  1884. * The formula for the Hoyt probability density function is
  1885. * @f[
  1886. * p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega}
  1887. * \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right)
  1888. * I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right)
  1889. * @f]
  1890. * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
  1891. * of order 0 and @f$0 < q < 1@f$.
  1892. *
  1893. * <table border=1 cellpadding=10 cellspacing=0>
  1894. * <caption align=top>Distribution Statistics</caption>
  1895. * <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}}
  1896. * E(1 - q^2) @f$</td></tr>
  1897. * <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)}
  1898. * {\pi (1 + q^2)}\right) @f$</td></tr>
  1899. * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
  1900. * </table>
  1901. * where @f$E(x)@f$ is the elliptic function of the second kind.
  1902. */
  1903. template<typename _RealType = double>
  1904. class
  1905. hoyt_distribution
  1906. {
  1907. static_assert(std::is_floating_point<_RealType>::value,
  1908. "template argument not a floating point type");
  1909. public:
  1910. /** The type of the range of the distribution. */
  1911. typedef _RealType result_type;
  1912. /** Parameter type. */
  1913. struct param_type
  1914. {
  1915. typedef hoyt_distribution<result_type> distribution_type;
  1916. param_type() : param_type(0.5) { }
  1917. param_type(result_type __q, result_type __omega = result_type(1))
  1918. : _M_q(__q), _M_omega(__omega)
  1919. {
  1920. __glibcxx_assert(_M_q > result_type(0));
  1921. __glibcxx_assert(_M_q < result_type(1));
  1922. }
  1923. result_type
  1924. q() const
  1925. { return _M_q; }
  1926. result_type
  1927. omega() const
  1928. { return _M_omega; }
  1929. friend bool
  1930. operator==(const param_type& __p1, const param_type& __p2)
  1931. { return __p1._M_q == __p2._M_q && __p1._M_omega == __p2._M_omega; }
  1932. friend bool
  1933. operator!=(const param_type& __p1, const param_type& __p2)
  1934. { return !(__p1 == __p2); }
  1935. private:
  1936. void _M_initialize();
  1937. result_type _M_q;
  1938. result_type _M_omega;
  1939. };
  1940. /**
  1941. * @brief Constructors.
  1942. * @{
  1943. */
  1944. hoyt_distribution() : hoyt_distribution(0.5) { }
  1945. explicit
  1946. hoyt_distribution(result_type __q, result_type __omega = result_type(1))
  1947. : _M_param(__q, __omega),
  1948. _M_ad(result_type(0.5L) * (result_type(1) + __q * __q),
  1949. result_type(0.5L) * (result_type(1) + __q * __q)
  1950. / (__q * __q)),
  1951. _M_ed(result_type(1))
  1952. { }
  1953. explicit
  1954. hoyt_distribution(const param_type& __p)
  1955. : _M_param(__p),
  1956. _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()),
  1957. result_type(0.5L) * (result_type(1) + __p.q() * __p.q())
  1958. / (__p.q() * __p.q())),
  1959. _M_ed(result_type(1))
  1960. { }
  1961. /**
  1962. * @brief Resets the distribution state.
  1963. */
  1964. void
  1965. reset()
  1966. {
  1967. _M_ad.reset();
  1968. _M_ed.reset();
  1969. }
  1970. /**
  1971. * @brief Return the parameters of the distribution.
  1972. */
  1973. result_type
  1974. q() const
  1975. { return _M_param.q(); }
  1976. result_type
  1977. omega() const
  1978. { return _M_param.omega(); }
  1979. /**
  1980. * @brief Returns the parameter set of the distribution.
  1981. */
  1982. param_type
  1983. param() const
  1984. { return _M_param; }
  1985. /**
  1986. * @brief Sets the parameter set of the distribution.
  1987. * @param __param The new parameter set of the distribution.
  1988. */
  1989. void
  1990. param(const param_type& __param)
  1991. { _M_param = __param; }
  1992. /**
  1993. * @brief Returns the greatest lower bound value of the distribution.
  1994. */
  1995. result_type
  1996. min() const
  1997. { return result_type(0); }
  1998. /**
  1999. * @brief Returns the least upper bound value of the distribution.
  2000. */
  2001. result_type
  2002. max() const
  2003. { return std::numeric_limits<result_type>::max(); }
  2004. /**
  2005. * @brief Generating functions.
  2006. */
  2007. template<typename _UniformRandomNumberGenerator>
  2008. result_type
  2009. operator()(_UniformRandomNumberGenerator& __urng);
  2010. template<typename _UniformRandomNumberGenerator>
  2011. result_type
  2012. operator()(_UniformRandomNumberGenerator& __urng,
  2013. const param_type& __p);
  2014. template<typename _ForwardIterator,
  2015. typename _UniformRandomNumberGenerator>
  2016. void
  2017. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2018. _UniformRandomNumberGenerator& __urng)
  2019. { this->__generate(__f, __t, __urng, _M_param); }
  2020. template<typename _ForwardIterator,
  2021. typename _UniformRandomNumberGenerator>
  2022. void
  2023. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2024. _UniformRandomNumberGenerator& __urng,
  2025. const param_type& __p)
  2026. { this->__generate_impl(__f, __t, __urng, __p); }
  2027. template<typename _UniformRandomNumberGenerator>
  2028. void
  2029. __generate(result_type* __f, result_type* __t,
  2030. _UniformRandomNumberGenerator& __urng,
  2031. const param_type& __p)
  2032. { this->__generate_impl(__f, __t, __urng, __p); }
  2033. /**
  2034. * @brief Return true if two Hoyt distributions have
  2035. * the same parameters and the sequences that would
  2036. * be generated are equal.
  2037. */
  2038. friend bool
  2039. operator==(const hoyt_distribution& __d1,
  2040. const hoyt_distribution& __d2)
  2041. { return (__d1._M_param == __d2._M_param
  2042. && __d1._M_ad == __d2._M_ad
  2043. && __d1._M_ed == __d2._M_ed); }
  2044. /**
  2045. * @brief Inserts a %hoyt_distribution random number distribution
  2046. * @p __x into the output stream @p __os.
  2047. *
  2048. * @param __os An output stream.
  2049. * @param __x A %hoyt_distribution random number distribution.
  2050. *
  2051. * @returns The output stream with the state of @p __x inserted or in
  2052. * an error state.
  2053. */
  2054. template<typename _RealType1, typename _CharT, typename _Traits>
  2055. friend std::basic_ostream<_CharT, _Traits>&
  2056. operator<<(std::basic_ostream<_CharT, _Traits>&,
  2057. const hoyt_distribution<_RealType1>&);
  2058. /**
  2059. * @brief Extracts a %hoyt_distribution random number distribution
  2060. * @p __x from the input stream @p __is.
  2061. *
  2062. * @param __is An input stream.
  2063. * @param __x A %hoyt_distribution random number
  2064. * generator engine.
  2065. *
  2066. * @returns The input stream with @p __x extracted or in an error state.
  2067. */
  2068. template<typename _RealType1, typename _CharT, typename _Traits>
  2069. friend std::basic_istream<_CharT, _Traits>&
  2070. operator>>(std::basic_istream<_CharT, _Traits>&,
  2071. hoyt_distribution<_RealType1>&);
  2072. private:
  2073. template<typename _ForwardIterator,
  2074. typename _UniformRandomNumberGenerator>
  2075. void
  2076. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  2077. _UniformRandomNumberGenerator& __urng,
  2078. const param_type& __p);
  2079. param_type _M_param;
  2080. __gnu_cxx::arcsine_distribution<result_type> _M_ad;
  2081. std::exponential_distribution<result_type> _M_ed;
  2082. };
  2083. /**
  2084. * @brief Return true if two Hoyt distributions are not equal.
  2085. */
  2086. template<typename _RealType>
  2087. inline bool
  2088. operator!=(const hoyt_distribution<_RealType>& __d1,
  2089. const hoyt_distribution<_RealType>& __d2)
  2090. { return !(__d1 == __d2); }
  2091. /**
  2092. * @brief A triangular distribution for random numbers.
  2093. *
  2094. * The formula for the triangular probability density function is
  2095. * @f[
  2096. * / 0 for x < a
  2097. * p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)} for a <= x <= b
  2098. * | \frac{2(c-x)}{(c-a)(c-b)} for b < x <= c
  2099. * \ 0 for c < x
  2100. * @f]
  2101. *
  2102. * <table border=1 cellpadding=10 cellspacing=0>
  2103. * <caption align=top>Distribution Statistics</caption>
  2104. * <tr><td>Mean</td><td>@f$ \frac{a+b+c}{2} @f$</td></tr>
  2105. * <tr><td>Variance</td><td>@f$ \frac{a^2+b^2+c^2-ab-ac-bc}
  2106. * {18}@f$</td></tr>
  2107. * <tr><td>Range</td><td>@f$[a, c]@f$</td></tr>
  2108. * </table>
  2109. */
  2110. template<typename _RealType = double>
  2111. class triangular_distribution
  2112. {
  2113. static_assert(std::is_floating_point<_RealType>::value,
  2114. "template argument not a floating point type");
  2115. public:
  2116. /** The type of the range of the distribution. */
  2117. typedef _RealType result_type;
  2118. /** Parameter type. */
  2119. struct param_type
  2120. {
  2121. friend class triangular_distribution<_RealType>;
  2122. param_type() : param_type(0) { }
  2123. explicit
  2124. param_type(_RealType __a,
  2125. _RealType __b = _RealType(0.5),
  2126. _RealType __c = _RealType(1))
  2127. : _M_a(__a), _M_b(__b), _M_c(__c)
  2128. {
  2129. __glibcxx_assert(_M_a <= _M_b);
  2130. __glibcxx_assert(_M_b <= _M_c);
  2131. __glibcxx_assert(_M_a < _M_c);
  2132. _M_r_ab = (_M_b - _M_a) / (_M_c - _M_a);
  2133. _M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a);
  2134. _M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a);
  2135. }
  2136. _RealType
  2137. a() const
  2138. { return _M_a; }
  2139. _RealType
  2140. b() const
  2141. { return _M_b; }
  2142. _RealType
  2143. c() const
  2144. { return _M_c; }
  2145. friend bool
  2146. operator==(const param_type& __p1, const param_type& __p2)
  2147. {
  2148. return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b
  2149. && __p1._M_c == __p2._M_c);
  2150. }
  2151. friend bool
  2152. operator!=(const param_type& __p1, const param_type& __p2)
  2153. { return !(__p1 == __p2); }
  2154. private:
  2155. _RealType _M_a;
  2156. _RealType _M_b;
  2157. _RealType _M_c;
  2158. _RealType _M_r_ab;
  2159. _RealType _M_f_ab_ac;
  2160. _RealType _M_f_bc_ac;
  2161. };
  2162. triangular_distribution() : triangular_distribution(0.0) { }
  2163. /**
  2164. * @brief Constructs a triangle distribution with parameters
  2165. * @f$ a @f$, @f$ b @f$ and @f$ c @f$.
  2166. */
  2167. explicit
  2168. triangular_distribution(result_type __a,
  2169. result_type __b = result_type(0.5),
  2170. result_type __c = result_type(1))
  2171. : _M_param(__a, __b, __c)
  2172. { }
  2173. explicit
  2174. triangular_distribution(const param_type& __p)
  2175. : _M_param(__p)
  2176. { }
  2177. /**
  2178. * @brief Resets the distribution state.
  2179. */
  2180. void
  2181. reset()
  2182. { }
  2183. /**
  2184. * @brief Returns the @f$ a @f$ of the distribution.
  2185. */
  2186. result_type
  2187. a() const
  2188. { return _M_param.a(); }
  2189. /**
  2190. * @brief Returns the @f$ b @f$ of the distribution.
  2191. */
  2192. result_type
  2193. b() const
  2194. { return _M_param.b(); }
  2195. /**
  2196. * @brief Returns the @f$ c @f$ of the distribution.
  2197. */
  2198. result_type
  2199. c() const
  2200. { return _M_param.c(); }
  2201. /**
  2202. * @brief Returns the parameter set of the distribution.
  2203. */
  2204. param_type
  2205. param() const
  2206. { return _M_param; }
  2207. /**
  2208. * @brief Sets the parameter set of the distribution.
  2209. * @param __param The new parameter set of the distribution.
  2210. */
  2211. void
  2212. param(const param_type& __param)
  2213. { _M_param = __param; }
  2214. /**
  2215. * @brief Returns the greatest lower bound value of the distribution.
  2216. */
  2217. result_type
  2218. min() const
  2219. { return _M_param._M_a; }
  2220. /**
  2221. * @brief Returns the least upper bound value of the distribution.
  2222. */
  2223. result_type
  2224. max() const
  2225. { return _M_param._M_c; }
  2226. /**
  2227. * @brief Generating functions.
  2228. */
  2229. template<typename _UniformRandomNumberGenerator>
  2230. result_type
  2231. operator()(_UniformRandomNumberGenerator& __urng)
  2232. { return this->operator()(__urng, _M_param); }
  2233. template<typename _UniformRandomNumberGenerator>
  2234. result_type
  2235. operator()(_UniformRandomNumberGenerator& __urng,
  2236. const param_type& __p)
  2237. {
  2238. std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
  2239. __aurng(__urng);
  2240. result_type __rnd = __aurng();
  2241. if (__rnd <= __p._M_r_ab)
  2242. return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac);
  2243. else
  2244. return __p.c() - std::sqrt((result_type(1) - __rnd)
  2245. * __p._M_f_bc_ac);
  2246. }
  2247. template<typename _ForwardIterator,
  2248. typename _UniformRandomNumberGenerator>
  2249. void
  2250. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2251. _UniformRandomNumberGenerator& __urng)
  2252. { this->__generate(__f, __t, __urng, _M_param); }
  2253. template<typename _ForwardIterator,
  2254. typename _UniformRandomNumberGenerator>
  2255. void
  2256. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2257. _UniformRandomNumberGenerator& __urng,
  2258. const param_type& __p)
  2259. { this->__generate_impl(__f, __t, __urng, __p); }
  2260. template<typename _UniformRandomNumberGenerator>
  2261. void
  2262. __generate(result_type* __f, result_type* __t,
  2263. _UniformRandomNumberGenerator& __urng,
  2264. const param_type& __p)
  2265. { this->__generate_impl(__f, __t, __urng, __p); }
  2266. /**
  2267. * @brief Return true if two triangle distributions have the same
  2268. * parameters and the sequences that would be generated
  2269. * are equal.
  2270. */
  2271. friend bool
  2272. operator==(const triangular_distribution& __d1,
  2273. const triangular_distribution& __d2)
  2274. { return __d1._M_param == __d2._M_param; }
  2275. /**
  2276. * @brief Inserts a %triangular_distribution random number distribution
  2277. * @p __x into the output stream @p __os.
  2278. *
  2279. * @param __os An output stream.
  2280. * @param __x A %triangular_distribution random number distribution.
  2281. *
  2282. * @returns The output stream with the state of @p __x inserted or in
  2283. * an error state.
  2284. */
  2285. template<typename _RealType1, typename _CharT, typename _Traits>
  2286. friend std::basic_ostream<_CharT, _Traits>&
  2287. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  2288. const __gnu_cxx::triangular_distribution<_RealType1>& __x);
  2289. /**
  2290. * @brief Extracts a %triangular_distribution random number distribution
  2291. * @p __x from the input stream @p __is.
  2292. *
  2293. * @param __is An input stream.
  2294. * @param __x A %triangular_distribution random number generator engine.
  2295. *
  2296. * @returns The input stream with @p __x extracted or in an error state.
  2297. */
  2298. template<typename _RealType1, typename _CharT, typename _Traits>
  2299. friend std::basic_istream<_CharT, _Traits>&
  2300. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  2301. __gnu_cxx::triangular_distribution<_RealType1>& __x);
  2302. private:
  2303. template<typename _ForwardIterator,
  2304. typename _UniformRandomNumberGenerator>
  2305. void
  2306. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  2307. _UniformRandomNumberGenerator& __urng,
  2308. const param_type& __p);
  2309. param_type _M_param;
  2310. };
  2311. /**
  2312. * @brief Return true if two triangle distributions are different.
  2313. */
  2314. template<typename _RealType>
  2315. inline bool
  2316. operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1,
  2317. const __gnu_cxx::triangular_distribution<_RealType>& __d2)
  2318. { return !(__d1 == __d2); }
  2319. /**
  2320. * @brief A von Mises distribution for random numbers.
  2321. *
  2322. * The formula for the von Mises probability density function is
  2323. * @f[
  2324. * p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}}
  2325. * {2\pi I_0(\kappa)}
  2326. * @f]
  2327. *
  2328. * The generating functions use the method according to:
  2329. *
  2330. * D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the
  2331. * von Mises Distribution", Journal of the Royal Statistical Society.
  2332. * Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157.
  2333. *
  2334. * <table border=1 cellpadding=10 cellspacing=0>
  2335. * <caption align=top>Distribution Statistics</caption>
  2336. * <tr><td>Mean</td><td>@f$ \mu @f$</td></tr>
  2337. * <tr><td>Variance</td><td>@f$ 1-I_1(\kappa)/I_0(\kappa) @f$</td></tr>
  2338. * <tr><td>Range</td><td>@f$[-\pi, \pi]@f$</td></tr>
  2339. * </table>
  2340. */
  2341. template<typename _RealType = double>
  2342. class von_mises_distribution
  2343. {
  2344. static_assert(std::is_floating_point<_RealType>::value,
  2345. "template argument not a floating point type");
  2346. public:
  2347. /** The type of the range of the distribution. */
  2348. typedef _RealType result_type;
  2349. /** Parameter type. */
  2350. struct param_type
  2351. {
  2352. friend class von_mises_distribution<_RealType>;
  2353. param_type() : param_type(0) { }
  2354. explicit
  2355. param_type(_RealType __mu, _RealType __kappa = _RealType(1))
  2356. : _M_mu(__mu), _M_kappa(__kappa)
  2357. {
  2358. const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi;
  2359. __glibcxx_assert(_M_mu >= -__pi && _M_mu <= __pi);
  2360. __glibcxx_assert(_M_kappa >= _RealType(0));
  2361. auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa
  2362. + _RealType(1)) + _RealType(1);
  2363. auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau))
  2364. / (_RealType(2) * _M_kappa));
  2365. _M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho);
  2366. }
  2367. _RealType
  2368. mu() const
  2369. { return _M_mu; }
  2370. _RealType
  2371. kappa() const
  2372. { return _M_kappa; }
  2373. friend bool
  2374. operator==(const param_type& __p1, const param_type& __p2)
  2375. { return __p1._M_mu == __p2._M_mu && __p1._M_kappa == __p2._M_kappa; }
  2376. friend bool
  2377. operator!=(const param_type& __p1, const param_type& __p2)
  2378. { return !(__p1 == __p2); }
  2379. private:
  2380. _RealType _M_mu;
  2381. _RealType _M_kappa;
  2382. _RealType _M_r;
  2383. };
  2384. von_mises_distribution() : von_mises_distribution(0.0) { }
  2385. /**
  2386. * @brief Constructs a von Mises distribution with parameters
  2387. * @f$\mu@f$ and @f$\kappa@f$.
  2388. */
  2389. explicit
  2390. von_mises_distribution(result_type __mu,
  2391. result_type __kappa = result_type(1))
  2392. : _M_param(__mu, __kappa)
  2393. { }
  2394. explicit
  2395. von_mises_distribution(const param_type& __p)
  2396. : _M_param(__p)
  2397. { }
  2398. /**
  2399. * @brief Resets the distribution state.
  2400. */
  2401. void
  2402. reset()
  2403. { }
  2404. /**
  2405. * @brief Returns the @f$ \mu @f$ of the distribution.
  2406. */
  2407. result_type
  2408. mu() const
  2409. { return _M_param.mu(); }
  2410. /**
  2411. * @brief Returns the @f$ \kappa @f$ of the distribution.
  2412. */
  2413. result_type
  2414. kappa() const
  2415. { return _M_param.kappa(); }
  2416. /**
  2417. * @brief Returns the parameter set of the distribution.
  2418. */
  2419. param_type
  2420. param() const
  2421. { return _M_param; }
  2422. /**
  2423. * @brief Sets the parameter set of the distribution.
  2424. * @param __param The new parameter set of the distribution.
  2425. */
  2426. void
  2427. param(const param_type& __param)
  2428. { _M_param = __param; }
  2429. /**
  2430. * @brief Returns the greatest lower bound value of the distribution.
  2431. */
  2432. result_type
  2433. min() const
  2434. {
  2435. return -__gnu_cxx::__math_constants<result_type>::__pi;
  2436. }
  2437. /**
  2438. * @brief Returns the least upper bound value of the distribution.
  2439. */
  2440. result_type
  2441. max() const
  2442. {
  2443. return __gnu_cxx::__math_constants<result_type>::__pi;
  2444. }
  2445. /**
  2446. * @brief Generating functions.
  2447. */
  2448. template<typename _UniformRandomNumberGenerator>
  2449. result_type
  2450. operator()(_UniformRandomNumberGenerator& __urng)
  2451. { return this->operator()(__urng, _M_param); }
  2452. template<typename _UniformRandomNumberGenerator>
  2453. result_type
  2454. operator()(_UniformRandomNumberGenerator& __urng,
  2455. const param_type& __p);
  2456. template<typename _ForwardIterator,
  2457. typename _UniformRandomNumberGenerator>
  2458. void
  2459. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2460. _UniformRandomNumberGenerator& __urng)
  2461. { this->__generate(__f, __t, __urng, _M_param); }
  2462. template<typename _ForwardIterator,
  2463. typename _UniformRandomNumberGenerator>
  2464. void
  2465. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2466. _UniformRandomNumberGenerator& __urng,
  2467. const param_type& __p)
  2468. { this->__generate_impl(__f, __t, __urng, __p); }
  2469. template<typename _UniformRandomNumberGenerator>
  2470. void
  2471. __generate(result_type* __f, result_type* __t,
  2472. _UniformRandomNumberGenerator& __urng,
  2473. const param_type& __p)
  2474. { this->__generate_impl(__f, __t, __urng, __p); }
  2475. /**
  2476. * @brief Return true if two von Mises distributions have the same
  2477. * parameters and the sequences that would be generated
  2478. * are equal.
  2479. */
  2480. friend bool
  2481. operator==(const von_mises_distribution& __d1,
  2482. const von_mises_distribution& __d2)
  2483. { return __d1._M_param == __d2._M_param; }
  2484. /**
  2485. * @brief Inserts a %von_mises_distribution random number distribution
  2486. * @p __x into the output stream @p __os.
  2487. *
  2488. * @param __os An output stream.
  2489. * @param __x A %von_mises_distribution random number distribution.
  2490. *
  2491. * @returns The output stream with the state of @p __x inserted or in
  2492. * an error state.
  2493. */
  2494. template<typename _RealType1, typename _CharT, typename _Traits>
  2495. friend std::basic_ostream<_CharT, _Traits>&
  2496. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  2497. const __gnu_cxx::von_mises_distribution<_RealType1>& __x);
  2498. /**
  2499. * @brief Extracts a %von_mises_distribution random number distribution
  2500. * @p __x from the input stream @p __is.
  2501. *
  2502. * @param __is An input stream.
  2503. * @param __x A %von_mises_distribution random number generator engine.
  2504. *
  2505. * @returns The input stream with @p __x extracted or in an error state.
  2506. */
  2507. template<typename _RealType1, typename _CharT, typename _Traits>
  2508. friend std::basic_istream<_CharT, _Traits>&
  2509. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  2510. __gnu_cxx::von_mises_distribution<_RealType1>& __x);
  2511. private:
  2512. template<typename _ForwardIterator,
  2513. typename _UniformRandomNumberGenerator>
  2514. void
  2515. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  2516. _UniformRandomNumberGenerator& __urng,
  2517. const param_type& __p);
  2518. param_type _M_param;
  2519. };
  2520. /**
  2521. * @brief Return true if two von Mises distributions are different.
  2522. */
  2523. template<typename _RealType>
  2524. inline bool
  2525. operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1,
  2526. const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
  2527. { return !(__d1 == __d2); }
  2528. /**
  2529. * @brief A discrete hypergeometric random number distribution.
  2530. *
  2531. * The hypergeometric distribution is a discrete probability distribution
  2532. * that describes the probability of @p k successes in @p n draws @a without
  2533. * replacement from a finite population of size @p N containing exactly @p K
  2534. * successes.
  2535. *
  2536. * The formula for the hypergeometric probability density function is
  2537. * @f[
  2538. * p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}}
  2539. * @f]
  2540. * where @f$N@f$ is the total population of the distribution,
  2541. * @f$K@f$ is the total population of the distribution.
  2542. *
  2543. * <table border=1 cellpadding=10 cellspacing=0>
  2544. * <caption align=top>Distribution Statistics</caption>
  2545. * <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr>
  2546. * <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1}
  2547. * @f$</td></tr>
  2548. * <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr>
  2549. * </table>
  2550. */
  2551. template<typename _UIntType = unsigned int>
  2552. class hypergeometric_distribution
  2553. {
  2554. static_assert(std::is_unsigned<_UIntType>::value, "template argument "
  2555. "substituting _UIntType not an unsigned integral type");
  2556. public:
  2557. /** The type of the range of the distribution. */
  2558. typedef _UIntType result_type;
  2559. /** Parameter type. */
  2560. struct param_type
  2561. {
  2562. typedef hypergeometric_distribution<_UIntType> distribution_type;
  2563. friend class hypergeometric_distribution<_UIntType>;
  2564. param_type() : param_type(10) { }
  2565. explicit
  2566. param_type(result_type __N, result_type __K = 5,
  2567. result_type __n = 1)
  2568. : _M_N{__N}, _M_K{__K}, _M_n{__n}
  2569. {
  2570. __glibcxx_assert(_M_N >= _M_K);
  2571. __glibcxx_assert(_M_N >= _M_n);
  2572. }
  2573. result_type
  2574. total_size() const
  2575. { return _M_N; }
  2576. result_type
  2577. successful_size() const
  2578. { return _M_K; }
  2579. result_type
  2580. unsuccessful_size() const
  2581. { return _M_N - _M_K; }
  2582. result_type
  2583. total_draws() const
  2584. { return _M_n; }
  2585. friend bool
  2586. operator==(const param_type& __p1, const param_type& __p2)
  2587. { return (__p1._M_N == __p2._M_N)
  2588. && (__p1._M_K == __p2._M_K)
  2589. && (__p1._M_n == __p2._M_n); }
  2590. friend bool
  2591. operator!=(const param_type& __p1, const param_type& __p2)
  2592. { return !(__p1 == __p2); }
  2593. private:
  2594. result_type _M_N;
  2595. result_type _M_K;
  2596. result_type _M_n;
  2597. };
  2598. // constructors and member functions
  2599. hypergeometric_distribution() : hypergeometric_distribution(10) { }
  2600. explicit
  2601. hypergeometric_distribution(result_type __N, result_type __K = 5,
  2602. result_type __n = 1)
  2603. : _M_param{__N, __K, __n}
  2604. { }
  2605. explicit
  2606. hypergeometric_distribution(const param_type& __p)
  2607. : _M_param{__p}
  2608. { }
  2609. /**
  2610. * @brief Resets the distribution state.
  2611. */
  2612. void
  2613. reset()
  2614. { }
  2615. /**
  2616. * @brief Returns the distribution parameter @p N,
  2617. * the total number of items.
  2618. */
  2619. result_type
  2620. total_size() const
  2621. { return this->_M_param.total_size(); }
  2622. /**
  2623. * @brief Returns the distribution parameter @p K,
  2624. * the total number of successful items.
  2625. */
  2626. result_type
  2627. successful_size() const
  2628. { return this->_M_param.successful_size(); }
  2629. /**
  2630. * @brief Returns the total number of unsuccessful items @f$ N - K @f$.
  2631. */
  2632. result_type
  2633. unsuccessful_size() const
  2634. { return this->_M_param.unsuccessful_size(); }
  2635. /**
  2636. * @brief Returns the distribution parameter @p n,
  2637. * the total number of draws.
  2638. */
  2639. result_type
  2640. total_draws() const
  2641. { return this->_M_param.total_draws(); }
  2642. /**
  2643. * @brief Returns the parameter set of the distribution.
  2644. */
  2645. param_type
  2646. param() const
  2647. { return this->_M_param; }
  2648. /**
  2649. * @brief Sets the parameter set of the distribution.
  2650. * @param __param The new parameter set of the distribution.
  2651. */
  2652. void
  2653. param(const param_type& __param)
  2654. { this->_M_param = __param; }
  2655. /**
  2656. * @brief Returns the greatest lower bound value of the distribution.
  2657. */
  2658. result_type
  2659. min() const
  2660. {
  2661. using _IntType = typename std::make_signed<result_type>::type;
  2662. return static_cast<result_type>(std::max(static_cast<_IntType>(0),
  2663. static_cast<_IntType>(this->total_draws()
  2664. - this->unsuccessful_size())));
  2665. }
  2666. /**
  2667. * @brief Returns the least upper bound value of the distribution.
  2668. */
  2669. result_type
  2670. max() const
  2671. { return std::min(this->successful_size(), this->total_draws()); }
  2672. /**
  2673. * @brief Generating functions.
  2674. */
  2675. template<typename _UniformRandomNumberGenerator>
  2676. result_type
  2677. operator()(_UniformRandomNumberGenerator& __urng)
  2678. { return this->operator()(__urng, this->_M_param); }
  2679. template<typename _UniformRandomNumberGenerator>
  2680. result_type
  2681. operator()(_UniformRandomNumberGenerator& __urng,
  2682. const param_type& __p);
  2683. template<typename _ForwardIterator,
  2684. typename _UniformRandomNumberGenerator>
  2685. void
  2686. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2687. _UniformRandomNumberGenerator& __urng)
  2688. { this->__generate(__f, __t, __urng, this->_M_param); }
  2689. template<typename _ForwardIterator,
  2690. typename _UniformRandomNumberGenerator>
  2691. void
  2692. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2693. _UniformRandomNumberGenerator& __urng,
  2694. const param_type& __p)
  2695. { this->__generate_impl(__f, __t, __urng, __p); }
  2696. template<typename _UniformRandomNumberGenerator>
  2697. void
  2698. __generate(result_type* __f, result_type* __t,
  2699. _UniformRandomNumberGenerator& __urng,
  2700. const param_type& __p)
  2701. { this->__generate_impl(__f, __t, __urng, __p); }
  2702. /**
  2703. * @brief Return true if two hypergeometric distributions have the same
  2704. * parameters and the sequences that would be generated
  2705. * are equal.
  2706. */
  2707. friend bool
  2708. operator==(const hypergeometric_distribution& __d1,
  2709. const hypergeometric_distribution& __d2)
  2710. { return __d1._M_param == __d2._M_param; }
  2711. /**
  2712. * @brief Inserts a %hypergeometric_distribution random number
  2713. * distribution @p __x into the output stream @p __os.
  2714. *
  2715. * @param __os An output stream.
  2716. * @param __x A %hypergeometric_distribution random number
  2717. * distribution.
  2718. *
  2719. * @returns The output stream with the state of @p __x inserted or in
  2720. * an error state.
  2721. */
  2722. template<typename _UIntType1, typename _CharT, typename _Traits>
  2723. friend std::basic_ostream<_CharT, _Traits>&
  2724. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  2725. const __gnu_cxx::hypergeometric_distribution<_UIntType1>&
  2726. __x);
  2727. /**
  2728. * @brief Extracts a %hypergeometric_distribution random number
  2729. * distribution @p __x from the input stream @p __is.
  2730. *
  2731. * @param __is An input stream.
  2732. * @param __x A %hypergeometric_distribution random number generator
  2733. * distribution.
  2734. *
  2735. * @returns The input stream with @p __x extracted or in an error
  2736. * state.
  2737. */
  2738. template<typename _UIntType1, typename _CharT, typename _Traits>
  2739. friend std::basic_istream<_CharT, _Traits>&
  2740. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  2741. __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x);
  2742. private:
  2743. template<typename _ForwardIterator,
  2744. typename _UniformRandomNumberGenerator>
  2745. void
  2746. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  2747. _UniformRandomNumberGenerator& __urng,
  2748. const param_type& __p);
  2749. param_type _M_param;
  2750. };
  2751. /**
  2752. * @brief Return true if two hypergeometric distributions are different.
  2753. */
  2754. template<typename _UIntType>
  2755. inline bool
  2756. operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1,
  2757. const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
  2758. { return !(__d1 == __d2); }
  2759. /**
  2760. * @brief A logistic continuous distribution for random numbers.
  2761. *
  2762. * The formula for the logistic probability density function is
  2763. * @f[
  2764. * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2}
  2765. * @f]
  2766. * where @f$b > 0@f$.
  2767. *
  2768. * The formula for the logistic probability function is
  2769. * @f[
  2770. * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}}
  2771. * @f]
  2772. * where @f$b > 0@f$.
  2773. *
  2774. * <table border=1 cellpadding=10 cellspacing=0>
  2775. * <caption align=top>Distribution Statistics</caption>
  2776. * <tr><td>Mean</td><td>@f$a@f$</td></tr>
  2777. * <tr><td>Variance</td><td>@f$b^2\pi^2/3@f$</td></tr>
  2778. * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
  2779. * </table>
  2780. */
  2781. template<typename _RealType = double>
  2782. class
  2783. logistic_distribution
  2784. {
  2785. static_assert(std::is_floating_point<_RealType>::value,
  2786. "template argument not a floating point type");
  2787. public:
  2788. /** The type of the range of the distribution. */
  2789. typedef _RealType result_type;
  2790. /** Parameter type. */
  2791. struct param_type
  2792. {
  2793. typedef logistic_distribution<result_type> distribution_type;
  2794. param_type() : param_type(0) { }
  2795. explicit
  2796. param_type(result_type __a, result_type __b = result_type(1))
  2797. : _M_a(__a), _M_b(__b)
  2798. {
  2799. __glibcxx_assert(_M_b > result_type(0));
  2800. }
  2801. result_type
  2802. a() const
  2803. { return _M_a; }
  2804. result_type
  2805. b() const
  2806. { return _M_b; }
  2807. friend bool
  2808. operator==(const param_type& __p1, const param_type& __p2)
  2809. { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
  2810. friend bool
  2811. operator!=(const param_type& __p1, const param_type& __p2)
  2812. { return !(__p1 == __p2); }
  2813. private:
  2814. void _M_initialize();
  2815. result_type _M_a;
  2816. result_type _M_b;
  2817. };
  2818. /**
  2819. * @brief Constructors.
  2820. * @{
  2821. */
  2822. logistic_distribution() : logistic_distribution(0.0) { }
  2823. explicit
  2824. logistic_distribution(result_type __a, result_type __b = result_type(1))
  2825. : _M_param(__a, __b)
  2826. { }
  2827. explicit
  2828. logistic_distribution(const param_type& __p)
  2829. : _M_param(__p)
  2830. { }
  2831. // @}
  2832. /**
  2833. * @brief Resets the distribution state.
  2834. */
  2835. void
  2836. reset()
  2837. { }
  2838. /**
  2839. * @brief Return the parameters of the distribution.
  2840. */
  2841. result_type
  2842. a() const
  2843. { return _M_param.a(); }
  2844. result_type
  2845. b() const
  2846. { return _M_param.b(); }
  2847. /**
  2848. * @brief Returns the parameter set of the distribution.
  2849. */
  2850. param_type
  2851. param() const
  2852. { return _M_param; }
  2853. /**
  2854. * @brief Sets the parameter set of the distribution.
  2855. * @param __param The new parameter set of the distribution.
  2856. */
  2857. void
  2858. param(const param_type& __param)
  2859. { _M_param = __param; }
  2860. /**
  2861. * @brief Returns the greatest lower bound value of the distribution.
  2862. */
  2863. result_type
  2864. min() const
  2865. { return -std::numeric_limits<result_type>::max(); }
  2866. /**
  2867. * @brief Returns the least upper bound value of the distribution.
  2868. */
  2869. result_type
  2870. max() const
  2871. { return std::numeric_limits<result_type>::max(); }
  2872. /**
  2873. * @brief Generating functions.
  2874. */
  2875. template<typename _UniformRandomNumberGenerator>
  2876. result_type
  2877. operator()(_UniformRandomNumberGenerator& __urng)
  2878. { return this->operator()(__urng, this->_M_param); }
  2879. template<typename _UniformRandomNumberGenerator>
  2880. result_type
  2881. operator()(_UniformRandomNumberGenerator&,
  2882. const param_type&);
  2883. template<typename _ForwardIterator,
  2884. typename _UniformRandomNumberGenerator>
  2885. void
  2886. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2887. _UniformRandomNumberGenerator& __urng)
  2888. { this->__generate(__f, __t, __urng, this->param()); }
  2889. template<typename _ForwardIterator,
  2890. typename _UniformRandomNumberGenerator>
  2891. void
  2892. __generate(_ForwardIterator __f, _ForwardIterator __t,
  2893. _UniformRandomNumberGenerator& __urng,
  2894. const param_type& __p)
  2895. { this->__generate_impl(__f, __t, __urng, __p); }
  2896. template<typename _UniformRandomNumberGenerator>
  2897. void
  2898. __generate(result_type* __f, result_type* __t,
  2899. _UniformRandomNumberGenerator& __urng,
  2900. const param_type& __p)
  2901. { this->__generate_impl(__f, __t, __urng, __p); }
  2902. /**
  2903. * @brief Return true if two logistic distributions have
  2904. * the same parameters and the sequences that would
  2905. * be generated are equal.
  2906. */
  2907. template<typename _RealType1>
  2908. friend bool
  2909. operator==(const logistic_distribution<_RealType1>& __d1,
  2910. const logistic_distribution<_RealType1>& __d2)
  2911. { return __d1.param() == __d2.param(); }
  2912. /**
  2913. * @brief Inserts a %logistic_distribution random number distribution
  2914. * @p __x into the output stream @p __os.
  2915. *
  2916. * @param __os An output stream.
  2917. * @param __x A %logistic_distribution random number distribution.
  2918. *
  2919. * @returns The output stream with the state of @p __x inserted or in
  2920. * an error state.
  2921. */
  2922. template<typename _RealType1, typename _CharT, typename _Traits>
  2923. friend std::basic_ostream<_CharT, _Traits>&
  2924. operator<<(std::basic_ostream<_CharT, _Traits>&,
  2925. const logistic_distribution<_RealType1>&);
  2926. /**
  2927. * @brief Extracts a %logistic_distribution random number distribution
  2928. * @p __x from the input stream @p __is.
  2929. *
  2930. * @param __is An input stream.
  2931. * @param __x A %logistic_distribution random number
  2932. * generator engine.
  2933. *
  2934. * @returns The input stream with @p __x extracted or in an error state.
  2935. */
  2936. template<typename _RealType1, typename _CharT, typename _Traits>
  2937. friend std::basic_istream<_CharT, _Traits>&
  2938. operator>>(std::basic_istream<_CharT, _Traits>&,
  2939. logistic_distribution<_RealType1>&);
  2940. private:
  2941. template<typename _ForwardIterator,
  2942. typename _UniformRandomNumberGenerator>
  2943. void
  2944. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  2945. _UniformRandomNumberGenerator& __urng,
  2946. const param_type& __p);
  2947. param_type _M_param;
  2948. };
  2949. /**
  2950. * @brief Return true if two logistic distributions are not equal.
  2951. */
  2952. template<typename _RealType1>
  2953. inline bool
  2954. operator!=(const logistic_distribution<_RealType1>& __d1,
  2955. const logistic_distribution<_RealType1>& __d2)
  2956. { return !(__d1 == __d2); }
  2957. /**
  2958. * @brief A distribution for random coordinates on a unit sphere.
  2959. *
  2960. * The method used in the generation function is attributed by Donald Knuth
  2961. * to G. W. Brown, Modern Mathematics for the Engineer (1956).
  2962. */
  2963. template<std::size_t _Dimen, typename _RealType = double>
  2964. class uniform_on_sphere_distribution
  2965. {
  2966. static_assert(std::is_floating_point<_RealType>::value,
  2967. "template argument not a floating point type");
  2968. static_assert(_Dimen != 0, "dimension is zero");
  2969. public:
  2970. /** The type of the range of the distribution. */
  2971. typedef std::array<_RealType, _Dimen> result_type;
  2972. /** Parameter type. */
  2973. struct param_type
  2974. {
  2975. param_type() { }
  2976. friend bool
  2977. operator==(const param_type&, const param_type&)
  2978. { return true; }
  2979. friend bool
  2980. operator!=(const param_type&, const param_type&)
  2981. { return false; }
  2982. };
  2983. /**
  2984. * @brief Constructs a uniform on sphere distribution.
  2985. */
  2986. uniform_on_sphere_distribution()
  2987. : _M_param(), _M_nd()
  2988. { }
  2989. explicit
  2990. uniform_on_sphere_distribution(const param_type& __p)
  2991. : _M_param(__p), _M_nd()
  2992. { }
  2993. /**
  2994. * @brief Resets the distribution state.
  2995. */
  2996. void
  2997. reset()
  2998. { _M_nd.reset(); }
  2999. /**
  3000. * @brief Returns the parameter set of the distribution.
  3001. */
  3002. param_type
  3003. param() const
  3004. { return _M_param; }
  3005. /**
  3006. * @brief Sets the parameter set of the distribution.
  3007. * @param __param The new parameter set of the distribution.
  3008. */
  3009. void
  3010. param(const param_type& __param)
  3011. { _M_param = __param; }
  3012. /**
  3013. * @brief Returns the greatest lower bound value of the distribution.
  3014. * This function makes no sense for this distribution.
  3015. */
  3016. result_type
  3017. min() const
  3018. {
  3019. result_type __res;
  3020. __res.fill(0);
  3021. return __res;
  3022. }
  3023. /**
  3024. * @brief Returns the least upper bound value of the distribution.
  3025. * This function makes no sense for this distribution.
  3026. */
  3027. result_type
  3028. max() const
  3029. {
  3030. result_type __res;
  3031. __res.fill(0);
  3032. return __res;
  3033. }
  3034. /**
  3035. * @brief Generating functions.
  3036. */
  3037. template<typename _UniformRandomNumberGenerator>
  3038. result_type
  3039. operator()(_UniformRandomNumberGenerator& __urng)
  3040. { return this->operator()(__urng, _M_param); }
  3041. template<typename _UniformRandomNumberGenerator>
  3042. result_type
  3043. operator()(_UniformRandomNumberGenerator& __urng,
  3044. const param_type& __p);
  3045. template<typename _ForwardIterator,
  3046. typename _UniformRandomNumberGenerator>
  3047. void
  3048. __generate(_ForwardIterator __f, _ForwardIterator __t,
  3049. _UniformRandomNumberGenerator& __urng)
  3050. { this->__generate(__f, __t, __urng, this->param()); }
  3051. template<typename _ForwardIterator,
  3052. typename _UniformRandomNumberGenerator>
  3053. void
  3054. __generate(_ForwardIterator __f, _ForwardIterator __t,
  3055. _UniformRandomNumberGenerator& __urng,
  3056. const param_type& __p)
  3057. { this->__generate_impl(__f, __t, __urng, __p); }
  3058. template<typename _UniformRandomNumberGenerator>
  3059. void
  3060. __generate(result_type* __f, result_type* __t,
  3061. _UniformRandomNumberGenerator& __urng,
  3062. const param_type& __p)
  3063. { this->__generate_impl(__f, __t, __urng, __p); }
  3064. /**
  3065. * @brief Return true if two uniform on sphere distributions have
  3066. * the same parameters and the sequences that would be
  3067. * generated are equal.
  3068. */
  3069. friend bool
  3070. operator==(const uniform_on_sphere_distribution& __d1,
  3071. const uniform_on_sphere_distribution& __d2)
  3072. { return __d1._M_nd == __d2._M_nd; }
  3073. /**
  3074. * @brief Inserts a %uniform_on_sphere_distribution random number
  3075. * distribution @p __x into the output stream @p __os.
  3076. *
  3077. * @param __os An output stream.
  3078. * @param __x A %uniform_on_sphere_distribution random number
  3079. * distribution.
  3080. *
  3081. * @returns The output stream with the state of @p __x inserted or in
  3082. * an error state.
  3083. */
  3084. template<size_t _Dimen1, typename _RealType1, typename _CharT,
  3085. typename _Traits>
  3086. friend std::basic_ostream<_CharT, _Traits>&
  3087. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  3088. const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
  3089. _RealType1>&
  3090. __x);
  3091. /**
  3092. * @brief Extracts a %uniform_on_sphere_distribution random number
  3093. * distribution
  3094. * @p __x from the input stream @p __is.
  3095. *
  3096. * @param __is An input stream.
  3097. * @param __x A %uniform_on_sphere_distribution random number
  3098. * generator engine.
  3099. *
  3100. * @returns The input stream with @p __x extracted or in an error state.
  3101. */
  3102. template<std::size_t _Dimen1, typename _RealType1, typename _CharT,
  3103. typename _Traits>
  3104. friend std::basic_istream<_CharT, _Traits>&
  3105. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  3106. __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
  3107. _RealType1>& __x);
  3108. private:
  3109. template<typename _ForwardIterator,
  3110. typename _UniformRandomNumberGenerator>
  3111. void
  3112. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  3113. _UniformRandomNumberGenerator& __urng,
  3114. const param_type& __p);
  3115. param_type _M_param;
  3116. std::normal_distribution<_RealType> _M_nd;
  3117. };
  3118. /**
  3119. * @brief Return true if two uniform on sphere distributions are different.
  3120. */
  3121. template<std::size_t _Dimen, typename _RealType>
  3122. inline bool
  3123. operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
  3124. _RealType>& __d1,
  3125. const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
  3126. _RealType>& __d2)
  3127. { return !(__d1 == __d2); }
  3128. /**
  3129. * @brief A distribution for random coordinates inside a unit sphere.
  3130. */
  3131. template<std::size_t _Dimen, typename _RealType = double>
  3132. class uniform_inside_sphere_distribution
  3133. {
  3134. static_assert(std::is_floating_point<_RealType>::value,
  3135. "template argument not a floating point type");
  3136. static_assert(_Dimen != 0, "dimension is zero");
  3137. public:
  3138. /** The type of the range of the distribution. */
  3139. using result_type = std::array<_RealType, _Dimen>;
  3140. /** Parameter type. */
  3141. struct param_type
  3142. {
  3143. using distribution_type
  3144. = uniform_inside_sphere_distribution<_Dimen, _RealType>;
  3145. friend class uniform_inside_sphere_distribution<_Dimen, _RealType>;
  3146. param_type() : param_type(1.0) { }
  3147. explicit
  3148. param_type(_RealType __radius)
  3149. : _M_radius(__radius)
  3150. {
  3151. __glibcxx_assert(_M_radius > _RealType(0));
  3152. }
  3153. _RealType
  3154. radius() const
  3155. { return _M_radius; }
  3156. friend bool
  3157. operator==(const param_type& __p1, const param_type& __p2)
  3158. { return __p1._M_radius == __p2._M_radius; }
  3159. friend bool
  3160. operator!=(const param_type& __p1, const param_type& __p2)
  3161. { return !(__p1 == __p2); }
  3162. private:
  3163. _RealType _M_radius;
  3164. };
  3165. /**
  3166. * @brief Constructors.
  3167. * @{
  3168. */
  3169. uniform_inside_sphere_distribution()
  3170. : uniform_inside_sphere_distribution(1.0)
  3171. { }
  3172. explicit
  3173. uniform_inside_sphere_distribution(_RealType __radius)
  3174. : _M_param(__radius), _M_uosd()
  3175. { }
  3176. explicit
  3177. uniform_inside_sphere_distribution(const param_type& __p)
  3178. : _M_param(__p), _M_uosd()
  3179. { }
  3180. // @}
  3181. /**
  3182. * @brief Resets the distribution state.
  3183. */
  3184. void
  3185. reset()
  3186. { _M_uosd.reset(); }
  3187. /**
  3188. * @brief Returns the @f$radius@f$ of the distribution.
  3189. */
  3190. _RealType
  3191. radius() const
  3192. { return _M_param.radius(); }
  3193. /**
  3194. * @brief Returns the parameter set of the distribution.
  3195. */
  3196. param_type
  3197. param() const
  3198. { return _M_param; }
  3199. /**
  3200. * @brief Sets the parameter set of the distribution.
  3201. * @param __param The new parameter set of the distribution.
  3202. */
  3203. void
  3204. param(const param_type& __param)
  3205. { _M_param = __param; }
  3206. /**
  3207. * @brief Returns the greatest lower bound value of the distribution.
  3208. * This function makes no sense for this distribution.
  3209. */
  3210. result_type
  3211. min() const
  3212. {
  3213. result_type __res;
  3214. __res.fill(0);
  3215. return __res;
  3216. }
  3217. /**
  3218. * @brief Returns the least upper bound value of the distribution.
  3219. * This function makes no sense for this distribution.
  3220. */
  3221. result_type
  3222. max() const
  3223. {
  3224. result_type __res;
  3225. __res.fill(0);
  3226. return __res;
  3227. }
  3228. /**
  3229. * @brief Generating functions.
  3230. */
  3231. template<typename _UniformRandomNumberGenerator>
  3232. result_type
  3233. operator()(_UniformRandomNumberGenerator& __urng)
  3234. { return this->operator()(__urng, _M_param); }
  3235. template<typename _UniformRandomNumberGenerator>
  3236. result_type
  3237. operator()(_UniformRandomNumberGenerator& __urng,
  3238. const param_type& __p);
  3239. template<typename _ForwardIterator,
  3240. typename _UniformRandomNumberGenerator>
  3241. void
  3242. __generate(_ForwardIterator __f, _ForwardIterator __t,
  3243. _UniformRandomNumberGenerator& __urng)
  3244. { this->__generate(__f, __t, __urng, this->param()); }
  3245. template<typename _ForwardIterator,
  3246. typename _UniformRandomNumberGenerator>
  3247. void
  3248. __generate(_ForwardIterator __f, _ForwardIterator __t,
  3249. _UniformRandomNumberGenerator& __urng,
  3250. const param_type& __p)
  3251. { this->__generate_impl(__f, __t, __urng, __p); }
  3252. template<typename _UniformRandomNumberGenerator>
  3253. void
  3254. __generate(result_type* __f, result_type* __t,
  3255. _UniformRandomNumberGenerator& __urng,
  3256. const param_type& __p)
  3257. { this->__generate_impl(__f, __t, __urng, __p); }
  3258. /**
  3259. * @brief Return true if two uniform on sphere distributions have
  3260. * the same parameters and the sequences that would be
  3261. * generated are equal.
  3262. */
  3263. friend bool
  3264. operator==(const uniform_inside_sphere_distribution& __d1,
  3265. const uniform_inside_sphere_distribution& __d2)
  3266. { return __d1._M_param == __d2._M_param && __d1._M_uosd == __d2._M_uosd; }
  3267. /**
  3268. * @brief Inserts a %uniform_inside_sphere_distribution random number
  3269. * distribution @p __x into the output stream @p __os.
  3270. *
  3271. * @param __os An output stream.
  3272. * @param __x A %uniform_inside_sphere_distribution random number
  3273. * distribution.
  3274. *
  3275. * @returns The output stream with the state of @p __x inserted or in
  3276. * an error state.
  3277. */
  3278. template<size_t _Dimen1, typename _RealType1, typename _CharT,
  3279. typename _Traits>
  3280. friend std::basic_ostream<_CharT, _Traits>&
  3281. operator<<(std::basic_ostream<_CharT, _Traits>& __os,
  3282. const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1,
  3283. _RealType1>&
  3284. );
  3285. /**
  3286. * @brief Extracts a %uniform_inside_sphere_distribution random number
  3287. * distribution
  3288. * @p __x from the input stream @p __is.
  3289. *
  3290. * @param __is An input stream.
  3291. * @param __x A %uniform_inside_sphere_distribution random number
  3292. * generator engine.
  3293. *
  3294. * @returns The input stream with @p __x extracted or in an error state.
  3295. */
  3296. template<std::size_t _Dimen1, typename _RealType1, typename _CharT,
  3297. typename _Traits>
  3298. friend std::basic_istream<_CharT, _Traits>&
  3299. operator>>(std::basic_istream<_CharT, _Traits>& __is,
  3300. __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1,
  3301. _RealType1>&);
  3302. private:
  3303. template<typename _ForwardIterator,
  3304. typename _UniformRandomNumberGenerator>
  3305. void
  3306. __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
  3307. _UniformRandomNumberGenerator& __urng,
  3308. const param_type& __p);
  3309. param_type _M_param;
  3310. uniform_on_sphere_distribution<_Dimen, _RealType> _M_uosd;
  3311. };
  3312. /**
  3313. * @brief Return true if two uniform on sphere distributions are different.
  3314. */
  3315. template<std::size_t _Dimen, typename _RealType>
  3316. inline bool
  3317. operator!=(const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen,
  3318. _RealType>& __d1,
  3319. const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen,
  3320. _RealType>& __d2)
  3321. { return !(__d1 == __d2); }
  3322. _GLIBCXX_END_NAMESPACE_VERSION
  3323. } // namespace __gnu_cxx
  3324. #include <ext/opt_random.h>
  3325. #include <ext/random.tcc>
  3326. #endif // _GLIBCXX_USE_C99_STDINT_TR1 && UINT32_C
  3327. #endif // C++11
  3328. #endif // _EXT_RANDOM