~ubuntu-branches/ubuntu/saucy/deal.ii/saucy

« back to all changes in this revision

Viewing changes to contrib/boost/include/boost/random/linear_congruential.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam C. Powell, IV
  • Date: 2009-05-08 23:13:50 UTC
  • Revision ID: james.westby@ubuntu.com-20090508231350-rrh1ltgi0tifabwc
Tags: upstream-6.2.0
ImportĀ upstreamĀ versionĀ 6.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* boost random/linear_congruential.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: linear_congruential.hpp 29116 2005-05-21 15:57:01Z dgregor $
 
11
 *
 
12
 * Revision history
 
13
 *  2001-02-18  moved to individual header files
 
14
 */
 
15
 
 
16
#ifndef BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
 
17
#define BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
 
18
 
 
19
#include <iostream>
 
20
#include <cassert>
 
21
#include <stdexcept>
 
22
#include <boost/config.hpp>
 
23
#include <boost/limits.hpp>
 
24
#include <boost/static_assert.hpp>
 
25
#include <boost/random/detail/const_mod.hpp>
 
26
#include <boost/detail/workaround.hpp>
 
27
 
 
28
namespace boost {
 
29
namespace random {
 
30
 
 
31
// compile-time configurable linear congruential generator
 
32
template<class IntType, IntType a, IntType c, IntType m, IntType val>
 
33
class linear_congruential
 
34
{
 
35
public:
 
36
  typedef IntType result_type;
 
37
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 
38
  static const bool has_fixed_range = true;
 
39
  static const result_type min_value = ( c == 0 ? 1 : 0 );
 
40
  static const result_type max_value = m-1;
 
41
#else
 
42
  BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
 
43
#endif
 
44
  BOOST_STATIC_CONSTANT(IntType, multiplier = a);
 
45
  BOOST_STATIC_CONSTANT(IntType, increment = c);
 
46
  BOOST_STATIC_CONSTANT(IntType, modulus = m);
 
47
 
 
48
  // MSVC 6 and possibly others crash when encountering complicated integral
 
49
  // constant expressions.  Avoid the check for now.
 
50
  // BOOST_STATIC_ASSERT(m == 0 || a < m);
 
51
  // BOOST_STATIC_ASSERT(m == 0 || c < m);
 
52
 
 
53
  explicit linear_congruential(IntType x0 = 1)
 
54
    : _modulus(modulus), _x(_modulus ? (x0 % _modulus) : x0)
 
55
  { 
 
56
    assert(c || x0); /* if c == 0 and x(0) == 0 then x(n) = 0 for all n */
 
57
    // overflow check
 
58
    // disabled because it gives spurious "divide by zero" gcc warnings
 
59
    // assert(m == 0 || (a*(m-1)+c) % m == (c < a ? c-a+m : c-a)); 
 
60
 
 
61
    // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
 
62
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
 
63
    BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
 
64
#endif
 
65
  }
 
66
 
 
67
  template<class It>
 
68
  linear_congruential(It& first, It last) { seed(first, last); }
 
69
 
 
70
  // compiler-generated copy constructor and assignment operator are fine
 
71
  void seed(IntType x0 = 1)
 
72
  {
 
73
    assert(c || x0);
 
74
    _x = (_modulus ? (x0 % _modulus) : x0);
 
75
  }
 
76
 
 
77
  template<class It>
 
78
  void seed(It& first, It last)
 
79
  {
 
80
    if(first == last)
 
81
      throw std::invalid_argument("linear_congruential::seed");
 
82
    IntType value = *first++;
 
83
    _x = (_modulus ? (value % _modulus) : value);
 
84
  }
 
85
 
 
86
  result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return c == 0 ? 1 : 0; }
 
87
  result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return modulus-1; }
 
88
 
 
89
  IntType operator()()
 
90
  {
 
91
    _x = const_mod<IntType, m>::mult_add(a, _x, c);
 
92
    return _x;
 
93
  }
 
94
 
 
95
  static bool validation(IntType x) { return val == x; }
 
96
 
 
97
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
 
98
    
 
99
  // Use a member function; Streamable concept not supported.
 
100
  bool operator==(const linear_congruential& rhs) const
 
101
  { return _x == rhs._x; }
 
102
  bool operator!=(const linear_congruential& rhs) const
 
103
  { return !(*this == rhs); }
 
104
 
 
105
#else 
 
106
  friend bool operator==(const linear_congruential& x,
 
107
                         const linear_congruential& y)
 
108
  { return x._x == y._x; }
 
109
  friend bool operator!=(const linear_congruential& x,
 
110
                         const linear_congruential& y)
 
111
  { return !(x == y); }
 
112
    
 
113
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
 
114
  template<class CharT, class Traits>
 
115
  friend std::basic_ostream<CharT,Traits>&
 
116
  operator<<(std::basic_ostream<CharT,Traits>& os,
 
117
             const linear_congruential& lcg)
 
118
  {
 
119
    return os << lcg._x;
 
120
  }
 
121
 
 
122
  template<class CharT, class Traits>
 
123
  friend std::basic_istream<CharT,Traits>&
 
124
  operator>>(std::basic_istream<CharT,Traits>& is,
 
125
             linear_congruential& lcg)
 
126
  {
 
127
    return is >> lcg._x;
 
128
  }
 
129
 
 
130
private:
 
131
#endif
 
132
#endif
 
133
    
 
134
  IntType _modulus;   // work-around for gcc "divide by zero" warning in ctor
 
135
  IntType _x;
 
136
};
 
137
 
 
138
// probably needs the "no native streams" caveat for STLPort
 
139
#if !defined(__SGI_STL_PORT) && BOOST_WORKAROUND(__GNUC__, == 2)
 
140
template<class IntType, IntType a, IntType c, IntType m, IntType val>
 
