Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*-
  2.  
  3. // Copyright (C) 2007-2015 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 terms
  7. // of the GNU General Public License as published by the Free Software
  8. // Foundation; either version 3, or (at your option) any later
  9. // version.
  10.  
  11. // This library is distributed in the hope that it will be useful, but
  12. // WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. // General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file parallel/random_number.h
  26.  *  @brief Random number generator based on the Mersenne twister.
  27.  *  This file is a GNU parallel extension to the Standard C++ Library.
  28.  */
  29.  
  30. // Written by Johannes Singler.
  31.  
  32. #ifndef _GLIBCXX_PARALLEL_RANDOM_NUMBER_H
  33. #define _GLIBCXX_PARALLEL_RANDOM_NUMBER_H 1
  34.  
  35. #include <parallel/types.h>
  36. #include <tr1/random>
  37. #include <limits>
  38.  
  39. namespace __gnu_parallel
  40. {
  41.   /** @brief Random number generator, based on the Mersenne twister. */
  42.   class _RandomNumber
  43.   {
  44.   private:
  45.     std::tr1::mt19937   _M_mt;
  46.     uint64_t            _M_supremum;
  47.     uint64_t            _M_rand_sup;
  48.     double              _M_supremum_reciprocal;
  49.     double              _M_rand_sup_reciprocal;
  50.  
  51.     // Assumed to be twice as long as the usual random number.
  52.     uint64_t              __cache;
  53.  
  54.     // Bit results.
  55.     int __bits_left;
  56.    
  57.     static uint32_t
  58.     __scale_down(uint64_t __x,
  59. #if _GLIBCXX_SCALE_DOWN_FPU
  60.                uint64_t /*_M_supremum*/, double _M_supremum_reciprocal)
  61. #else
  62.                uint64_t _M_supremum, double /*_M_supremum_reciprocal*/)
  63. #endif
  64.         {
  65. #if _GLIBCXX_SCALE_DOWN_FPU
  66.           return uint32_t(__x * _M_supremum_reciprocal);
  67. #else
  68.           return static_cast<uint32_t>(__x % _M_supremum);
  69. #endif
  70.         }
  71.  
  72.   public:
  73.     /** @brief Default constructor. Seed with 0. */
  74.     _RandomNumber()
  75.     : _M_mt(0), _M_supremum(0x100000000ULL),
  76.       _M_rand_sup(1ULL << std::numeric_limits<uint32_t>::digits),
  77.       _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)),
  78.       _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)),
  79.       __cache(0), __bits_left(0) { }
  80.  
  81.     /** @brief Constructor.
  82.      *  @param __seed Random __seed.
  83.      *  @param _M_supremum Generate integer random numbers in the
  84.      *                  interval @c [0,_M_supremum). */
  85.     _RandomNumber(uint32_t __seed, uint64_t _M_supremum = 0x100000000ULL)
  86.     : _M_mt(__seed), _M_supremum(_M_supremum),
  87.       _M_rand_sup(1ULL << std::numeric_limits<uint32_t>::digits),
  88.       _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)),
  89.       _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)),
  90.       __cache(0), __bits_left(0) { }
  91.  
  92.     /** @brief Generate unsigned random 32-bit integer. */
  93.     uint32_t
  94.     operator()()
  95.     { return __scale_down(_M_mt(), _M_supremum, _M_supremum_reciprocal); }
  96.  
  97.     /** @brief Generate unsigned random 32-bit integer in the
  98.         interval @c [0,local_supremum). */
  99.     uint32_t
  100.     operator()(uint64_t local_supremum)
  101.     {
  102.       return __scale_down(_M_mt(), local_supremum,
  103.                         double(local_supremum * _M_rand_sup_reciprocal));
  104.     }
  105.  
  106.     /** @brief Generate a number of random bits, run-time parameter.
  107.      *  @param __bits Number of bits to generate. */
  108.     unsigned long
  109.     __genrand_bits(int __bits)
  110.     {
  111.       unsigned long __res = __cache & ((1 << __bits) - 1);
  112.       __cache = __cache >> __bits;
  113.       __bits_left -= __bits;
  114.       if (__bits_left < 32)
  115.         {
  116.           __cache |= ((uint64_t(_M_mt())) << __bits_left);
  117.           __bits_left += 32;
  118.         }
  119.       return __res;
  120.     }
  121. };
  122.  
  123. } // namespace __gnu_parallel
  124.  
  125. #endif /* _GLIBCXX_PARALLEL_RANDOM_NUMBER_H */
  126.