PageRenderTime 32ms CodeModel.GetById 12ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

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