141
std::ostream&
 
142
operator<<(std::ostream& os,
 
143
           const linear_congruential<IntType,a,c,m,val>& lcg)
 
144
{
 
145
    return os << lcg._x;
 
146
}
 
147
 
 
148
template<class IntType, IntType a, IntType c, IntType m, IntType val>
 
149
std::istream&
 
150
operator>>(std::istream& is,
 
151
           linear_congruential<IntType,a,c,m,val>& lcg)
 
152
{
 
153
    return is >> lcg._x;
 
154
}
 
155
#elif defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
 
156
template<class CharT, class Traits, class IntType, IntType a, IntType c, IntType m, IntType val>
 
157
std::basic_ostream<CharT,Traits>&
 
158
operator<<(std::basic_ostream<CharT,Traits>& os,
 
159
           const linear_congruential<IntType,a,c,m,val>& lcg)
 
160
{
 
161
    return os << lcg._x;
 
162
}
 
163
 
 
164
template<class CharT, class Traits, class IntType, IntType a, IntType c, IntType m, IntType val>
 
165
std::basic_istream<CharT,Traits>&
 
166
operator>>(std::basic_istream<CharT,Traits>& is,
 
167
           linear_congruential<IntType,a,c,m,val>& lcg)
 
168
{
 
169
    return is >> lcg._x;
 
170
}
 
171
#endif
 
172
 
 
173
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 
174
//  A definition is required even for integral static constants
 
175
template<class IntType, IntType a, IntType c, IntType m, IntType val>
 
176
const bool linear_congruential<IntType, a, c, m, val>::has_fixed_range;
 
177
template<class IntType, IntType a, IntType c, IntType m, IntType val>
 
178
const typename linear_congruential<IntType, a, c, m, val>::result_type linear_congruential<IntType, a, c, m, val>::min_value;
 
179
template<class IntType, IntType a, IntType c, IntType m, IntType val>
 
180
const typename linear_congruential<IntType, a, c, m, val>::result_type linear_congruential<IntType, a, c, m, val>::max_value;
 
181
template<class IntType, IntType a, IntType c, IntType m, IntType val>
 
182
const IntType linear_congruential<IntType,a,c,m,val>::modulus;
 
183
#endif
 
184
 
 
185
} // namespace random
 
186
 
 
187
// validation values from the publications
 
188
typedef random::linear_congruential<int32_t, 16807, 0, 2147483647, 
 
189
  1043618065> minstd_rand0;
 
190
typedef random::linear_congruential<int32_t, 48271, 0, 2147483647,
 
191
  399268537> minstd_rand;
 
192
 
 
193
 
 
194
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
 
195
// emulate the lrand48() C library function; requires support for uint64_t
 
196
class rand48 
 
197
{
 
198
public:
 
199
  typedef int32_t result_type;
 
200
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 
201
  static const bool has_fixed_range = true;
 
202
  static const int32_t min_value = 0;
 
203
  static const int32_t max_value = integer_traits<int32_t>::const_max;
 
204
#else
 
205
  enum { has_fixed_range = false };
 
206
#endif
 
207
  int32_t min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
 
208
  int32_t max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::numeric_limits<int32_t>::max BOOST_PREVENT_MACRO_SUBSTITUTION (); }
 
209
  
 
210
  explicit rand48(int32_t x0 = 1) : lcf(cnv(x0)) { }
 
211
  explicit rand48(uint64_t x0) : lcf(x0) { }
 
212
  template<class It> rand48(It& first, It last) : lcf(first, last) { }
 
213
  // compiler-generated copy ctor and assignment operator are fine
 
214
  void seed(int32_t x0 = 1) { lcf.seed(cnv(x0)); }
 
215
  void seed(uint64_t x0) { lcf.seed(x0); }
 
216
  template<class It> void seed(It& first, It last) { lcf.seed(first,last); }
 
217
 
 
218
  int32_t operator()() { return static_cast<int32_t>(lcf() >> 17); }
 
219
  // by experiment from lrand48()
 
220
  static bool validation(int32_t x) { return x == 1993516219; }
 
221
 
 
222
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
 
223
 
 
224
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 
225
  template<class CharT,class Traits>
 
226
  friend std::basic_ostream<CharT,Traits>&
 
227
  operator<<(std::basic_ostream<CharT,Traits>& os, const rand48& r)
 
228
  { os << r.lcf; return os; }
 
229
 
 
230
  template<class CharT,class Traits>
 
231
  friend std::basic_istream<CharT,Traits>&
 
232
  operator>>(std::basic_istream<CharT,Traits>& is, rand48& r)
 
233
  { is >> r.lcf; return is; }
 
234
#endif
 
235
 
 
236
  friend bool operator==(const rand48& x, const rand48& y)
 
237
  { return x.lcf == y.lcf; }
 
238
  friend bool operator!=(const rand48& x, const rand48& y)
 
239
  { return !(x == y); }
 
240
#else
 
241
  // Use a member function; Streamable concept not supported.
 
242
  bool operator==(const rand48& rhs) const
 
243
  { return lcf == rhs.lcf; }
 
244
  bool operator!=(const rand48& rhs) const
 
245
  { return !(*this == rhs); }
 
246
#endif
 
247
private:
 
248
  random::linear_congruential<uint64_t,
 
249
    uint64_t(0xDEECE66DUL) | (uint64_t(0x5) << 32), // xxxxULL is not portable
 
250
    0xB, uint64_t(1)<<48, /* unknown */ 0> lcf;
 
251
  static uint64_t cnv(int32_t x) 
 
252
  { return (static_cast<uint64_t>(x) << 16) | 0x330e;  }
 
253
};
 
254
#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */
 
255
 
 
256
} // namespace boost
 
257
 
 
258
#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP