00001
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #ifndef BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP
00047 #define BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP
00048
00049 #include <boost/config/no_tr1/cmath.hpp>
00050 #include <istream>
00051 #include <iosfwd>
00052 #include <boost/assert.hpp>
00053 #include <boost/limits.hpp>
00054 #include <boost/static_assert.hpp>
00055 #include <boost/integer.hpp>
00056 #include <boost/integer/integer_mask.hpp>
00057 #include <boost/type_traits/is_integral.hpp>
00058 #include <boost/type_traits/make_unsigned.hpp>
00059 #include <boost/random/detail/config.hpp>
00060
00061 #if BOOST_VERSION < 104700 // Old version
00062
00063 #include <boost/random/detail/config.hpp>
00064 #include <boost/detail/workaround.hpp>
00065
00066 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) \
00067 || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
00068
00069 #define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \
00070 template<class CharT, class Traits> \
00071 friend std::basic_ostream<CharT,Traits>& \
00072 operator<<(std::basic_ostream<CharT,Traits>& os, const T& t) { \
00073 t.print(os, t); \
00074 return os; \
00075 } \
00076 template<class CharT, class Traits> \
00077 static std::basic_ostream<CharT,Traits>& \
00078 print(std::basic_ostream<CharT,Traits>& os, const T& t)
00079
00080 #define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \
00081 template<class CharT, class Traits> \
00082 friend std::basic_istream<CharT,Traits>& \
00083 operator>>(std::basic_istream<CharT,Traits>& is, T& t) { \
00084 t.read(is, t); \
00085 return is; \
00086 } \
00087 template<class CharT, class Traits> \
00088 static std::basic_istream<CharT,Traits>& \
00089 read(std::basic_istream<CharT,Traits>& is, T& t)
00090
00091 #endif
00092
00093 #if defined(__BORLANDC__)
00094
00095 #define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \
00096 bool operator==(const T& rhs) const \
00097 { return T::is_equal(*this, rhs); } \
00098 static bool is_equal(const T& lhs, const T& rhs)
00099
00100 #define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \
00101 bool operator!=(const T& rhs) const \
00102 { return !T::is_equal(*this, rhs); }
00103
00104 #endif
00105
00106 #ifndef BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR
00107 #define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \
00108 template<class CharT, class Traits> \
00109 friend std::basic_ostream<CharT,Traits>& \
00110 operator<<(std::basic_ostream<CharT,Traits>& os, const T& t)
00111 #endif
00112
00113 #ifndef BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR
00114 #define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \
00115 template<class CharT, class Traits> \
00116 friend std::basic_istream<CharT,Traits>& \
00117 operator>>(std::basic_istream<CharT,Traits>& is, T& t)
00118 #endif
00119
00120 #ifndef BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR
00121 #define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \
00122 friend bool operator==(const T& lhs, const T& rhs)
00123 #endif
00124
00125 #ifndef BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR
00126 #define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \
00127 friend bool operator!=(const T& lhs, const T& rhs) \
00128 { return !(lhs == rhs); }
00129 #endif
00130
00131 #include <boost/pending/integer_log2.hpp>
00132 #else
00133 #include <boost/random/detail/operators.hpp>
00134 #include <boost/random/detail/integer_log2.hpp>
00135
00136 #endif
00137
00138 #include <boost/random/uniform_01.hpp>
00139 #include <boost/random/mersenne_twister.hpp>
00140
00141 #if BOOST_VERSION < 104700
00142 #include <boost/random/uniform_int.hpp>
00144 #else
00145 #include <boost/random/uniform_int_distribution.hpp>
00146 #endif
00147
00148
00149
00150
00151 #include <boost/random/detail/signed_unsigned_tools.hpp>
00152 #include <boost/type_traits/make_unsigned.hpp>
00153
00154 #include <boost/random/exponential_distribution.hpp>
00155 #include <boost/random/variate_generator.hpp>
00156
00157
00158
00159 namespace boost {
00160 namespace random {
00161
00162 namespace detail {
00163
00164
00165 template<class RealType>
00166 struct normal_table {
00167 static const RealType table_x[129];
00168 static const RealType table_y[129];
00169 };
00170
00171 template<class RealType>
00172 const RealType normal_table<RealType>::table_x[129] = {
00173 3.7130862467403632609, 3.4426198558966521214, 3.2230849845786185446, 3.0832288582142137009,
00174 2.9786962526450169606, 2.8943440070186706210, 2.8231253505459664379, 2.7611693723841538514,
00175 2.7061135731187223371, 2.6564064112581924999, 2.6109722484286132035, 2.5690336259216391328,
00176 2.5300096723854666170, 2.4934545220919507609, 2.4590181774083500943, 2.4264206455302115930,
00177 2.3954342780074673425, 2.3658713701139875435, 2.3375752413355307354, 2.3104136836950021558,
00178 2.2842740596736568056, 2.2590595738653295251, 2.2346863955870569803, 2.2110814088747278106,
00179 2.1881804320720206093, 2.1659267937448407377, 2.1442701823562613518, 2.1231657086697899595,
00180 2.1025731351849988838, 2.0824562379877246441, 2.0627822745039633575, 2.0435215366506694976,
00181 2.0246469733729338782, 2.0061338699589668403, 1.9879595741230607243, 1.9701032608497132242,
00182 1.9525457295488889058, 1.9352692282919002011, 1.9182573008597320303, 1.9014946531003176140,
00183 1.8849670357028692380, 1.8686611409895420085, 1.8525645117230870617, 1.8366654602533840447,
00184 1.8209529965910050740, 1.8054167642140487420, 1.7900469825946189862, 1.7748343955807692457,
00185 1.7597702248942318749, 1.7448461281083765085, 1.7300541605582435350, 1.7153867407081165482,
00186 1.7008366185643009437, 1.6863968467734863258, 1.6720607540918522072, 1.6578219209482075462,
00187 1.6436741568569826489, 1.6296114794646783962, 1.6156280950371329644, 1.6017183802152770587,
00188 1.5878768648844007019, 1.5740982160167497219, 1.5603772223598406870, 1.5467087798535034608,
00189 1.5330878776675560787, 1.5195095847593707806, 1.5059690368565502602, 1.4924614237746154081,
00190 1.4789819769830978546, 1.4655259573357946276, 1.4520886428822164926, 1.4386653166774613138,
00191 1.4252512545068615734, 1.4118417124397602509, 1.3984319141236063517, 1.3850170377251486449,
00192 1.3715922024197322698, 1.3581524543224228739, 1.3446927517457130432, 1.3312079496576765017,
00193 1.3176927832013429910, 1.3041418501204215390, 1.2905495919178731508, 1.2769102735516997175,
00194 1.2632179614460282310, 1.2494664995643337480, 1.2356494832544811749, 1.2217602305309625678,
00195 1.2077917504067576028, 1.1937367078237721994, 1.1795873846544607035, 1.1653356361550469083,
00196 1.1509728421389760651, 1.1364898520030755352, 1.1218769225722540661, 1.1071236475235353980,
00197 1.0922188768965537614, 1.0771506248819376573, 1.0619059636836193998, 1.0464709007525802629,
00198 1.0308302360564555907, 1.0149673952392994716, 0.99886423348064351303, 0.98250080350276038481,
00199 0.96585507938813059489, 0.94890262549791195381, 0.93161619660135381056, 0.91396525100880177644,
00200 0.89591535256623852894, 0.87742742909771569142, 0.85845684317805086354, 0.83895221428120745572,
00201 0.81885390668331772331, 0.79809206062627480454, 0.77658398787614838598, 0.75423066443451007146,
00202 0.73091191062188128150, 0.70647961131360803456, 0.68074791864590421664, 0.65347863871504238702,
00203 0.62435859730908822111, 0.59296294244197797913, 0.55869217837551797140, 0.52065603872514491759,
00204 0.47743783725378787681, 0.42654798630330512490, 0.36287143102841830424, 0.27232086470466385065,
00205 0
00206 };
00207
00208 template<class RealType>
00209 const RealType normal_table<RealType>::table_y[129] = {
00210 0, 0.0026696290839025035092, 0.0055489952208164705392, 0.0086244844129304709682,
00211 0.011839478657982313715, 0.015167298010672042468, 0.018592102737165812650, 0.022103304616111592615,
00212 0.025693291936149616572, 0.029356317440253829618, 0.033087886146505155566, 0.036884388786968774128,
00213 0.040742868074790604632, 0.044660862200872429800, 0.048636295860284051878, 0.052667401903503169793,
00214 0.056752663481538584188, 0.060890770348566375972, 0.065080585213631873753, 0.069321117394180252601,
00215 0.073611501884754893389, 0.077950982514654714188, 0.082338898242957408243, 0.086774671895542968998,
00216 0.091257800827634710201, 0.09578784912257815216, 0.10036444102954554013, 0.10498725541035453978,
00217 0.10965602101581776100, 0.11437051244988827452, 0.11913054670871858767, 0.12393598020398174246,
00218 0.12878670619710396109, 0.13368265258464764118, 0.13862377998585103702, 0.14361008009193299469,
00219 0.14864157424369696566, 0.15371831220958657066, 0.15884037114093507813, 0.16400785468492774791,
00220 0.16922089223892475176, 0.17447963833240232295, 0.17978427212496211424, 0.18513499701071343216,
00221 0.19053204032091372112, 0.19597565311811041399, 0.20146611007620324118, 0.20700370944187380064,
00222 0.21258877307373610060, 0.21822164655637059599, 0.22390269938713388747, 0.22963232523430270355,
00223 0.23541094226572765600, 0.24123899354775131610, 0.24711694751469673582, 0.25304529850976585934,
00224 0.25902456739871074263, 0.26505530225816194029, 0.27113807914102527343, 0.27727350292189771153,
00225 0.28346220822601251779, 0.28970486044581049771, 0.29600215684985583659, 0.30235482778947976274,
00226 0.30876363800925192282, 0.31522938806815752222, 0.32175291587920862031, 0.32833509837615239609,
00227 0.33497685331697116147, 0.34167914123501368412, 0.34844296754987246935, 0.35526938485154714435,
00228 0.36215949537303321162, 0.36911445366827513952, 0.37613546951445442947, 0.38322381105988364587,
00229 0.39038080824138948916, 0.39760785649804255208, 0.40490642081148835099, 0.41227804010702462062,
00230 0.41972433205403823467, 0.42724699830956239880, 0.43484783025466189638, 0.44252871528024661483,
00231 0.45029164368692696086, 0.45813871627287196483, 0.46607215269457097924, 0.47409430069824960453,
00232 0.48220764633483869062, 0.49041482528932163741, 0.49871863547658432422, 0.50712205108130458951,
00233 0.51562823824987205196, 0.52424057267899279809, 0.53296265938998758838, 0.54179835503172412311,
00234 0.55075179312105527738, 0.55982741271069481791, 0.56902999107472161225, 0.57836468112670231279,
00235 0.58783705444182052571, 0.59745315095181228217, 0.60721953663260488551, 0.61714337082656248870,
00236 0.62723248525781456578, 0.63749547734314487428, 0.64794182111855080873, 0.65858200005865368016,
00237 0.66942766735770616891, 0.68049184100641433355, 0.69178914344603585279, 0.70333609902581741633,
00238 0.71515150742047704368, 0.72725691835450587793, 0.73967724368333814856, 0.75244155918570380145,
00239 0.76558417390923599480, 0.77914608594170316563, 0.79317701178385921053, 0.80773829469612111340,
00240 0.82290721139526200050, 0.83878360531064722379, 0.85550060788506428418, 0.87324304892685358879,
00241 0.89228165080230272301, 0.91304364799203805999, 0.93628268170837107547, 0.96359969315576759960,
00242 1
00243 };
00244
00245 template<class Engine>
00246 inline typename boost::make_unsigned<typename Engine::result_type>::type
00247 generate_one_digit(Engine& eng, std::size_t bits)
00248 {
00249 typedef typename Engine::result_type base_result;
00250 typedef typename boost::make_unsigned<base_result>::type base_unsigned;
00251
00252 base_unsigned range =
00253 detail::subtract<base_result>()((eng.max)(), (eng.min)());
00254 base_unsigned y0_mask = (base_unsigned(2) << (bits - 1)) - 1;
00255 base_unsigned y0 = (range + 1) & ~y0_mask;
00256 base_unsigned u;
00257 do {
00258 u = detail::subtract<base_result>()(eng(), (eng.min)());
00259 } while(y0 != 0 && u > base_unsigned(y0 - 1));
00260 return u & y0_mask;
00261 }
00262
00263 template<class RealType, std::size_t w, class Engine>
00264 std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::mpl::true_)
00265 {
00266 typedef typename Engine::result_type base_result;
00267 typedef typename boost::make_unsigned<base_result>::type base_unsigned;
00268
00269 base_unsigned range =
00270 detail::subtract<base_result>()((eng.max)(), (eng.min)());
00271
00272 std::size_t m =
00273 (range == (std::numeric_limits<base_unsigned>::max)()) ?
00274 std::numeric_limits<base_unsigned>::digits :
00275 #if BOOST_VERSION < 104700
00276
00277 integer_log2(range + 1);
00278 #else
00279
00280 detail::integer_log2(range + 1);
00281 #endif
00282
00283 int bucket = 0;
00284
00285 for(std::size_t i = 0; i < w/m; ++i) {
00286 #define COVERAGE_IGNORE
00287 base_unsigned u = generate_one_digit(eng, m);
00288 bucket = (bucket << m) | u;
00289 #undef COVERAGE_IGNORE
00290 }
00291 RealType r;
00292
00293 const std::size_t digits = std::numeric_limits<RealType>::digits;
00294 {
00295 base_unsigned u = generate_one_digit(eng, m);
00296 base_unsigned mask = (base_unsigned(1) << (w%m)) - 1;
00297 bucket = (bucket << (w%m)) | (mask & u);
00298 const RealType mult = RealType(1)/RealType(base_unsigned(1) << (m - w%m));
00299
00300 if (m - w%m > digits) {
00301 #define COVERAGE_IGNORE
00302 u &= ~(base_unsigned(1) << (m - digits));
00303 #undef COVERAGE_IGNORE
00304 }
00305 r = RealType(u >> (w%m)) * mult;
00306 }
00307 for(std::size_t i = m - w%m; i + m < digits; ++i) {
00308 #define COVERAGE_IGNORE
00309 base_unsigned u = generate_one_digit(eng, m);
00310 r += u;
00311 r *= RealType(0.5)/RealType(base_unsigned(1) << (m - 1));
00312 #undef COVERAGE_IGNORE
00313 }
00314 if (m - w%m < digits)
00315 {
00316 const std::size_t remaining = (digits - m + w%m) % m;
00317 base_unsigned u = generate_one_digit(eng, m);
00318 r += u & ((base_unsigned(2) << (remaining - 1)) - 1);
00319 const RealType mult = RealType(0.5)/RealType(base_unsigned(1) << (remaining - 1));
00320 r *= mult;
00321 }
00322 return std::make_pair(r, bucket);
00323 }
00324
00325 template<class RealType, std::size_t w, class Engine>
00326 inline std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::mpl::false_)
00327 {
00328 #if BOOST_VERSION < 104700
00329 int bucket = uniform_int<>(0, (1 << w) - 1)(eng);
00330 #else
00331 int bucket = uniform_int_distribution<>(0, (1 << w) - 1)(eng);
00332 #endif
00333 RealType r = uniform_01<RealType>()(eng);
00334 return std::make_pair(r, bucket);
00335 }
00336
00337 template<class RealType, std::size_t w, class Engine>
00338 inline std::pair<RealType, int> generate_int_float_pair(Engine& eng)
00339 {
00340 typedef typename Engine::result_type base_result;
00341 return generate_int_float_pair<RealType, w>(eng,
00342 boost::is_integral<base_result>());
00343 }
00344
00345 template<class RealType = double>
00346 struct unit_normal_distribution
00347 {
00348 template<class Engine>
00349 RealType operator()(Engine& eng) {
00350 const double * const table_x = normal_table<double>::table_x;
00351 const double * const table_y = normal_table<double>::table_y;
00352 for(;;) {
00353 std::pair<RealType, int> vals = generate_int_float_pair<RealType, 8>(eng);
00354 int i = vals.second;
00355 int sign = (i & 1) * 2 - 1;
00356 i = i >> 1;
00357 RealType x = vals.first * RealType(table_x[i]);
00358 if(x < table_x[i + 1]) return x * sign;
00359 if(i == 0) return generate_tail(eng) * sign;
00360 RealType y = RealType(table_y[i]) + uniform_01<RealType>()(eng) * RealType(table_y[i + 1] - table_y[i]);
00361 if (y < f(x)) return x * sign;
00362 }
00363 }
00364 static RealType f(RealType x) {
00365 using std::exp;
00366 return exp(-x*x/2);
00367 }
00368 template<class Engine>
00369 RealType generate_tail(Engine& eng) {
00370 boost::exponential_distribution<RealType> exponential;
00371 boost::variate_generator<Engine& , boost::exponential_distribution<RealType> > var_exponential(eng, exponential);
00372 const RealType tail_start = RealType(normal_table<double>::table_x[1]);
00373 #define COVERAGE_IGNORE
00374 for(;;) {
00375 #undef COVERAGE_IGNORE
00376 RealType x = var_exponential()/tail_start;
00377 RealType y = var_exponential();
00378 if(2*y > x*x) return x + tail_start;
00379 }
00380 }
00381 };
00382
00383 }
00384
00385
00386
00396 template<class RealType = double>
00397 class normal_distribution_v156
00398 {
00399 public:
00400 typedef RealType input_type;
00401 typedef RealType result_type;
00402
00403 class param_type {
00404 public:
00405 typedef normal_distribution_v156 distribution_type;
00406
00413 explicit param_type(RealType mean_arg = RealType(0.0),
00414 RealType sigma_arg = RealType(1.0))
00415 : _mean(mean_arg),
00416 _sigma(sigma_arg)
00417 {}
00418
00420 RealType mean() const { return _mean; }
00421
00423 RealType sigma() const { return _sigma; }
00424
00426 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
00427 { os << parm._mean << " " << parm._sigma ; return os; }
00428
00430 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
00431 { is >> parm._mean >> std::ws >> parm._sigma; return is; }
00432
00434 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
00435 { return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma; }
00436
00438 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
00439
00440 private:
00441 RealType _mean;
00442 RealType _sigma;
00443 };
00444
00451 explicit normal_distribution_v156(boost::mt19937& engine_arg,
00452 const RealType& mean_arg = RealType(0.0),
00453 const RealType& sigma_arg = RealType(1.0)
00454 )
00455 : _mean(mean_arg), _sigma(sigma_arg), _engine(engine_arg)
00456 {
00457 BOOST_ASSERT(_sigma >= RealType(0));
00458 }
00459
00463 explicit normal_distribution_v156(const param_type& parm)
00464 : _mean(parm.mean()), _sigma(parm.sigma())
00465 {}
00466
00468 RealType mean() const { return _mean; }
00470 RealType sigma() const { return _sigma; }
00471
00473 RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
00474 { return -std::numeric_limits<RealType>::infinity(); }
00476 RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
00477 { return std::numeric_limits<RealType>::infinity(); }
00478
00480 param_type param() const { return param_type(_mean, _sigma); }
00482 void param(const param_type& parm)
00483 {
00484 _mean = parm.mean();
00485 _sigma = parm.sigma();
00486 }
00487
00492 void reset() { }
00493
00495 template<class Engine>
00496 result_type operator()(Engine& eng)
00497 {
00498 detail::unit_normal_distribution<RealType> impl;
00499 #if BOOST_VERSION < 104700
00500 return impl(_engine) * _sigma + _mean;
00501 #else
00502 return impl(eng) * _sigma + _mean;
00503 #endif
00504 }
00505
00507 template<class URNG>
00508 result_type operator()(URNG& urng, const param_type& parm)
00509 {
00510 return normal_distribution_v156(parm)(urng);
00511 }
00512
00514 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, normal_distribution_v156, nd)
00515 {
00516 os << nd._mean << " " << nd._sigma;
00517 return os;
00518 }
00519
00521 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, normal_distribution_v156, nd)
00522 {
00523 is >> std::ws >> nd._mean >> std::ws >> nd._sigma;
00524 return is;
00525 }
00526
00531 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(normal_distribution_v156, lhs, rhs)
00532 {
00533 return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma;
00534 }
00535
00540 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(normal_distribution_v156)
00541
00542 private:
00543 RealType _mean, _sigma;
00544 boost::mt19937& _engine;
00545
00546 };
00547
00548 }
00549
00550 }
00551
00552 #endif // BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP