1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
/* hashRandom.cc
*/
#include "osl/hash/hashRandom.h"
#include "osl/misc/milliSeconds.h"
// #include <boost/random/normal_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/noncopyable.hpp>
#include <cmath>
osl::CArray<int,osl::hash::HashRandom::Length> osl::hash::HashRandom::table;
// ---------------------------------------------------------------
// 2009-06-12 A slightly modified version of boost::normal_distribution is defined here.
// It is because g++ 4.3 and 4.4 warn about uninitialized values of _r1 and _cached_rho in the original source code.
// This should be temporal and will be removed in near future.
// ---------------------------------------------------------------
/* boost random/normal_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: normal_distribution.hpp 49314 2008-10-13 09:00:03Z johnmaddock $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
namespace osl
{
class normal_distribution : boost::noncopyable
{
public:
explicit normal_distribution(const double& mean_arg = double(0),
const double& sigma_arg = double(1))
: _mean(mean_arg), _sigma(sigma_arg),
_r1(0), _r2(0), _cached_rho(0),
_valid(false)
{
assert(_sigma >= double(0));
}
double mean() const { return _mean; }
double sigma() const { return _sigma; }
void reset() { _valid = false; }
template<class Engine>
double operator()(Engine& eng)
{
if(!_valid) {
_r1 = eng();
_r2 = eng();
_cached_rho = sqrt(-double(2) * log(double(1)-_r2));
_valid = true;
} else {
_valid = false;
}
const double pi = double(3.14159265358979323846);
return _cached_rho * (_valid ?
cos(double(2)*pi*_r1) :
sin(double(2)*pi*_r1))
* _sigma + _mean;
}
private:
double _mean, _sigma;
double _r1, _r2, _cached_rho;
bool _valid;
};
}
// ---------------------------------------------------------------
// end of modified version of boost::normal_distribution
// ---------------------------------------------------------------
void osl::hash::HashRandom::setUp(double sigma)
{
static boost::mt11213b mt_random(MilliSeconds::now().value());
static boost::uniform_01<boost::mt11213b> u0(mt_random);
// boost::normal_distribution<> n(0, sigma);
normal_distribution n(0, sigma);
for (size_t i=0; i<Length; ++i)
table[i] = static_cast<int>(n(u0))/2*2;
}
|