OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [bits/] [random.tcc] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// random number generation (out of line) -*- C++ -*-
2
 
3
// Copyright (C) 2009-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
// .
24
 
25
/** @file bits/random.tcc
26
 *  This is an internal header file, included by other library headers.
27
 *  Do not attempt to use it directly. @headername{random}
28
 */
29
 
30
#ifndef _RANDOM_TCC
31
#define _RANDOM_TCC 1
32
 
33
#include  // std::accumulate and std::partial_sum
34
 
35
namespace std _GLIBCXX_VISIBILITY(default)
36
{
37
  /*
38
   * (Further) implementation-space details.
39
   */
40
  namespace __detail
41
  {
42
  _GLIBCXX_BEGIN_NAMESPACE_VERSION
43
 
44
    // General case for x = (ax + c) mod m -- use Schrage's algorithm
45
    // to avoid integer overflow.
46
    //
47
    // Preconditions:  a > 0, m > 0.
48
    //
49
    // Note: only works correctly for __m % __a < __m / __a.
50
    template
51
      _Tp
52
      _Mod<_Tp, __m, __a, __c, false, true>::
53
      __calc(_Tp __x)
54
      {
55
        if (__a == 1)
56
          __x %= __m;
57
        else
58
          {
59
            static const _Tp __q = __m / __a;
60
            static const _Tp __r = __m % __a;
61
 
62
            _Tp __t1 = __a * (__x % __q);
63
            _Tp __t2 = __r * (__x / __q);
64
            if (__t1 >= __t2)
65
              __x = __t1 - __t2;
66
            else
67
              __x = __m - __t2 + __t1;
68
          }
69
 
70
        if (__c != 0)
71
          {
72
            const _Tp __d = __m - __x;
73
            if (__d > __c)
74
              __x += __c;
75
            else
76
              __x = __c - __d;
77
          }
78
        return __x;
79
      }
80
 
81
    template
82
             typename _UnaryOperation>
83
      _OutputIterator
84
      __transform(_InputIterator __first, _InputIterator __last,
85
                  _OutputIterator __result, _UnaryOperation __unary_op)
86
      {
87
        for (; __first != __last; ++__first, ++__result)
88
          *__result = __unary_op(*__first);
89
        return __result;
90
      }
91
 
92
  _GLIBCXX_END_NAMESPACE_VERSION
93
  } // namespace __detail
94
 
95
_GLIBCXX_BEGIN_NAMESPACE_VERSION
96
 
97
  template
98
    constexpr _UIntType
99
    linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;
100
 
101
  template
102
    constexpr _UIntType
103
    linear_congruential_engine<_UIntType, __a, __c, __m>::increment;
104
 
105
  template
106
    constexpr _UIntType
107
    linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;
108
 
109
  template
110
    constexpr _UIntType
111
    linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
112
 
113
  /**
114
   * Seeds the LCR with integral value @p __s, adjusted so that the
115
   * ring identity is never a member of the convergence set.
116
   */
117
  template
118
    void
119
    linear_congruential_engine<_UIntType, __a, __c, __m>::
120
    seed(result_type __s)
121
    {
122
      if ((__detail::__mod<_UIntType, __m>(__c) == 0)
123
          && (__detail::__mod<_UIntType, __m>(__s) == 0))
124
        _M_x = 1;
125
      else
126
        _M_x = __detail::__mod<_UIntType, __m>(__s);
127
    }
128
 
129
  /**
130
   * Seeds the LCR engine with a value generated by @p __q.
131
   */
132
  template
133
    template
134
      typename std::enable_if::value>::type
135
      linear_congruential_engine<_UIntType, __a, __c, __m>::
136
      seed(_Sseq& __q)
137
      {
138
        const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
139
                                        : std::__lg(__m);
140
        const _UIntType __k = (__k0 + 31) / 32;
141
        uint_least32_t __arr[__k + 3];
142
        __q.generate(__arr + 0, __arr + __k + 3);
143
        _UIntType __factor = 1u;
144
        _UIntType __sum = 0u;
145
        for (size_t __j = 0; __j < __k; ++__j)
146
          {
147
            __sum += __arr[__j + 3] * __factor;
148
            __factor *= __detail::_Shift<_UIntType, 32>::__value;
149
          }
150
        seed(__sum);
151
      }
152
 
153
  template
154
           typename _CharT, typename _Traits>
155
    std::basic_ostream<_CharT, _Traits>&
156
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
157
               const linear_congruential_engine<_UIntType,
158
                                                __a, __c, __m>& __lcr)
159
    {
160
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
161
      typedef typename __ostream_type::ios_base    __ios_base;
162
 
163
      const typename __ios_base::fmtflags __flags = __os.flags();
164
      const _CharT __fill = __os.fill();
165
      __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
166
      __os.fill(__os.widen(' '));
167
 
168
      __os << __lcr._M_x;
169
 
170
      __os.flags(__flags);
171
      __os.fill(__fill);
172
      return __os;
173
    }
174
 
175
  template
176
           typename _CharT, typename _Traits>
177
    std::basic_istream<_CharT, _Traits>&
178
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
179
               linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr)
180
    {
181
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
182
      typedef typename __istream_type::ios_base    __ios_base;
183
 
184
      const typename __ios_base::fmtflags __flags = __is.flags();
185
      __is.flags(__ios_base::dec);
186
 
187
      __is >> __lcr._M_x;
188
 
189
      __is.flags(__flags);
190
      return __is;
191
    }
192
 
193
 
194
  template
195
           size_t __w, size_t __n, size_t __m, size_t __r,
196
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
197
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
198
           _UIntType __f>
199
    constexpr size_t
200
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
201
                            __s, __b, __t, __c, __l, __f>::word_size;
202
 
203
  template
204
           size_t __w, size_t __n, size_t __m, size_t __r,
205
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
206
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
207
           _UIntType __f>
208
    constexpr size_t
209
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
210
                            __s, __b, __t, __c, __l, __f>::state_size;
211
 
212
  template
213
           size_t __w, size_t __n, size_t __m, size_t __r,
214
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
215
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
216
           _UIntType __f>
217
    constexpr size_t
218
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
219
                            __s, __b, __t, __c, __l, __f>::shift_size;
220
 
221
  template
222
           size_t __w, size_t __n, size_t __m, size_t __r,
223
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
224
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
225
           _UIntType __f>
226
    constexpr size_t
227
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
228
                            __s, __b, __t, __c, __l, __f>::mask_bits;
229
 
230
  template
231
           size_t __w, size_t __n, size_t __m, size_t __r,
232
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
233
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
234
           _UIntType __f>
235
    constexpr _UIntType
236
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
237
                            __s, __b, __t, __c, __l, __f>::xor_mask;
238
 
239
  template
240
           size_t __w, size_t __n, size_t __m, size_t __r,
241
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
242
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
243
           _UIntType __f>
244
    constexpr size_t
245
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
246
                            __s, __b, __t, __c, __l, __f>::tempering_u;
247
 
248
  template
249
           size_t __w, size_t __n, size_t __m, size_t __r,
250
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
251
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
252
           _UIntType __f>
253
    constexpr _UIntType
254
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
255
                            __s, __b, __t, __c, __l, __f>::tempering_d;
256
 
257
  template
258
           size_t __w, size_t __n, size_t __m, size_t __r,
259
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
260
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
261
           _UIntType __f>
262
    constexpr size_t
263
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
264
                            __s, __b, __t, __c, __l, __f>::tempering_s;
265
 
266
  template
267
           size_t __w, size_t __n, size_t __m, size_t __r,
268
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
269
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
270
           _UIntType __f>
271
    constexpr _UIntType
272
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
273
                            __s, __b, __t, __c, __l, __f>::tempering_b;
274
 
275
  template
276
           size_t __w, size_t __n, size_t __m, size_t __r,
277
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
278
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
279
           _UIntType __f>
280
    constexpr size_t
281
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
282
                            __s, __b, __t, __c, __l, __f>::tempering_t;
283
 
284
  template
285
           size_t __w, size_t __n, size_t __m, size_t __r,
286
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
287
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
288
           _UIntType __f>
289
    constexpr _UIntType
290
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
291
                            __s, __b, __t, __c, __l, __f>::tempering_c;
292
 
293
  template
294
           size_t __w, size_t __n, size_t __m, size_t __r,
295
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
296
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
297
           _UIntType __f>
298
    constexpr size_t
299
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
300
                            __s, __b, __t, __c, __l, __f>::tempering_l;
301
 
302
  template
303
           size_t __w, size_t __n, size_t __m, size_t __r,
304
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
305
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
306
           _UIntType __f>
307
    constexpr _UIntType
308
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
309
                            __s, __b, __t, __c, __l, __f>::
310
                                              initialization_multiplier;
311
 
312
  template
313
           size_t __w, size_t __n, size_t __m, size_t __r,
314
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
315
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
316
           _UIntType __f>
317
    constexpr _UIntType
318
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
319
                            __s, __b, __t, __c, __l, __f>::default_seed;
320
 
321
  template
322
           size_t __w, size_t __n, size_t __m, size_t __r,
323
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
324
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
325
           _UIntType __f>
326
    void
327
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
328
                            __s, __b, __t, __c, __l, __f>::
329
    seed(result_type __sd)
330
    {
331
      _M_x[0] = __detail::__mod<_UIntType,
332
        __detail::_Shift<_UIntType, __w>::__value>(__sd);
333
 
334
      for (size_t __i = 1; __i < state_size; ++__i)
335
        {
336
          _UIntType __x = _M_x[__i - 1];
337
          __x ^= __x >> (__w - 2);
338
          __x *= __f;
339
          __x += __detail::__mod<_UIntType, __n>(__i);
340
          _M_x[__i] = __detail::__mod<_UIntType,
341
            __detail::_Shift<_UIntType, __w>::__value>(__x);
342
        }
343
      _M_p = state_size;
344
    }
345
 
346
  template
347
           size_t __w, size_t __n, size_t __m, size_t __r,
348
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
349
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
350
           _UIntType __f>
351
    template
352
      typename std::enable_if::value>::type
353
      mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
354
                              __s, __b, __t, __c, __l, __f>::
355
      seed(_Sseq& __q)
356
      {
357
        const _UIntType __upper_mask = (~_UIntType()) << __r;
358
        const size_t __k = (__w + 31) / 32;
359
        uint_least32_t __arr[__n * __k];
360
        __q.generate(__arr + 0, __arr + __n * __k);
361
 
362
        bool __zero = true;
363
        for (size_t __i = 0; __i < state_size; ++__i)
364
          {
365
            _UIntType __factor = 1u;
366
            _UIntType __sum = 0u;
367
            for (size_t __j = 0; __j < __k; ++__j)
368
              {
369
                __sum += __arr[__k * __i + __j] * __factor;
370
                __factor *= __detail::_Shift<_UIntType, 32>::__value;
371
              }
372
            _M_x[__i] = __detail::__mod<_UIntType,
373
              __detail::_Shift<_UIntType, __w>::__value>(__sum);
374
 
375
            if (__zero)
376
              {
377
                if (__i == 0)
378
                  {
379
                    if ((_M_x[0] & __upper_mask) != 0u)
380
                      __zero = false;
381
                  }
382
                else if (_M_x[__i] != 0u)
383
                  __zero = false;
384
              }
385
          }
386
        if (__zero)
387
          _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value;
388
        _M_p = state_size;
389
      }
390
 
391
  template
392
           size_t __n, size_t __m, size_t __r,
393
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
394
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
395
           _UIntType __f>
396
    void
397
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
398
                            __s, __b, __t, __c, __l, __f>::
399
    _M_gen_rand(void)
400
    {
401
      const _UIntType __upper_mask = (~_UIntType()) << __r;
402
      const _UIntType __lower_mask = ~__upper_mask;
403
 
404
      for (size_t __k = 0; __k < (__n - __m); ++__k)
405
        {
406
          _UIntType __y = ((_M_x[__k] & __upper_mask)
407
                           | (_M_x[__k + 1] & __lower_mask));
408
          _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
409
                       ^ ((__y & 0x01) ? __a : 0));
410
        }
411
 
412
      for (size_t __k = (__n - __m); __k < (__n - 1); ++__k)
413
        {
414
          _UIntType __y = ((_M_x[__k] & __upper_mask)
415
                           | (_M_x[__k + 1] & __lower_mask));
416
          _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
417
                       ^ ((__y & 0x01) ? __a : 0));
418
        }
419
 
420
      _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
421
                       | (_M_x[0] & __lower_mask));
422
      _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
423
                       ^ ((__y & 0x01) ? __a : 0));
424
      _M_p = 0;
425
    }
426
 
427
  template
428
           size_t __n, size_t __m, size_t __r,
429
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
430
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
431
           _UIntType __f>
432
    void
433
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
434
                            __s, __b, __t, __c, __l, __f>::
435
    discard(unsigned long long __z)
436
    {
437
      while (__z > state_size - _M_p)
438
        {
439
          __z -= state_size - _M_p;
440
          _M_gen_rand();
441
        }
442
      _M_p += __z;
443
    }
444
 
445
  template
446
           size_t __n, size_t __m, size_t __r,
447
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
448
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
449
           _UIntType __f>
450
    typename
451
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
452
                            __s, __b, __t, __c, __l, __f>::result_type
453
    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
454
                            __s, __b, __t, __c, __l, __f>::
455
    operator()()
456
    {
457
      // Reload the vector - cost is O(n) amortized over n calls.
458
      if (_M_p >= state_size)
459
        _M_gen_rand();
460
 
461
      // Calculate o(x(i)).
462
      result_type __z = _M_x[_M_p++];
463
      __z ^= (__z >> __u) & __d;
464
      __z ^= (__z << __s) & __b;
465
      __z ^= (__z << __t) & __c;
466
      __z ^= (__z >> __l);
467
 
468
      return __z;
469
    }
470
 
471
  template
472
           size_t __n, size_t __m, size_t __r,
473
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
474
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
475
           _UIntType __f, typename _CharT, typename _Traits>
476
    std::basic_ostream<_CharT, _Traits>&
477
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
478
               const mersenne_twister_engine<_UIntType, __w, __n, __m,
479
               __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
480
    {
481
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
482
      typedef typename __ostream_type::ios_base    __ios_base;
483
 
484
      const typename __ios_base::fmtflags __flags = __os.flags();
485
      const _CharT __fill = __os.fill();
486
      const _CharT __space = __os.widen(' ');
487
      __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
488
      __os.fill(__space);
489
 
490
      for (size_t __i = 0; __i < __n; ++__i)
491
        __os << __x._M_x[__i] << __space;
492
      __os << __x._M_p;
493
 
494
      __os.flags(__flags);
495
      __os.fill(__fill);
496
      return __os;
497
    }
