/src/contrib/boost/random/additive_combine.hpp

http://pythonocc.googlecode.com/ · C++ Header · 234 lines · 100 code · 20 blank · 114 comment · 10 complexity · 824100e86765212c9909dc0f8e814bb9 MD5 · raw file

  1. /* boost random/additive_combine.hpp header file
  2. *
  3. * Copyright Jens Maurer 2000-2001
  4. * Distributed under the Boost Software License, Version 1.0. (See
  5. * accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * See http://www.boost.org for most recent version including documentation.
  9. *
  10. * $Id: additive_combine.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $
  11. *
  12. * Revision history
  13. * 2001-02-18 moved to individual header files
  14. */
  15. #ifndef BOOST_RANDOM_ADDITIVE_COMBINE_HPP
  16. #define BOOST_RANDOM_ADDITIVE_COMBINE_HPP
  17. #include <iostream>
  18. #include <algorithm> // for std::min and std::max
  19. #include <boost/config.hpp>
  20. #include <boost/cstdint.hpp>
  21. #include <boost/random/detail/config.hpp>
  22. #include <boost/random/linear_congruential.hpp>
  23. namespace boost {
  24. namespace random {
  25. /**
  26. * An instantiation of class template \additive_combine model a
  27. * \pseudo_random_number_generator. It combines two multiplicative
  28. * \linear_congruential number generators, i.e. those with @c c = 0.
  29. * It is described in
  30. *
  31. * @blockquote
  32. * "Efficient and Portable Combined Random Number Generators", Pierre L'Ecuyer,
  33. * Communications of the ACM, Vol. 31, No. 6, June 1988, pp. 742-749, 774
  34. * @endblockquote
  35. *
  36. * The template parameters MLCG1 and MLCG2 shall denote two different
  37. * \linear_congruential number generators, each with c = 0. Each invocation
  38. * returns a random number X(n) := (MLCG1(n) - MLCG2(n)) mod (m1 - 1), where
  39. * m1 denotes the modulus of MLCG1.
  40. *
  41. * The template parameter @c val is the validation value checked by validation.
  42. */
  43. template<class MLCG1, class MLCG2,
  44. #ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
  45. typename MLCG1::result_type
  46. #else
  47. int32_t
  48. #endif
  49. val>
  50. class additive_combine
  51. {
  52. public:
  53. typedef MLCG1 first_base;
  54. typedef MLCG2 second_base;
  55. typedef typename MLCG1::result_type result_type;
  56. #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  57. static const bool has_fixed_range = true;
  58. static const result_type min_value = 1;
  59. static const result_type max_value = MLCG1::max_value-1;
  60. #else
  61. enum { has_fixed_range = false };
  62. #endif
  63. /**
  64. * Returns: The smallest value that the generator can produce
  65. */
  66. result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 1; }
  67. /**
  68. * Returns: The largest value that the generator can produce
  69. */
  70. result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_mlcg1.max)()-1; }
  71. /**
  72. * Constructs an \additive_combine generator using the
  73. * default constructors of the two base generators.
  74. */
  75. additive_combine() : _mlcg1(), _mlcg2() { }
  76. /**
  77. * Constructs an \additive_combine generator, using aseed as
  78. * the constructor argument for both base generators.
  79. */
  80. explicit additive_combine(result_type aseed)
  81. : _mlcg1(aseed), _mlcg2(aseed) { }
  82. /**
  83. * Constructs an \additive_combine generator, using
  84. * @c seed1 and @c seed2 as the constructor argument to
  85. * the first and second base generators, respectively.
  86. */
  87. additive_combine(typename MLCG1::result_type seed1,
  88. typename MLCG2::result_type seed2)
  89. : _mlcg1(seed1), _mlcg2(seed2) { }
  90. /**
  91. * Contructs an \additive_combine generator with
  92. * values from the range defined by the input iterators first
  93. * and last. first will be modified to point to the element
  94. * after the last one used.
  95. *
  96. * Throws: @c std::invalid_argument if the input range is too small.
  97. *
  98. * Exception Safety: Basic
  99. */
  100. template<class It> additive_combine(It& first, It last)
  101. : _mlcg1(first, last), _mlcg2(first, last) { }
  102. /**
  103. * Seeds an \additive_combine generator using the default
  104. * seeds of the two base generators.
  105. */
  106. void seed()
  107. {
  108. _mlcg1.seed();
  109. _mlcg2.seed();
  110. }
  111. /**
  112. * Seeds an \additive_combine generator, using @c aseed as the
  113. * seed for both base generators.
  114. */
  115. void seed(result_type aseed)
  116. {
  117. _mlcg1.seed(aseed);
  118. _mlcg2.seed(aseed);
  119. }
  120. /**
  121. * Seeds an \additive_combine generator, using @c seed1 and @c seed2 as
  122. * the seeds to the first and second base generators, respectively.
  123. */
  124. void seed(typename MLCG1::result_type seed1,
  125. typename MLCG2::result_type seed2)
  126. {
  127. _mlcg1.seed(seed1);
  128. _mlcg2.seed(seed2);
  129. }
  130. /**
  131. * Seeds an \additive_combine generator with
  132. * values from the range defined by the input iterators first
  133. * and last. first will be modified to point to the element
  134. * after the last one used.
  135. *
  136. * Throws: @c std::invalid_argument if the input range is too small.
  137. *
  138. * Exception Safety: Basic
  139. */
  140. template<class It> void seed(It& first, It last)
  141. {
  142. _mlcg1.seed(first, last);
  143. _mlcg2.seed(first, last);
  144. }
  145. /**
  146. * Returns: the next value of the generator
  147. */
  148. result_type operator()() {
  149. result_type z = _mlcg1() - _mlcg2();
  150. if(z < 1)
  151. z += MLCG1::modulus-1;
  152. return z;
  153. }
  154. static bool validation(result_type x) { return val == x; }
  155. #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
  156. #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
  157. /**
  158. * Writes the state of an \additive_combine generator to a @c
  159. * std::ostream. The textual representation of an \additive_combine
  160. * generator is the textual representation of the first base
  161. * generator followed by the textual representation of the
  162. * second base generator.
  163. */
  164. template<class CharT, class Traits>
  165. friend std::basic_ostream<CharT,Traits>&
  166. operator<<(std::basic_ostream<CharT,Traits>& os, const additive_combine& r)
  167. { os << r._mlcg1 << " " << r._mlcg2; return os; }
  168. /**
  169. * Reads the state of an \additive_combine generator from a
  170. * @c std::istream.
  171. */
  172. template<class CharT, class Traits>
  173. friend std::basic_istream<CharT,Traits>&
  174. operator>>(std::basic_istream<CharT,Traits>& is, additive_combine& r)
  175. { is >> r._mlcg1 >> std::ws >> r._mlcg2; return is; }
  176. #endif
  177. /**
  178. * Returns: true iff the two \additive_combine generators will
  179. * produce the same sequence of values.
  180. */
  181. friend bool operator==(const additive_combine& x, const additive_combine& y)
  182. { return x._mlcg1 == y._mlcg1 && x._mlcg2 == y._mlcg2; }
  183. /**
  184. * Returns: true iff the two \additive_combine generators will
  185. * produce different sequences of values.
  186. */
  187. friend bool operator!=(const additive_combine& x, const additive_combine& y)
  188. { return !(x == y); }
  189. #else
  190. // Use a member function; Streamable concept not supported.
  191. bool operator==(const additive_combine& rhs) const
  192. { return _mlcg1 == rhs._mlcg1 && _mlcg2 == rhs._mlcg2; }
  193. bool operator!=(const additive_combine& rhs) const
  194. { return !(*this == rhs); }
  195. #endif
  196. private:
  197. MLCG1 _mlcg1;
  198. MLCG2 _mlcg2;
  199. };
  200. } // namespace random
  201. /**
  202. * The specialization \ecuyer1988 was suggested in
  203. *
  204. * @blockquote
  205. * "Efficient and Portable Combined Random Number Generators", Pierre L'Ecuyer,
  206. * Communications of the ACM, Vol. 31, No. 6, June 1988, pp. 742-749, 774
  207. * @endblockquote
  208. */
  209. typedef random::additive_combine<
  210. random::linear_congruential<int32_t, 40014, 0, 2147483563, 0>,
  211. random::linear_congruential<int32_t, 40692, 0, 2147483399, 0>,
  212. 2060321752> ecuyer1988;
  213. } // namespace boost
  214. #endif // BOOST_RANDOM_ADDITIVE_COMBINE_HPP