lemon/random.h
changeset 183 0c6556a8e105
parent 177 b685e12e08c0
child 209 765619b7cbb2
     1.1 --- a/lemon/random.h	Wed Jun 18 13:52:23 2008 +0100
     1.2 +++ b/lemon/random.h	Fri Jun 20 11:09:30 2008 +0100
     1.3 @@ -66,10 +66,20 @@
     1.4  #include <iterator>
     1.5  #include <vector>
     1.6  #include <limits>
     1.7 +#include <fstream>
     1.8  
     1.9  #include <lemon/math.h>
    1.10  #include <lemon/dim2.h>
    1.11  
    1.12 +#ifndef WIN32
    1.13 +#include <sys/time.h>
    1.14 +#include <ctime>
    1.15 +#include <sys/types.h>
    1.16 +#include <unistd.h>
    1.17 +#else
    1.18 +#include <windows.h>
    1.19 +#endif
    1.20 +
    1.21  ///\ingroup misc
    1.22  ///\file
    1.23  ///\brief Mersenne Twister random number generator
    1.24 @@ -526,6 +536,14 @@
    1.25  
    1.26    public:
    1.27  
    1.28 +    ///\name Initialization
    1.29 +    ///
    1.30 +    /// @{
    1.31 +
    1.32 +    ///\name Initialization
    1.33 +    ///
    1.34 +    /// @{
    1.35 +
    1.36      /// \brief Default constructor
    1.37      ///
    1.38      /// Constructor with constant seeding.
    1.39 @@ -594,6 +612,73 @@
    1.40        _random_bits::Initializer<Number, Word>::init(core, begin, end);
    1.41      }
    1.42  
    1.43 +    /// \brief Seeding from file or from process id and time
    1.44 +    ///
    1.45 +    /// By default, this function calls the \c seedFromFile() member
    1.46 +    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
    1.47 +    /// it uses the \c seedFromTime().
    1.48 +    /// \return Currently always true.
    1.49 +    bool seed() {
    1.50 +#ifndef WIN32
    1.51 +      if (seedFromFile("/dev/urandom", 0)) return true;
    1.52 +#endif
    1.53 +      if (seedFromTime()) return true;
    1.54 +      return false;
    1.55 +    }
    1.56 +    
    1.57 +    /// \brief Seeding from file
    1.58 +    ///
    1.59 +    /// Seeding the random sequence from file. The linux kernel has two
    1.60 +    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
    1.61 +    /// could give good seed values for pseudo random generators (The
    1.62 +    /// difference between two devices is that the <tt>random</tt> may
    1.63 +    /// block the reading operation while the kernel can give good
    1.64 +    /// source of randomness, while the <tt>urandom</tt> does not
    1.65 +    /// block the input, but it could give back bytes with worse
    1.66 +    /// entropy).
    1.67 +    /// \param file The source file
    1.68 +    /// \param offset The offset, from the file read.
    1.69 +    /// \return True when the seeding successes.
    1.70 +#ifndef WIN32
    1.71 +    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0) 
    1.72 +#else
    1.73 +    bool seedFromFile(const std::string& file = "", int offset = 0) 
    1.74 +#endif
    1.75 +    {
    1.76 +      std::ifstream rs(file.c_str());
    1.77 +      const int size = 4;
    1.78 +      Word buf[size];
    1.79 +      if (offset != 0 && !rs.seekg(offset)) return false;
    1.80 +      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
    1.81 +      seed(buf, buf + size);
    1.82 +      return true;
    1.83 +    }
    1.84 +
    1.85 +    /// \brief Seding from process id and time
    1.86 +    ///
    1.87 +    /// Seding from process id and time. This function uses the
    1.88 +    /// current process id and the current time for initialize the
    1.89 +    /// random sequence.
    1.90 +    /// \return Currently always true.
    1.91 +    bool seedFromTime() { 	
    1.92 +#ifndef WIN32
    1.93 +      timeval tv;
    1.94 +      gettimeofday(&tv, 0);
    1.95 +      seed(getpid() + tv.tv_sec + tv.tv_usec);
    1.96 +#else
    1.97 +      FILETIME time;
    1.98 +      GetSystemTimeAsFileTime(&time);
    1.99 +      seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime);
   1.100 +#endif
   1.101 +      return true;
   1.102 +    }
   1.103 +
   1.104 +    /// @}
   1.105 +
   1.106 +    ///\name Uniform distributions
   1.107 +    ///
   1.108 +    /// @{
   1.109 +
   1.110      /// \brief Returns a random real number from the range [0, 1)
   1.111      ///
   1.112      /// It returns a random real number from the range [0, 1). The
   1.113 @@ -623,6 +708,12 @@
   1.114        return real<Number>() * (b - a) + a; 
   1.115      }
   1.116  
   1.117 +    /// @}
   1.118 +
   1.119 +    ///\name Uniform distributions
   1.120 +    ///
   1.121 +    /// @{
   1.122 +
   1.123      /// \brief Returns a random real number from the range [0, 1)
   1.124      ///
   1.125      /// It returns a random double from the range [0, 1).
   1.126 @@ -680,6 +771,8 @@
   1.127        return _random_bits::IntConversion<Number, Word>::convert(core);
   1.128      }
   1.129  
   1.130 +    /// @}
   1.131 +
   1.132      unsigned int uinteger() {
   1.133        return uinteger<unsigned int>();
   1.134      }
   1.135 @@ -709,6 +802,8 @@
   1.136        return bool_producer.convert(core);
   1.137      }
   1.138  
   1.139 +    /// @}
   1.140 +
   1.141      ///\name Non-uniform distributions
   1.142      ///
   1.143