Chaste  Release::3.4
Boost156NormalDistribution.hpp
Go to the documentation of this file.
1 
30 /* boost random/normal_distribution.hpp header file
31  *
32  * Copyright Jens Maurer 2000-2001
33  * Copyright Steven Watanabe 2010-2011
34  * Distributed under the Boost Software License, Version 1.0. (See
35  * accompanying file LICENSE_1_0.txt or copy at
36  * http://www.boost.org/LICENSE_1_0.txt)
37  *
38  * See http://www.boost.org for most recent version including documentation.
39  *
40  * $Id$
41  *
42  * Revision history
43  * 2001-02-18 moved to individual header files
44  */
45 
46 #ifndef BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP
47 #define BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP
48 
49 #include <boost/config/no_tr1/cmath.hpp>
50 #include <istream>
51 #include <iosfwd>
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>
60 
61 #if BOOST_VERSION < 104700 // Old version
62 
63 #include <boost/random/detail/config.hpp>
64 #include <boost/detail/workaround.hpp>
65 
66 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) \
67  || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
68 
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) { \
73  t.print(os, t); \
74  return os; \
75  } \
76  template<class CharT, class Traits> \
77  static std::basic_ostream<CharT,Traits>& \
78  print(std::basic_ostream<CharT,Traits>& os, const T& t)
79 
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) { \
84  t.read(is, t); \
85  return is; \
86  } \
87  template<class CharT, class Traits> \
88  static std::basic_istream<CharT,Traits>& \
89  read(std::basic_istream<CharT,Traits>& is, T& t)
90 
91 #endif
92 
93 #if defined(__BORLANDC__)
94 
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)
99 
100 #define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \
101  bool operator!=(const T& rhs) const \
102  { return !T::is_equal(*this, rhs); }
103 
104 #endif
105 
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)
111 #endif
112 
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)
118 #endif
119 
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)
123 #endif
124 
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); }
129 #endif
130 
131 #include <boost/pending/integer_log2.hpp>
132 #else
133 #include <boost/random/detail/operators.hpp>
134 #include <boost/random/detail/integer_log2.hpp>
135 
136 #endif
137 
138 #include <boost/random/uniform_01.hpp>
139 #include <boost/random/mersenne_twister.hpp>
140 
141 #if BOOST_VERSION < 104700
142 #include <boost/random/uniform_int.hpp>
144 #else
145 #include <boost/random/uniform_int_distribution.hpp>
146 #endif
147 //#include <boost/random/uniform_int_distribution.hpp>
148 // Header we had to include after commenting out the one above
149 
150 
151 #include <boost/random/detail/signed_unsigned_tools.hpp>
152 #include <boost/type_traits/make_unsigned.hpp>
153 
154 #include <boost/random/exponential_distribution.hpp>
155 #include <boost/random/variate_generator.hpp>
156 
157 
158 
159 namespace boost {
160 namespace random {
161 
162 namespace detail {
163 
164 // tables for the ziggurat algorithm
165 template<class RealType>
166 struct normal_table {
167  static const RealType table_x[129];
168  static const RealType table_y[129];
169 };
170 
171 template<class RealType>
172 const RealType normal_table<RealType>::table_x[129] = {
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,
205  0
206 };
207 
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,
242  1
243 };
244 
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)
248 {
249  typedef typename Engine::result_type base_result;
250  typedef typename boost::make_unsigned<base_result>::type base_unsigned;
251 
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;
256  base_unsigned u;
257  do {
258  u = detail::subtract<base_result>()(eng(), (eng.min)());
259  } while(y0 != 0 && u > base_unsigned(y0 - 1));
260  return u & y0_mask;
261 }
262 
263 template<class RealType, std::size_t w, class Engine>
264 std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::mpl::true_)
265 {
266  typedef typename Engine::result_type base_result;
267  typedef typename boost::make_unsigned<base_result>::type base_unsigned;
268 
269  base_unsigned range =
270  detail::subtract<base_result>()((eng.max)(), (eng.min)());
271 
272  std::size_t m =
273  (range == (std::numeric_limits<base_unsigned>::max)()) ?
274  std::numeric_limits<base_unsigned>::digits :
275 #if BOOST_VERSION < 104700
276  // Just in the boost namespace
277  integer_log2(range + 1);
278 #else
279  // In the detail namespace
280  detail::integer_log2(range + 1);
281 #endif
282 
283  int bucket = 0;
284  // process as many full digits as possible into the int part
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
290  }
291  RealType r;
292 
293  const std::size_t digits = std::numeric_limits<RealType>::digits;
294  {
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));
299  // zero out unused bits
300  if (m - w%m > digits) {
301 #define COVERAGE_IGNORE
302  u &= ~(base_unsigned(1) << (m - digits));
303 #undef COVERAGE_IGNORE
304  }
305  r = RealType(u >> (w%m)) * mult;
306  }
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);
310  r += u;
311  r *= RealType(0.5)/RealType(base_unsigned(1) << (m - 1));
312 #undef COVERAGE_IGNORE
313  }
314  if (m - w%m < digits)
315  {
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));
320  r *= mult;
321  }
322  return std::make_pair(r, bucket);
323 }
324 
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_)
327 {
328 #if BOOST_VERSION < 104700
329  int bucket = uniform_int<>(0, (1 << w) - 1)(eng);
330 #else
331  int bucket = uniform_int_distribution<>(0, (1 << w) - 1)(eng);
332 #endif
333  RealType r = uniform_01<RealType>()(eng);
334  return std::make_pair(r, bucket);
335 }
336 
337 template<class RealType, std::size_t w, class Engine>
338 inline std::pair<RealType, int> generate_int_float_pair(Engine& eng)
339 {
340  typedef typename Engine::result_type base_result;
341  return generate_int_float_pair<RealType, w>(eng,
342  boost::is_integral<base_result>());
343 }
344 
345 template<class RealType = double>
347 {
348  template<class Engine>
349  RealType operator()(Engine& eng) {
350  const double * const table_x = normal_table<double>::table_x;
351  const double * const table_y = normal_table<double>::table_y;
352  for(;;) {
353  std::pair<RealType, int> vals = generate_int_float_pair<RealType, 8>(eng);
354  int i = vals.second;
355  int sign = (i & 1) * 2 - 1;
356  i = i >> 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;
362  }
363  }
364  static RealType f(RealType x) {
365  using std::exp;
366  return exp(-x*x/2);
367  }
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);
372  const RealType tail_start = RealType(normal_table<double>::table_x[1]);
373 #define COVERAGE_IGNORE
374  for(;;) {
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;
379  }
380  }
381 };
382 
383 }
384 
385 // deterministic Box-Muller method, uses trigonometric functions
386 
396 template<class RealType = double>
398 {
399 public:
400  typedef RealType input_type;
401  typedef RealType result_type;
402 
403  class param_type {
404  public:
406 
413  explicit param_type(RealType mean_arg = RealType(0.0),
414  RealType sigma_arg = RealType(1.0))
415  : _mean(mean_arg),
416  _sigma(sigma_arg)
417  {}
418 
420  RealType mean() const { return _mean; }
421 
423  RealType sigma() const { return _sigma; }
424 
427  { os << parm._mean << " " << parm._sigma ; return os; }
428 
431  { is >> parm._mean >> std::ws >> parm._sigma; return is; }
432 
435  { return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma; }
436 
438  BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
439 
440  private:
441  RealType _mean;
442  RealType _sigma;
443  };
444 
451  explicit normal_distribution_v156(boost::mt19937& engine_arg,
452  const RealType& mean_arg = RealType(0.0),
453  const RealType& sigma_arg = RealType(1.0)
454  )
455  : _mean(mean_arg), _sigma(sigma_arg), _engine(engine_arg)
456  {
457  BOOST_ASSERT(_sigma >= RealType(0));
458  }
459 
461  RealType mean() const { return _mean; }
463  RealType sigma() const { return _sigma; }
464 
466  RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
467  { return -std::numeric_limits<RealType>::infinity(); }
469  RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
470  { return std::numeric_limits<RealType>::infinity(); }
471 
473  param_type param() const { return param_type(_mean, _sigma); }
475  void param(const param_type& parm)
476  {
477  _mean = parm.mean();
478  _sigma = parm.sigma();
479  }
480 
485  void reset() { }
486 
488  template<class Engine>
489  result_type operator()(Engine& eng)
490  {
492 #if BOOST_VERSION < 104700
493  return impl(_engine) * _sigma + _mean;
494 #else
495  return impl(eng) * _sigma + _mean;
496 #endif
497  }
498 
501  {
502  os << nd._mean << " " << nd._sigma;
503  return os;
504  }
505 
508  {
509  is >> std::ws >> nd._mean >> std::ws >> nd._sigma;
510  return is;
511  }
512 
518  {
519  return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma;
520  }
521 
526  BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(normal_distribution_v156)
527 
528 private:
529  RealType _mean, _sigma;
530  boost::mt19937& _engine;
531 };
532 
533 } // namespace random
534 
535 } // namespace boost
536 
537 #endif // BOOST_156_RANDOM_NORMAL_DISTRIBUTION_HPP
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, normal_distribution_v156, nd)
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(normal_distribution_v156, lhs, rhs)
param_type(RealType mean_arg=RealType(0.0), RealType sigma_arg=RealType(1.0))
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, normal_distribution_v156, nd)