498
 
499
  template
500
           size_t __n, size_t __m, size_t __r,
501
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
502
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
503
           _UIntType __f, typename _CharT, typename _Traits>
504
    std::basic_istream<_CharT, _Traits>&
505
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
506
               mersenne_twister_engine<_UIntType, __w, __n, __m,
507
               __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
508
    {
509
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
510
      typedef typename __istream_type::ios_base    __ios_base;
511
 
512
      const typename __ios_base::fmtflags __flags = __is.flags();
513
      __is.flags(__ios_base::dec | __ios_base::skipws);
514
 
515
      for (size_t __i = 0; __i < __n; ++__i)
516
        __is >> __x._M_x[__i];
517
      __is >> __x._M_p;
518
 
519
      __is.flags(__flags);
520
      return __is;
521
    }
522
 
523
 
524
  template
525
    constexpr size_t
526
    subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size;
527
 
528
  template
529
    constexpr size_t
530
    subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag;
531
 
532
  template
533
    constexpr size_t
534
    subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag;
535
 
536
  template
537
    constexpr _UIntType
538
    subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed;
539
 
540
  template
541
    void
542
    subtract_with_carry_engine<_UIntType, __w, __s, __r>::
543
    seed(result_type __value)
544
    {
545
      std::linear_congruential_engine
546
        __lcg(__value == 0u ? default_seed : __value);
547
 
548
      const size_t __n = (__w + 31) / 32;
549
 
550
      for (size_t __i = 0; __i < long_lag; ++__i)
551
        {
552
          _UIntType __sum = 0u;
553
          _UIntType __factor = 1u;
554
          for (size_t __j = 0; __j < __n; ++__j)
555
            {
556
              __sum += __detail::__mod
557
                       __detail::_Shift::__value>
558
                         (__lcg()) * __factor;
559
              __factor *= __detail::_Shift<_UIntType, 32>::__value;
560
            }
561
          _M_x[__i] = __detail::__mod<_UIntType,
562
            __detail::_Shift<_UIntType, __w>::__value>(__sum);
563
        }
564
      _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
565
      _M_p = 0;
566
    }
567
 
568
  template
569
    template
570
      typename std::enable_if::value>::type
571
      subtract_with_carry_engine<_UIntType, __w, __s, __r>::
572
      seed(_Sseq& __q)
573
      {
574
        const size_t __k = (__w + 31) / 32;
575
        uint_least32_t __arr[__r * __k];
576
        __q.generate(__arr + 0, __arr + __r * __k);
577
 
578
        for (size_t __i = 0; __i < long_lag; ++__i)
579
          {
580
            _UIntType __sum = 0u;
581
            _UIntType __factor = 1u;
582
            for (size_t __j = 0; __j < __k; ++__j)
583
              {
584
                __sum += __arr[__k * __i + __j] * __factor;
585
                __factor *= __detail::_Shift<_UIntType, 32>::__value;
586
              }
587
            _M_x[__i] = __detail::__mod<_UIntType,
588
              __detail::_Shift<_UIntType, __w>::__value>(__sum);
589
          }
590
        _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
591
        _M_p = 0;
592
      }
593
 
594
  template
595
    typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::
596
             result_type
597
    subtract_with_carry_engine<_UIntType, __w, __s, __r>::
598
    operator()()
599
    {
600
      // Derive short lag index from current index.
601
      long __ps = _M_p - short_lag;
602
      if (__ps < 0)
603
        __ps += long_lag;
604
 
605
      // Calculate new x(i) without overflow or division.
606
      // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry
607
      // cannot overflow.
608
      _UIntType __xi;
609
      if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
610
        {
611
          __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
612
          _M_carry = 0;
613
        }
614
      else
615
        {
616
          __xi = (__detail::_Shift<_UIntType, __w>::__value
617
                  - _M_x[_M_p] - _M_carry + _M_x[__ps]);
618
          _M_carry = 1;
619
        }
620
      _M_x[_M_p] = __xi;
621
 
622
      // Adjust current index to loop around in ring buffer.
623
      if (++_M_p >= long_lag)
624
        _M_p = 0;
625
 
626
      return __xi;
627
    }
628
 
629
  template
630
           typename _CharT, typename _Traits>
631
    std::basic_ostream<_CharT, _Traits>&
632
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
633
               const subtract_with_carry_engine<_UIntType,
634
                                                __w, __s, __r>& __x)
635
    {
636
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
637
      typedef typename __ostream_type::ios_base    __ios_base;
638
 
639
      const typename __ios_base::fmtflags __flags = __os.flags();
640
      const _CharT __fill = __os.fill();
641
      const _CharT __space = __os.widen(' ');
642
      __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
643
      __os.fill(__space);
644
 
645
      for (size_t __i = 0; __i < __r; ++__i)
646
        __os << __x._M_x[__i] << __space;
647
      __os << __x._M_carry << __space << __x._M_p;
648
 
649
      __os.flags(__flags);
650
      __os.fill(__fill);
651
      return __os;
652
    }
653
 
654
  template
655
           typename _CharT, typename _Traits>
656
    std::basic_istream<_CharT, _Traits>&
657
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
658
               subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x)
659
    {
660
      typedef std::basic_ostream<_CharT, _Traits>  __istream_type;
661
      typedef typename __istream_type::ios_base    __ios_base;
662
 
663
      const typename __ios_base::fmtflags __flags = __is.flags();
664
      __is.flags(__ios_base::dec | __ios_base::skipws);
665
 
666
      for (size_t __i = 0; __i < __r; ++__i)
667
        __is >> __x._M_x[__i];
668
      __is >> __x._M_carry;
669
      __is >> __x._M_p;
670
 
671
      __is.flags(__flags);
672
      return __is;
673
    }
674
 
675
 
676
  template
677
    constexpr size_t
678
    discard_block_engine<_RandomNumberEngine, __p, __r>::block_size;
679
 
680
  template
681
    constexpr size_t
682
    discard_block_engine<_RandomNumberEngine, __p, __r>::used_block;
683
 
684
  template
685
    typename discard_block_engine<_RandomNumberEngine,
686
                           __p, __r>::result_type
687
    discard_block_engine<_RandomNumberEngine, __p, __r>::
688
    operator()()
689
    {
690
      if (_M_n >= used_block)
691
        {
692
          _M_b.discard(block_size - _M_n);
693
          _M_n = 0;
694
        }
695
      ++_M_n;
696
      return _M_b();
697
    }
698
 
699
  template
700
           typename _CharT, typename _Traits>
701
    std::basic_ostream<_CharT, _Traits>&
702
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
703
               const discard_block_engine<_RandomNumberEngine,
704
               __p, __r>& __x)
705
    {
706
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
707
      typedef typename __ostream_type::ios_base    __ios_base;
708
 
709
      const typename __ios_base::fmtflags __flags = __os.flags();
710
      const _CharT __fill = __os.fill();
711
      const _CharT __space = __os.widen(' ');
712
      __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
713
      __os.fill(__space);
714
 
715
      __os << __x.base() << __space << __x._M_n;
716
 
717
      __os.flags(__flags);
718
      __os.fill(__fill);
719
      return __os;
720
    }
721
 
722
  template
723
           typename _CharT, typename _Traits>
724
    std::basic_istream<_CharT, _Traits>&
725
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
726
               discard_block_engine<_RandomNumberEngine, __p, __r>& __x)
727
    {
728
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
729
      typedef typename __istream_type::ios_base    __ios_base;
730
 
731
      const typename __ios_base::fmtflags __flags = __is.flags();
732
      __is.flags(__ios_base::dec | __ios_base::skipws);
733
 
734
      __is >> __x._M_b >> __x._M_n;
735
 
736
      __is.flags(__flags);
737
      return __is;
738
    }
739
 
740
 
741
  template
742
    typename independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
743
      result_type
744
    independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
745
    operator()()
746
    {
747
      typedef typename _RandomNumberEngine::result_type _Eresult_type;
748
      const _Eresult_type __r
749
        = (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max()
750
           ? _M_b.max() - _M_b.min() + 1 : 0);
751
      const unsigned __edig = std::numeric_limits<_Eresult_type>::digits;
752
      const unsigned __m = __r ? std::__lg(__r) : __edig;
753
 
754
      typedef typename std::common_type<_Eresult_type, result_type>::type
755
        __ctype;
756
      const unsigned __cdig = std::numeric_limits<__ctype>::digits;
757
 
758
      unsigned __n, __n0;
759
      __ctype __s0, __s1, __y0, __y1;
760
 
761
      for (size_t __i = 0; __i < 2; ++__i)
762
        {
763
          __n = (__w + __m - 1) / __m + __i;
764
          __n0 = __n - __w % __n;
765
          const unsigned __w0 = __w / __n;  // __w0 <= __m
766
 
767
          __s0 = 0;
768
          __s1 = 0;
769
          if (__w0 < __cdig)
770
            {
771
              __s0 = __ctype(1) << __w0;
772
              __s1 = __s0 << 1;
773
            }
774
 
775
          __y0 = 0;
776
          __y1 = 0;
777
          if (__r)
778
            {
779
              __y0 = __s0 * (__r / __s0);
780
              if (__s1)
781
                __y1 = __s1 * (__r / __s1);
782
 
783
              if (__r - __y0 <= __y0 / __n)
784
                break;
785
            }
786
          else
787
            break;
788
        }
789
 
790
      result_type __sum = 0;
791
      for (size_t __k = 0; __k < __n0; ++__k)
792
        {
793
          __ctype __u;
794
          do
795
            __u = _M_b() - _M_b.min();
796
          while (__y0 && __u >= __y0);
797
          __sum = __s0 * __sum + (__s0 ? __u % __s0 : __u);
798
        }
799
      for (size_t __k = __n0; __k < __n; ++__k)
800
        {
801
          __ctype __u;
802
          do
803
            __u = _M_b() - _M_b.min();
804
          while (__y1 && __u >= __y1);
805
          __sum = __s1 * __sum + (__s1 ? __u % __s1 : __u);
806
        }
807
      return __sum;
808
    }
809
 
810
 
811
  template
812
    constexpr size_t
813
    shuffle_order_engine<_RandomNumberEngine, __k>::table_size;
814
 
815
  template
816
    typename shuffle_order_engine<_RandomNumberEngine, __k>::result_type
817
    shuffle_order_engine<_RandomNumberEngine, __k>::
818
    operator()()
819
    {
820
      size_t __j = __k * ((_M_y - _M_b.min())
821
                          / (_M_b.max() - _M_b.min() + 1.0L));
822
      _M_y = _M_v[__j];
823
      _M_v[__j] = _M_b();
824
 
825
      return _M_y;
826
    }
827
 
828
  template
829
           typename _CharT, typename _Traits>
830
    std::basic_ostream<_CharT, _Traits>&
831
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
832
               const shuffle_order_engine<_RandomNumberEngine, __k>& __x)
833
    {
834
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
835
      typedef typename __ostream_type::ios_base    __ios_base;
836
 
837
      const typename __ios_base::fmtflags __flags = __os.flags();
838
      const _CharT __fill = __os.fill();
839
      const _CharT __space = __os.widen(' ');
840
      __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
841
      __os.fill(__space);
842
 
843
      __os << __x.base();
844
      for (size_t __i = 0; __i < __k; ++__i)
845
        __os << __space << __x._M_v[__i];
846
      __os << __space << __x._M_y;
847
 
848
      __os.flags(__flags);
849
      __os.fill(__fill);
850
      return __os;
851
    }
852
 
853
  template
854
           typename _CharT, typename _Traits>
855
    std::basic_istream<_CharT, _Traits>&
856
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
857
               shuffle_order_engine<_RandomNumberEngine, __k>& __x)
858
    {
859
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
860
      typedef typename __istream_type::ios_base    __ios_base;
861
 
862
      const typename __ios_base::fmtflags __flags = __is.flags();
863
      __is.flags(__ios_base::dec | __ios_base::skipws);
864
 
865
      __is >> __x._M_b;
866
      for (size_t __i = 0; __i < __k; ++__i)
867
        __is >> __x._M_v[__i];
868
      __is >> __x._M_y;
869
 
870
      __is.flags(__flags);
871
      return __is;
872
    }
873
 
874
 
875
  template
876
    template
877
      typename uniform_int_distribution<_IntType>::result_type
878
      uniform_int_distribution<_IntType>::
879
      operator()(_UniformRandomNumberGenerator& __urng,
880
                 const param_type& __param)
881
      {
882
        typedef typename _UniformRandomNumberGenerator::result_type
883
          _Gresult_type;
884
        typedef typename std::make_unsigned::type __utype;
885
        typedef typename std::common_type<_Gresult_type, __utype>::type
886
          __uctype;
887
 
888
        const __uctype __urngmin = __urng.min();
889
        const __uctype __urngmax = __urng.max();
890
        const __uctype __urngrange = __urngmax - __urngmin;
891
        const __uctype __urange
892
          = __uctype(__param.b()) - __uctype(__param.a());
893
 
894
        __uctype __ret;
895
 
896
        if (__urngrange > __urange)
897
          {
898
            // downscaling
899
            const __uctype __uerange = __urange + 1; // __urange can be zero
900
            const __uctype __scaling = __urngrange / __uerange;
901
            const __uctype __past = __uerange * __scaling;
902
            do
903
              __ret = __uctype(__urng()) - __urngmin;
904
            while (__ret >= __past);
905
            __ret /= __scaling;
906
          }
907
        else if (__urngrange < __urange)
908
          {
909
            // upscaling
910
            /*
911
              Note that every value in [0, urange]
912
              can be written uniquely as
913
 
914
              (urngrange + 1) * high + low
915
 
916
              where
917
 
918
              high in [0, urange / (urngrange + 1)]
919
 
920
              and
921
 
922
              low in [0, urngrange].
923
            */
924
            __uctype __tmp; // wraparound control
925
            do
926
              {
927
                const __uctype __uerngrange = __urngrange + 1;
928
                __tmp = (__uerngrange * operator()
929
                         (__urng, param_type(0, __urange / __uerngrange)));
930
                __ret = __tmp + (__uctype(__urng()) - __urngmin);
931
              }
932
            while (__ret > __urange || __ret < __tmp);
933
          }
934
        else
935
          __ret = __uctype(__urng()) - __urngmin;
936
 
937
        return __ret + __param.a();
938
      }
