46 #ifndef BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP
47 #define BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP
49 #include <boost/config/no_tr1/cmath.hpp>
52 #include <boost/assert.hpp>
53 #include <boost/limits.hpp>
54 #include <boost/static_assert.hpp>
55 #include <boost/integer.hpp>
56 #include <boost/integer/integer_mask.hpp>
57 #include <boost/type_traits/is_integral.hpp>
58 #include <boost/type_traits/make_unsigned.hpp>
59 #include <boost/random/detail/config.hpp>
61 #if BOOST_VERSION < 104700 // Old version
63 #include <boost/random/detail/config.hpp>
64 #include <boost/detail/workaround.hpp>
66 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) \
67 || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
69 #define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \
70 template<class CharT, class Traits> \
71 friend std::basic_ostream<CharT,Traits>& \
72 operator<<(std::basic_ostream<CharT,Traits>& os, const T& t) { \
76 template<class CharT, class Traits> \
77 static std::basic_ostream<CharT,Traits>& \
78 print(std::basic_ostream<CharT,Traits>& os, const T& t)
80 #define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \
81 template<class CharT, class Traits> \
82 friend std::basic_istream<CharT,Traits>& \
83 operator>>(std::basic_istream<CharT,Traits>& is, T& t) { \
87 template<class CharT, class Traits> \
88 static std::basic_istream<CharT,Traits>& \
89 read(std::basic_istream<CharT,Traits>& is, T& t)
93 #if defined(__BORLANDC__)
95 #define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \
96 bool operator==(const T& rhs) const \
97 { return T::is_equal(*this, rhs); } \
98 static bool is_equal(const T& lhs, const T& rhs)
100 #define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \
101 bool operator!=(const T& rhs) const \
102 { return !T::is_equal(*this, rhs); }
106 #ifndef BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR
107 #define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \
108 template<class CharT, class Traits> \
109 friend std::basic_ostream<CharT,Traits>& \
110 operator<<(std::basic_ostream<CharT,Traits>& os, const T& t)
113 #ifndef BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR
114 #define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \
115 template<class CharT, class Traits> \
116 friend std::basic_istream<CharT,Traits>& \
117 operator>>(std::basic_istream<CharT,Traits>& is, T& t)
120 #ifndef BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR
121 #define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \
122 friend bool operator==(const T& lhs, const T& rhs)
125 #ifndef BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR
126 #define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \
127 friend bool operator!=(const T& lhs, const T& rhs) \
128 { return !(lhs == rhs); }
131 #include <boost/pending/integer_log2.hpp>
133 #include <boost/random/detail/operators.hpp>
134 #include <boost/random/detail/integer_log2.hpp>
138 #include <boost/random/uniform_01.hpp>
139 #include <boost/random/mersenne_twister.hpp>
141 #if BOOST_VERSION < 104700
142 #include <boost/random/uniform_int.hpp>
145 #include <boost/random/uniform_int_distribution.hpp>
151 #include <boost/random/detail/signed_unsigned_tools.hpp>
152 #include <boost/type_traits/make_unsigned.hpp>
154 #include <boost/random/exponential_distribution.hpp>
155 #include <boost/random/variate_generator.hpp>
165 template<
class RealType>
167 static const RealType table_x[129];
168 static const RealType table_y[129];
171 template<
class RealType>
173 3.7130862467403632609, 3.4426198558966521214, 3.2230849845786185446, 3.0832288582142137009,
174 2.9786962526450169606, 2.8943440070186706210, 2.8231253505459664379, 2.7611693723841538514,
175 2.7061135731187223371, 2.6564064112581924999, 2.6109722484286132035, 2.5690336259216391328,
176 2.5300096723854666170, 2.4934545220919507609, 2.4590181774083500943, 2.4264206455302115930,
177 2.3954342780074673425, 2.3658713701139875435, 2.3375752413355307354, 2.3104136836950021558,
178 2.2842740596736568056, 2.2590595738653295251, 2.2346863955870569803, 2.2110814088747278106,
179 2.1881804320720206093, 2.1659267937448407377, 2.1442701823562613518, 2.1231657086697899595,
180 2.1025731351849988838, 2.0824562379877246441, 2.0627822745039633575, 2.0435215366506694976,
181 2.0246469733729338782, 2.0061338699589668403, 1.9879595741230607243, 1.9701032608497132242,
182 1.9525457295488889058, 1.9352692282919002011, 1.9182573008597320303, 1.9014946531003176140,
183 1.8849670357028692380, 1.8686611409895420085, 1.8525645117230870617, 1.8366654602533840447,
184 1.8209529965910050740, 1.8054167642140487420, 1.7900469825946189862, 1.7748343955807692457,
185 1.7597702248942318749, 1.7448461281083765085, 1.7300541605582435350, 1.7153867407081165482,
186 1.7008366185643009437, 1.6863968467734863258, 1.6720607540918522072, 1.6578219209482075462,
187 1.6436741568569826489, 1.6296114794646783962, 1.6156280950371329644, 1.6017183802152770587,
188 1.5878768648844007019, 1.5740982160167497219, 1.5603772223598406870, 1.5467087798535034608,
189 1.5330878776675560787, 1.5195095847593707806, 1.5059690368565502602, 1.4924614237746154081,
190 1.4789819769830978546, 1.4655259573357946276, 1.4520886428822164926, 1.4386653166774613138,
191 1.4252512545068615734, 1.4118417124397602509, 1.3984319141236063517, 1.3850170377251486449,
192 1.3715922024197322698, 1.3581524543224228739, 1.3446927517457130432, 1.3312079496576765017,
193 1.3176927832013429910, 1.3041418501204215390, 1.2905495919178731508, 1.2769102735516997175,
194 1.2632179614460282310, 1.2494664995643337480, 1.2356494832544811749, 1.2217602305309625678,
195 1.2077917504067576028, 1.1937367078237721994, 1.1795873846544607035, 1.1653356361550469083,
196 1.1509728421389760651, 1.1364898520030755352, 1.1218769225722540661, 1.1071236475235353980,
197 1.0922188768965537614, 1.0771506248819376573, 1.0619059636836193998, 1.0464709007525802629,
198 1.0308302360564555907, 1.0149673952392994716, 0.99886423348064351303, 0.98250080350276038481,
199 0.96585507938813059489, 0.94890262549791195381, 0.93161619660135381056, 0.91396525100880177644,
200 0.89591535256623852894, 0.87742742909771569142, 0.85845684317805086354, 0.83895221428120745572,
201 0.81885390668331772331, 0.79809206062627480454, 0.77658398787614838598, 0.75423066443451007146,
202 0.73091191062188128150, 0.70647961131360803456, 0.68074791864590421664, 0.65347863871504238702,
203 0.62435859730908822111, 0.59296294244197797913, 0.55869217837551797140, 0.52065603872514491759,
204 0.47743783725378787681, 0.42654798630330512490, 0.36287143102841830424, 0.27232086470466385065,
208 template<
class RealType>
209 const RealType normal_table<RealType>::table_y[129] = {
210 0, 0.0026696290839025035092, 0.0055489952208164705392, 0.0086244844129304709682,
211 0.011839478657982313715, 0.015167298010672042468, 0.018592102737165812650, 0.022103304616111592615,
212 0.025693291936149616572, 0.029356317440253829618, 0.033087886146505155566, 0.036884388786968774128,
213 0.040742868074790604632, 0.044660862200872429800, 0.048636295860284051878, 0.052667401903503169793,
214 0.056752663481538584188, 0.060890770348566375972, 0.065080585213631873753, 0.069321117394180252601,
215 0.073611501884754893389, 0.077950982514654714188, 0.082338898242957408243, 0.086774671895542968998,
216 0.091257800827634710201, 0.09578784912257815216, 0.10036444102954554013, 0.10498725541035453978,
217 0.10965602101581776100, 0.11437051244988827452, 0.11913054670871858767, 0.12393598020398174246,
218 0.12878670619710396109, 0.13368265258464764118, 0.13862377998585103702, 0.14361008009193299469,
219 0.14864157424369696566, 0.15371831220958657066, 0.15884037114093507813, 0.16400785468492774791,
220 0.16922089223892475176, 0.17447963833240232295, 0.17978427212496211424, 0.18513499701071343216,
221 0.19053204032091372112, 0.19597565311811041399, 0.20146611007620324118, 0.20700370944187380064,
222 0.21258877307373610060, 0.21822164655637059599, 0.22390269938713388747, 0.22963232523430270355,
223 0.23541094226572765600, 0.24123899354775131610, 0.24711694751469673582, 0.25304529850976585934,
224 0.25902456739871074263, 0.26505530225816194029, 0.27113807914102527343, 0.27727350292189771153,
225 0.28346220822601251779, 0.28970486044581049771, 0.29600215684985583659, 0.30235482778947976274,
226 0.30876363800925192282, 0.31522938806815752222, 0.32175291587920862031, 0.32833509837615239609,
227 0.33497685331697116147, 0.34167914123501368412, 0.34844296754987246935, 0.35526938485154714435,
228 0.36215949537303321162, 0.36911445366827513952, 0.37613546951445442947, 0.38322381105988364587,
229 0.39038080824138948916, 0.39760785649804255208, 0.40490642081148835099, 0.41227804010702462062,
230 0.41972433205403823467, 0.42724699830956239880, 0.43484783025466189638, 0.44252871528024661483,
231 0.45029164368692696086, 0.45813871627287196483, 0.46607215269457097924, 0.47409430069824960453,
232 0.48220764633483869062, 0.49041482528932163741, 0.49871863547658432422, 0.50712205108130458951,
233 0.51562823824987205196, 0.52424057267899279809, 0.53296265938998758838, 0.54179835503172412311,
234 0.55075179312105527738, 0.55982741271069481791, 0.56902999107472161225, 0.57836468112670231279,
235 0.58783705444182052571, 0.59745315095181228217, 0.60721953663260488551, 0.61714337082656248870,
236 0.62723248525781456578, 0.63749547734314487428, 0.64794182111855080873, 0.65858200005865368016,
237 0.66942766735770616891, 0.68049184100641433355, 0.69178914344603585279, 0.70333609902581741633,
238 0.71515150742047704368, 0.72725691835450587793, 0.73967724368333814856, 0.75244155918570380145,
239 0.76558417390923599480, 0.77914608594170316563, 0.79317701178385921053, 0.80773829469612111340,
240 0.82290721139526200050, 0.83878360531064722379, 0.85550060788506428418, 0.87324304892685358879,
241 0.89228165080230272301, 0.91304364799203805999, 0.93628268170837107547, 0.96359969315576759960,
245 template<
class Engine>
246 inline typename boost::make_unsigned<typename Engine::result_type>::type
247 generate_one_digit(Engine& eng, std::size_t bits)
249 typedef typename Engine::result_type base_result;
250 typedef typename boost::make_unsigned<base_result>::type base_unsigned;
252 base_unsigned range =
253 detail::subtract<base_result>()((eng.max)(), (eng.min)());
254 base_unsigned y0_mask = (base_unsigned(2) << (bits - 1)) - 1;
255 base_unsigned y0 = (range + 1) & ~y0_mask;
258 u = detail::subtract<base_result>()(eng(), (eng.min)());
259 }
while(y0 != 0 && u > base_unsigned(y0 - 1));
263 template<
class RealType, std::
size_t w,
class Engine>
264 std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::mpl::true_)
266 typedef typename Engine::result_type base_result;
267 typedef typename boost::make_unsigned<base_result>::type base_unsigned;
269 base_unsigned range =
270 detail::subtract<base_result>()((eng.max)(), (eng.min)());
273 (range == (std::numeric_limits<base_unsigned>::max)()) ?
274 std::numeric_limits<base_unsigned>::digits :
275 #
if BOOST_VERSION < 104700
277 integer_log2(range + 1);
280 detail::integer_log2(range + 1);
285 for(std::size_t i = 0; i < w/m; ++i) {
286 #define COVERAGE_IGNORE
287 base_unsigned u = generate_one_digit(eng, m);
288 bucket = (bucket << m) | u;
289 #undef COVERAGE_IGNORE
293 const std::size_t digits = std::numeric_limits<RealType>::digits;
295 base_unsigned u = generate_one_digit(eng, m);
296 base_unsigned mask = (base_unsigned(1) << (w%m)) - 1;
297 bucket = (bucket << (w%m)) | (mask & u);
298 const RealType mult = RealType(1)/RealType(base_unsigned(1) << (m - w%m));
300 if (m - w%m > digits) {
301 #define COVERAGE_IGNORE
302 u &= ~(base_unsigned(1) << (m - digits));
303 #undef COVERAGE_IGNORE
305 r = RealType(u >> (w%m)) * mult;
307 for(std::size_t i = m - w%m; i + m < digits; ++i) {
308 #define COVERAGE_IGNORE
309 base_unsigned u = generate_one_digit(eng, m);
311 r *= RealType(0.5)/RealType(base_unsigned(1) << (m - 1));
312 #undef COVERAGE_IGNORE
314 if (m - w%m < digits)
316 const std::size_t remaining = (digits - m + w%m) % m;
317 base_unsigned u = generate_one_digit(eng, m);
318 r += u & ((base_unsigned(2) << (remaining - 1)) - 1);
319 const RealType mult = RealType(0.5)/RealType(base_unsigned(1) << (remaining - 1));
322 return std::make_pair(r, bucket);
325 template<
class RealType, std::
size_t w,
class Engine>
326 inline std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::mpl::false_)
328 #if BOOST_VERSION < 104700
329 int bucket = uniform_int<>(0, (1 << w) - 1)(eng);
331 int bucket = uniform_int_distribution<>(0, (1 << w) - 1)(eng);
333 RealType r = uniform_01<RealType>()(eng);
334 return std::make_pair(r, bucket);
337 template<
class RealType, std::
size_t w,
class Engine>
338 inline std::pair<RealType, int> generate_int_float_pair(Engine& eng)
340 typedef typename Engine::result_type base_result;
341 return generate_int_float_pair<RealType, w>(eng,
342 boost::is_integral<base_result>());
345 template<
class RealType =
double>
348 template<
class Engine>
349 RealType operator()(Engine& eng) {
353 std::pair<RealType, int> vals = generate_int_float_pair<RealType, 8>(eng);
355 int sign = (i & 1) * 2 - 1;
357 RealType x = vals.first * RealType(table_x[i]);
358 if(x < table_x[i + 1])
return x * sign;
359 if(i == 0)
return generate_tail(eng) * sign;
360 RealType y = RealType(table_y[i]) + uniform_01<RealType>()(eng) * RealType(table_y[i + 1] - table_y[i]);
361 if (y < f(x))
return x * sign;
364 static RealType f(RealType x) {
368 template<
class Engine>
369 RealType generate_tail(Engine& eng) {
370 boost::exponential_distribution<RealType> exponential;
371 boost::variate_generator<Engine& , boost::exponential_distribution<RealType> > var_exponential(eng, exponential);
373 #define COVERAGE_IGNORE
375 #undef COVERAGE_IGNORE
376 RealType x = var_exponential()/tail_start;
377 RealType y = var_exponential();
378 if(2*y > x*x)
return x + tail_start;
396 template<
class RealType =
double>
400 typedef RealType input_type;
401 typedef RealType result_type;
414 RealType sigma_arg = RealType(1.0))
423 RealType
sigma()
const {
return _sigma; }
427 { os << parm._mean <<
" " << parm._sigma ;
return os; }
431 { is >> parm._mean >> std::ws >> parm._sigma;
return is; }
435 {
return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma; }
438 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(
param_type)
452 const RealType& mean_arg = RealType(0.0),
453 const RealType& sigma_arg = RealType(1.0)
455 : _mean(mean_arg), _sigma(sigma_arg), _engine(engine_arg)
457 BOOST_ASSERT(_sigma >= RealType(0));
463 RealType
sigma()
const {
return _sigma; }
467 {
return -std::numeric_limits<RealType>::infinity(); }
470 {
return std::numeric_limits<RealType>::infinity(); }
478 _sigma = parm.
sigma();
488 template<
class Engine>
492 #if BOOST_VERSION < 104700
493 return impl(_engine) * _sigma +
_mean;
495 return impl(eng) * _sigma +
_mean;
502 os << nd._mean <<
" " << nd._sigma;
509 is >> std::ws >> nd._mean >> std::ws >> nd._sigma;
519 return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma;
530 boost::mt19937& _engine;
537 #endif // BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, normal_distribution_v156, nd)
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION() const
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(normal_distribution_v156, lhs, rhs)
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
void param(const param_type &parm)
param_type(RealType mean_arg=RealType(0.0), RealType sigma_arg=RealType(1.0))
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, normal_distribution_v156, nd)
result_type operator()(Engine &eng)
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)