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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [libstdc++-v3/] [include/] [bits/] [random.tcc] - Blame information for rev 424

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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