939
 
940
 
941
  template
942
    template
943
             typename _UniformRandomNumberGenerator>
944
      void
945
      uniform_int_distribution<_IntType>::
946
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
947
                      _UniformRandomNumberGenerator& __urng,
948
                      const param_type& __param)
949
      {
950
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
951
        typedef typename _UniformRandomNumberGenerator::result_type
952
          _Gresult_type;
953
        typedef typename std::make_unsigned::type __utype;
954
        typedef typename std::common_type<_Gresult_type, __utype>::type
955
          __uctype;
956
 
957
        const __uctype __urngmin = __urng.min();
958
        const __uctype __urngmax = __urng.max();
959
        const __uctype __urngrange = __urngmax - __urngmin;
960
        const __uctype __urange
961
          = __uctype(__param.b()) - __uctype(__param.a());
962
 
963
        __uctype __ret;
964
 
965
        if (__urngrange > __urange)
966
          {
967
            if (__detail::_Power_of_2(__urngrange + 1)
968
                && __detail::_Power_of_2(__urange + 1))
969
              {
970
                while (__f != __t)
971
                  {
972
                    __ret = __uctype(__urng()) - __urngmin;
973
                    *__f++ = (__ret & __urange) + __param.a();
974
                  }
975
              }
976
            else
977
              {
978
                // downscaling
979
                const __uctype __uerange = __urange + 1; // __urange can be zero
980
                const __uctype __scaling = __urngrange / __uerange;
981
                const __uctype __past = __uerange * __scaling;
982
                while (__f != __t)
983
                  {
984
                    do
985
                      __ret = __uctype(__urng()) - __urngmin;
986
                    while (__ret >= __past);
987
                    *__f++ = __ret / __scaling + __param.a();
988
                  }
989
              }
990
          }
991
        else if (__urngrange < __urange)
992
          {
993
            // upscaling
994
            /*
995
              Note that every value in [0, urange]
996
              can be written uniquely as
997
 
998
              (urngrange + 1) * high + low
999
 
1000
              where
1001
 
1002
              high in [0, urange / (urngrange + 1)]
1003
 
1004
              and
1005
 
1006
              low in [0, urngrange].
1007
            */
1008
            __uctype __tmp; // wraparound control
1009
            while (__f != __t)
1010
              {
1011
                do
1012
                  {
1013
                    const __uctype __uerngrange = __urngrange + 1;
1014
                    __tmp = (__uerngrange * operator()
1015
                             (__urng, param_type(0, __urange / __uerngrange)));
1016
                    __ret = __tmp + (__uctype(__urng()) - __urngmin);
1017
                  }
1018
                while (__ret > __urange || __ret < __tmp);
1019
                *__f++ = __ret;
1020
              }
1021
          }
1022
        else
1023
          while (__f != __t)
1024
            *__f++ = __uctype(__urng()) - __urngmin + __param.a();
1025
      }
1026
 
1027
  template
1028
    std::basic_ostream<_CharT, _Traits>&
1029
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1030
               const uniform_int_distribution<_IntType>& __x)
1031
    {
1032
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1033
      typedef typename __ostream_type::ios_base    __ios_base;
1034
 
1035
      const typename __ios_base::fmtflags __flags = __os.flags();
1036
      const _CharT __fill = __os.fill();
1037
      const _CharT __space = __os.widen(' ');
1038
      __os.flags(__ios_base::scientific | __ios_base::left);
1039
      __os.fill(__space);
1040
 
1041
      __os << __x.a() << __space << __x.b();
1042
 
1043
      __os.flags(__flags);
1044
      __os.fill(__fill);
1045
      return __os;
1046
    }
1047
 
1048
  template
1049
    std::basic_istream<_CharT, _Traits>&
1050
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
1051
               uniform_int_distribution<_IntType>& __x)
1052
    {
1053
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1054
      typedef typename __istream_type::ios_base    __ios_base;
1055
 
1056
      const typename __ios_base::fmtflags __flags = __is.flags();
1057
      __is.flags(__ios_base::dec | __ios_base::skipws);
1058
 
1059
      _IntType __a, __b;
1060
      __is >> __a >> __b;
1061
      __x.param(typename uniform_int_distribution<_IntType>::
1062
                param_type(__a, __b));
1063
 
1064
      __is.flags(__flags);
1065
      return __is;
1066
    }
1067
 
1068
 
1069
  template
1070
    template
1071
             typename _UniformRandomNumberGenerator>
1072
      void
1073
      uniform_real_distribution<_RealType>::
1074
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1075
                      _UniformRandomNumberGenerator& __urng,
1076
                      const param_type& __p)
1077
      {
1078
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1079
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1080
          __aurng(__urng);
1081
        auto __range = __p.b() - __p.a();
1082
        while (__f != __t)
1083
          *__f++ = __aurng() * __range + __p.a();
1084
      }
1085
 
1086
  template
1087
    std::basic_ostream<_CharT, _Traits>&
1088
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1089
               const uniform_real_distribution<_RealType>& __x)
1090
    {
1091
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1092
      typedef typename __ostream_type::ios_base    __ios_base;
1093
 
1094
      const typename __ios_base::fmtflags __flags = __os.flags();
1095
      const _CharT __fill = __os.fill();
1096
      const std::streamsize __precision = __os.precision();
1097
      const _CharT __space = __os.widen(' ');
1098
      __os.flags(__ios_base::scientific | __ios_base::left);
1099
      __os.fill(__space);
1100
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
1101
 
1102
      __os << __x.a() << __space << __x.b();
1103
 
1104
      __os.flags(__flags);
1105
      __os.fill(__fill);
1106
      __os.precision(__precision);
1107
      return __os;
1108
    }
1109
 
1110
  template
1111
    std::basic_istream<_CharT, _Traits>&
1112
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
1113
               uniform_real_distribution<_RealType>& __x)
1114
    {
1115
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1116
      typedef typename __istream_type::ios_base    __ios_base;
1117
 
1118
      const typename __ios_base::fmtflags __flags = __is.flags();
1119
      __is.flags(__ios_base::skipws);
1120
 
1121
      _RealType __a, __b;
1122
      __is >> __a >> __b;
1123
      __x.param(typename uniform_real_distribution<_RealType>::
1124
                param_type(__a, __b));
1125
 
1126
      __is.flags(__flags);
1127
      return __is;
1128
    }
1129
 
1130
 
1131
  template
1132
           typename _UniformRandomNumberGenerator>
1133
    void
1134
    std::bernoulli_distribution::
1135
    __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1136
                    _UniformRandomNumberGenerator& __urng,
1137
                    const param_type& __p)
1138
    {
1139
      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1140
      __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1141
        __aurng(__urng);
1142
      auto __limit = __p.p() * (__aurng.max() - __aurng.min());
1143
 
1144
      while (__f != __t)
1145
        *__f++ = (__aurng() - __aurng.min()) < __limit;
1146
    }
1147
 
1148
  template
1149
    std::basic_ostream<_CharT, _Traits>&
1150
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1151
               const bernoulli_distribution& __x)
1152
    {
1153
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1154
      typedef typename __ostream_type::ios_base    __ios_base;
1155
 
1156
      const typename __ios_base::fmtflags __flags = __os.flags();
1157
      const _CharT __fill = __os.fill();
1158
      const std::streamsize __precision = __os.precision();
1159
      __os.flags(__ios_base::scientific | __ios_base::left);
1160
      __os.fill(__os.widen(' '));
1161
      __os.precision(std::numeric_limits::max_digits10);
1162
 
1163
      __os << __x.p();
1164
 
1165
      __os.flags(__flags);
1166
      __os.fill(__fill);
1167
      __os.precision(__precision);
1168
      return __os;
1169
    }
1170
 
1171
 
1172
  template
1173
    template
1174
      typename geometric_distribution<_IntType>::result_type
1175
      geometric_distribution<_IntType>::
1176
      operator()(_UniformRandomNumberGenerator& __urng,
1177
                 const param_type& __param)
1178
      {
1179
        // About the epsilon thing see this thread:
1180
        // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
1181
        const double __naf =
1182
          (1 - std::numeric_limits::epsilon()) / 2;
1183
        // The largest _RealType convertible to _IntType.
1184
        const double __thr =
1185
          std::numeric_limits<_IntType>::max() + __naf;
1186
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1187
          __aurng(__urng);
1188
 
1189
        double __cand;
1190
        do
1191
          __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p);
1192
        while (__cand >= __thr);
1193
 
1194
        return result_type(__cand + __naf);
1195
      }
1196
 
1197
  template
1198
    template
1199
             typename _UniformRandomNumberGenerator>
1200
      void
1201
      geometric_distribution<_IntType>::
1202
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1203
                      _UniformRandomNumberGenerator& __urng,
1204
                      const param_type& __param)
1205
      {
1206
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1207
        // About the epsilon thing see this thread:
1208
        // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
1209
        const double __naf =
1210
          (1 - std::numeric_limits::epsilon()) / 2;
1211
        // The largest _RealType convertible to _IntType.
1212
        const double __thr =
1213
          std::numeric_limits<_IntType>::max() + __naf;
1214
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1215
          __aurng(__urng);
1216
 
1217
        while (__f != __t)
1218
          {
1219
            double __cand;
1220
            do
1221
              __cand = std::floor(std::log(1.0 - __aurng())
1222
                                  / __param._M_log_1_p);
1223
            while (__cand >= __thr);
1224
 
1225
            *__f++ = __cand + __naf;
1226
          }
1227
      }
1228
 
1229
  template
1230
           typename _CharT, typename _Traits>
1231
    std::basic_ostream<_CharT, _Traits>&
1232
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1233
               const geometric_distribution<_IntType>& __x)
1234
    {
1235
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1236
      typedef typename __ostream_type::ios_base    __ios_base;
1237
 
1238
      const typename __ios_base::fmtflags __flags = __os.flags();
1239
      const _CharT __fill = __os.fill();
1240
      const std::streamsize __precision = __os.precision();
1241
      __os.flags(__ios_base::scientific | __ios_base::left);
1242
      __os.fill(__os.widen(' '));
1243
      __os.precision(std::numeric_limits::max_digits10);
1244
 
1245
      __os << __x.p();
1246
 
1247
      __os.flags(__flags);
1248
      __os.fill(__fill);
1249
      __os.precision(__precision);
1250
      return __os;
1251
    }
1252
 
1253
  template
1254
           typename _CharT, typename _Traits>
1255
    std::basic_istream<_CharT, _Traits>&
1256
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
1257
               geometric_distribution<_IntType>& __x)
1258
    {
1259
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1260
      typedef typename __istream_type::ios_base    __ios_base;
1261
 
1262
      const typename __ios_base::fmtflags __flags = __is.flags();
1263
      __is.flags(__ios_base::skipws);
1264
 
1265
      double __p;
1266
      __is >> __p;
1267
      __x.param(typename geometric_distribution<_IntType>::param_type(__p));
1268
 
1269
      __is.flags(__flags);
1270
      return __is;
1271
    }
1272
 
1273
  // This is Leger's algorithm, also in Devroye, Ch. X, Example 1.5.
1274
  template
1275
    template
1276
      typename negative_binomial_distribution<_IntType>::result_type
1277
      negative_binomial_distribution<_IntType>::
1278
      operator()(_UniformRandomNumberGenerator& __urng)
1279
      {
1280
        const double __y = _M_gd(__urng);
1281
 
1282
        // XXX Is the constructor too slow?
1283
        std::poisson_distribution __poisson(__y);
1284
        return __poisson(__urng);
1285
      }
1286
 
1287
  template
1288
    template
1289
      typename negative_binomial_distribution<_IntType>::result_type
1290
      negative_binomial_distribution<_IntType>::
1291
      operator()(_UniformRandomNumberGenerator& __urng,
1292
                 const param_type& __p)
1293
      {
1294
        typedef typename std::gamma_distribution::param_type
1295
          param_type;
1296
 
1297
        const double __y =
1298
          _M_gd(__urng, param_type(__p.k(), (1.0 - __p.p()) / __p.p()));
1299
 
1300
        std::poisson_distribution __poisson(__y);
1301
        return __poisson(__urng);
1302
      }
1303
 
1304
  template
1305
    template
1306
             typename _UniformRandomNumberGenerator>
1307
      void
1308
      negative_binomial_distribution<_IntType>::
1309
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1310
                      _UniformRandomNumberGenerator& __urng)
1311
      {
1312
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1313
        while (__f != __t)
1314
          {
1315
            const double __y = _M_gd(__urng);
1316
 
1317
            // XXX Is the constructor too slow?
1318
            std::poisson_distribution __poisson(__y);
1319
            *__f++ = __poisson(__urng);
1320
          }
1321
      }
1322
 
1323
  template
1324
    template
1325
             typename _UniformRandomNumberGenerator>
1326
      void
1327
      negative_binomial_distribution<_IntType>::
1328
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1329
                      _UniformRandomNumberGenerator& __urng,
1330
                      const param_type& __p)
1331
      {
1332
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1333
        typename std::gamma_distribution::param_type
1334
          __p2(__p.k(), (1.0 - __p.p()) / __p.p());
1335
 
1336
        while (__f != __t)
1337
          {
1338
            const double __y = _M_gd(__urng, __p2);
1339
 
1340
            std::poisson_distribution __poisson(__y);
1341
            *__f++ = __poisson(__urng);
1342
          }
1343
      }
1344
 
1345
  template
1346
    std::basic_ostream<_CharT, _Traits>&
1347
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1348
               const negative_binomial_distribution<_IntType>& __x)
1349
    {
1350
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1351
      typedef typename __ostream_type::ios_base    __ios_base;
1352
 
1353
      const typename __ios_base::fmtflags __flags = __os.flags();
1354
      const _CharT __fill = __os.fill();
1355
      const std::streamsize __precision = __os.precision();
1356
      const _CharT __space = __os.widen(' ');
1357
      __os.flags(__ios_base::scientific | __ios_base::left);
1358
      __os.fill(__os.widen(' '));
1359
      __os.precision(std::numeric_limits::max_digits10);
1360
 
1361
      __os << __x.k() << __space << __x.p()
1362
           << __space << __x._M_gd;
1363
 
1364
      __os.flags(__flags);
1365
      __os.fill(__fill);
1366
      __os.precision(__precision);
1367
      return __os;
1368
    }
1369
 
1370
  template
1371
    std::basic_istream<_CharT, _Traits>&
