]>
Commit | Line | Data |
---|---|---|
1860430a UD |
1 | // Random number extensions -*- C++ -*- |
2 | ||
3 | // Copyright (C) 2012 Free Software Foundation, Inc. | |
4 | // | |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
8 | // Free Software Foundation; either version 3, or (at your option) | |
9 | // any later version. | |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
16 | // Under Section 7 of GPL version 3, you are granted additional | |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
24 | ||
25 | /** @file ext/random | |
26 | * This file is a GNU extension to the Standard C++ Library. | |
27 | */ | |
28 | ||
29 | #ifndef _EXT_RANDOM | |
30 | #define _EXT_RANDOM 1 | |
31 | ||
32 | #pragma GCC system_header | |
33 | ||
8054b82e PC |
34 | #ifndef __GXX_EXPERIMENTAL_CXX0X__ |
35 | # include <bits/c++0x_warning.h> | |
36 | #else | |
37 | ||
1860430a | 38 | #include <random> |
bf30f229 | 39 | #include <array> |
1860430a UD |
40 | #ifdef __SSE2__ |
41 | # include <x86intrin.h> | |
42 | #endif | |
43 | ||
8054b82e | 44 | #ifdef _GLIBCXX_USE_C99_STDINT_TR1 |
1860430a UD |
45 | |
46 | namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) | |
47 | { | |
48 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
49 | ||
eeeef8f4 PC |
50 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
51 | ||
1860430a UD |
52 | /* Mersenne twister implementation optimized for vector operations. |
53 | * | |
54 | * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/ | |
55 | */ | |
56 | template<typename _UIntType, size_t __m, | |
57 | size_t __pos1, size_t __sl1, size_t __sl2, | |
58 | size_t __sr1, size_t __sr2, | |
59 | uint32_t __msk1, uint32_t __msk2, | |
60 | uint32_t __msk3, uint32_t __msk4, | |
61 | uint32_t __parity1, uint32_t __parity2, | |
62 | uint32_t __parity3, uint32_t __parity4> | |
63 | class simd_fast_mersenne_twister_engine | |
64 | { | |
65 | static_assert(std::is_unsigned<_UIntType>::value, "template argument " | |
66 | "substituting _UIntType not an unsigned integral type"); | |
67 | static_assert(__sr1 < 32, "first right shift too large"); | |
68 | static_assert(__sr2 < 16, "second right shift too large"); | |
69 | static_assert(__sl1 < 32, "first left shift too large"); | |
70 | static_assert(__sl2 < 16, "second left shift too large"); | |
71 | ||
72 | public: | |
73 | typedef _UIntType result_type; | |
74 | ||
75 | private: | |
76 | static constexpr size_t m_w = sizeof(result_type) * 8; | |
77 | static constexpr size_t _M_nstate = __m / 128 + 1; | |
78 | static constexpr size_t _M_nstate32 = _M_nstate * 4; | |
79 | ||
80 | static_assert(std::is_unsigned<_UIntType>::value, "template argument " | |
81 | "substituting _UIntType not an unsigned integral type"); | |
82 | static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size"); | |
83 | static_assert(16 % sizeof(_UIntType) == 0, | |
84 | "UIntType size must divide 16"); | |
85 | ||
86 | public: | |
87 | static constexpr size_t state_size = _M_nstate * (16 | |
88 | / sizeof(result_type)); | |
89 | static constexpr result_type default_seed = 5489u; | |
90 | ||
91 | // constructors and member function | |
92 | explicit | |
93 | simd_fast_mersenne_twister_engine(result_type __sd = default_seed) | |
94 | { seed(__sd); } | |
95 | ||
96 | template<typename _Sseq, typename = typename | |
d9d69f64 PC |
97 | std::enable_if<!std::is_same<_Sseq, |
98 | simd_fast_mersenne_twister_engine>::value> | |
1860430a UD |
99 | ::type> |
100 | explicit | |
101 | simd_fast_mersenne_twister_engine(_Sseq& __q) | |
102 | { seed(__q); } | |
103 | ||
104 | void | |
105 | seed(result_type __sd = default_seed); | |
106 | ||
107 | template<typename _Sseq> | |
108 | typename std::enable_if<std::is_class<_Sseq>::value>::type | |
109 | seed(_Sseq& __q); | |
110 | ||
111 | static constexpr result_type | |
112 | min() | |
113 | { return 0; }; | |
114 | ||
115 | static constexpr result_type | |
116 | max() | |
117 | { return std::numeric_limits<result_type>::max(); } | |
118 | ||
119 | void | |
120 | discard(unsigned long long __z); | |
121 | ||
122 | result_type | |
123 | operator()() | |
124 | { | |
125 | if (__builtin_expect(_M_pos >= state_size, 0)) | |
126 | _M_gen_rand(); | |
127 | ||
128 | return _M_stateT[_M_pos++]; | |
129 | } | |
130 | ||
9bf714c2 UD |
131 | template<typename _UIntType_2, size_t __m_2, |
132 | size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, | |
133 | size_t __sr1_2, size_t __sr2_2, | |
134 | uint32_t __msk1_2, uint32_t __msk2_2, | |
135 | uint32_t __msk3_2, uint32_t __msk4_2, | |
136 | uint32_t __parity1_2, uint32_t __parity2_2, | |
137 | uint32_t __parity3_2, uint32_t __parity4_2> | |
138 | friend bool | |
139 | operator==(const simd_fast_mersenne_twister_engine<_UIntType_2, | |
140 | __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, | |
141 | __msk1_2, __msk2_2, __msk3_2, __msk4_2, | |
142 | __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs, | |
143 | const simd_fast_mersenne_twister_engine<_UIntType_2, | |
144 | __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, | |
145 | __msk1_2, __msk2_2, __msk3_2, __msk4_2, | |
146 | __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs); | |
1860430a UD |
147 | |
148 | template<typename _UIntType_2, size_t __m_2, | |
149 | size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, | |
150 | size_t __sr1_2, size_t __sr2_2, | |
151 | uint32_t __msk1_2, uint32_t __msk2_2, | |
152 | uint32_t __msk3_2, uint32_t __msk4_2, | |
153 | uint32_t __parity1_2, uint32_t __parity2_2, | |
154 | uint32_t __parity3_2, uint32_t __parity4_2, | |
155 | typename _CharT, typename _Traits> | |
156 | friend std::basic_ostream<_CharT, _Traits>& | |
157 | operator<<(std::basic_ostream<_CharT, _Traits>& __os, | |
d9d69f64 PC |
158 | const __gnu_cxx::simd_fast_mersenne_twister_engine |
159 | <_UIntType_2, | |
1860430a UD |
160 | __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, |
161 | __msk1_2, __msk2_2, __msk3_2, __msk4_2, | |
162 | __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); | |
163 | ||
164 | template<typename _UIntType_2, size_t __m_2, | |
165 | size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, | |
166 | size_t __sr1_2, size_t __sr2_2, | |
167 | uint32_t __msk1_2, uint32_t __msk2_2, | |
168 | uint32_t __msk3_2, uint32_t __msk4_2, | |
169 | uint32_t __parity1_2, uint32_t __parity2_2, | |
170 | uint32_t __parity3_2, uint32_t __parity4_2, | |
171 | typename _CharT, typename _Traits> | |
172 | friend std::basic_istream<_CharT, _Traits>& | |
173 | operator>>(std::basic_istream<_CharT, _Traits>& __is, | |
174 | __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2, | |
175 | __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, | |
176 | __msk1_2, __msk2_2, __msk3_2, __msk4_2, | |
177 | __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); | |
178 | ||
179 | private: | |
180 | union | |
181 | { | |
182 | #ifdef __SSE2__ | |
183 | __m128i _M_state[_M_nstate]; | |
184 | #endif | |
185 | uint32_t _M_state32[_M_nstate32]; | |
186 | result_type _M_stateT[state_size]; | |
187 | } __attribute__ ((__aligned__ (16))); | |
188 | size_t _M_pos; | |
189 | ||
190 | void _M_gen_rand(void); | |
191 | void _M_period_certification(); | |
192 | }; | |
193 | ||
194 | ||
195 | template<typename _UIntType, size_t __m, | |
196 | size_t __pos1, size_t __sl1, size_t __sl2, | |
197 | size_t __sr1, size_t __sr2, | |
198 | uint32_t __msk1, uint32_t __msk2, | |
199 | uint32_t __msk3, uint32_t __msk4, | |
200 | uint32_t __parity1, uint32_t __parity2, | |
201 | uint32_t __parity3, uint32_t __parity4> | |
202 | inline bool | |
203 | operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, | |
204 | __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, | |
205 | __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, | |
206 | const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, | |
207 | __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, | |
208 | __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) | |
209 | { return !(__lhs == __rhs); } | |
210 | ||
211 | ||
212 | /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined | |
213 | * in the C implementation by Daito and Matsumoto, as both a 32-bit | |
214 | * and 64-bit version. | |
215 | */ | |
216 | typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2, | |
217 | 15, 3, 13, 3, | |
218 | 0xfdff37ffU, 0xef7f3f7dU, | |
219 | 0xff777b7dU, 0x7ff7fb2fU, | |
220 | 0x00000001U, 0x00000000U, | |
221 | 0x00000000U, 0x5986f054U> | |
222 | sfmt607; | |
223 | ||
224 | typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2, | |
225 | 15, 3, 13, 3, | |
226 | 0xfdff37ffU, 0xef7f3f7dU, | |
227 | 0xff777b7dU, 0x7ff7fb2fU, | |
228 | 0x00000001U, 0x00000000U, | |
229 | 0x00000000U, 0x5986f054U> | |
230 | sfmt607_64; | |
231 | ||
232 | ||
233 | typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7, | |
234 | 14, 3, 5, 1, | |
235 | 0xf7fefffdU, 0x7fefcfffU, | |
236 | 0xaff3ef3fU, 0xb5ffff7fU, | |
237 | 0x00000001U, 0x00000000U, | |
238 | 0x00000000U, 0x20000000U> | |
239 | sfmt1279; | |
240 | ||
241 | typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7, | |
242 | 14, 3, 5, 1, | |
243 | 0xf7fefffdU, 0x7fefcfffU, | |
244 | 0xaff3ef3fU, 0xb5ffff7fU, | |
245 | 0x00000001U, 0x00000000U, | |
246 | 0x00000000U, 0x20000000U> | |
247 | sfmt1279_64; | |
248 | ||
249 | ||
250 | typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12, | |
251 | 19, 1, 5, 1, | |
252 | 0xbff7ffbfU, 0xfdfffffeU, | |
253 | 0xf7ffef7fU, 0xf2f7cbbfU, | |
254 | 0x00000001U, 0x00000000U, | |
255 | 0x00000000U, 0x41dfa600U> | |
256 | sfmt2281; | |
257 | ||
258 | typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12, | |
259 | 19, 1, 5, 1, | |
260 | 0xbff7ffbfU, 0xfdfffffeU, | |
261 | 0xf7ffef7fU, 0xf2f7cbbfU, | |
262 | 0x00000001U, 0x00000000U, | |
263 | 0x00000000U, 0x41dfa600U> | |
264 | sfmt2281_64; | |
265 | ||
266 | ||
267 | typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17, | |
268 | 20, 1, 7, 1, | |
269 | 0x9f7bffffU, 0x9fffff5fU, | |
270 | 0x3efffffbU, 0xfffff7bbU, | |
271 | 0xa8000001U, 0xaf5390a3U, | |
272 | 0xb740b3f8U, 0x6c11486dU> | |
273 | sfmt4253; | |
274 | ||
275 | typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17, | |
276 | 20, 1, 7, 1, | |
277 | 0x9f7bffffU, 0x9fffff5fU, | |
278 | 0x3efffffbU, 0xfffff7bbU, | |
279 | 0xa8000001U, 0xaf5390a3U, | |
280 | 0xb740b3f8U, 0x6c11486dU> | |
281 | sfmt4253_64; | |
282 | ||
283 | ||
284 | typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68, | |
285 | 14, 3, 7, 3, | |
286 | 0xeffff7fbU, 0xffffffefU, | |
287 | 0xdfdfbfffU, 0x7fffdbfdU, | |
288 | 0x00000001U, 0x00000000U, | |
289 | 0xe8148000U, 0xd0c7afa3U> | |
290 | sfmt11213; | |
291 | ||
292 | typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68, | |
293 | 14, 3, 7, 3, | |
294 | 0xeffff7fbU, 0xffffffefU, | |
295 | 0xdfdfbfffU, 0x7fffdbfdU, | |
296 | 0x00000001U, 0x00000000U, | |
297 | 0xe8148000U, 0xd0c7afa3U> | |
298 | sfmt11213_64; | |
299 | ||
300 | ||
301 | typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122, | |
302 | 18, 1, 11, 1, | |
303 | 0xdfffffefU, 0xddfecb7fU, | |
304 | 0xbffaffffU, 0xbffffff6U, | |
305 | 0x00000001U, 0x00000000U, | |
306 | 0x00000000U, 0x13c9e684U> | |
307 | sfmt19937; | |
308 | ||
309 | typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122, | |
310 | 18, 1, 11, 1, | |
311 | 0xdfffffefU, 0xddfecb7fU, | |
312 | 0xbffaffffU, 0xbffffff6U, | |
313 | 0x00000001U, 0x00000000U, | |
314 | 0x00000000U, 0x13c9e684U> | |
315 | sfmt19937_64; | |
316 | ||
317 | ||
318 | typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330, | |
319 | 5, 3, 9, 3, | |
320 | 0xeffffffbU, 0xdfbebfffU, | |
321 | 0xbfbf7befU, 0x9ffd7bffU, | |
322 | 0x00000001U, 0x00000000U, | |
323 | 0xa3ac4000U, 0xecc1327aU> | |
324 | sfmt44497; | |
325 | ||
326 | typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330, | |
327 | 5, 3, 9, 3, | |
328 | 0xeffffffbU, 0xdfbebfffU, | |
329 | 0xbfbf7befU, 0x9ffd7bffU, | |
330 | 0x00000001U, 0x00000000U, | |
331 | 0xa3ac4000U, 0xecc1327aU> | |
332 | sfmt44497_64; | |
333 | ||
334 | ||
335 | typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366, | |
336 | 6, 7, 19, 1, | |
337 | 0xfdbffbffU, 0xbff7ff3fU, | |
338 | 0xfd77efffU, 0xbf9ff3ffU, | |
339 | 0x00000001U, 0x00000000U, | |
340 | 0x00000000U, 0xe9528d85U> | |
341 | sfmt86243; | |
342 | ||
343 | typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366, | |
344 | 6, 7, 19, 1, | |
345 | 0xfdbffbffU, 0xbff7ff3fU, | |
346 | 0xfd77efffU, 0xbf9ff3ffU, | |
347 | 0x00000001U, 0x00000000U, | |
348 | 0x00000000U, 0xe9528d85U> | |
349 | sfmt86243_64; | |
350 | ||
351 | ||
352 | typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110, | |
353 | 19, 1, 21, 1, | |
354 | 0xffffbb5fU, 0xfb6ebf95U, | |
355 | 0xfffefffaU, 0xcff77fffU, | |
356 | 0x00000001U, 0x00000000U, | |
357 | 0xcb520000U, 0xc7e91c7dU> | |
358 | sfmt132049; | |
359 | ||
360 | typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110, | |
361 | 19, 1, 21, 1, | |
362 | 0xffffbb5fU, 0xfb6ebf95U, | |
363 | 0xfffefffaU, 0xcff77fffU, | |
364 | 0x00000001U, 0x00000000U, | |
365 | 0xcb520000U, 0xc7e91c7dU> | |
366 | sfmt132049_64; | |
367 | ||
368 | ||
369 | typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627, | |
370 | 11, 3, 10, 1, | |
371 | 0xbff7bff7U, 0xbfffffffU, | |
372 | 0xbffffa7fU, 0xffddfbfbU, | |
373 | 0xf8000001U, 0x89e80709U, | |
374 | 0x3bd2b64bU, 0x0c64b1e4U> | |
375 | sfmt216091; | |
376 | ||
377 | typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627, | |
378 | 11, 3, 10, 1, | |
379 | 0xbff7bff7U, 0xbfffffffU, | |
380 | 0xbffffa7fU, 0xffddfbfbU, | |
381 | 0xf8000001U, 0x89e80709U, | |
382 | 0x3bd2b64bU, 0x0c64b1e4U> | |
383 | sfmt216091_64; | |
384 | ||
eeeef8f4 | 385 | #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
d4d348a9 UD |
386 | |
387 | /** | |
388 | * @brief A beta continuous distribution for random numbers. | |
389 | * | |
390 | * The formula for the beta probability density function is: | |
391 | * @f[ | |
392 | * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)} | |
393 | * x^{\alpha - 1} (1 - x)^{\beta - 1} | |
394 | * @f] | |
395 | */ | |
396 | template<typename _RealType = double> | |
397 | class beta_distribution | |
398 | { | |
399 | static_assert(std::is_floating_point<_RealType>::value, | |
400 | "template argument not a floating point type"); | |
401 | ||
402 | public: | |
403 | /** The type of the range of the distribution. */ | |
404 | typedef _RealType result_type; | |
405 | /** Parameter type. */ | |
406 | struct param_type | |
407 | { | |
408 | typedef beta_distribution<_RealType> distribution_type; | |
409 | friend class beta_distribution<_RealType>; | |
410 | ||
411 | explicit | |
412 | param_type(_RealType __alpha_val = _RealType(1), | |
413 | _RealType __beta_val = _RealType(1)) | |
414 | : _M_alpha(__alpha_val), _M_beta(__beta_val) | |
415 | { | |
416 | _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0)); | |
417 | _GLIBCXX_DEBUG_ASSERT(_M_beta > _RealType(0)); | |
418 | } | |
419 | ||
420 | _RealType | |
421 | alpha() const | |
422 | { return _M_alpha; } | |
423 | ||
424 | _RealType | |
425 | beta() const | |
426 | { return _M_beta; } | |
427 | ||
428 | friend bool | |
429 | operator==(const param_type& __p1, const param_type& __p2) | |
430 | { return (__p1._M_alpha == __p2._M_alpha | |
431 | && __p1._M_beta == __p2._M_beta); } | |
432 | ||
433 | private: | |
434 | void | |
435 | _M_initialize(); | |
436 | ||
437 | _RealType _M_alpha; | |
438 | _RealType _M_beta; | |
439 | }; | |
440 | ||
441 | public: | |
442 | /** | |
443 | * @brief Constructs a beta distribution with parameters | |
444 | * @f$\alpha@f$ and @f$\beta@f$. | |
445 | */ | |
446 | explicit | |
447 | beta_distribution(_RealType __alpha_val = _RealType(1), | |
448 | _RealType __beta_val = _RealType(1)) | |
449 | : _M_param(__alpha_val, __beta_val) | |
450 | { } | |
451 | ||
452 | explicit | |
453 | beta_distribution(const param_type& __p) | |
454 | : _M_param(__p) | |
455 | { } | |
456 | ||
457 | /** | |
458 | * @brief Resets the distribution state. | |
459 | */ | |
460 | void | |
461 | reset() | |
462 | { } | |
463 | ||
464 | /** | |
465 | * @brief Returns the @f$\alpha@f$ of the distribution. | |
466 | */ | |
467 | _RealType | |
468 | alpha() const | |
469 | { return _M_param.alpha(); } | |
470 | ||
471 | /** | |
472 | * @brief Returns the @f$\beta@f$ of the distribution. | |
473 | */ | |
474 | _RealType | |
475 | beta() const | |
476 | { return _M_param.beta(); } | |
477 | ||
478 | /** | |
479 | * @brief Returns the parameter set of the distribution. | |
480 | */ | |
481 | param_type | |
482 | param() const | |
483 | { return _M_param; } | |
484 | ||
485 | /** | |
486 | * @brief Sets the parameter set of the distribution. | |
487 | * @param __param The new parameter set of the distribution. | |
488 | */ | |
489 | void | |
490 | param(const param_type& __param) | |
491 | { _M_param = __param; } | |
492 | ||
493 | /** | |
494 | * @brief Returns the greatest lower bound value of the distribution. | |
495 | */ | |
496 | result_type | |
497 | min() const | |
498 | { return result_type(0); } | |
499 | ||
500 | /** | |
501 | * @brief Returns the least upper bound value of the distribution. | |
502 | */ | |
503 | result_type | |
504 | max() const | |
505 | { return result_type(1); } | |
506 | ||
507 | /** | |
508 | * @brief Generating functions. | |
509 | */ | |
510 | template<typename _UniformRandomNumberGenerator> | |
511 | result_type | |
512 | operator()(_UniformRandomNumberGenerator& __urng) | |
513 | { return this->operator()(__urng, this->param()); } | |
514 | ||
515 | template<typename _UniformRandomNumberGenerator> | |
516 | result_type | |
517 | operator()(_UniformRandomNumberGenerator& __urng, | |
518 | const param_type& __p); | |
519 | ||
520 | template<typename _ForwardIterator, | |
521 | typename _UniformRandomNumberGenerator> | |
522 | void | |
523 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
524 | _UniformRandomNumberGenerator& __urng) | |
525 | { this->__generate(__f, __t, __urng, this->param()); } | |
526 | ||
527 | template<typename _ForwardIterator, | |
528 | typename _UniformRandomNumberGenerator> | |
529 | void | |
530 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
531 | _UniformRandomNumberGenerator& __urng, | |
532 | const param_type& __p) | |
533 | { this->__generate_impl(__f, __t, __urng, __p); } | |
534 | ||
535 | template<typename _UniformRandomNumberGenerator> | |
536 | void | |
537 | __generate(result_type* __f, result_type* __t, | |
538 | _UniformRandomNumberGenerator& __urng, | |
539 | const param_type& __p) | |
540 | { this->__generate_impl(__f, __t, __urng, __p); } | |
541 | ||
d4d348a9 UD |
542 | /** |
543 | * @brief Inserts a %beta_distribution random number distribution | |
544 | * @p __x into the output stream @p __os. | |
545 | * | |
546 | * @param __os An output stream. | |
547 | * @param __x A %beta_distribution random number distribution. | |
548 | * | |
549 | * @returns The output stream with the state of @p __x inserted or in | |
550 | * an error state. | |
551 | */ | |
552 | template<typename _RealType1, typename _CharT, typename _Traits> | |
553 | friend std::basic_ostream<_CharT, _Traits>& | |
554 | operator<<(std::basic_ostream<_CharT, _Traits>& __os, | |
555 | const __gnu_cxx::beta_distribution<_RealType1>& __x); | |
556 | ||
557 | /** | |
558 | * @brief Extracts a %beta_distribution random number distribution | |
559 | * @p __x from the input stream @p __is. | |
560 | * | |
561 | * @param __is An input stream. | |
562 | * @param __x A %beta_distribution random number generator engine. | |
563 | * | |
564 | * @returns The input stream with @p __x extracted or in an error state. | |
565 | */ | |
566 | template<typename _RealType1, typename _CharT, typename _Traits> | |
567 | friend std::basic_istream<_CharT, _Traits>& | |
568 | operator>>(std::basic_istream<_CharT, _Traits>& __is, | |
569 | __gnu_cxx::beta_distribution<_RealType1>& __x); | |
570 | ||
571 | private: | |
572 | template<typename _ForwardIterator, | |
573 | typename _UniformRandomNumberGenerator> | |
574 | void | |
575 | __generate_impl(_ForwardIterator __f, _ForwardIterator __t, | |
576 | _UniformRandomNumberGenerator& __urng, | |
577 | const param_type& __p); | |
578 | ||
579 | param_type _M_param; | |
580 | }; | |
581 | ||
28312618 ESR |
582 | /** |
583 | * @brief Return true if two beta distributions have the same | |
584 | * parameters and the sequences that would be generated | |
585 | * are equal. | |
586 | */ | |
587 | template<typename _RealType> | |
588 | inline bool | |
589 | operator==(const __gnu_cxx::beta_distribution<_RealType>& __d1, | |
590 | const __gnu_cxx::beta_distribution<_RealType>& __d2) | |
591 | { return __d1.param() == __d2.param(); } | |
592 | ||
d4d348a9 UD |
593 | /** |
594 | * @brief Return true if two beta distributions are different. | |
595 | */ | |
28312618 ESR |
596 | template<typename _RealType> |
597 | inline bool | |
598 | operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1, | |
599 | const __gnu_cxx::beta_distribution<_RealType>& __d2) | |
600 | { return !(__d1 == __d2); } | |
d4d348a9 UD |
601 | |
602 | ||
bf30f229 UD |
603 | /** |
604 | * @brief A multi-variate normal continuous distribution for random numbers. | |
605 | * | |
606 | * The formula for the normal probability density function is | |
607 | * @f[ | |
608 | * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) = | |
609 | * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}} | |
610 | * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T} | |
611 | * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})} | |
612 | * @f] | |
613 | * | |
614 | * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are | |
615 | * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance | |
616 | * matrix (which must be positive-definite). | |
617 | */ | |
618 | template<std::size_t _Dimen, typename _RealType = double> | |
619 | class normal_mv_distribution | |
620 | { | |
621 | static_assert(std::is_floating_point<_RealType>::value, | |
622 | "template argument not a floating point type"); | |
623 | static_assert(_Dimen != 0, "dimension is zero"); | |
624 | ||
625 | public: | |
626 | /** The type of the range of the distribution. */ | |
627 | typedef std::array<_RealType, _Dimen> result_type; | |
628 | /** Parameter type. */ | |
629 | class param_type | |
630 | { | |
631 | static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2; | |
632 | ||
633 | public: | |
634 | typedef normal_mv_distribution<_Dimen, _RealType> distribution_type; | |
635 | friend class normal_mv_distribution<_Dimen, _RealType>; | |
636 | ||
637 | param_type() | |
638 | { | |
639 | std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0)); | |
640 | auto __it = _M_t.begin(); | |
641 | for (size_t __i = 0; __i < _Dimen; ++__i) | |
642 | { | |
643 | std::fill_n(__it, __i, _RealType(0)); | |
644 | __it += __i; | |
645 | *__it++ = _RealType(1); | |
646 | } | |
647 | } | |
648 | ||
649 | template<typename _ForwardIterator1, typename _ForwardIterator2> | |
650 | param_type(_ForwardIterator1 __meanbegin, | |
651 | _ForwardIterator1 __meanend, | |
652 | _ForwardIterator2 __varcovbegin, | |
653 | _ForwardIterator2 __varcovend) | |
654 | { | |
655 | __glibcxx_function_requires(_ForwardIteratorConcept< | |
656 | _ForwardIterator1>) | |
657 | __glibcxx_function_requires(_ForwardIteratorConcept< | |
658 | _ForwardIterator2>) | |
659 | _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend) | |
660 | <= _Dimen); | |
661 | const auto __dist = std::distance(__varcovbegin, __varcovend); | |
662 | _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen | |
663 | || __dist == _Dimen * (_Dimen + 1) / 2 | |
664 | || __dist == _Dimen); | |
665 | ||
666 | if (__dist == _Dimen * _Dimen) | |
667 | _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend); | |
668 | else if (__dist == _Dimen * (_Dimen + 1) / 2) | |
669 | _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend); | |
670 | else | |
671 | _M_init_diagonal(__meanbegin, __meanend, | |
672 | __varcovbegin, __varcovend); | |
673 | } | |
674 | ||
675 | param_type(std::initializer_list<_RealType> __mean, | |
676 | std::initializer_list<_RealType> __varcov) | |
677 | { | |
678 | _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen); | |
679 | _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen | |
680 | || __varcov.size() == _Dimen * (_Dimen + 1) / 2 | |
681 | || __varcov.size() == _Dimen); | |
682 | ||
683 | if (__varcov.size() == _Dimen * _Dimen) | |
684 | _M_init_full(__mean.begin(), __mean.end(), | |
685 | __varcov.begin(), __varcov.end()); | |
686 | else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2) | |
687 | _M_init_lower(__mean.begin(), __mean.end(), | |
688 | __varcov.begin(), __varcov.end()); | |
689 | else | |
690 | _M_init_diagonal(__mean.begin(), __mean.end(), | |
691 | __varcov.begin(), __varcov.end()); | |
692 | } | |
693 | ||
694 | std::array<_RealType, _Dimen> | |
695 | mean() const | |
696 | { return _M_mean; } | |
697 | ||
698 | std::array<_RealType, _M_t_size> | |
699 | varcov() const | |
700 | { return _M_t; } | |
701 | ||
702 | friend bool | |
703 | operator==(const param_type& __p1, const param_type& __p2) | |
704 | { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; } | |
705 | ||
706 | private: | |
707 | template <typename _InputIterator1, typename _InputIterator2> | |
708 | void _M_init_full(_InputIterator1 __meanbegin, | |
709 | _InputIterator1 __meanend, | |
710 | _InputIterator2 __varcovbegin, | |
711 | _InputIterator2 __varcovend); | |
712 | template <typename _InputIterator1, typename _InputIterator2> | |
713 | void _M_init_lower(_InputIterator1 __meanbegin, | |
714 | _InputIterator1 __meanend, | |
715 | _InputIterator2 __varcovbegin, | |
716 | _InputIterator2 __varcovend); | |
717 | template <typename _InputIterator1, typename _InputIterator2> | |
718 | void _M_init_diagonal(_InputIterator1 __meanbegin, | |
719 | _InputIterator1 __meanend, | |
720 | _InputIterator2 __varbegin, | |
721 | _InputIterator2 __varend); | |
722 | ||
723 | std::array<_RealType, _Dimen> _M_mean; | |
724 | std::array<_RealType, _M_t_size> _M_t; | |
725 | }; | |
726 | ||
727 | public: | |
728 | normal_mv_distribution() | |
729 | : _M_param(), _M_nd() | |
730 | { } | |
731 | ||
732 | template<typename _ForwardIterator1, typename _ForwardIterator2> | |
733 | normal_mv_distribution(_ForwardIterator1 __meanbegin, | |
734 | _ForwardIterator1 __meanend, | |
735 | _ForwardIterator2 __varcovbegin, | |
736 | _ForwardIterator2 __varcovend) | |
737 | : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend), | |
738 | _M_nd() | |
739 | { } | |
740 | ||
741 | normal_mv_distribution(std::initializer_list<_RealType> __mean, | |
742 | std::initializer_list<_RealType> __varcov) | |
743 | : _M_param(__mean, __varcov), _M_nd() | |
744 | { } | |
745 | ||
746 | explicit | |
747 | normal_mv_distribution(const param_type& __p) | |
748 | : _M_param(__p), _M_nd() | |
749 | { } | |
750 | ||
751 | /** | |
752 | * @brief Resets the distribution state. | |
753 | */ | |
754 | void | |
755 | reset() | |
756 | { _M_nd.reset(); } | |
757 | ||
758 | /** | |
759 | * @brief Returns the mean of the distribution. | |
760 | */ | |
761 | result_type | |
762 | mean() const | |
763 | { return _M_param.mean(); } | |
764 | ||
765 | /** | |
766 | * @brief Returns the compact form of the variance/covariance | |
767 | * matrix of the distribution. | |
768 | */ | |
769 | std::array<_RealType, _Dimen * (_Dimen + 1) / 2> | |
770 | varcov() const | |
771 | { return _M_param.varcov(); } | |
772 | ||
773 | /** | |
774 | * @brief Returns the parameter set of the distribution. | |
775 | */ | |
776 | param_type | |
777 | param() const | |
778 | { return _M_param; } | |
779 | ||
780 | /** | |
781 | * @brief Sets the parameter set of the distribution. | |
782 | * @param __param The new parameter set of the distribution. | |
783 | */ | |
784 | void | |
785 | param(const param_type& __param) | |
786 | { _M_param = __param; } | |
787 | ||
788 | /** | |
789 | * @brief Returns the greatest lower bound value of the distribution. | |
790 | */ | |
791 | result_type | |
792 | min() const | |
793 | { result_type __res; | |
794 | __res.fill(std::numeric_limits<_RealType>::min()); | |
795 | return __res; } | |
796 | ||
797 | /** | |
798 | * @brief Returns the least upper bound value of the distribution. | |
799 | */ | |
800 | result_type | |
801 | max() const | |
802 | { result_type __res; | |
803 | __res.fill(std::numeric_limits<_RealType>::max()); | |
804 | return __res; } | |
805 | ||
806 | /** | |
807 | * @brief Generating functions. | |
808 | */ | |
809 | template<typename _UniformRandomNumberGenerator> | |
810 | result_type | |
811 | operator()(_UniformRandomNumberGenerator& __urng) | |
812 | { return this->operator()(__urng, this->param()); } | |
813 | ||
814 | template<typename _UniformRandomNumberGenerator> | |
815 | result_type | |
816 | operator()(_UniformRandomNumberGenerator& __urng, | |
817 | const param_type& __p); | |
818 | ||
819 | template<typename _ForwardIterator, | |
820 | typename _UniformRandomNumberGenerator> | |
821 | void | |
822 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
823 | _UniformRandomNumberGenerator& __urng) | |
824 | { return this->__generate_impl(__f, __t, __urng, this->param()); } | |
825 | ||
826 | template<typename _ForwardIterator, | |
827 | typename _UniformRandomNumberGenerator> | |
828 | void | |
829 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
830 | _UniformRandomNumberGenerator& __urng, | |
831 | const param_type& __p) | |
832 | { return this->__generate_impl(__f, __t, __urng, __p); } | |
833 | ||
834 | /** | |
835 | * @brief Return true if two multi-variant normal distributions have | |
836 | * the same parameters and the sequences that would | |
837 | * be generated are equal. | |
838 | */ | |
839 | template<size_t _Dimen1, typename _RealType1> | |
840 | friend bool | |
841 | operator==(const | |
842 | __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& | |
843 | __d1, | |
844 | const | |
845 | __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& | |
846 | __d2); | |
847 | ||
848 | /** | |
849 | * @brief Inserts a %normal_mv_distribution random number distribution | |
850 | * @p __x into the output stream @p __os. | |
851 | * | |
852 | * @param __os An output stream. | |
853 | * @param __x A %normal_mv_distribution random number distribution. | |
854 | * | |
855 | * @returns The output stream with the state of @p __x inserted or in | |
856 | * an error state. | |
857 | */ | |
858 | template<size_t _Dimen1, typename _RealType1, | |
859 | typename _CharT, typename _Traits> | |
860 | friend std::basic_ostream<_CharT, _Traits>& | |
861 | operator<<(std::basic_ostream<_CharT, _Traits>& __os, | |
862 | const | |
863 | __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& | |
864 | __x); | |
865 | ||
866 | /** | |
867 | * @brief Extracts a %normal_mv_distribution random number distribution | |
868 | * @p __x from the input stream @p __is. | |
869 | * | |
870 | * @param __is An input stream. | |
871 | * @param __x A %normal_mv_distribution random number generator engine. | |
872 | * | |
873 | * @returns The input stream with @p __x extracted or in an error | |
874 | * state. | |
875 | */ | |
876 | template<size_t _Dimen1, typename _RealType1, | |
877 | typename _CharT, typename _Traits> | |
878 | friend std::basic_istream<_CharT, _Traits>& | |
879 | operator>>(std::basic_istream<_CharT, _Traits>& __is, | |
880 | __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& | |
881 | __x); | |
882 | ||
883 | private: | |
884 | template<typename _ForwardIterator, | |
885 | typename _UniformRandomNumberGenerator> | |
886 | void | |
887 | __generate_impl(_ForwardIterator __f, _ForwardIterator __t, | |
888 | _UniformRandomNumberGenerator& __urng, | |
889 | const param_type& __p); | |
890 | ||
891 | param_type _M_param; | |
892 | std::normal_distribution<_RealType> _M_nd; | |
893 | }; | |
894 | ||
895 | /** | |
896 | * @brief Return true if two multi-variate normal distributions are | |
897 | * different. | |
898 | */ | |
899 | template<size_t _Dimen, typename _RealType> | |
900 | inline bool | |
901 | operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& | |
902 | __d1, | |
903 | const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& | |
904 | __d2) | |
905 | { return !(__d1 == __d2); } | |
906 | ||
d4d348a9 | 907 | |
28312618 ESR |
908 | /** |
909 | * @brief A Rice continuous distribution for random numbers. | |
910 | * | |
911 | * The formula for the Rice probability density function is | |
912 | * @f[ | |
913 | * p(x|\nu,\sigma) = \frac{x}{\sigma^2} | |
914 | * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right) | |
915 | * I_0\left(\frac{x \nu}{\sigma^2}\right) | |
916 | * @f] | |
917 | * where @f$I_0(z)@f$ is the modified Bessel function of the first kind | |
918 | * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$. | |
919 | * | |
920 | * <table border=1 cellpadding=10 cellspacing=0> | |
921 | * <caption align=top>Distribution Statistics</caption> | |
922 | * <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr> | |
923 | * <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2 | |
924 | * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr> | |
925 | * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> | |
926 | * </table> | |
927 | * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2. | |
928 | */ | |
929 | template<typename _RealType = double> | |
930 | class | |
931 | rice_distribution | |
932 | { | |
933 | static_assert(std::is_floating_point<_RealType>::value, | |
934 | "template argument not a floating point type"); | |
935 | public: | |
936 | /** The type of the range of the distribution. */ | |
937 | typedef _RealType result_type; | |
938 | /** Parameter type. */ | |
939 | struct param_type | |
940 | { | |
941 | typedef rice_distribution<result_type> distribution_type; | |
942 | ||
37f1d5c9 UB |
943 | param_type(result_type __nu_val = result_type(0), |
944 | result_type __sigma_val = result_type(1)) | |
945 | : _M_nu(__nu_val), _M_sigma(__sigma_val) | |
28312618 ESR |
946 | { |
947 | _GLIBCXX_DEBUG_ASSERT(_M_nu >= result_type(0)); | |
948 | _GLIBCXX_DEBUG_ASSERT(_M_sigma > result_type(0)); | |
949 | } | |
950 | ||
951 | result_type | |
952 | nu() const | |
953 | { return _M_nu; } | |
954 | ||
955 | result_type | |
956 | sigma() const | |
957 | { return _M_sigma; } | |
958 | ||
959 | friend bool | |
960 | operator==(const param_type& __p1, const param_type& __p2) | |
961 | { return __p1._M_nu == __p2._M_nu | |
962 | && __p1._M_sigma == __p2._M_sigma; } | |
963 | ||
964 | private: | |
965 | void _M_initialize(); | |
966 | ||
967 | result_type _M_nu; | |
968 | result_type _M_sigma; | |
969 | }; | |
970 | ||
971 | /** | |
972 | * @brief Constructors. | |
973 | */ | |
974 | explicit | |
37f1d5c9 UB |
975 | rice_distribution(result_type __nu_val = result_type(0), |
976 | result_type __sigma_val = result_type(1)) | |
977 | : _M_param(__nu_val, __sigma_val), | |
978 | _M_ndx(__nu_val, __sigma_val), | |
979 | _M_ndy(result_type(0), __sigma_val) | |
28312618 ESR |
980 | { } |
981 | ||
982 | explicit | |
983 | rice_distribution(const param_type& __p) | |
984 | : _M_param(__p), | |
985 | _M_ndx(__p.nu(), __p.sigma()), | |
986 | _M_ndy(result_type(0), __p.sigma()) | |
987 | { } | |
988 | ||
989 | /** | |
990 | * @brief Resets the distribution state. | |
991 | */ | |
992 | void | |
993 | reset() | |
994 | { | |
995 | _M_ndx.reset(); | |
996 | _M_ndy.reset(); | |
997 | } | |
998 | ||
999 | /** | |
1000 | * @brief Return the parameters of the distribution. | |
1001 | */ | |
1002 | result_type | |
1003 | nu() const | |
1004 | { return _M_param.nu(); } | |
1005 | ||
1006 | result_type | |
1007 | sigma() const | |
1008 | { return _M_param.sigma(); } | |
1009 | ||
1010 | /** | |
1011 | * @brief Returns the parameter set of the distribution. | |
1012 | */ | |
1013 | param_type | |
1014 | param() const | |
1015 | { return _M_param; } | |
1016 | ||
1017 | /** | |
1018 | * @brief Sets the parameter set of the distribution. | |
1019 | * @param __param The new parameter set of the distribution. | |
1020 | */ | |
1021 | void | |
1022 | param(const param_type& __param) | |
1023 | { _M_param = __param; } | |
1024 | ||
1025 | /** | |
1026 | * @brief Returns the greatest lower bound value of the distribution. | |
1027 | */ | |
1028 | result_type | |
1029 | min() const | |
1030 | { return result_type(0); } | |
1031 | ||
1032 | /** | |
1033 | * @brief Returns the least upper bound value of the distribution. | |
1034 | */ | |
1035 | result_type | |
1036 | max() const | |
1037 | { return std::numeric_limits<result_type>::max(); } | |
1038 | ||
1039 | /** | |
1040 | * @brief Generating functions. | |
1041 | */ | |
1042 | template<typename _UniformRandomNumberGenerator> | |
1043 | result_type | |
1044 | operator()(_UniformRandomNumberGenerator& __urng) | |
1045 | { | |
1046 | result_type __x = this->_M_ndx(__urng); | |
1047 | result_type __y = this->_M_ndy(__urng); | |
decf0e27 | 1048 | #if _GLIBCXX_USE_C99_MATH_TR1 |
28312618 | 1049 | return std::hypot(__x, __y); |
decf0e27 PC |
1050 | #else |
1051 | return std::sqrt(__x * __x + __y * __y); | |
1052 | #endif | |
28312618 ESR |
1053 | } |
1054 | ||
1055 | template<typename _UniformRandomNumberGenerator> | |
1056 | result_type | |
1057 | operator()(_UniformRandomNumberGenerator& __urng, | |
1058 | const param_type& __p) | |
1059 | { | |
1060 | typename std::normal_distribution<result_type>::param_type | |
1061 | __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); | |
1062 | result_type __x = this->_M_ndx(__px, __urng); | |
1063 | result_type __y = this->_M_ndy(__py, __urng); | |
decf0e27 | 1064 | #if _GLIBCXX_USE_C99_MATH_TR1 |
28312618 | 1065 | return std::hypot(__x, __y); |
decf0e27 PC |
1066 | #else |
1067 | return std::sqrt(__x * __x + __y * __y); | |
1068 | #endif | |
28312618 ESR |
1069 | } |
1070 | ||
1071 | template<typename _ForwardIterator, | |
1072 | typename _UniformRandomNumberGenerator> | |
1073 | void | |
1074 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
1075 | _UniformRandomNumberGenerator& __urng) | |
1076 | { this->__generate(__f, __t, __urng, this->param()); } | |
1077 | ||
1078 | template<typename _ForwardIterator, | |
1079 | typename _UniformRandomNumberGenerator> | |
1080 | void | |
1081 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
1082 | _UniformRandomNumberGenerator& __urng, | |
1083 | const param_type& __p) | |
1084 | { this->__generate_impl(__f, __t, __urng, __p); } | |
1085 | ||
1086 | template<typename _UniformRandomNumberGenerator> | |
1087 | void | |
1088 | __generate(result_type* __f, result_type* __t, | |
1089 | _UniformRandomNumberGenerator& __urng, | |
1090 | const param_type& __p) | |
1091 | { this->__generate_impl(__f, __t, __urng, __p); } | |
1092 | ||
1093 | /** | |
1094 | * @brief Return true if two Rice distributions have | |
1095 | * the same parameters and the sequences that would | |
1096 | * be generated are equal. | |
1097 | */ | |
d9d69f64 PC |
1098 | friend bool |
1099 | operator==(const rice_distribution& __d1, | |
1100 | const rice_distribution& __d2) | |
1101 | { return (__d1.param() == __d2.param() | |
1102 | && __d1._M_ndx == __d2._M_ndx | |
1103 | && __d1._M_ndy == __d2._M_ndy); } | |
28312618 ESR |
1104 | |
1105 | /** | |
1106 | * @brief Inserts a %rice_distribution random number distribution | |
1107 | * @p __x into the output stream @p __os. | |
1108 | * | |
1109 | * @param __os An output stream. | |
1110 | * @param __x A %rice_distribution random number distribution. | |
1111 | * | |
1112 | * @returns The output stream with the state of @p __x inserted or in | |
1113 | * an error state. | |
1114 | */ | |
1115 | template<typename _RealType1, typename _CharT, typename _Traits> | |
1116 | friend std::basic_ostream<_CharT, _Traits>& | |
1117 | operator<<(std::basic_ostream<_CharT, _Traits>&, | |
1118 | const rice_distribution<_RealType1>&); | |
1119 | ||
1120 | /** | |
1121 | * @brief Extracts a %rice_distribution random number distribution | |
1122 | * @p __x from the input stream @p __is. | |
1123 | * | |
1124 | * @param __is An input stream. | |
1125 | * @param __x A %rice_distribution random number | |
1126 | * generator engine. | |
1127 | * | |
1128 | * @returns The input stream with @p __x extracted or in an error state. | |
1129 | */ | |
1130 | template<typename _RealType1, typename _CharT, typename _Traits> | |
1131 | friend std::basic_istream<_CharT, _Traits>& | |
1132 | operator>>(std::basic_istream<_CharT, _Traits>&, | |
1133 | rice_distribution<_RealType1>&); | |
1134 | ||
1135 | private: | |
1136 | template<typename _ForwardIterator, | |
1137 | typename _UniformRandomNumberGenerator> | |
1138 | void | |
1139 | __generate_impl(_ForwardIterator __f, _ForwardIterator __t, | |
1140 | _UniformRandomNumberGenerator& __urng, | |
1141 | const param_type& __p); | |
1142 | ||
1143 | param_type _M_param; | |
1144 | ||
1145 | std::normal_distribution<result_type> _M_ndx; | |
1146 | std::normal_distribution<result_type> _M_ndy; | |
1147 | }; | |
1148 | ||
1149 | /** | |
1150 | * @brief Return true if two Rice distributions are not equal. | |
1151 | */ | |
1152 | template<typename _RealType1> | |
1153 | inline bool | |
1154 | operator!=(const rice_distribution<_RealType1>& __d1, | |
1155 | const rice_distribution<_RealType1>& __d2) | |
1156 | { return !(__d1 == __d2); } | |
1157 | ||
19ece7ec ESR |
1158 | |
1159 | /** | |
1160 | * @brief A Nakagami continuous distribution for random numbers. | |
1161 | * | |
1162 | * The formula for the Nakagami probability density function is | |
1163 | * @f[ | |
1164 | * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu} | |
1165 | * x^{2\mu-1}e^{-\mu x / \omega} | |
1166 | * @f] | |
1167 | * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$ | |
1168 | * and @f$\omega > 0@f$. | |
1169 | */ | |
1170 | template<typename _RealType = double> | |
1171 | class | |
1172 | nakagami_distribution | |
1173 | { | |
1174 | static_assert(std::is_floating_point<_RealType>::value, | |
1175 | "template argument not a floating point type"); | |
1176 | ||
1177 | public: | |
1178 | /** The type of the range of the distribution. */ | |
1179 | typedef _RealType result_type; | |
1180 | /** Parameter type. */ | |
1181 | struct param_type | |
1182 | { | |
1183 | typedef nakagami_distribution<result_type> distribution_type; | |
1184 | ||
37f1d5c9 UB |
1185 | param_type(result_type __mu_val = result_type(1), |
1186 | result_type __omega_val = result_type(1)) | |
1187 | : _M_mu(__mu_val), _M_omega(__omega_val) | |
19ece7ec ESR |
1188 | { |
1189 | _GLIBCXX_DEBUG_ASSERT(_M_mu >= result_type(0.5L)); | |
1190 | _GLIBCXX_DEBUG_ASSERT(_M_omega > result_type(0)); | |
1191 | } | |
1192 | ||
1193 | result_type | |
1194 | mu() const | |
1195 | { return _M_mu; } | |
1196 | ||
1197 | result_type | |
1198 | omega() const | |
1199 | { return _M_omega; } | |
1200 | ||
1201 | friend bool | |
1202 | operator==(const param_type& __p1, const param_type& __p2) | |
1203 | { return __p1._M_mu == __p2._M_mu | |
1204 | && __p1._M_omega == __p2._M_omega; } | |
1205 | ||
1206 | private: | |
1207 | void _M_initialize(); | |
1208 | ||
1209 | result_type _M_mu; | |
1210 | result_type _M_omega; | |
1211 | }; | |
1212 | ||
1213 | /** | |
1214 | * @brief Constructors. | |
1215 | */ | |
1216 | explicit | |
37f1d5c9 UB |
1217 | nakagami_distribution(result_type __mu_val = result_type(1), |
1218 | result_type __omega_val = result_type(1)) | |
1219 | : _M_param(__mu_val, __omega_val), | |
1220 | _M_gd(__mu_val, __omega_val / __mu_val) | |
19ece7ec ESR |
1221 | { } |
1222 | ||
1223 | explicit | |
1224 | nakagami_distribution(const param_type& __p) | |
1225 | : _M_param(__p), | |
1226 | _M_gd(__p.mu(), __p.omega() / __p.mu()) | |
1227 | { } | |
1228 | ||
1229 | /** | |
1230 | * @brief Resets the distribution state. | |
1231 | */ | |
1232 | void | |
1233 | reset() | |
1234 | { _M_gd.reset(); } | |
1235 | ||
1236 | /** | |
1237 | * @brief Return the parameters of the distribution. | |
1238 | */ | |
1239 | result_type | |
1240 | mu() const | |
1241 | { return _M_param.mu(); } | |
1242 | ||
1243 | result_type | |
1244 | omega() const | |
1245 | { return _M_param.omega(); } | |
1246 | ||
1247 | /** | |
1248 | * @brief Returns the parameter set of the distribution. | |
1249 | */ | |
1250 | param_type | |
1251 | param() const | |
1252 | { return _M_param; } | |
1253 | ||
1254 | /** | |
1255 | * @brief Sets the parameter set of the distribution. | |
1256 | * @param __param The new parameter set of the distribution. | |
1257 | */ | |
1258 | void | |
1259 | param(const param_type& __param) | |
1260 | { _M_param = __param; } | |
1261 | ||
1262 | /** | |
1263 | * @brief Returns the greatest lower bound value of the distribution. | |
1264 | */ | |
1265 | result_type | |
1266 | min() const | |
1267 | { return result_type(0); } | |
1268 | ||
1269 | /** | |
1270 | * @brief Returns the least upper bound value of the distribution. | |
1271 | */ | |
1272 | result_type | |
1273 | max() const | |
1274 | { return std::numeric_limits<result_type>::max(); } | |
1275 | ||
1276 | /** | |
1277 | * @brief Generating functions. | |
1278 | */ | |
1279 | template<typename _UniformRandomNumberGenerator> | |
1280 | result_type | |
1281 | operator()(_UniformRandomNumberGenerator& __urng) | |
1282 | { return std::sqrt(this->_M_gd(__urng)); } | |
1283 | ||
1284 | template<typename _UniformRandomNumberGenerator> | |
1285 | result_type | |
1286 | operator()(_UniformRandomNumberGenerator& __urng, | |
1287 | const param_type& __p) | |
1288 | { | |
1289 | typename std::gamma_distribution<result_type>::param_type | |
1290 | __pg(__p.mu(), __p.omega() / __p.mu()); | |
1291 | return std::sqrt(this->_M_gd(__pg, __urng)); | |
1292 | } | |
1293 | ||
1294 | template<typename _ForwardIterator, | |
1295 | typename _UniformRandomNumberGenerator> | |
1296 | void | |
1297 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
1298 | _UniformRandomNumberGenerator& __urng) | |
1299 | { this->__generate(__f, __t, __urng, this->param()); } | |
1300 | ||
1301 | template<typename _ForwardIterator, | |
1302 | typename _UniformRandomNumberGenerator> | |
1303 | void | |
1304 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
1305 | _UniformRandomNumberGenerator& __urng, | |
1306 | const param_type& __p) | |
1307 | { this->__generate_impl(__f, __t, __urng, __p); } | |
1308 | ||
1309 | template<typename _UniformRandomNumberGenerator> | |
1310 | void | |
1311 | __generate(result_type* __f, result_type* __t, | |
1312 | _UniformRandomNumberGenerator& __urng, | |
1313 | const param_type& __p) | |
1314 | { this->__generate_impl(__f, __t, __urng, __p); } | |
1315 | ||
1316 | /** | |
1317 | * @brief Return true if two Nakagami distributions have | |
1318 | * the same parameters and the sequences that would | |
1319 | * be generated are equal. | |
1320 | */ | |
1321 | friend bool | |
1322 | operator==(const nakagami_distribution& __d1, | |
1323 | const nakagami_distribution& __d2) | |
1324 | { return (__d1.param() == __d2.param() | |
1325 | && __d1._M_gd == __d2._M_gd); } | |
1326 | ||
1327 | /** | |
1328 | * @brief Inserts a %nakagami_distribution random number distribution | |
1329 | * @p __x into the output stream @p __os. | |
1330 | * | |
1331 | * @param __os An output stream. | |
1332 | * @param __x A %nakagami_distribution random number distribution. | |
1333 | * | |
1334 | * @returns The output stream with the state of @p __x inserted or in | |
1335 | * an error state. | |
1336 | */ | |
1337 | template<typename _RealType1, typename _CharT, typename _Traits> | |
1338 | friend std::basic_ostream<_CharT, _Traits>& | |
1339 | operator<<(std::basic_ostream<_CharT, _Traits>&, | |
1340 | const nakagami_distribution<_RealType1>&); | |
1341 | ||
1342 | /** | |
1343 | * @brief Extracts a %nakagami_distribution random number distribution | |
1344 | * @p __x from the input stream @p __is. | |
1345 | * | |
1346 | * @param __is An input stream. | |
1347 | * @param __x A %nakagami_distribution random number | |
1348 | * generator engine. | |
1349 | * | |
1350 | * @returns The input stream with @p __x extracted or in an error state. | |
1351 | */ | |
1352 | template<typename _RealType1, typename _CharT, typename _Traits> | |
1353 | friend std::basic_istream<_CharT, _Traits>& | |
1354 | operator>>(std::basic_istream<_CharT, _Traits>&, | |
1355 | nakagami_distribution<_RealType1>&); | |
1356 | ||
1357 | private: | |
1358 | template<typename _ForwardIterator, | |
1359 | typename _UniformRandomNumberGenerator> | |
1360 | void | |
1361 | __generate_impl(_ForwardIterator __f, _ForwardIterator __t, | |
1362 | _UniformRandomNumberGenerator& __urng, | |
1363 | const param_type& __p); | |
1364 | ||
1365 | param_type _M_param; | |
1366 | ||
1367 | std::gamma_distribution<result_type> _M_gd; | |
1368 | }; | |
1369 | ||
1370 | /** | |
1371 | * @brief Return true if two Nakagami distributions are not equal. | |
1372 | */ | |
1373 | template<typename _RealType> | |
1374 | inline bool | |
1375 | operator!=(const nakagami_distribution<_RealType>& __d1, | |
1376 | const nakagami_distribution<_RealType>& __d2) | |
1377 | { return !(__d1 == __d2); } | |
1378 | ||
0c105b72 ESR |
1379 | |
1380 | /** | |
1381 | * @brief A Pareto continuous distribution for random numbers. | |
1382 | * | |
1383 | * The formula for the Pareto cumulative probability function is | |
1384 | * @f[ | |
1385 | * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha | |
1386 | * @f] | |
1387 | * The formula for the Pareto probability density function is | |
1388 | * @f[ | |
1389 | * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu} | |
1390 | * \left(\frac{\mu}{x}\right)^{\alpha + 1} | |
1391 | * @f] | |
1392 | * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$. | |
1393 | * | |
1394 | * <table border=1 cellpadding=10 cellspacing=0> | |
1395 | * <caption align=top>Distribution Statistics</caption> | |
1396 | * <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$ | |
1397 | * for @f$\alpha > 1@f$</td></tr> | |
1398 | * <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$ | |
1399 | * for @f$\alpha > 2@f$</td></tr> | |
1400 | * <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr> | |
1401 | * </table> | |
1402 | */ | |
1403 | template<typename _RealType = double> | |
1404 | class | |
1405 | pareto_distribution | |
1406 | { | |
1407 | static_assert(std::is_floating_point<_RealType>::value, | |
1408 | "template argument not a floating point type"); | |
1409 | ||
1410 | public: | |
1411 | /** The type of the range of the distribution. */ | |
1412 | typedef _RealType result_type; | |
1413 | /** Parameter type. */ | |
1414 | struct param_type | |
1415 | { | |
1416 | typedef pareto_distribution<result_type> distribution_type; | |
1417 | ||
37f1d5c9 UB |
1418 | param_type(result_type __alpha_val = result_type(1), |
1419 | result_type __mu_val = result_type(1)) | |
1420 | : _M_alpha(__alpha_val), _M_mu(__mu_val) | |
0c105b72 ESR |
1421 | { |
1422 | _GLIBCXX_DEBUG_ASSERT(_M_alpha > result_type(0)); | |
1423 | _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0)); | |
1424 | } | |
1425 | ||
1426 | result_type | |
1427 | alpha() const | |
1428 | { return _M_alpha; } | |
1429 | ||
1430 | result_type | |
1431 | mu() const | |
1432 | { return _M_mu; } | |
1433 | ||
1434 | friend bool | |
1435 | operator==(const param_type& __p1, const param_type& __p2) | |
1436 | { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; } | |
1437 | ||
1438 | private: | |
1439 | void _M_initialize(); | |
1440 | ||
1441 | result_type _M_alpha; | |
1442 | result_type _M_mu; | |
1443 | }; | |
1444 | ||
1445 | /** | |
1446 | * @brief Constructors. | |
1447 | */ | |
1448 | explicit | |
37f1d5c9 UB |
1449 | pareto_distribution(result_type __alpha_val = result_type(1), |
1450 | result_type __mu_val = result_type(1)) | |
1451 | : _M_param(__alpha_val, __mu_val), | |
0c105b72 ESR |
1452 | _M_ud() |
1453 | { } | |
1454 | ||
1455 | explicit | |
1456 | pareto_distribution(const param_type& __p) | |
1457 | : _M_param(__p), | |
1458 | _M_ud() | |
1459 | { } | |
1460 | ||
1461 | /** | |
1462 | * @brief Resets the distribution state. | |
1463 | */ | |
1464 | void | |
1465 | reset() | |
1466 | { | |
1467 | _M_ud.reset(); | |
1468 | } | |
1469 | ||
1470 | /** | |
1471 | * @brief Return the parameters of the distribution. | |
1472 | */ | |
1473 | result_type | |
1474 | alpha() const | |
1475 | { return _M_param.alpha(); } | |
1476 | ||
1477 | result_type | |
1478 | mu() const | |
1479 | { return _M_param.mu(); } | |
1480 | ||
1481 | /** | |
1482 | * @brief Returns the parameter set of the distribution. | |
1483 | */ | |
1484 | param_type | |
1485 | param() const | |
1486 | { return _M_param; } | |
1487 | ||
1488 | /** | |
1489 | * @brief Sets the parameter set of the distribution. | |
1490 | * @param __param The new parameter set of the distribution. | |
1491 | */ | |
1492 | void | |
1493 | param(const param_type& __param) | |
1494 | { _M_param = __param; } | |
1495 | ||
1496 | /** | |
1497 | * @brief Returns the greatest lower bound value of the distribution. | |
1498 | */ | |
1499 | result_type | |
1500 | min() const | |
1501 | { return this->mu(); } | |
1502 | ||
1503 | /** | |
1504 | * @brief Returns the least upper bound value of the distribution. | |
1505 | */ | |
1506 | result_type | |
1507 | max() const | |
1508 | { return std::numeric_limits<result_type>::max(); } | |
1509 | ||
1510 | /** | |
1511 | * @brief Generating functions. | |
1512 | */ | |
1513 | template<typename _UniformRandomNumberGenerator> | |
1514 | result_type | |
1515 | operator()(_UniformRandomNumberGenerator& __urng) | |
1516 | { | |
1517 | return this->mu() * std::pow(this->_M_ud(__urng), | |
1518 | -result_type(1) / this->alpha()); | |
1519 | } | |
1520 | ||
1521 | template<typename _UniformRandomNumberGenerator> | |
1522 | result_type | |
1523 | operator()(_UniformRandomNumberGenerator& __urng, | |
1524 | const param_type& __p) | |
1525 | { | |
1526 | return __p.mu() * std::pow(this->_M_ud(__urng), | |
1527 | -result_type(1) / __p.alpha()); | |
1528 | } | |
1529 | ||
1530 | template<typename _ForwardIterator, | |
1531 | typename _UniformRandomNumberGenerator> | |
1532 | void | |
1533 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
1534 | _UniformRandomNumberGenerator& __urng) | |
1535 | { this->__generate(__f, __t, __urng, this->param()); } | |
1536 | ||
1537 | template<typename _ForwardIterator, | |
1538 | typename _UniformRandomNumberGenerator> | |
1539 | void | |
1540 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
1541 | _UniformRandomNumberGenerator& __urng, | |
1542 | const param_type& __p) | |
1543 | { this->__generate_impl(__f, __t, __urng, __p); } | |
1544 | ||
1545 | template<typename _UniformRandomNumberGenerator> | |
1546 | void | |
1547 | __generate(result_type* __f, result_type* __t, | |
1548 | _UniformRandomNumberGenerator& __urng, | |
1549 | const param_type& __p) | |
1550 | { this->__generate_impl(__f, __t, __urng, __p); } | |
1551 | ||
1552 | /** | |
1553 | * @brief Return true if two Pareto distributions have | |
1554 | * the same parameters and the sequences that would | |
1555 | * be generated are equal. | |
1556 | */ | |
1557 | friend bool | |
1558 | operator==(const pareto_distribution& __d1, | |
1559 | const pareto_distribution& __d2) | |
1560 | { return (__d1.param() == __d2.param() | |
1561 | && __d1._M_ud == __d2._M_ud); } | |
1562 | ||
1563 | /** | |
1564 | * @brief Inserts a %pareto_distribution random number distribution | |
1565 | * @p __x into the output stream @p __os. | |
1566 | * | |
1567 | * @param __os An output stream. | |
1568 | * @param __x A %pareto_distribution random number distribution. | |
1569 | * | |
1570 | * @returns The output stream with the state of @p __x inserted or in | |
1571 | * an error state. | |
1572 | */ | |
1573 | template<typename _RealType1, typename _CharT, typename _Traits> | |
1574 | friend std::basic_ostream<_CharT, _Traits>& | |
1575 | operator<<(std::basic_ostream<_CharT, _Traits>&, | |
1576 | const pareto_distribution<_RealType1>&); | |
1577 | ||
1578 | /** | |
1579 | * @brief Extracts a %pareto_distribution random number distribution | |
1580 | * @p __x from the input stream @p __is. | |
1581 | * | |
1582 | * @param __is An input stream. | |
1583 | * @param __x A %pareto_distribution random number | |
1584 | * generator engine. | |
1585 | * | |
1586 | * @returns The input stream with @p __x extracted or in an error state. | |
1587 | */ | |
1588 | template<typename _RealType1, typename _CharT, typename _Traits> | |
1589 | friend std::basic_istream<_CharT, _Traits>& | |
1590 | operator>>(std::basic_istream<_CharT, _Traits>&, | |
1591 | pareto_distribution<_RealType1>&); | |
1592 | ||
1593 | private: | |
1594 | template<typename _ForwardIterator, | |
1595 | typename _UniformRandomNumberGenerator> | |
1596 | void | |
1597 | __generate_impl(_ForwardIterator __f, _ForwardIterator __t, | |
1598 | _UniformRandomNumberGenerator& __urng, | |
1599 | const param_type& __p); | |
1600 | ||
1601 | param_type _M_param; | |
1602 | ||
1603 | std::uniform_real_distribution<result_type> _M_ud; | |
1604 | }; | |
1605 | ||
1606 | /** | |
1607 | * @brief Return true if two Pareto distributions are not equal. | |
1608 | */ | |
1609 | template<typename _RealType> | |
1610 | inline bool | |
1611 | operator!=(const pareto_distribution<_RealType>& __d1, | |
1612 | const pareto_distribution<_RealType>& __d2) | |
1613 | { return !(__d1 == __d2); } | |
1614 | ||
21a8ccc0 ESR |
1615 | |
1616 | /** | |
1617 | * @brief A K continuous distribution for random numbers. | |
1618 | * | |
1619 | * The formula for the K probability density function is | |
1620 | * @f[ | |
1621 | * p(x|\lambda, \mu, \nu) = \frac{2}{x} | |
1622 | * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}} | |
1623 | * \frac{1}{\Gamma(\lambda)\Gamma(\nu)} | |
1624 | * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right) | |
1625 | * @f] | |
1626 | * where @f$I_0(z)@f$ is the modified Bessel function of the second kind | |
1627 | * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$ | |
1628 | * and @f$\nu > 0@f$. | |
1629 | * | |
1630 | * <table border=1 cellpadding=10 cellspacing=0> | |
1631 | * <caption align=top>Distribution Statistics</caption> | |
1632 | * <tr><td>Mean</td><td>@f$\mu@f$</td></tr> | |
1633 | * <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr> | |
1634 | * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> | |
1635 | * </table> | |
1636 | */ | |
1637 | template<typename _RealType = double> | |
1638 | class | |
1639 | k_distribution | |
1640 | { | |
1641 | static_assert(std::is_floating_point<_RealType>::value, | |
1642 | "template argument not a floating point type"); | |
1643 | ||
1644 | public: | |
1645 | /** The type of the range of the distribution. */ | |
1646 | typedef _RealType result_type; | |
1647 | /** Parameter type. */ | |
1648 | struct param_type | |
1649 | { | |
1650 | typedef k_distribution<result_type> distribution_type; | |
1651 | ||
1652 | param_type(result_type __lambda_val = result_type(1), | |
1653 | result_type __mu_val = result_type(1), | |
1654 | result_type __nu_val = result_type(1)) | |
1655 | : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val) | |
1656 | { | |
1657 | _GLIBCXX_DEBUG_ASSERT(_M_lambda > result_type(0)); | |
1658 | _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0)); | |
1659 | _GLIBCXX_DEBUG_ASSERT(_M_nu > result_type(0)); | |
1660 | } | |
1661 | ||
1662 | result_type | |
1663 | lambda() const | |
1664 | { return _M_lambda; } | |
1665 | ||
1666 | result_type | |
1667 | mu() const | |
1668 | { return _M_mu; } | |
1669 | ||
1670 | result_type | |
1671 | nu() const | |
1672 | { return _M_nu; } | |
1673 | ||
1674 | friend bool | |
1675 | operator==(const param_type& __p1, const param_type& __p2) | |
1676 | { return __p1._M_lambda == __p2._M_lambda | |
1677 | && __p1._M_mu == __p2._M_mu | |
1678 | && __p1._M_nu == __p2._M_nu; } | |
1679 | ||
1680 | private: | |
1681 | void _M_initialize(); | |
1682 | ||
1683 | result_type _M_lambda; | |
1684 | result_type _M_mu; | |
1685 | result_type _M_nu; | |
1686 | }; | |
1687 | ||
1688 | /** | |
1689 | * @brief Constructors. | |
1690 | */ | |
1691 | explicit | |
1692 | k_distribution(result_type __lambda_val = result_type(1), | |
1693 | result_type __mu_val = result_type(1), | |
1694 | result_type __nu_val = result_type(1)) | |
1695 | : _M_param(__lambda_val, __mu_val, __nu_val), | |
1696 | _M_gd1(__lambda_val, result_type(1) / __lambda_val), | |
1697 | _M_gd2(__nu_val, __mu_val / __nu_val) | |
1698 | { } | |
1699 | ||
1700 | explicit | |
1701 | k_distribution(const param_type& __p) | |
1702 | : _M_param(__p), | |
1703 | _M_gd1(__p.lambda(), result_type(1) / __p.lambda()), | |
1704 | _M_gd2(__p.nu(), __p.mu() / __p.nu()) | |
1705 | { } | |
1706 | ||
1707 | /** | |
1708 | * @brief Resets the distribution state. | |
1709 | */ | |
1710 | void | |
1711 | reset() | |
1712 | { | |
1713 | _M_gd1.reset(); | |
1714 | _M_gd2.reset(); | |
1715 | } | |
1716 | ||
1717 | /** | |
1718 | * @brief Return the parameters of the distribution. | |
1719 | */ | |
1720 | result_type | |
1721 | lambda() const | |
1722 | { return _M_param.lambda(); } | |
1723 | ||
1724 | result_type | |
1725 | mu() const | |
1726 | { return _M_param.mu(); } | |
1727 | ||
1728 | result_type | |
1729 | nu() const | |
1730 | { return _M_param.nu(); } | |
1731 | ||
1732 | /** | |
1733 | * @brief Returns the parameter set of the distribution. | |
1734 | */ | |
1735 | param_type | |
1736 | param() const | |
1737 | { return _M_param; } | |
1738 | ||
1739 | /** | |
1740 | * @brief Sets the parameter set of the distribution. | |
1741 | * @param __param The new parameter set of the distribution. | |
1742 | */ | |
1743 | void | |
1744 | param(const param_type& __param) | |
1745 | { _M_param = __param; } | |
1746 | ||
1747 | /** | |
1748 | * @brief Returns the greatest lower bound value of the distribution. | |
1749 | */ | |
1750 | result_type | |
1751 | min() const | |
1752 | { return result_type(0); } | |
1753 | ||
1754 | /** | |
1755 | * @brief Returns the least upper bound value of the distribution. | |
1756 | */ | |
1757 | result_type | |
1758 | max() const | |
1759 | { return std::numeric_limits<result_type>::max(); } | |
1760 | ||
1761 | /** | |
1762 | * @brief Generating functions. | |
1763 | */ | |
1764 | template<typename _UniformRandomNumberGenerator> | |
1765 | result_type | |
1766 | operator()(_UniformRandomNumberGenerator&); | |
1767 | ||
1768 | template<typename _UniformRandomNumberGenerator> | |
1769 | result_type | |
1770 | operator()(_UniformRandomNumberGenerator&, const param_type&); | |
1771 | ||
1772 | template<typename _ForwardIterator, | |
1773 | typename _UniformRandomNumberGenerator> | |
1774 | void | |
1775 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
1776 | _UniformRandomNumberGenerator& __urng) | |
1777 | { this->__generate(__f, __t, __urng, this->param()); } | |
1778 | ||
1779 | template<typename _ForwardIterator, | |
1780 | typename _UniformRandomNumberGenerator> | |
1781 | void | |
1782 | __generate(_ForwardIterator __f, _ForwardIterator __t, | |
1783 | _UniformRandomNumberGenerator& __urng, | |
1784 | const param_type& __p) | |
1785 | { this->__generate_impl(__f, __t, __urng, __p); } | |
1786 | ||
1787 | template<typename _UniformRandomNumberGenerator> | |
1788 | void | |
1789 | __generate(result_type* __f, result_type* __t, | |
1790 | _UniformRandomNumberGenerator& __urng, | |
1791 | const param_type& __p) | |
1792 | { this->__generate_impl(__f, __t, __urng, __p); } | |
1793 | ||
1794 | /** | |
1795 | * @brief Return true if two K distributions have | |
1796 | * the same parameters and the sequences that would | |
1797 | * be generated are equal. | |
1798 | */ | |
1799 | friend bool | |
1800 | operator==(const k_distribution& __d1, | |
1801 | const k_distribution& __d2) | |
1802 | { return (__d1.param() == __d2.param() | |
1803 | && __d1._M_gd1 == __d2._M_gd1 | |
1804 | && __d1._M_gd2 == __d2._M_gd2); } | |
1805 | ||
1806 | /** | |
1807 | * @brief Inserts a %k_distribution random number distribution | |
1808 | * @p __x into the output stream @p __os. | |
1809 | * | |
1810 | * @param __os An output stream. | |
1811 | * @param __x A %k_distribution random number distribution. | |
1812 | * | |
1813 | * @returns The output stream with the state of @p __x inserted or in | |
1814 | * an error state. | |
1815 | */ | |
1816 | template<typename _RealType1, typename _CharT, typename _Traits> | |
1817 | friend std::basic_ostream<_CharT, _Traits>& | |
1818 | operator<<(std::basic_ostream<_CharT, _Traits>&, | |
1819 | const k_distribution<_RealType1>&); | |
1820 | ||
1821 | /** | |
1822 | * @brief Extracts a %k_distribution random number distribution | |
1823 | * @p __x from the input stream @p __is. | |
1824 | * | |
1825 | * @param __is An input stream. | |
1826 | * @param __x A %k_distribution random number | |
1827 | * generator engine. | |
1828 | * | |
1829 | * @returns The input stream with @p __x extracted or in an error state. | |
1830 | */ | |
1831 | template<typename _RealType1, typename _CharT, typename _Traits> | |
1832 | friend std::basic_istream<_CharT, _Traits>& | |
1833 | operator>>(std::basic_istream<_CharT, _Traits>&, | |
1834 | k_distribution<_RealType1>&); | |
1835 | ||
1836 | private: | |
1837 | template<typename _ForwardIterator, | |
1838 | typename _UniformRandomNumberGenerator> | |
1839 | void | |
1840 | __generate_impl(_ForwardIterator __f, _ForwardIterator __t, | |
1841 | _UniformRandomNumberGenerator& __urng, | |
1842 | const param_type& __p); | |
1843 | ||
1844 | param_type _M_param; | |
1845 | ||
1846 | std::gamma_distribution<result_type> _M_gd1; | |
1847 | std::gamma_distribution<result_type> _M_gd2; | |
1848 | }; | |
1849 | ||
1850 | /** | |
1851 | * @brief Return true if two K distributions are not equal. | |
1852 | */ | |
1853 | template<typename _RealType> | |
1854 | inline bool | |
1855 | operator!=(const k_distribution<_RealType>& __d1, | |
1856 | const k_distribution<_RealType>& __d2) | |
1857 | { return !(__d1 == __d2); } | |
1858 | ||
1860430a | 1859 | _GLIBCXX_END_NAMESPACE_VERSION |
9bf714c2 | 1860 | } // namespace __gnu_cxx |
1860430a | 1861 | |
9bf714c2 | 1862 | #include "opt_random.h" |
1860430a UD |
1863 | #include "random.tcc" |
1864 | ||
8054b82e PC |
1865 | #endif // _GLIBCXX_USE_C99_STDINT_TR1 |
1866 | ||
1867 | #endif // __GXX_EXPERIMENTAL_CXX0X__ | |
1868 | ||
1869 | #endif // _EXT_RANDOM |