# HG changeset patch
# User Alpar Juttner <alpar@cs.elte.hu>
# Date 1213956570 -3600
# Node ID 0c6556a8e1053e483f829338b701d57536183886
# Parent  9c6dfb5141d37ae0d3df1aafc182d23fa8bff535# Parent  d2bac07f174234a37a21860c8c8a9ed4d14b3415
Merge

diff -r 9c6dfb5141d3 -r 0c6556a8e105 configure.ac
--- a/configure.ac	Wed Jun 18 13:52:23 2008 +0100
+++ b/configure.ac	Fri Jun 20 11:09:30 2008 +0100
@@ -1,13 +1,9 @@
 dnl Process this file with autoconf to produce a configure script.
 
 dnl Version information.
-m4_define([lemon_version_major], [0])
-m4_define([lemon_version_minor], [99])
-m4_define([lemon_version_micro], [])
-m4_define([lemon_version_nano], [])
-m4_define([lemon_version_tag], [hg])
+m4_define([lemon_version_number], [])
 m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))])
-m4_define([lemon_version], [lemon_version_major().lemon_version_minor()ifelse(lemon_version_micro(), [], [], [.lemon_version_micro()])ifelse(lemon_version_nano(), [], [], [.lemon_version_nano()])ifelse(lemon_version_tag(), [], [], lemon_version_tag(), [hg], [[_]lemon_version_tag()[_]lemon_hg_revision()], [[_]lemon_version_tag()])])
+m4_define([lemon_version], [ifelse(lemon_version_number(), [], [lemon_hg_revision()], [lemon_version_number()])])
 
 AC_PREREQ([2.59])
 AC_INIT([LEMON], [lemon_version()], [lemon-devel@lemon.cs.elte.hu], [lemon])
diff -r 9c6dfb5141d3 -r 0c6556a8e105 lemon/random.h
--- a/lemon/random.h	Wed Jun 18 13:52:23 2008 +0100
+++ b/lemon/random.h	Fri Jun 20 11:09:30 2008 +0100
@@ -66,10 +66,20 @@
 #include <iterator>
 #include <vector>
 #include <limits>
+#include <fstream>
 
 #include <lemon/math.h>
 #include <lemon/dim2.h>
 
+#ifndef WIN32
+#include <sys/time.h>
+#include <ctime>
+#include <sys/types.h>
+#include <unistd.h>
+#else
+#include <windows.h>
+#endif
+
 ///\ingroup misc
 ///\file
 ///\brief Mersenne Twister random number generator
@@ -526,6 +536,14 @@
 
   public:
 
+    ///\name Initialization
+    ///
+    /// @{
+
+    ///\name Initialization
+    ///
+    /// @{
+
     /// \brief Default constructor
     ///
     /// Constructor with constant seeding.
@@ -594,6 +612,73 @@
       _random_bits::Initializer<Number, Word>::init(core, begin, end);
     }
 
+    /// \brief Seeding from file or from process id and time
+    ///
+    /// By default, this function calls the \c seedFromFile() member
+    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
+    /// it uses the \c seedFromTime().
+    /// \return Currently always true.
+    bool seed() {
+#ifndef WIN32
+      if (seedFromFile("/dev/urandom", 0)) return true;
+#endif
+      if (seedFromTime()) return true;
+      return false;
+    }
+    
+    /// \brief Seeding from file
+    ///
+    /// Seeding the random sequence from file. The linux kernel has two
+    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
+    /// could give good seed values for pseudo random generators (The
+    /// difference between two devices is that the <tt>random</tt> may
+    /// block the reading operation while the kernel can give good
+    /// source of randomness, while the <tt>urandom</tt> does not
+    /// block the input, but it could give back bytes with worse
+    /// entropy).
+    /// \param file The source file
+    /// \param offset The offset, from the file read.
+    /// \return True when the seeding successes.
+#ifndef WIN32
+    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0) 
+#else
+    bool seedFromFile(const std::string& file = "", int offset = 0) 
+#endif
+    {
+      std::ifstream rs(file.c_str());
+      const int size = 4;
+      Word buf[size];
+      if (offset != 0 && !rs.seekg(offset)) return false;
+      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
+      seed(buf, buf + size);
+      return true;
+    }
+
+    /// \brief Seding from process id and time
+    ///
+    /// Seding from process id and time. This function uses the
+    /// current process id and the current time for initialize the
+    /// random sequence.
+    /// \return Currently always true.
+    bool seedFromTime() { 	
+#ifndef WIN32
+      timeval tv;
+      gettimeofday(&tv, 0);
+      seed(getpid() + tv.tv_sec + tv.tv_usec);
+#else
+      FILETIME time;
+      GetSystemTimeAsFileTime(&time);
+      seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime);
+#endif
+      return true;
+    }
+
+    /// @}
+
+    ///\name Uniform distributions
+    ///
+    /// @{
+
     /// \brief Returns a random real number from the range [0, 1)
     ///
     /// It returns a random real number from the range [0, 1). The
@@ -623,6 +708,12 @@
       return real<Number>() * (b - a) + a; 
     }
 
+    /// @}
+
+    ///\name Uniform distributions
+    ///
+    /// @{
+
     /// \brief Returns a random real number from the range [0, 1)
     ///
     /// It returns a random double from the range [0, 1).
@@ -680,6 +771,8 @@
       return _random_bits::IntConversion<Number, Word>::convert(core);
     }
 
+    /// @}
+
     unsigned int uinteger() {
       return uinteger<unsigned int>();
     }
@@ -709,6 +802,8 @@
       return bool_producer.convert(core);
     }
 
+    /// @}
+
     ///\name Non-uniform distributions
     ///