1372
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
1373
               negative_binomial_distribution<_IntType>& __x)
1374
    {
1375
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1376
      typedef typename __istream_type::ios_base    __ios_base;
1377
 
1378
      const typename __ios_base::fmtflags __flags = __is.flags();
1379
      __is.flags(__ios_base::skipws);
1380
 
1381
      _IntType __k;
1382
      double __p;
1383
      __is >> __k >> __p >> __x._M_gd;
1384
      __x.param(typename negative_binomial_distribution<_IntType>::
1385
                param_type(__k, __p));
1386
 
1387
      __is.flags(__flags);
1388
      return __is;
1389
    }
1390
 
1391
 
1392
  template
1393
    void
1394
    poisson_distribution<_IntType>::param_type::
1395
    _M_initialize()
1396
    {
1397
#if _GLIBCXX_USE_C99_MATH_TR1
1398
      if (_M_mean >= 12)
1399
        {
1400
          const double __m = std::floor(_M_mean);
1401
          _M_lm_thr = std::log(_M_mean);
1402
          _M_lfm = std::lgamma(__m + 1);
1403
          _M_sm = std::sqrt(__m);
1404
 
1405
          const double __pi_4 = 0.7853981633974483096156608458198757L;
1406
          const double __dx = std::sqrt(2 * __m * std::log(32 * __m
1407
                                                              / __pi_4));
1408
          _M_d = std::round(std::max(6.0, std::min(__m, __dx)));
1409
          const double __cx = 2 * __m + _M_d;
1410
          _M_scx = std::sqrt(__cx / 2);
1411
          _M_1cx = 1 / __cx;
1412
 
1413
          _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
1414
          _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2))
1415
                / _M_d;
1416
        }
1417
      else
1418
#endif
1419
        _M_lm_thr = std::exp(-_M_mean);
1420
      }
1421
 
1422
  /**
1423
   * A rejection algorithm when mean >= 12 and a simple method based
1424
   * upon the multiplication of uniform random variates otherwise.
1425
   * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
1426
   * is defined.
1427
   *
1428
   * Reference:
1429
   * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1430
   * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
1431
   */
1432
  template
1433
    template
1434
      typename poisson_distribution<_IntType>::result_type
1435
      poisson_distribution<_IntType>::
1436
      operator()(_UniformRandomNumberGenerator& __urng,
1437
                 const param_type& __param)
1438
      {
1439
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1440
          __aurng(__urng);
1441
#if _GLIBCXX_USE_C99_MATH_TR1
1442
        if (__param.mean() >= 12)
1443
          {
1444
            double __x;
1445
 
1446
            // See comments above...
1447
            const double __naf =
1448
              (1 - std::numeric_limits::epsilon()) / 2;
1449
            const double __thr =
1450
              std::numeric_limits<_IntType>::max() + __naf;
1451
 
1452
            const double __m = std::floor(__param.mean());
1453
            // sqrt(pi / 2)
1454
            const double __spi_2 = 1.2533141373155002512078826424055226L;
1455
            const double __c1 = __param._M_sm * __spi_2;
1456
            const double __c2 = __param._M_c2b + __c1;
1457
            const double __c3 = __c2 + 1;
1458
            const double __c4 = __c3 + 1;
1459
            // e^(1 / 78)
1460
            const double __e178 = 1.0129030479320018583185514777512983L;
1461
            const double __c5 = __c4 + __e178;
1462
            const double __c = __param._M_cb + __c5;
1463
            const double __2cx = 2 * (2 * __m + __param._M_d);
1464
 
1465
            bool __reject = true;
1466
            do
1467
              {
1468
                const double __u = __c * __aurng();
1469
                const double __e = -std::log(1.0 - __aurng());
1470
 
1471
                double __w = 0.0;
1472
 
1473
                if (__u <= __c1)
1474
                  {
1475
                    const double __n = _M_nd(__urng);
1476
                    const double __y = -std::abs(__n) * __param._M_sm - 1;
1477
                    __x = std::floor(__y);
1478
                    __w = -__n * __n / 2;
1479
                    if (__x < -__m)
1480
                      continue;
1481
                  }
1482
                else if (__u <= __c2)
1483
                  {
1484
                    const double __n = _M_nd(__urng);
1485
                    const double __y = 1 + std::abs(__n) * __param._M_scx;
1486
                    __x = std::ceil(__y);
1487
                    __w = __y * (2 - __y) * __param._M_1cx;
1488
                    if (__x > __param._M_d)
1489
                      continue;
1490
                  }
1491
                else if (__u <= __c3)
1492
                  // NB: This case not in the book, nor in the Errata,
1493
                  // but should be ok...
1494
                  __x = -1;
1495
                else if (__u <= __c4)
1496
                  __x = 0;
1497
                else if (__u <= __c5)
1498
                  __x = 1;
1499
                else
1500
                  {
1501
                    const double __v = -std::log(1.0 - __aurng());
1502
                    const double __y = __param._M_d
1503
                                     + __v * __2cx / __param._M_d;
1504
                    __x = std::ceil(__y);
1505
                    __w = -__param._M_d * __param._M_1cx * (1 + __y / 2);
1506
                  }
1507
 
1508
                __reject = (__w - __e - __x * __param._M_lm_thr
1509
                            > __param._M_lfm - std::lgamma(__x + __m + 1));
1510
 
1511
                __reject |= __x + __m >= __thr;
1512
 
1513
              } while (__reject);
1514
 
1515
            return result_type(__x + __m + __naf);
1516
          }
1517
        else
1518
#endif
1519
          {
1520
            _IntType     __x = 0;
1521
            double __prod = 1.0;
1522
 
1523
            do
1524
              {
1525
                __prod *= __aurng();
1526
                __x += 1;
1527
              }
1528
            while (__prod > __param._M_lm_thr);
1529
 
1530
            return __x - 1;
1531
          }
1532
      }
1533
 
1534
  template
1535
    template
1536
             typename _UniformRandomNumberGenerator>
1537
      void
1538
      poisson_distribution<_IntType>::
1539
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1540
                      _UniformRandomNumberGenerator& __urng,
1541
                      const param_type& __param)
1542
      {
1543
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1544
        // We could duplicate everything from operator()...
1545
        while (__f != __t)
1546
          *__f++ = this->operator()(__urng, __param);
1547
      }
1548
 
1549
  template
1550
           typename _CharT, typename _Traits>
1551
    std::basic_ostream<_CharT, _Traits>&
1552
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1553
               const poisson_distribution<_IntType>& __x)
1554
    {
1555
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1556
      typedef typename __ostream_type::ios_base    __ios_base;
1557
 
1558
      const typename __ios_base::fmtflags __flags = __os.flags();
1559
      const _CharT __fill = __os.fill();
1560
      const std::streamsize __precision = __os.precision();
1561
      const _CharT __space = __os.widen(' ');
1562
      __os.flags(__ios_base::scientific | __ios_base::left);
1563
      __os.fill(__space);
1564
      __os.precision(std::numeric_limits::max_digits10);
1565
 
1566
      __os << __x.mean() << __space << __x._M_nd;
1567
 
1568
      __os.flags(__flags);
1569
      __os.fill(__fill);
1570
      __os.precision(__precision);
1571
      return __os;
1572
    }
1573
 
1574
  template
1575
           typename _CharT, typename _Traits>
1576
    std::basic_istream<_CharT, _Traits>&
1577
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
1578
               poisson_distribution<_IntType>& __x)
1579
    {
1580
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1581
      typedef typename __istream_type::ios_base    __ios_base;
1582
 
1583
      const typename __ios_base::fmtflags __flags = __is.flags();
1584
      __is.flags(__ios_base::skipws);
1585
 
1586
      double __mean;
1587
      __is >> __mean >> __x._M_nd;
1588
      __x.param(typename poisson_distribution<_IntType>::param_type(__mean));
1589
 
1590
      __is.flags(__flags);
1591
      return __is;
1592
    }
1593
 
1594
 
1595
  template
1596
    void
1597
    binomial_distribution<_IntType>::param_type::
1598
    _M_initialize()
1599
    {
1600
      const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
1601
 
1602
      _M_easy = true;
1603
 
1604
#if _GLIBCXX_USE_C99_MATH_TR1
1605
      if (_M_t * __p12 >= 8)
1606
        {
1607
          _M_easy = false;
1608
          const double __np = std::floor(_M_t * __p12);
1609
          const double __pa = __np / _M_t;
1610
          const double __1p = 1 - __pa;
1611
 
1612
          const double __pi_4 = 0.7853981633974483096156608458198757L;
1613
          const double __d1x =
1614
            std::sqrt(__np * __1p * std::log(32 * __np
1615
                                             / (81 * __pi_4 * __1p)));
1616
          _M_d1 = std::round(std::max(1.0, __d1x));
1617
          const double __d2x =
1618
            std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
1619
                                             / (__pi_4 * __pa)));
1620
          _M_d2 = std::round(std::max(1.0, __d2x));
1621
 
1622
          // sqrt(pi / 2)
1623
          const double __spi_2 = 1.2533141373155002512078826424055226L;
1624
          _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
1625
          _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
1626
          _M_c = 2 * _M_d1 / __np;
1627
          _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
1628
          const double __a12 = _M_a1 + _M_s2 * __spi_2;
1629
          const double __s1s = _M_s1 * _M_s1;
1630
          _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
1631
                             * 2 * __s1s / _M_d1
1632
                             * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
1633
          const double __s2s = _M_s2 * _M_s2;
1634
          _M_s = (_M_a123 + 2 * __s2s / _M_d2
1635
                  * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
1636
          _M_lf = (std::lgamma(__np + 1)
1637
                   + std::lgamma(_M_t - __np + 1));
1638
          _M_lp1p = std::log(__pa / __1p);
1639
 
1640
          _M_q = -std::log(1 - (__p12 - __pa) / __1p);
1641
        }
1642
      else
1643
#endif
1644
        _M_q = -std::log(1 - __p12);
1645
    }
1646
 
1647
  template
1648
    template
1649
      typename binomial_distribution<_IntType>::result_type
1650
      binomial_distribution<_IntType>::
1651
      _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t)
1652
      {
1653
        _IntType __x = 0;
1654
        double __sum = 0.0;
1655
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1656
          __aurng(__urng);
1657
 
1658
        do
1659
          {
1660
            const double __e = -std::log(1.0 - __aurng());
1661
            __sum += __e / (__t - __x);
1662
            __x += 1;
1663
          }
1664
        while (__sum <= _M_param._M_q);
1665
 
1666
        return __x - 1;
1667
      }
1668
 
1669
  /**
1670
   * A rejection algorithm when t * p >= 8 and a simple waiting time
1671
   * method - the second in the referenced book - otherwise.
1672
   * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
1673
   * is defined.
1674
   *
1675
   * Reference:
1676
   * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1677
   * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
1678
   */
1679
  template
1680
    template
1681
      typename binomial_distribution<_IntType>::result_type
1682
      binomial_distribution<_IntType>::
1683
      operator()(_UniformRandomNumberGenerator& __urng,
1684
                 const param_type& __param)
1685
      {
1686
        result_type __ret;
1687
        const _IntType __t = __param.t();
1688
        const double __p = __param.p();
1689
        const double __p12 = __p <= 0.5 ? __p : 1.0 - __p;
1690
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1691
          __aurng(__urng);
1692
 
1693
#if _GLIBCXX_USE_C99_MATH_TR1
1694
        if (!__param._M_easy)
1695
          {
1696
            double __x;
1697
 
1698
            // See comments above...
1699
            const double __naf =
1700
              (1 - std::numeric_limits::epsilon()) / 2;
1701
            const double __thr =
1702
              std::numeric_limits<_IntType>::max() + __naf;
1703
 
1704
            const double __np = std::floor(__t * __p12);
1705
 
1706
            // sqrt(pi / 2)
1707
            const double __spi_2 = 1.2533141373155002512078826424055226L;
1708
            const double __a1 = __param._M_a1;
1709
            const double __a12 = __a1 + __param._M_s2 * __spi_2;
1710
            const double __a123 = __param._M_a123;
1711
            const double __s1s = __param._M_s1 * __param._M_s1;
1712
            const double __s2s = __param._M_s2 * __param._M_s2;
1713
 
1714
            bool __reject;
1715
            do
1716
              {
1717
                const double __u = __param._M_s * __aurng();
1718
 
1719
                double __v;
1720
 
1721
                if (__u <= __a1)
1722
                  {
1723
                    const double __n = _M_nd(__urng);
1724
                    const double __y = __param._M_s1 * std::abs(__n);
1725
                    __reject = __y >= __param._M_d1;
1726
                    if (!__reject)
1727
                      {
1728
                        const double __e = -std::log(1.0 - __aurng());
1729
                        __x = std::floor(__y);
1730
                        __v = -__e - __n * __n / 2 + __param._M_c;
1731
                      }
1732
                  }
1733
                else if (__u <= __a12)
1734
                  {
1735
                    const double __n = _M_nd(__urng);
1736
                    const double __y = __param._M_s2 * std::abs(__n);
1737
                    __reject = __y >= __param._M_d2;
1738
                    if (!__reject)
1739
                      {
1740
                        const double __e = -std::log(1.0 - __aurng());
1741
                        __x = std::floor(-__y);
1742
                        __v = -__e - __n * __n / 2;
1743
                      }
1744
                  }
1745
                else if (__u <= __a123)
1746
                  {
1747
                    const double __e1 = -std::log(1.0 - __aurng());
1748
                    const double __e2 = -std::log(1.0 - __aurng());
1749
 
1750
                    const double __y = __param._M_d1
1751
                                     + 2 * __s1s * __e1 / __param._M_d1;
1752
                    __x = std::floor(__y);
1753
                    __v = (-__e2 + __param._M_d1 * (1 / (__t - __np)
1754
                                                    -__y / (2 * __s1s)));
1755
                    __reject = false;
1756
                  }
1757
                else
1758
                  {
1759
                    const double __e1 = -std::log(1.0 - __aurng());
1760
                    const double __e2 = -std::log(1.0 - __aurng());
1761
 
1762
                    const double __y = __param._M_d2
1763
                                     + 2 * __s2s * __e1 / __param._M_d2;
1764
                    __x = std::floor(-__y);
1765
                    __v = -__e2 - __param._M_d2 * __y / (2 * __s2s);
1766
                    __reject = false;
1767
                  }
1768
 
1769
                __reject = __reject || __x < -__np || __x > __t - __np;
1770
                if (!__reject)
1771
                  {
1772
                    const double __lfx =
1773
                      std::lgamma(__np + __x + 1)
1774
                      + std::lgamma(__t - (__np + __x) + 1);
1775
                    __reject = __v > __param._M_lf - __lfx
1776
                             + __x * __param._M_lp1p;
1777
                  }
1778
 
1779
                __reject |= __x + __np >= __thr;
1780
              }
1781
            while (__reject);
1782
 
1783
            __x += __np + __naf;
1784
 
1785
            const _IntType __z = _M_waiting(__urng, __t - _IntType(__x));
1786
            __ret = _IntType(__x) + __z;
1787
          }
1788
        else
1789
#endif
1790
          __ret = _M_waiting(__urng, __t);
1791
 
1792
        if (__p12 != __p)
1793
          __ret = __t - __ret;
1794
        return __ret;
1795
      }
