]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/random/linear_congruential.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
71e186b2b4ab3f661d55cd081af73673e67a5e42
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / random / linear_congruential.hpp
1 /* boost random/linear_congruential.hpp header file\r
2  *\r
3  * Copyright Jens Maurer 2000-2001\r
4  * Distributed under the Boost Software License, Version 1.0. (See\r
5  * accompanying file LICENSE_1_0.txt or copy at\r
6  * http://www.boost.org/LICENSE_1_0.txt)\r
7  *\r
8  * See http://www.boost.org for most recent version including documentation.\r
9  *\r
10  * $Id: linear_congruential.hpp 58649 2010-01-02 21:23:17Z steven_watanabe $\r
11  *\r
12  * Revision history\r
13  *  2001-02-18  moved to individual header files\r
14  */\r
15 \r
16 #ifndef BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP\r
17 #define BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP\r
18 \r
19 #include <iostream>\r
20 #include <cassert>\r
21 #include <stdexcept>\r
22 #include <boost/config.hpp>\r
23 #include <boost/limits.hpp>\r
24 #include <boost/static_assert.hpp>\r
25 #include <boost/random/detail/config.hpp>\r
26 #include <boost/random/detail/const_mod.hpp>\r
27 #include <boost/detail/workaround.hpp>\r
28 \r
29 #include <boost/random/detail/disable_warnings.hpp>\r
30 \r
31 namespace boost {\r
32 namespace random {\r
33 \r
34 // compile-time configurable linear congruential generator\r
35 template<class IntType, IntType a, IntType c, IntType m, IntType val>\r
36 class linear_congruential\r
37 {\r
38 public:\r
39   typedef IntType result_type;\r
40 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION\r
41   static const bool has_fixed_range = true;\r
42   static const result_type min_value = ( c == 0 ? 1 : 0 );\r
43   static const result_type max_value = m-1;\r
44 #else\r
45   BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);\r
46 #endif\r
47   BOOST_STATIC_CONSTANT(IntType, multiplier = a);\r
48   BOOST_STATIC_CONSTANT(IntType, increment = c);\r
49   BOOST_STATIC_CONSTANT(IntType, modulus = m);\r
50 \r
51   // MSVC 6 and possibly others crash when encountering complicated integral\r
52   // constant expressions.  Avoid the check for now.\r
53   // BOOST_STATIC_ASSERT(m == 0 || a < m);\r
54   // BOOST_STATIC_ASSERT(m == 0 || c < m);\r
55 \r
56   explicit linear_congruential(IntType x0 = 1)\r
57   { \r
58     seed(x0);\r
59 \r
60     // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope\r
61 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS\r
62     BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);\r
63 #endif\r
64   }\r
65 \r
66   template<class It>\r
67   linear_congruential(It& first, It last)\r
68   {\r
69       seed(first, last);\r
70   }\r
71 \r
72   // compiler-generated copy constructor and assignment operator are fine\r
73   void seed(IntType x0 = 1)\r
74   {\r
75     // wrap _x if it doesn't fit in the destination\r
76     if(modulus == 0) {\r
77       _x = x0;\r
78     } else {\r
79       _x = x0 % modulus;\r
80     }\r
81     // handle negative seeds\r
82     if(_x <= 0 && _x != 0) {\r
83       _x += modulus;\r
84     }\r
85     // adjust to the correct range\r
86     if(increment == 0 && _x == 0) {\r
87       _x = 1;\r
88     }\r
89     assert(_x >= (min)());\r
90     assert(_x <= (max)());\r
91   }\r
92 \r
93   template<class It>\r
94   void seed(It& first, It last)\r
95   {\r
96     if(first == last)\r
97       throw std::invalid_argument("linear_congruential::seed");\r
98     seed(*first++);\r
99   }\r
100 \r
101   result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return c == 0 ? 1 : 0; }\r
102   result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return modulus-1; }\r
103 \r
104   IntType operator()()\r
105   {\r
106     _x = const_mod<IntType, m>::mult_add(a, _x, c);\r
107     return _x;\r
108   }\r
109 \r
110   static bool validation(IntType x) { return val == x; }\r
111 \r
112 #ifdef BOOST_NO_OPERATORS_IN_NAMESPACE\r
113     \r
114   // Use a member function; Streamable concept not supported.\r
115   bool operator==(const linear_congruential& rhs) const\r
116   { return _x == rhs._x; }\r
117   bool operator!=(const linear_congruential& rhs) const\r
118   { return !(*this == rhs); }\r
119 \r
120 #else \r
121   friend bool operator==(const linear_congruential& x,\r
122                          const linear_congruential& y)\r
123   { return x._x == y._x; }\r
124   friend bool operator!=(const linear_congruential& x,\r
125                          const linear_congruential& y)\r
126   { return !(x == y); }\r
127     \r
128 #if !defined(BOOST_RANDOM_NO_STREAM_OPERATORS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))\r
129   template<class CharT, class Traits>\r
130   friend std::basic_ostream<CharT,Traits>&\r
131   operator<<(std::basic_ostream<CharT,Traits>& os,\r
132              const linear_congruential& lcg)\r
133   {\r
134     return os << lcg._x;\r
135   }\r
136 \r
137   template<class CharT, class Traits>\r
138   friend std::basic_istream<CharT,Traits>&\r
139   operator>>(std::basic_istream<CharT,Traits>& is,\r
140              linear_congruential& lcg)\r
141   {\r
142     return is >> lcg._x;\r
143   }\r
144  \r
145 private:\r
146 #endif\r
147 #endif\r
148 \r
149   IntType _x;\r
150 };\r
151 \r
152 // probably needs the "no native streams" caveat for STLPort\r
153 #if !defined(__SGI_STL_PORT) && BOOST_WORKAROUND(__GNUC__, == 2)\r
154 template<class IntType, IntType a, IntType c, IntType m, IntType val>\r
155 std::ostream&\r
156 operator<<(std::ostream& os,\r
157            const linear_congruential<IntType,a,c,m,val>& lcg)\r
158 {\r
159     return os << lcg._x;\r
160 }\r
161 \r
162 template<class IntType, IntType a, IntType c, IntType m, IntType val>\r
163 std::istream&\r
164 operator>>(std::istream& is,\r
165            linear_congruential<IntType,a,c,m,val>& lcg)\r
166 {\r
167     return is >> lcg._x;\r
168 }\r
169 #elif defined(BOOST_RANDOM_NO_STREAM_OPERATORS) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))\r
170 template<class CharT, class Traits, class IntType, IntType a, IntType c, IntType m, IntType val>\r
171 std::basic_ostream<CharT,Traits>&\r
172 operator<<(std::basic_ostream<CharT,Traits>& os,\r
173            const linear_congruential<IntType,a,c,m,val>& lcg)\r
174 {\r
175     return os << lcg._x;\r
176 }\r
177 \r
178 template<class CharT, class Traits, class IntType, IntType a, IntType c, IntType m, IntType val>\r
179 std::basic_istream<CharT,Traits>&\r
180 operator>>(std::basic_istream<CharT,Traits>& is,\r
181            linear_congruential<IntType,a,c,m,val>& lcg)\r
182 {\r
183     return is >> lcg._x;\r
184 }\r
185 #endif\r
186 \r
187 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION\r
188 //  A definition is required even for integral static constants\r
189 template<class IntType, IntType a, IntType c, IntType m, IntType val>\r
190 const bool linear_congruential<IntType, a, c, m, val>::has_fixed_range;\r
191 template<class IntType, IntType a, IntType c, IntType m, IntType val>\r
192 const typename linear_congruential<IntType, a, c, m, val>::result_type linear_congruential<IntType, a, c, m, val>::min_value;\r
193 template<class IntType, IntType a, IntType c, IntType m, IntType val>\r
194 const typename linear_congruential<IntType, a, c, m, val>::result_type linear_congruential<IntType, a, c, m, val>::max_value;\r
195 template<class IntType, IntType a, IntType c, IntType m, IntType val>\r
196 const IntType linear_congruential<IntType,a,c,m,val>::modulus;\r
197 #endif\r
198 \r
199 } // namespace random\r
200 \r
201 // validation values from the publications\r
202 typedef random::linear_congruential<int32_t, 16807, 0, 2147483647, \r
203   1043618065> minstd_rand0;\r
204 typedef random::linear_congruential<int32_t, 48271, 0, 2147483647,\r
205   399268537> minstd_rand;\r
206 \r
207 \r
208 #if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)\r
209 // emulate the lrand48() C library function; requires support for uint64_t\r
210 class rand48 \r
211 {\r
212 public:\r
213   typedef int32_t result_type;\r
214 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION\r
215   static const bool has_fixed_range = true;\r
216   static const int32_t min_value = 0;\r
217   static const int32_t max_value = integer_traits<int32_t>::const_max;\r
218 #else\r
219   enum { has_fixed_range = false };\r
220 #endif\r
221   int32_t min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }\r
222   int32_t max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::numeric_limits<int32_t>::max BOOST_PREVENT_MACRO_SUBSTITUTION (); }\r
223   \r
224   rand48() : lcf(cnv(static_cast<int32_t>(1))) {}\r
225   template<class T> explicit rand48(T x0) : lcf(cnv(x0)) { }\r
226   template<class It> rand48(It& first, It last) : lcf(first, last) { }\r
227   // compiler-generated copy ctor and assignment operator are fine\r
228   void seed() { seed(static_cast<int32_t>(1)); }\r
229   template<class T> void seed(T x0) { lcf.seed(cnv(x0)); }\r
230   template<class It> void seed(It& first, It last) { lcf.seed(first,last); }\r
231 \r
232   int32_t operator()() { return static_cast<int32_t>(lcf() >> 17); }\r
233   // by experiment from lrand48()\r
234   static bool validation(int32_t x) { return x == 1993516219; }\r
235 \r
236 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE\r
237 \r
238 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS\r
239   template<class CharT,class Traits>\r
240   friend std::basic_ostream<CharT,Traits>&\r
241   operator<<(std::basic_ostream<CharT,Traits>& os, const rand48& r)\r
242   { os << r.lcf; return os; }\r
243 \r
244   template<class CharT,class Traits>\r
245   friend std::basic_istream<CharT,Traits>&\r
246   operator>>(std::basic_istream<CharT,Traits>& is, rand48& r)\r
247   { is >> r.lcf; return is; }\r
248 #endif\r
249 \r
250   friend bool operator==(const rand48& x, const rand48& y)\r
251   { return x.lcf == y.lcf; }\r
252   friend bool operator!=(const rand48& x, const rand48& y)\r
253   { return !(x == y); }\r
254 #else\r
255   // Use a member function; Streamable concept not supported.\r
256   bool operator==(const rand48& rhs) const\r
257   { return lcf == rhs.lcf; }\r
258   bool operator!=(const rand48& rhs) const\r
259   { return !(*this == rhs); }\r
260 #endif\r
261 private:\r
262   random::linear_congruential<uint64_t,\r
263     uint64_t(0xDEECE66DUL) | (uint64_t(0x5) << 32), // xxxxULL is not portable\r
264     0xB, uint64_t(1)<<48, /* unknown */ 0> lcf;\r
265   template<class T>\r
266   static uint64_t cnv(T x) \r
267   {\r
268     if(sizeof(T) < sizeof(uint64_t)) {\r
269       return (static_cast<uint64_t>(x) << 16) | 0x330e;\r
270     } else {\r
271       return(static_cast<uint64_t>(x));\r
272     }\r
273   }\r
274   static uint64_t cnv(float x) { return(static_cast<uint64_t>(x)); }\r
275   static uint64_t cnv(double x) { return(static_cast<uint64_t>(x)); }\r
276   static uint64_t cnv(long double x) { return(static_cast<uint64_t>(x)); }\r
277 };\r
278 #endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */\r
279 \r
280 } // namespace boost\r
281 \r
282 #include <boost/random/detail/enable_warnings.hpp>\r
283 \r
284 #endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP\r