1796
 
1797
  template
1798
    template
1799
             typename _UniformRandomNumberGenerator>
1800
      void
1801
      binomial_distribution<_IntType>::
1802
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1803
                      _UniformRandomNumberGenerator& __urng,
1804
                      const param_type& __param)
1805
      {
1806
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1807
        // We could duplicate everything from operator()...
1808
        while (__f != __t)
1809
          *__f++ = this->operator()(__urng, __param);
1810
      }
1811
 
1812
  template
1813
           typename _CharT, typename _Traits>
1814
    std::basic_ostream<_CharT, _Traits>&
1815
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1816
               const binomial_distribution<_IntType>& __x)
1817
    {
1818
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1819
      typedef typename __ostream_type::ios_base    __ios_base;
1820
 
1821
      const typename __ios_base::fmtflags __flags = __os.flags();
1822
      const _CharT __fill = __os.fill();
1823
      const std::streamsize __precision = __os.precision();
1824
      const _CharT __space = __os.widen(' ');
1825
      __os.flags(__ios_base::scientific | __ios_base::left);
1826
      __os.fill(__space);
1827
      __os.precision(std::numeric_limits::max_digits10);
1828
 
1829
      __os << __x.t() << __space << __x.p()
1830
           << __space << __x._M_nd;
1831
 
1832
      __os.flags(__flags);
1833
      __os.fill(__fill);
1834
      __os.precision(__precision);
1835
      return __os;
1836
    }
1837
 
1838
  template
1839
           typename _CharT, typename _Traits>
1840
    std::basic_istream<_CharT, _Traits>&
1841
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
1842
               binomial_distribution<_IntType>& __x)
1843
    {
1844
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1845
      typedef typename __istream_type::ios_base    __ios_base;
1846
 
1847
      const typename __ios_base::fmtflags __flags = __is.flags();
1848
      __is.flags(__ios_base::dec | __ios_base::skipws);
1849
 
1850
      _IntType __t;
1851
      double __p;
1852
      __is >> __t >> __p >> __x._M_nd;
1853
      __x.param(typename binomial_distribution<_IntType>::
1854
                param_type(__t, __p));
1855
 
1856
      __is.flags(__flags);
1857
      return __is;
1858
    }
1859
 
1860
 
1861
  template
1862
    template
1863
             typename _UniformRandomNumberGenerator>
1864
      void
1865
      std::exponential_distribution<_RealType>::
1866
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1867
                      _UniformRandomNumberGenerator& __urng,
1868
                      const param_type& __p)
1869
      {
1870
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1871
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1872
          __aurng(__urng);
1873
        while (__f != __t)
1874
          *__f++ = -std::log(result_type(1) - __aurng()) / __p.lambda();
1875
      }
1876
 
1877
  template
1878
    std::basic_ostream<_CharT, _Traits>&
1879
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1880
               const exponential_distribution<_RealType>& __x)
1881
    {
1882
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1883
      typedef typename __ostream_type::ios_base    __ios_base;
1884
 
1885
      const typename __ios_base::fmtflags __flags = __os.flags();
1886
      const _CharT __fill = __os.fill();
1887
      const std::streamsize __precision = __os.precision();
1888
      __os.flags(__ios_base::scientific | __ios_base::left);
1889
      __os.fill(__os.widen(' '));
1890
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
1891
 
1892
      __os << __x.lambda();
1893
 
1894
      __os.flags(__flags);
1895
      __os.fill(__fill);
1896
      __os.precision(__precision);
1897
      return __os;
1898
    }
1899
 
1900
  template
1901
    std::basic_istream<_CharT, _Traits>&
1902
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
1903
               exponential_distribution<_RealType>& __x)
1904
    {
1905
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1906
      typedef typename __istream_type::ios_base    __ios_base;
1907
 
1908
      const typename __ios_base::fmtflags __flags = __is.flags();
1909
      __is.flags(__ios_base::dec | __ios_base::skipws);
1910
 
1911
      _RealType __lambda;
1912
      __is >> __lambda;
1913
      __x.param(typename exponential_distribution<_RealType>::
1914
                param_type(__lambda));
1915
 
1916
      __is.flags(__flags);
1917
      return __is;
1918
    }
1919
 
1920
 
1921
  /**
1922
   * Polar method due to Marsaglia.
1923
   *
1924
   * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1925
   * New York, 1986, Ch. V, Sect. 4.4.
1926
   */
1927
  template
1928
    template
1929
      typename normal_distribution<_RealType>::result_type
1930
      normal_distribution<_RealType>::
1931
      operator()(_UniformRandomNumberGenerator& __urng,
1932
                 const param_type& __param)
1933
      {
1934
        result_type __ret;
1935
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1936
          __aurng(__urng);
1937
 
1938
        if (_M_saved_available)
1939
          {
1940
            _M_saved_available = false;
1941
            __ret = _M_saved;
1942
          }
1943
        else
1944
          {
1945
            result_type __x, __y, __r2;
1946
            do
1947
              {
1948
                __x = result_type(2.0) * __aurng() - 1.0;
1949
                __y = result_type(2.0) * __aurng() - 1.0;
1950
                __r2 = __x * __x + __y * __y;
1951
              }
1952
            while (__r2 > 1.0 || __r2 == 0.0);
1953
 
1954
            const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
1955
            _M_saved = __x * __mult;
1956
            _M_saved_available = true;
1957
            __ret = __y * __mult;
1958
          }
1959
 
1960
        __ret = __ret * __param.stddev() + __param.mean();
1961
        return __ret;
1962
      }
1963
 
1964
  template
1965
    template
1966
             typename _UniformRandomNumberGenerator>
1967
      void
1968
      normal_distribution<_RealType>::
1969
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1970
                      _UniformRandomNumberGenerator& __urng,
1971
                      const param_type& __param)
1972
      {
1973
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1974
 
1975
        if (__f == __t)
1976
          return;
1977
 
1978
        if (_M_saved_available)
1979
          {
1980
            _M_saved_available = false;
1981
            *__f++ = _M_saved * __param.stddev() + __param.mean();
1982
 
1983
            if (__f == __t)
1984
              return;
1985
          }
1986
 
1987
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1988
          __aurng(__urng);
1989
 
1990
        while (__f + 1 < __t)
1991
          {
1992
            result_type __x, __y, __r2;
1993
            do
1994
              {
1995
                __x = result_type(2.0) * __aurng() - 1.0;
1996
                __y = result_type(2.0) * __aurng() - 1.0;
1997
                __r2 = __x * __x + __y * __y;
1998
              }
1999
            while (__r2 > 1.0 || __r2 == 0.0);
2000
 
2001
            const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
2002
            *__f++ = __y * __mult * __param.stddev() + __param.mean();
2003
            *__f++ = __x * __mult * __param.stddev() + __param.mean();
2004
          }
2005
 
2006
        if (__f != __t)
2007
          {
2008
            result_type __x, __y, __r2;
2009
            do
2010
              {
2011
                __x = result_type(2.0) * __aurng() - 1.0;
2012
                __y = result_type(2.0) * __aurng() - 1.0;
2013
                __r2 = __x * __x + __y * __y;
2014
              }
2015
            while (__r2 > 1.0 || __r2 == 0.0);
2016
 
2017
            const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
2018
            _M_saved = __x * __mult;
2019
            _M_saved_available = true;
2020
            *__f = __y * __mult * __param.stddev() + __param.mean();
2021
          }
2022
      }
2023
 
2024
  template
2025
    bool
2026
    operator==(const std::normal_distribution<_RealType>& __d1,
2027
               const std::normal_distribution<_RealType>& __d2)
2028
    {
2029
      if (__d1._M_param == __d2._M_param
2030
          && __d1._M_saved_available == __d2._M_saved_available)
2031
        {
2032
          if (__d1._M_saved_available
2033
              && __d1._M_saved == __d2._M_saved)
2034
            return true;
2035
          else if(!__d1._M_saved_available)
2036
            return true;
2037
          else
2038
            return false;
2039
        }
2040
      else
2041
        return false;
2042
    }
2043
 
2044
  template
2045
    std::basic_ostream<_CharT, _Traits>&
2046
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2047
               const normal_distribution<_RealType>& __x)
2048
    {
2049
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2050
      typedef typename __ostream_type::ios_base    __ios_base;
2051
 
2052
      const typename __ios_base::fmtflags __flags = __os.flags();
2053
      const _CharT __fill = __os.fill();
2054
      const std::streamsize __precision = __os.precision();
2055
      const _CharT __space = __os.widen(' ');
2056
      __os.flags(__ios_base::scientific | __ios_base::left);
2057
      __os.fill(__space);
2058
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2059
 
2060
      __os << __x.mean() << __space << __x.stddev()
2061
           << __space << __x._M_saved_available;
2062
      if (__x._M_saved_available)
2063
        __os << __space << __x._M_saved;
2064
 
2065
      __os.flags(__flags);
2066
      __os.fill(__fill);
2067
      __os.precision(__precision);
2068
      return __os;
2069
    }
2070
 
2071
  template
2072
    std::basic_istream<_CharT, _Traits>&
2073
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2074
               normal_distribution<_RealType>& __x)
2075
    {
2076
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2077
      typedef typename __istream_type::ios_base    __ios_base;
2078
 
2079
      const typename __ios_base::fmtflags __flags = __is.flags();
2080
      __is.flags(__ios_base::dec | __ios_base::skipws);
2081
 
2082
      double __mean, __stddev;
2083
      __is >> __mean >> __stddev
2084
           >> __x._M_saved_available;
2085
      if (__x._M_saved_available)
2086
        __is >> __x._M_saved;
2087
      __x.param(typename normal_distribution<_RealType>::
2088
                param_type(__mean, __stddev));
2089
 
2090
      __is.flags(__flags);
2091
      return __is;
2092
    }
2093
 
2094
 
2095
  template
2096
    template
2097
             typename _UniformRandomNumberGenerator>
2098
      void
2099
      lognormal_distribution<_RealType>::
2100
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2101
                      _UniformRandomNumberGenerator& __urng,
2102
                      const param_type& __p)
2103
      {
2104
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2105
          while (__f != __t)
2106
            *__f++ = std::exp(__p.s() * _M_nd(__urng) + __p.m());
2107
      }
2108
 
2109
  template
2110
    std::basic_ostream<_CharT, _Traits>&
2111
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2112
               const lognormal_distribution<_RealType>& __x)
2113
    {
2114
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2115
      typedef typename __ostream_type::ios_base    __ios_base;
2116
 
2117
      const typename __ios_base::fmtflags __flags = __os.flags();
2118
      const _CharT __fill = __os.fill();
2119
      const std::streamsize __precision = __os.precision();
2120
      const _CharT __space = __os.widen(' ');
2121
      __os.flags(__ios_base::scientific | __ios_base::left);
2122
      __os.fill(__space);
2123
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2124
 
2125
      __os << __x.m() << __space << __x.s()
2126
           << __space << __x._M_nd;
2127
 
2128
      __os.flags(__flags);
2129
      __os.fill(__fill);
2130
      __os.precision(__precision);
2131
      return __os;
2132
    }
2133
 
2134
  template
2135
    std::basic_istream<_CharT, _Traits>&
2136
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2137
               lognormal_distribution<_RealType>& __x)
2138
    {
2139
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2140
      typedef typename __istream_type::ios_base    __ios_base;
2141
 
2142
      const typename __ios_base::fmtflags __flags = __is.flags();
2143
      __is.flags(__ios_base::dec | __ios_base::skipws);
2144
 
2145
      _RealType __m, __s;
2146
      __is >> __m >> __s >> __x._M_nd;
2147
      __x.param(typename lognormal_distribution<_RealType>::
2148
                param_type(__m, __s));
2149
 
2150
      __is.flags(__flags);
2151
      return __is;
2152
    }
2153
 
2154
  template
2155
    template
2156
             typename _UniformRandomNumberGenerator>
2157
      void
2158
      std::chi_squared_distribution<_RealType>::
2159
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2160
                      _UniformRandomNumberGenerator& __urng)
2161
      {
2162
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2163
        while (__f != __t)
2164
          *__f++ = 2 * _M_gd(__urng);
2165
      }
2166
 
2167
  template
2168
    template
2169
             typename _UniformRandomNumberGenerator>
2170
      void
2171
      std::chi_squared_distribution<_RealType>::
2172
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2173
                      _UniformRandomNumberGenerator& __urng,
2174
                      const typename
2175
                      std::gamma_distribution::param_type& __p)
2176
      {
2177
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2178
        while (__f != __t)
2179
          *__f++ = 2 * _M_gd(__urng, __p);
2180
      }
2181
 
2182
  template
2183
    std::basic_ostream<_CharT, _Traits>&
2184
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2185
               const chi_squared_distribution<_RealType>& __x)
2186
    {
2187
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2188
      typedef typename __ostream_type::ios_base    __ios_base;
2189
 
2190
      const typename __ios_base::fmtflags __flags = __os.flags();
2191
      const _CharT __fill = __os.fill();
2192
      const std::streamsize __precision = __os.precision();
2193
      const _CharT __space = __os.widen(' ');
2194
      __os.flags(__ios_base::scientific | __ios_base::left);
2195
      __os.fill(__space);
2196
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2197
 
2198
      __os << __x.n() << __space << __x._M_gd;
2199
 
2200
      __os.flags(__flags);
2201
      __os.fill(__fill);
2202
      __os.precision(__precision);
2203
      return __os;
2204
    }
2205
 
2206
  template
2207
    std::basic_istream<_CharT, _Traits>&
2208
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2209
               chi_squared_distribution<_RealType>& __x)
2210
    {
2211
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2212
      typedef typename __istream_type::ios_base    __ios_base;
2213
 
2214
      const typename __ios_base::fmtflags __flags = __is.flags();
2215
      __is.flags(__ios_base::dec | __ios_base::skipws);
2216
 
2217
      _RealType __n;
2218
      __is >> __n >> __x._M_gd;
2219
      __x.param(typename chi_squared_distribution<_RealType>::
2220
                param_type(__n));
2221
 
2222
      __is.flags(__flags);
2223
      return __is;
2224
    }
2225
 
2226
 
2227
  template
2228
    template
2229
      typename cauchy_distribution<_RealType>::result_type
2230
      cauchy_distribution<_RealType>::
2231
      operator()(_UniformRandomNumberGenerator& __urng,
2232
                 const param_type& __p)
2233
      {
2234
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2235
          __aurng(__urng);
2236
        _RealType __u;
2237
        do
2238
          __u = __aurng();
2239
        while (__u == 0.5);
2240
 
2241
        const _RealType __pi = 3.1415926535897932384626433832795029L;
2242
        return __p.a() + __p.b() * std::tan(__pi * __u);
2243
      }
2244
 
2245
  template
2246
    template
2247
             typename _UniformRandomNumberGenerator>
2248
      void
2249
      cauchy_distribution<_RealType>::
2250
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2251
                      _UniformRandomNumberGenerator& __urng,
2252
                      const param_type& __p)
2253
      {
2254
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2255
        const _RealType __pi = 3.1415926535897932384626433832795029L;
2256
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2257
          __aurng(__urng);
2258
        while (__f != __t)
2259
          {
2260
            _RealType __u;
2261
            do
2262
              __u = __aurng();
2263
            while (__u == 0.5);
2264
 
2265
            *__f++ = __p.a() + __p.b() * std::tan(__pi * __u);
2266
          }
2267
      }
2268
 
2269
  template
2270
    std::basic_ostream<_CharT, _Traits>&
2271
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2272
               const cauchy_distribution<_RealType>& __x)
2273
    {
2274
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2275
      typedef typename __ostream_type::ios_base    __ios_base;
2276
 
2277
      const typename __ios_base::fmtflags __flags = __os.flags();
2278
      const _CharT __fill = __os.fill();
2279
      const std::streamsize __precision = __os.precision();
2280
      const _CharT __space = __os.widen(' ');
2281
      __os.flags(__ios_base::scientific | __ios_base::left);
2282
      __os.fill(__space);
2283
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2284
 
2285
      __os << __x.a() << __space << __x.b();
2286
 
2287
      __os.flags(__flags);
2288
      __os.fill(__fill);
2289
      __os.precision(__precision);
2290
      return __os;
2291
    }
2292
 
2293
  template
2294
    std::basic_istream<_CharT, _Traits>&
2295
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2296
               cauchy_distribution<_RealType>& __x)
2297
    {
2298
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2299
      typedef typename __istream_type::ios_base    __ios_base;
2300
 
2301
      const typename __ios_base::fmtflags __flags = __is.flags();
2302
      __is.flags(__ios_base::dec | __ios_base::skipws);
2303
 
2304
      _RealType __a, __b;
2305
      __is >> __a >> __b;
2306
      __x.param(typename cauchy_distribution<_RealType>::
2307
                param_type(__a, __b));
2308
 
2309
      __is.flags(__flags);
2310
      return __is;
2311
    }
2312
 
2313
 
2314
  template
2315
    template
2316
             typename _UniformRandomNumberGenerator>
2317
      void
2318
      std::fisher_f_distribution<_RealType>::
2319
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2320
                      _UniformRandomNumberGenerator& __urng)
2321
      {
2322
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2323
        while (__f != __t)
2324
          *__f++ = ((_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()));
2325
      }
2326
 
2327
  template
2328
    template
2329
             typename _UniformRandomNumberGenerator>
2330
      void
2331
      std::fisher_f_distribution<_RealType>::
2332
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2333
                      _UniformRandomNumberGenerator& __urng,
2334
                      const param_type& __p)
2335
      {
2336
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2337
        typedef typename std::gamma_distribution::param_type
2338
          param_type;
2339
        param_type __p1(__p.m() / 2);
2340
        param_type __p2(__p.n() / 2);
2341
        while (__f != __t)
2342
          *__f++ = ((_M_gd_x(__urng, __p1) * n())
2343
                    / (_M_gd_y(__urng, __p2) * m()));
2344
      }
2345
 
2346
  template
2347
    std::basic_ostream<_CharT, _Traits>&
2348
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2349
               const fisher_f_distribution<_RealType>& __x)
2350
    {
2351
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2352
      typedef typename __ostream_type::ios_base    __ios_base;
2353
 
2354
      const typename __ios_base::fmtflags __flags = __os.flags();
2355
      const _CharT __fill = __os.fill();
2356
      const std::streamsize __precision = __os.precision();
2357
      const _CharT __space = __os.widen(' ');
2358
      __os.flags(__ios_base::scientific | __ios_base::left);
2359
      __os.fill(__space);
2360
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2361
 
2362
      __os << __x.m() << __space << __x.n()
2363
           << __space << __x._M_gd_x << __space << __x._M_gd_y;
2364
 
2365
      __os.flags(__flags);
2366
      __os.fill(__fill);
2367
      __os.precision(__precision);
2368
      return __os;
2369
    }
2370
 
2371
  template
2372
    std::basic_istream<_CharT, _Traits>&
2373
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2374
               fisher_f_distribution<_RealType>& __x)
2375
    {
2376
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2377
      typedef typename __istream_type::ios_base    __ios_base;
2378
 
2379
      const typename __ios_base::fmtflags __flags = __is.flags();
2380
      __is.flags(__ios_base::dec | __ios_base::skipws);
2381
 
2382
      _RealType __m, __n;
2383
      __is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y;
2384
      __x.param(typename fisher_f_distribution<_RealType>::
2385
                param_type(__m, __n));
2386
 
2387
      __is.flags(__flags);
2388
      return __is;
2389
    }
2390
 
2391
 
2392
  template
2393
    template
2394
             typename _UniformRandomNumberGenerator>
2395
      void
2396
      std::student_t_distribution<_RealType>::
2397
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2398
                      _UniformRandomNumberGenerator& __urng)
2399
      {
2400
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2401
        while (__f != __t)
2402
          *__f++ = _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng));
2403
      }
2404
 
2405
  template
2406
    template
2407
             typename _UniformRandomNumberGenerator>
2408
      void
2409
      std::student_t_distribution<_RealType>::
2410
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2411
                      _UniformRandomNumberGenerator& __urng,
2412
                      const param_type& __p)
2413
      {
2414
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2415
        typename std::gamma_distribution::param_type
2416
          __p2(__p.n() / 2, 2);
2417
        while (__f != __t)
2418
          *__f++ =  _M_nd(__urng) * std::sqrt(__p.n() / _M_gd(__urng, __p2));
2419
      }
2420
 
2421
  template
2422
    std::basic_ostream<_CharT, _Traits>&
2423
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2424
               const student_t_distribution<_RealType>& __x)
2425
    {
2426
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2427
      typedef typename __ostream_type::ios_base    __ios_base;
2428
 
2429
      const typename __ios_base::fmtflags __flags = __os.flags();
2430
      const _CharT __fill = __os.fill();
2431
      const std::streamsize __precision = __os.precision();
2432
      const _CharT __space = __os.widen(' ');
2433
      __os.flags(__ios_base::scientific | __ios_base::left);
2434
      __os.fill(__space);
2435
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2436
 
2437
      __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd;
2438
 
2439
      __os.flags(__flags);
2440
      __os.fill(__fill);
2441
      __os.precision(__precision);
2442
      return __os;
2443
    }
2444
 
2445
  template
2446
    std::basic_istream<_CharT, _Traits>&
2447
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2448
               student_t_distribution<_RealType>& __x)
2449
    {
2450
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2451
      typedef typename __istream_type::ios_base    __ios_base;
2452
 
2453
      const typename __ios_base::fmtflags __flags = __is.flags();
2454
      __is.flags(__ios_base::dec | __ios_base::skipws);
2455
 
2456
      _RealType __n;
2457
      __is >> __n >> __x._M_nd >> __x._M_gd;
2458
      __x.param(typename student_t_distribution<_RealType>::param_type(__n));
2459
 
2460
      __is.flags(__flags);
2461
      return __is;
2462
    }
2463
 
2464
 
2465
  template
2466
    void
2467
    gamma_distribution<_RealType>::param_type::
2468
    _M_initialize()
2469
    {
2470
      _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha;
2471
 
2472
      const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0);
2473
      _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1);
2474
    }
2475
 
2476
  /**
2477
   * Marsaglia, G. and Tsang, W. W.
2478
   * "A Simple Method for Generating Gamma Variables"
2479
   * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000.
2480
   */
2481
  template
2482
    template
2483
      typename gamma_distribution<_RealType>::result_type
2484
      gamma_distribution<_RealType>::
2485
      operator()(_UniformRandomNumberGenerator& __urng,
2486
                 const param_type& __param)
2487
      {
2488
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2489
          __aurng(__urng);
2490
 
2491
        result_type __u, __v, __n;
2492
        const result_type __a1 = (__param._M_malpha
2493
                                  - _RealType(1.0) / _RealType(3.0));
2494
 
2495
        do
2496
          {
2497
            do
2498
              {
2499
                __n = _M_nd(__urng);
2500
                __v = result_type(1.0) + __param._M_a2 * __n;
2501
              }
2502
            while (__v <= 0.0);
2503
 
2504
            __v = __v * __v * __v;
2505
            __u = __aurng();
2506
          }
2507
        while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n
2508
               && (std::log(__u) > (0.5 * __n * __n + __a1
2509
                                    * (1.0 - __v + std::log(__v)))));
2510
 
2511
        if (__param.alpha() == __param._M_malpha)
2512
          return __a1 * __v * __param.beta();
2513
        else
2514
          {
2515
            do
2516
              __u = __aurng();
2517
            while (__u == 0.0);
2518
 
2519
            return (std::pow(__u, result_type(1.0) / __param.alpha())
2520
                    * __a1 * __v * __param.beta());
2521
          }
2522
      }
2523
 
2524
  template
2525
    template
2526
             typename _UniformRandomNumberGenerator>
2527
      void
2528
      gamma_distribution<_RealType>::
2529
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2530
                      _UniformRandomNumberGenerator& __urng,
2531
                      const param_type& __param)
2532
      {
2533
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2534
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2535
          __aurng(__urng);
2536
 
2537
        result_type __u, __v, __n;
2538
        const result_type __a1 = (__param._M_malpha
2539
                                  - _RealType(1.0) / _RealType(3.0));
2540
 
2541
        if (__param.alpha() == __param._M_malpha)
2542
          while (__f != __t)
2543
            {
2544
              do
2545
                {
2546
                  do
2547
                    {
2548
                      __n = _M_nd(__urng);
2549
                      __v = result_type(1.0) + __param._M_a2 * __n;
2550
                    }
2551
                  while (__v <= 0.0);
2552
 
2553
                  __v = __v * __v * __v;
2554
                  __u = __aurng();
2555
                }
2556
              while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n
2557
                     && (std::log(__u) > (0.5 * __n * __n + __a1
2558
                                          * (1.0 - __v + std::log(__v)))));
2559
 
2560
              *__f++ = __a1 * __v * __param.beta();
2561
            }
2562
        else
2563
          while (__f != __t)
2564
            {
2565
              do
2566
                {
2567
                  do
2568
                    {
2569
                      __n = _M_nd(__urng);
2570
                      __v = result_type(1.0) + __param._M_a2 * __n;
2571
                    }
2572
                  while (__v <= 0.0);
2573
 
2574
                  __v = __v * __v * __v;
2575
                  __u = __aurng();
2576
                }
2577
              while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n
2578
                     && (std::log(__u) > (0.5 * __n * __n + __a1
2579
                                          * (1.0 - __v + std::log(__v)))));
2580
 
2581
              do
2582
                __u = __aurng();
2583
              while (__u == 0.0);
2584
 
2585
              *__f++ = (std::pow(__u, result_type(1.0) / __param.alpha())
2586
                        * __a1 * __v * __param.beta());
2587
            }
2588
      }
2589
 
2590
  template
2591
    std::basic_ostream<_CharT, _Traits>&
2592
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2593
               const gamma_distribution<_RealType>& __x)
2594
    {
2595
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2596
      typedef typename __ostream_type::ios_base    __ios_base;
2597
 
2598
      const typename __ios_base::fmtflags __flags = __os.flags();
2599
      const _CharT __fill = __os.fill();
2600
      const std::streamsize __precision = __os.precision();
2601
      const _CharT __space = __os.widen(' ');
2602
      __os.flags(__ios_base::scientific | __ios_base::left);
2603
      __os.fill(__space);
2604
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2605
 
2606
      __os << __x.alpha() << __space << __x.beta()
2607
           << __space << __x._M_nd;
2608
 
2609
      __os.flags(__flags);
2610
      __os.fill(__fill);
2611
      __os.precision(__precision);
2612
      return __os;
2613
    }
2614
 
2615
  template
2616
    std::basic_istream<_CharT, _Traits>&
2617
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2618
               gamma_distribution<_RealType>& __x)
2619
    {
2620
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2621
      typedef typename __istream_type::ios_base    __ios_base;
2622
 
2623
      const typename __ios_base::fmtflags __flags = __is.flags();
2624
      __is.flags(__ios_base::dec | __ios_base::skipws);
2625
 
2626
      _RealType __alpha_val, __beta_val;
2627
      __is >> __alpha_val >> __beta_val >> __x._M_nd;
2628
      __x.param(typename gamma_distribution<_RealType>::
2629
                param_type(__alpha_val, __beta_val));
2630
 
2631
      __is.flags(__flags);
2632
      return __is;
2633
    }
2634
 
2635
 
2636
  template
2637
    template
2638
      typename weibull_distribution<_RealType>::result_type
2639
      weibull_distribution<_RealType>::
2640
      operator()(_UniformRandomNumberGenerator& __urng,
2641
                 const param_type& __p)
2642
      {
2643
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2644
          __aurng(__urng);
2645
        return __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
2646
                                  result_type(1) / __p.a());
2647
      }
2648
 
2649
  template
2650
    template
2651
             typename _UniformRandomNumberGenerator>
2652
      void
2653
      weibull_distribution<_RealType>::
2654
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2655
                      _UniformRandomNumberGenerator& __urng,
2656
                      const param_type& __p)
2657
      {
2658
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2659
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2660
          __aurng(__urng);
2661
        auto __inv_a = result_type(1) / __p.a();
2662
 
2663
        while (__f != __t)
2664
          *__f++ = __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
2665
                                      __inv_a);
2666
      }
2667
 
2668
  template
2669
    std::basic_ostream<_CharT, _Traits>&
2670
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2671
               const weibull_distribution<_RealType>& __x)
2672
    {
2673
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2674
      typedef typename __ostream_type::ios_base    __ios_base;
2675
 
2676
      const typename __ios_base::fmtflags __flags = __os.flags();
2677
      const _CharT __fill = __os.fill();
2678
      const std::streamsize __precision = __os.precision();
2679
      const _CharT __space = __os.widen(' ');
2680
      __os.flags(__ios_base::scientific | __ios_base::left);
2681
      __os.fill(__space);
2682
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2683
 
2684
      __os << __x.a() << __space << __x.b();
2685
 
2686
      __os.flags(__flags);
2687
      __os.fill(__fill);
2688
      __os.precision(__precision);
2689
      return __os;
2690
    }
2691
 
2692
  template
2693
    std::basic_istream<_CharT, _Traits>&
2694
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2695
               weibull_distribution<_RealType>& __x)
2696
    {
2697
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2698
      typedef typename __istream_type::ios_base    __ios_base;
2699
 
2700
      const typename __ios_base::fmtflags __flags = __is.flags();
2701
      __is.flags(__ios_base::dec | __ios_base::skipws);
2702
 
2703
      _RealType __a, __b;
2704
      __is >> __a >> __b;
2705
      __x.param(typename weibull_distribution<_RealType>::
2706
                param_type(__a, __b));
2707
 
2708
      __is.flags(__flags);
2709
      return __is;
2710
    }
2711
 
2712
 
2713
  template
2714
    template
2715
      typename extreme_value_distribution<_RealType>::result_type
2716
      extreme_value_distribution<_RealType>::
2717
      operator()(_UniformRandomNumberGenerator& __urng,
2718
                 const param_type& __p)
2719
      {
2720
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2721
          __aurng(__urng);
2722
        return __p.a() - __p.b() * std::log(-std::log(result_type(1)
2723
                                                      - __aurng()));
2724
      }
2725
 
2726
  template
2727
    template
2728
             typename _UniformRandomNumberGenerator>
2729
      void
2730
      extreme_value_distribution<_RealType>::
2731
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2732
                      _UniformRandomNumberGenerator& __urng,
2733
                      const param_type& __p)
2734
      {
2735
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2736
        __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2737
          __aurng(__urng);
2738
 
2739
        while (__f != __t)
2740
          *__f++ = __p.a() - __p.b() * std::log(-std::log(result_type(1)
2741
                                                          - __aurng()));
2742
      }
2743
 
2744
  template
2745
    std::basic_ostream<_CharT, _Traits>&
2746
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2747
               const extreme_value_distribution<_RealType>& __x)
2748
    {
2749
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2750
      typedef typename __ostream_type::ios_base    __ios_base;
2751
 
2752
      const typename __ios_base::fmtflags __flags = __os.flags();
2753
      const _CharT __fill = __os.fill();
2754
      const std::streamsize __precision = __os.precision();
2755
      const _CharT __space = __os.widen(' ');
2756
      __os.flags(__ios_base::scientific | __ios_base::left);
2757
      __os.fill(__space);
2758
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
2759
 
2760
      __os << __x.a() << __space << __x.b();
2761
 
2762
      __os.flags(__flags);
2763
      __os.fill(__fill);
2764
      __os.precision(__precision);
2765
      return __os;
2766
    }
2767
 
2768
  template
2769
    std::basic_istream<_CharT, _Traits>&
2770
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2771
               extreme_value_distribution<_RealType>& __x)
2772
    {
2773
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2774
      typedef typename __istream_type::ios_base    __ios_base;
2775
 
2776
      const typename __ios_base::fmtflags __flags = __is.flags();
2777
      __is.flags(__ios_base::dec | __ios_base::skipws);
2778
 
2779
      _RealType __a, __b;
2780
      __is >> __a >> __b;
2781
      __x.param(typename extreme_value_distribution<_RealType>::
2782
                param_type(__a, __b));
2783
 
2784
      __is.flags(__flags);
2785
      return __is;
2786
    }
2787
 
2788
 
2789
  template
2790
    void
2791
    discrete_distribution<_IntType>::param_type::
2792
    _M_initialize()
2793
    {
2794
      if (_M_prob.size() < 2)
2795
        {
2796
          _M_prob.clear();
2797
          return;
2798
        }
2799
 
2800
      const double __sum = std::accumulate(_M_prob.begin(),
2801
                                           _M_prob.end(), 0.0);
2802
      // Now normalize the probabilites.
2803
      __detail::__transform(_M_prob.begin(), _M_prob.end(), _M_prob.begin(),
2804
                          std::bind2nd(std::divides(), __sum));
2805
      // Accumulate partial sums.
2806
      _M_cp.reserve(_M_prob.size());
2807
      std::partial_sum(_M_prob.begin(), _M_prob.end(),
2808
                       std::back_inserter(_M_cp));
2809
      // Make sure the last cumulative probability is one.
2810
      _M_cp[_M_cp.size() - 1] = 1.0;
2811
    }
2812
 
2813
  template
2814
    template
2815
      discrete_distribution<_IntType>::param_type::
2816
      param_type(size_t __nw, double __xmin, double __xmax, _Func __fw)
2817
      : _M_prob(), _M_cp()
2818
      {
2819
        const size_t __n = __nw == 0 ? 1 : __nw;
2820
        const double __delta = (__xmax - __xmin) / __n;
2821
 
2822
        _M_prob.reserve(__n);
2823
        for (size_t __k = 0; __k < __nw; ++__k)
2824
          _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta));
2825
 
2826
        _M_initialize();
2827
      }
2828
 
2829
  template
2830
    template
2831
      typename discrete_distribution<_IntType>::result_type
2832
      discrete_distribution<_IntType>::
2833
      operator()(_UniformRandomNumberGenerator& __urng,
2834
                 const param_type& __param)
2835
      {
2836
        if (__param._M_cp.empty())
2837
          return result_type(0);
2838
 
2839
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
2840
          __aurng(__urng);
2841
 
2842
        const double __p = __aurng();
2843
        auto __pos = std::lower_bound(__param._M_cp.begin(),
2844
                                      __param._M_cp.end(), __p);
2845
 
2846
        return __pos - __param._M_cp.begin();
2847
      }
2848
 
2849
  template
2850
    template
2851
             typename _UniformRandomNumberGenerator>
2852
      void
2853
      discrete_distribution<_IntType>::
2854
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2855
                      _UniformRandomNumberGenerator& __urng,
2856
                      const param_type& __param)
2857
      {
2858
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2859
 
2860
        if (__param._M_cp.empty())
2861
          {
2862
            while (__f != __t)
2863
              *__f++ = result_type(0);
2864
            return;
2865
          }
2866
 
2867
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
2868
          __aurng(__urng);
2869
 
2870
        while (__f != __t)
2871
          {
2872
            const double __p = __aurng();
2873
            auto __pos = std::lower_bound(__param._M_cp.begin(),
2874
                                          __param._M_cp.end(), __p);
2875
 
2876
            *__f++ = __pos - __param._M_cp.begin();
2877
          }
2878
      }
2879
 
2880
  template
2881
    std::basic_ostream<_CharT, _Traits>&
2882
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2883
               const discrete_distribution<_IntType>& __x)
2884
    {
2885
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2886
      typedef typename __ostream_type::ios_base    __ios_base;
2887
 
2888
      const typename __ios_base::fmtflags __flags = __os.flags();
2889
      const _CharT __fill = __os.fill();
2890
      const std::streamsize __precision = __os.precision();
2891
      const _CharT __space = __os.widen(' ');
2892
      __os.flags(__ios_base::scientific | __ios_base::left);
2893
      __os.fill(__space);
2894
      __os.precision(std::numeric_limits::max_digits10);
2895
 
2896
      std::vector __prob = __x.probabilities();
2897
      __os << __prob.size();
2898
      for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit)
2899
        __os << __space << *__dit;
2900
 
2901
      __os.flags(__flags);
2902
      __os.fill(__fill);
2903
      __os.precision(__precision);
2904
      return __os;
2905
    }
2906
 
2907
  template
2908
    std::basic_istream<_CharT, _Traits>&
2909
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
2910
               discrete_distribution<_IntType>& __x)
2911
    {
2912
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2913
      typedef typename __istream_type::ios_base    __ios_base;
2914
 
2915
      const typename __ios_base::fmtflags __flags = __is.flags();
2916
      __is.flags(__ios_base::dec | __ios_base::skipws);
2917
 
2918
      size_t __n;
2919
      __is >> __n;
2920
 
2921
      std::vector __prob_vec;
2922
      __prob_vec.reserve(__n);
2923
      for (; __n != 0; --__n)
2924
        {
2925
          double __prob;
2926
          __is >> __prob;
2927
          __prob_vec.push_back(__prob);
2928
        }
2929
 
2930
      __x.param(typename discrete_distribution<_IntType>::
2931
                param_type(__prob_vec.begin(), __prob_vec.end()));
2932
 
2933
      __is.flags(__flags);
2934
      return __is;
2935
    }
2936
 
2937
 
2938
  template
2939
    void
2940
    piecewise_constant_distribution<_RealType>::param_type::
2941
    _M_initialize()
2942
    {
2943
      if (_M_int.size() < 2
2944
          || (_M_int.size() == 2
2945
              && _M_int[0] == _RealType(0)
2946
              && _M_int[1] == _RealType(1)))
2947
        {
2948
          _M_int.clear();
2949
          _M_den.clear();
2950
          return;
2951
        }
2952
 
2953
      const double __sum = std::accumulate(_M_den.begin(),
2954
                                           _M_den.end(), 0.0);
2955
 
2956
      __detail::__transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
2957
                            std::bind2nd(std::divides(), __sum));
2958
 
2959
      _M_cp.reserve(_M_den.size());
2960
      std::partial_sum(_M_den.begin(), _M_den.end(),
2961
                       std::back_inserter(_M_cp));
2962
 
2963
      // Make sure the last cumulative probability is one.
2964
      _M_cp[_M_cp.size() - 1] = 1.0;
2965
 
2966
      for (size_t __k = 0; __k < _M_den.size(); ++__k)
2967
        _M_den[__k] /= _M_int[__k + 1] - _M_int[__k];
2968
    }
2969
 
2970
  template
2971
    template
2972
      piecewise_constant_distribution<_RealType>::param_type::
2973
      param_type(_InputIteratorB __bbegin,
2974
                 _InputIteratorB __bend,
2975
                 _InputIteratorW __wbegin)
2976
      : _M_int(), _M_den(), _M_cp()
2977
      {
2978
        if (__bbegin != __bend)
2979
          {
2980
            for (;;)
2981
              {
2982
                _M_int.push_back(*__bbegin);
2983
                ++__bbegin;
2984
                if (__bbegin == __bend)
2985
                  break;
2986
 
2987
                _M_den.push_back(*__wbegin);
2988
                ++__wbegin;
2989
              }
2990
          }
2991
 
2992
        _M_initialize();
2993
      }
2994
 
2995
  template
2996
    template
2997
      piecewise_constant_distribution<_RealType>::param_type::
2998
      param_type(initializer_list<_RealType> __bl, _Func __fw)
2999
      : _M_int(), _M_den(), _M_cp()
3000
      {
3001
        _M_int.reserve(__bl.size());
3002
        for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
3003
          _M_int.push_back(*__biter);
3004
 
3005
        _M_den.reserve(_M_int.size() - 1);
3006
        for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
3007
          _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k])));
3008
 
3009
        _M_initialize();
3010
      }
3011
 
3012
  template
3013
    template
3014
      piecewise_constant_distribution<_RealType>::param_type::
3015
      param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
3016
      : _M_int(), _M_den(), _M_cp()
3017
      {
3018
        const size_t __n = __nw == 0 ? 1 : __nw;
3019
        const _RealType __delta = (__xmax - __xmin) / __n;
3020
 
3021
        _M_int.reserve(__n + 1);
3022
        for (size_t __k = 0; __k <= __nw; ++__k)
3023
          _M_int.push_back(__xmin + __k * __delta);
3024
 
3025
        _M_den.reserve(__n);
3026
        for (size_t __k = 0; __k < __nw; ++__k)
3027
          _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta));
3028
 
3029
        _M_initialize();
3030
      }
3031
 
3032
  template
3033
    template
3034
      typename piecewise_constant_distribution<_RealType>::result_type
3035
      piecewise_constant_distribution<_RealType>::
3036
      operator()(_UniformRandomNumberGenerator& __urng,
3037
                 const param_type& __param)
3038
      {
3039
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3040
          __aurng(__urng);
3041
 
3042
        const double __p = __aurng();
3043
        if (__param._M_cp.empty())
3044
          return __p;
3045
 
3046
        auto __pos = std::lower_bound(__param._M_cp.begin(),
3047
                                      __param._M_cp.end(), __p);
3048
        const size_t __i = __pos - __param._M_cp.begin();
3049
 
3050
        const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3051
 
3052
        return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i];
3053
      }
3054
 
3055
  template
3056
    template
3057
             typename _UniformRandomNumberGenerator>
3058
      void
3059
      piecewise_constant_distribution<_RealType>::
3060
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3061
                      _UniformRandomNumberGenerator& __urng,
3062
                      const param_type& __param)
3063
      {
3064
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
3065
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3066
          __aurng(__urng);
3067
 
3068
        if (__param._M_cp.empty())
3069
          {
3070
            while (__f != __t)
3071
              *__f++ = __aurng();
3072
            return;
3073
          }
3074
 
3075
        while (__f != __t)
3076
          {
3077
            const double __p = __aurng();
3078
 
3079
            auto __pos = std::lower_bound(__param._M_cp.begin(),
3080
                                          __param._M_cp.end(), __p);
3081
            const size_t __i = __pos - __param._M_cp.begin();
3082
 
3083
            const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3084
 
3085
            *__f++ = (__param._M_int[__i]
3086
                      + (__p - __pref) / __param._M_den[__i]);
3087
          }
3088
      }
3089
 
3090
  template
3091
    std::basic_ostream<_CharT, _Traits>&
3092
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3093
               const piecewise_constant_distribution<_RealType>& __x)
3094
    {
3095
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
3096
      typedef typename __ostream_type::ios_base    __ios_base;
3097
 
3098
      const typename __ios_base::fmtflags __flags = __os.flags();
3099
      const _CharT __fill = __os.fill();
3100
      const std::streamsize __precision = __os.precision();
3101
      const _CharT __space = __os.widen(' ');
3102
      __os.flags(__ios_base::scientific | __ios_base::left);
3103
      __os.fill(__space);
3104
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
3105
 
3106
      std::vector<_RealType> __int = __x.intervals();
3107
      __os << __int.size() - 1;
3108
 
3109
      for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
3110
        __os << __space << *__xit;
3111
 
3112
      std::vector __den = __x.densities();
3113
      for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
3114
        __os << __space << *__dit;
3115
 
3116
      __os.flags(__flags);
3117
      __os.fill(__fill);
3118
      __os.precision(__precision);
3119
      return __os;
3120
    }
3121
 
3122
  template
3123
    std::basic_istream<_CharT, _Traits>&
3124
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
3125
               piecewise_constant_distribution<_RealType>& __x)
3126
    {
3127
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
3128
      typedef typename __istream_type::ios_base    __ios_base;
3129
 
3130
      const typename __ios_base::fmtflags __flags = __is.flags();
3131
      __is.flags(__ios_base::dec | __ios_base::skipws);
3132
 
3133
      size_t __n;
3134
      __is >> __n;
3135
 
3136
      std::vector<_RealType> __int_vec;
3137
      __int_vec.reserve(__n + 1);
3138
      for (size_t __i = 0; __i <= __n; ++__i)
3139
        {
3140
          _RealType __int;
3141
          __is >> __int;
3142
          __int_vec.push_back(__int);
3143
        }
3144
 
3145
      std::vector __den_vec;
3146
      __den_vec.reserve(__n);
3147
      for (size_t __i = 0; __i < __n; ++__i)
3148
        {
3149
          double __den;
3150
          __is >> __den;
3151
          __den_vec.push_back(__den);
3152
        }
3153
 
3154
      __x.param(typename piecewise_constant_distribution<_RealType>::
3155
          param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin()));
3156
 
3157
      __is.flags(__flags);
3158
      return __is;
3159
    }
3160
 
3161
 
3162
  template
3163
    void
3164
    piecewise_linear_distribution<_RealType>::param_type::
3165
    _M_initialize()
3166
    {
3167
      if (_M_int.size() < 2
3168
          || (_M_int.size() == 2
3169
              && _M_int[0] == _RealType(0)
3170
              && _M_int[1] == _RealType(1)
3171
              && _M_den[0] == _M_den[1]))
3172
        {
3173
          _M_int.clear();
3174
          _M_den.clear();
3175
          return;
3176
        }
3177
 
3178
      double __sum = 0.0;
3179
      _M_cp.reserve(_M_int.size() - 1);
3180
      _M_m.reserve(_M_int.size() - 1);
3181
      for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
3182
        {
3183
          const _RealType __delta = _M_int[__k + 1] - _M_int[__k];
3184
          __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta;
3185
          _M_cp.push_back(__sum);
3186
          _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta);
3187
        }
3188
 
3189
      //  Now normalize the densities...
3190
      __detail::__transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
3191
                          std::bind2nd(std::divides(), __sum));
3192
      //  ... and partial sums...
3193
      __detail::__transform(_M_cp.begin(), _M_cp.end(), _M_cp.begin(),
3194
                            std::bind2nd(std::divides(), __sum));
3195
      //  ... and slopes.
3196
      __detail::__transform(_M_m.begin(), _M_m.end(), _M_m.begin(),
3197
                            std::bind2nd(std::divides(), __sum));
3198
      //  Make sure the last cumulative probablility is one.
3199
      _M_cp[_M_cp.size() - 1] = 1.0;
3200
     }
3201
 
3202
  template
3203
    template
3204
      piecewise_linear_distribution<_RealType>::param_type::
3205
      param_type(_InputIteratorB __bbegin,
3206
                 _InputIteratorB __bend,
3207
                 _InputIteratorW __wbegin)
3208
      : _M_int(), _M_den(), _M_cp(), _M_m()
3209
      {
3210
        for (; __bbegin != __bend; ++__bbegin, ++__wbegin)
3211
          {
3212
            _M_int.push_back(*__bbegin);
3213
            _M_den.push_back(*__wbegin);
3214
          }
3215
 
3216
        _M_initialize();
3217
      }
3218
 
3219
  template
3220
    template
3221
      piecewise_linear_distribution<_RealType>::param_type::
3222
      param_type(initializer_list<_RealType> __bl, _Func __fw)
3223
      : _M_int(), _M_den(), _M_cp(), _M_m()
3224
      {
3225
        _M_int.reserve(__bl.size());
3226
        _M_den.reserve(__bl.size());
3227
        for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
3228
          {
3229
            _M_int.push_back(*__biter);
3230
            _M_den.push_back(__fw(*__biter));
3231
          }
3232
 
3233
        _M_initialize();
3234
      }
3235
 
3236
  template
3237
    template
3238
      piecewise_linear_distribution<_RealType>::param_type::
3239
      param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
3240
      : _M_int(), _M_den(), _M_cp(), _M_m()
3241
      {
3242
        const size_t __n = __nw == 0 ? 1 : __nw;
3243
        const _RealType __delta = (__xmax - __xmin) / __n;
3244
 
3245
        _M_int.reserve(__n + 1);
3246
        _M_den.reserve(__n + 1);
3247
        for (size_t __k = 0; __k <= __nw; ++__k)
3248
          {
3249
            _M_int.push_back(__xmin + __k * __delta);
3250
            _M_den.push_back(__fw(_M_int[__k] + __delta));
3251
          }
3252
 
3253
        _M_initialize();
3254
      }
3255
 
3256
  template
3257
    template
3258
      typename piecewise_linear_distribution<_RealType>::result_type
3259
      piecewise_linear_distribution<_RealType>::
3260
      operator()(_UniformRandomNumberGenerator& __urng,
3261
                 const param_type& __param)
3262
      {
3263
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3264
          __aurng(__urng);
3265
 
3266
        const double __p = __aurng();
3267
        if (__param._M_cp.empty())
3268
          return __p;
3269
 
3270
        auto __pos = std::lower_bound(__param._M_cp.begin(),
3271
                                      __param._M_cp.end(), __p);
3272
        const size_t __i = __pos - __param._M_cp.begin();
3273
 
3274
        const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3275
 
3276
        const double __a = 0.5 * __param._M_m[__i];
3277
        const double __b = __param._M_den[__i];
3278
        const double __cm = __p - __pref;
3279
 
3280
        _RealType __x = __param._M_int[__i];
3281
        if (__a == 0)
3282
          __x += __cm / __b;
3283
        else
3284
          {
3285
            const double __d = __b * __b + 4.0 * __a * __cm;
3286
            __x += 0.5 * (std::sqrt(__d) - __b) / __a;
3287
          }
3288
 
3289
        return __x;
3290
      }
3291
 
3292
  template
3293
    template
3294
             typename _UniformRandomNumberGenerator>
3295
      void
3296
      piecewise_linear_distribution<_RealType>::
3297
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3298
                      _UniformRandomNumberGenerator& __urng,
3299
                      const param_type& __param)
3300
      {
3301
        __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
3302
        // We could duplicate everything from operator()...
3303
        while (__f != __t)
3304
          *__f++ = this->operator()(__urng, __param);
3305
      }
3306
 
3307
  template
3308
    std::basic_ostream<_CharT, _Traits>&
3309
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3310
               const piecewise_linear_distribution<_RealType>& __x)
3311
    {
3312
      typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
3313
      typedef typename __ostream_type::ios_base    __ios_base;
3314
 
3315
      const typename __ios_base::fmtflags __flags = __os.flags();
3316
      const _CharT __fill = __os.fill();
3317
      const std::streamsize __precision = __os.precision();
3318
      const _CharT __space = __os.widen(' ');
3319
      __os.flags(__ios_base::scientific | __ios_base::left);
3320
      __os.fill(__space);
3321
      __os.precision(std::numeric_limits<_RealType>::max_digits10);
3322
 
3323
      std::vector<_RealType> __int = __x.intervals();
3324
      __os << __int.size() - 1;
3325
 
3326
      for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
3327
        __os << __space << *__xit;
3328
 
3329
      std::vector __den = __x.densities();
3330
      for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
3331
        __os << __space << *__dit;
3332
 
3333
      __os.flags(__flags);
3334
      __os.fill(__fill);
3335
      __os.precision(__precision);
3336
      return __os;
3337
    }
3338
 
3339
  template
3340
    std::basic_istream<_CharT, _Traits>&
3341
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
3342
               piecewise_linear_distribution<_RealType>& __x)
3343
    {
3344
      typedef std::basic_istream<_CharT, _Traits>  __istream_type;
3345
      typedef typename __istream_type::ios_base    __ios_base;
3346
 
3347
      const typename __ios_base::fmtflags __flags = __is.flags();
3348
      __is.flags(__ios_base::dec | __ios_base::skipws);
3349
 
3350
      size_t __n;
3351
      __is >> __n;
3352
 
3353
      std::vector<_RealType> __int_vec;
3354
      __int_vec.reserve(__n + 1);
3355
      for (size_t __i = 0; __i <= __n; ++__i)
3356
        {
3357
          _RealType __int;
3358
          __is >> __int;
3359
          __int_vec.push_back(__int);
3360
        }
3361
 
3362
      std::vector __den_vec;
3363
      __den_vec.reserve(__n + 1);
3364
      for (size_t __i = 0; __i <= __n; ++__i)
3365
        {
3366
          double __den;
3367
          __is >> __den;
3368
          __den_vec.push_back(__den);
3369
        }
3370
 
3371
      __x.param(typename piecewise_linear_distribution<_RealType>::
3372
          param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin()));
3373
 
3374
      __is.flags(__flags);
3375
      return __is;
3376
    }
3377
 
3378
 
3379
  template
3380
    seed_seq::seed_seq(std::initializer_list<_IntType> __il)
3381
    {
3382
      for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter)
3383
        _M_v.push_back(__detail::__mod
3384
                       __detail::_Shift::__value>(*__iter));
3385
    }
3386
 
3387
  template
3388
    seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end)
3389
    {
3390
      for (_InputIterator __iter = __begin; __iter != __end; ++__iter)
3391
        _M_v.push_back(__detail::__mod
3392
                       __detail::_Shift::__value>(*__iter));
3393
    }
3394
 
3395
  template
3396
    void
3397
    seed_seq::generate(_RandomAccessIterator __begin,
3398
                       _RandomAccessIterator __end)
3399
    {
3400
      typedef typename iterator_traits<_RandomAccessIterator>::value_type
3401
        _Type;
3402
 
3403
      if (__begin == __end)
3404
        return;
3405
 
3406
      std::fill(__begin, __end, _Type(0x8b8b8b8bu));
3407
 
3408
      const size_t __n = __end - __begin;
3409
      const size_t __s = _M_v.size();
3410
      const size_t __t = (__n >= 623) ? 11
3411
                       : (__n >=  68) ? 7
3412
                       : (__n >=  39) ? 5
3413
                       : (__n >=   7) ? 3
3414
                       : (__n - 1) / 2;
3415
      const size_t __p = (__n - __t) / 2;
3416
      const size_t __q = __p + __t;
3417
      const size_t __m = std::max(size_t(__s + 1), __n);
3418
 
3419
      for (size_t __k = 0; __k < __m; ++__k)
3420
        {
3421
          _Type __arg = (__begin[__k % __n]
3422
                         ^ __begin[(__k + __p) % __n]
3423
                         ^ __begin[(__k - 1) % __n]);
3424
          _Type __r1 = __arg ^ (__arg >> 27);
3425
          __r1 = __detail::__mod<_Type,
3426
                    __detail::_Shift<_Type, 32>::__value>(1664525u * __r1);
3427
          _Type __r2 = __r1;
3428
          if (__k == 0)
3429
            __r2 += __s;
3430
          else if (__k <= __s)
3431
            __r2 += __k % __n + _M_v[__k - 1];
3432
          else
3433
            __r2 += __k % __n;
3434
          __r2 = __detail::__mod<_Type,
3435
                   __detail::_Shift<_Type, 32>::__value>(__r2);
3436
          __begin[(__k + __p) % __n] += __r1;
3437
          __begin[(__k + __q) % __n] += __r2;
3438
          __begin[__k % __n] = __r2;
3439
        }
3440
 
3441
      for (size_t __k = __m; __k < __m + __n; ++__k)
3442
        {
3443
          _Type __arg = (__begin[__k % __n]
3444
                         + __begin[(__k + __p) % __n]
3445
                         + __begin[(__k - 1) % __n]);
3446
          _Type __r3 = __arg ^ (__arg >> 27);
3447
          __r3 = __detail::__mod<_Type,
3448
                   __detail::_Shift<_Type, 32>::__value>(1566083941u * __r3);
3449
          _Type __r4 = __r3 - __k % __n;
3450
          __r4 = __detail::__mod<_Type,
3451
                   __detail::_Shift<_Type, 32>::__value>(__r4);
3452
          __begin[(__k + __p) % __n] ^= __r3;
3453
          __begin[(__k + __q) % __n] ^= __r4;
3454
          __begin[__k % __n] = __r4;
3455
        }
3456
    }
3457
 
3458
  template
3459
           typename _UniformRandomNumberGenerator>
3460
    _RealType
3461
    generate_canonical(_UniformRandomNumberGenerator& __urng)
3462
    {
3463
      const size_t __b
3464
        = std::min(static_cast(std::numeric_limits<_RealType>::digits),
3465
                   __bits);
3466
      const long double __r = static_cast(__urng.max())
3467
                            - static_cast(__urng.min()) + 1.0L;
3468
      const size_t __log2r = std::log(__r) / std::log(2.0L);
3469
      size_t __k = std::max(1UL, (__b + __log2r - 1UL) / __log2r);
3470
      _RealType __sum = _RealType(0);
3471
      _RealType __tmp = _RealType(1);
3472
      for (; __k != 0; --__k)
3473
        {
3474
          __sum += _RealType(__urng() - __urng.min()) * __tmp;
3475
          __tmp *= __r;
3476
        }
3477
      return __sum / __tmp;
3478
    }
3479
 
3480
_GLIBCXX_END_NAMESPACE_VERSION
3481
} // namespace
3482
 
3483
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.