1 | // (C) Copyright John Maddock 2005. |
---|
2 | // Use, modification and distribution are subject to the |
---|
3 | // Boost Software License, Version 1.0. (See accompanying file |
---|
4 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
---|
5 | |
---|
6 | #ifdef TEST_STD_HEADERS |
---|
7 | #include <random> |
---|
8 | #else |
---|
9 | #include <boost/tr1/random.hpp> |
---|
10 | #endif |
---|
11 | |
---|
12 | #include <boost/type_traits/is_arithmetic.hpp> |
---|
13 | #include <boost/static_assert.hpp> |
---|
14 | #include "verify_return.hpp" |
---|
15 | #include <iostream> |
---|
16 | |
---|
17 | template <class T> |
---|
18 | void check_uniform(T*) |
---|
19 | { |
---|
20 | typedef typename T::result_type result_type; |
---|
21 | BOOST_STATIC_ASSERT(::boost::is_arithmetic<result_type>::value); |
---|
22 | |
---|
23 | T t; |
---|
24 | result_type r = 0; |
---|
25 | verify_return_type((t.min)(), r); |
---|
26 | verify_return_type((t.max)(), r); |
---|
27 | verify_return_type(t(), r); |
---|
28 | } |
---|
29 | |
---|
30 | struct seed_architype |
---|
31 | { |
---|
32 | typedef unsigned result_type; |
---|
33 | unsigned operator()()const |
---|
34 | { |
---|
35 | return 0; |
---|
36 | } |
---|
37 | }; |
---|
38 | |
---|
39 | unsigned seed_proc(); |
---|
40 | |
---|
41 | class uniform_random_generator_architype |
---|
42 | { |
---|
43 | public: |
---|
44 | typedef unsigned long result_type; |
---|
45 | result_type operator()() |
---|
46 | { return 0; } |
---|
47 | result_type min BOOST_PREVENT_MACRO_SUBSTITUTION()const |
---|
48 | { return 0; } |
---|
49 | result_type max BOOST_PREVENT_MACRO_SUBSTITUTION()const |
---|
50 | { return 0; } |
---|
51 | |
---|
52 | static uniform_random_generator_architype& get() |
---|
53 | { |
---|
54 | static uniform_random_generator_architype r; |
---|
55 | return r; |
---|
56 | } |
---|
57 | private: |
---|
58 | uniform_random_generator_architype(); |
---|
59 | uniform_random_generator_architype(const uniform_random_generator_architype&); |
---|
60 | uniform_random_generator_architype& operator=(const uniform_random_generator_architype&); |
---|
61 | }; |
---|
62 | |
---|
63 | class pseudo_random_generator_architype |
---|
64 | { |
---|
65 | public: |
---|
66 | pseudo_random_generator_architype(){} |
---|
67 | pseudo_random_generator_architype(const pseudo_random_generator_architype&){} |
---|
68 | pseudo_random_generator_architype& operator=(const pseudo_random_generator_architype&) |
---|
69 | { return *this; } |
---|
70 | |
---|
71 | typedef unsigned long result_type; |
---|
72 | result_type operator()() |
---|
73 | { return 0; } |
---|
74 | result_type min BOOST_PREVENT_MACRO_SUBSTITUTION()const |
---|
75 | { return 0; } |
---|
76 | result_type max BOOST_PREVENT_MACRO_SUBSTITUTION()const |
---|
77 | { return 0; } |
---|
78 | |
---|
79 | pseudo_random_generator_architype(unsigned long){} |
---|
80 | template <class Gen> pseudo_random_generator_architype(Gen&){} |
---|
81 | void seed(){} |
---|
82 | void seed(unsigned long){} |
---|
83 | template <class Gen> void seed(Gen&){} |
---|
84 | |
---|
85 | bool operator == (const pseudo_random_generator_architype&)const |
---|
86 | { return false; } |
---|
87 | bool operator != (const pseudo_random_generator_architype&)const |
---|
88 | { return false; } |
---|
89 | |
---|
90 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) |
---|
91 | template<class CharT, class Traits> |
---|
92 | friend std::basic_ostream<CharT,Traits>& |
---|
93 | operator<<(std::basic_ostream<CharT,Traits>& os, |
---|
94 | const pseudo_random_generator_architype& lcg) |
---|
95 | { |
---|
96 | return os; |
---|
97 | } |
---|
98 | |
---|
99 | template<class CharT, class Traits> |
---|
100 | friend std::basic_istream<CharT,Traits>& |
---|
101 | operator>>(std::basic_istream<CharT,Traits>& is, |
---|
102 | pseudo_random_generator_architype& lcg) |
---|
103 | { |
---|
104 | return is; |
---|
105 | } |
---|
106 | #endif |
---|
107 | }; |
---|
108 | |
---|
109 | class random_distribution_architype |
---|
110 | { |
---|
111 | public: |
---|
112 | random_distribution_architype(){} |
---|
113 | random_distribution_architype(const random_distribution_architype&){} |
---|
114 | random_distribution_architype& operator=(const random_distribution_architype&) |
---|
115 | { return *this; } |
---|
116 | |
---|
117 | typedef unsigned input_type; |
---|
118 | typedef double result_type; |
---|
119 | |
---|
120 | void reset(){} |
---|
121 | |
---|
122 | template <class U> |
---|
123 | result_type operator()(U& u) |
---|
124 | { |
---|
125 | return u(); |
---|
126 | } |
---|
127 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) |
---|
128 | template<class CharT, class Traits> |
---|
129 | friend std::basic_ostream<CharT,Traits>& |
---|
130 | operator<<(std::basic_ostream<CharT,Traits>& os, |
---|
131 | const random_distribution_architype& lcg) |
---|
132 | { |
---|
133 | return os; |
---|
134 | } |
---|
135 | |
---|
136 | template<class CharT, class Traits> |
---|
137 | friend std::basic_istream<CharT,Traits>& |
---|
138 | operator>>(std::basic_istream<CharT,Traits>& is, |
---|
139 | random_distribution_architype& lcg) |
---|
140 | { |
---|
141 | return is; |
---|
142 | } |
---|
143 | #endif |
---|
144 | }; |
---|
145 | |
---|
146 | |
---|
147 | template <class T> |
---|
148 | void check_pseudo_random(T* p) |
---|
149 | { |
---|
150 | typedef typename T::result_type result_type; |
---|
151 | check_uniform(p); |
---|
152 | T t1; |
---|
153 | T t2(t1); |
---|
154 | t1 = t2; |
---|
155 | unsigned long s = 0; |
---|
156 | T t3(s); |
---|
157 | seed_architype seed; |
---|
158 | T t4(seed); |
---|
159 | t1.seed(); |
---|
160 | t1.seed(s); |
---|
161 | t1.seed(seed); |
---|
162 | T t5(seed_proc); |
---|
163 | t1.seed(seed_proc); |
---|
164 | const T& x = t1; |
---|
165 | const T& y = t2; |
---|
166 | verify_return_type(x == y, true); |
---|
167 | verify_return_type(x == y, false); |
---|
168 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) |
---|
169 | std::cout << t1; |
---|
170 | std::cin >> t1; |
---|
171 | #endif |
---|
172 | } |
---|
173 | |
---|
174 | template <class T> |
---|
175 | void check_random_distribution(T* pd) |
---|
176 | { |
---|
177 | T t1(*pd); |
---|
178 | t1 = *pd; |
---|
179 | uniform_random_generator_architype& gen = uniform_random_generator_architype::get(); |
---|
180 | typedef typename T::input_type input_type; |
---|
181 | typedef typename T::result_type result_type; |
---|
182 | t1.reset(); |
---|
183 | verify_return_type(t1(gen), result_type()); |
---|
184 | const T& ct = t1; |
---|
185 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) |
---|
186 | std::cout << ct << std::endl; |
---|
187 | std::cin >> t1 >> std::ws; |
---|
188 | #endif |
---|
189 | } |
---|
190 | |
---|
191 | template <class VG> |
---|
192 | void check_generator(VG* g) |
---|
193 | { |
---|
194 | typedef typename VG::engine_type engine_type; |
---|
195 | typedef typename VG::engine_value_type engine_value_type; |
---|
196 | typedef typename VG::distribution_type distribution_type; |
---|
197 | typedef typename distribution_type::input_type input_type; |
---|
198 | typedef typename VG::result_type result_type; |
---|
199 | verify_return_type((*g)(), result_type(0)); |
---|
200 | const VG* cg = g; |
---|
201 | verify_return_type(&g->engine(), static_cast<engine_value_type*>(0)); |
---|
202 | verify_return_type(&cg->engine(), static_cast<const engine_value_type*>(0)); |
---|
203 | verify_return_type(&g->distribution(), static_cast<distribution_type*>(0)); |
---|
204 | verify_return_type(&cg->distribution(), static_cast<const distribution_type*>(0)); |
---|
205 | } |
---|
206 | |
---|
207 | template <class VG> |
---|
208 | void check_generator_extended(VG* g) |
---|
209 | { |
---|
210 | typedef typename VG::engine_type engine_type; |
---|
211 | typedef typename VG::engine_value_type engine_value_type; |
---|
212 | typedef typename VG::distribution_type distribution_type; |
---|
213 | typedef typename distribution_type::input_type input_type; |
---|
214 | typedef typename VG::result_type result_type; |
---|
215 | //verify_return_type((*g)(input_type(0)), result_type(0)); |
---|
216 | const VG* cg = g; |
---|
217 | verify_return_type((cg->min)(), result_type(0)); |
---|
218 | verify_return_type((cg->max)(), result_type(0)); |
---|
219 | } |
---|
220 | |
---|
221 | int main() |
---|
222 | { |
---|
223 | typedef std::tr1::linear_congruential< ::boost::int32_t, 16807, 0, 2147483647> lc_t; |
---|
224 | lc_t lc; |
---|
225 | BOOST_STATIC_ASSERT(lc_t::multiplier == 16807); |
---|
226 | BOOST_STATIC_ASSERT(lc_t::increment == 0); |
---|
227 | BOOST_STATIC_ASSERT(lc_t::modulus == 2147483647); |
---|
228 | check_pseudo_random(&lc); |
---|
229 | |
---|
230 | typedef std::tr1::mersenne_twister< ::boost::uint32_t,32,351,175,19,0xccab8ee7,11,7,0x31b6ab00,15,0xffe50000,17> mt11213b; |
---|
231 | mt11213b mt; |
---|
232 | check_pseudo_random(&mt); |
---|
233 | |
---|
234 | typedef std::tr1::subtract_with_carry< ::boost::int32_t, 24, 10, 24> sub_t; |
---|
235 | sub_t sub; |
---|
236 | check_pseudo_random(&sub); |
---|
237 | |
---|
238 | typedef std::tr1::subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01; |
---|
239 | ranlux_base_01 rl1; |
---|
240 | check_pseudo_random(&rl1); |
---|
241 | typedef std::tr1::subtract_with_carry_01<double, 48, 10, 24> ranlux64_base_01; |
---|
242 | ranlux64_base_01 rl2; |
---|
243 | check_pseudo_random(&rl2); |
---|
244 | |
---|
245 | typedef std::tr1::discard_block< std::tr1::subtract_with_carry< ::boost::int32_t , (1<<24), 10, 24>, 223, 24> ranlux3; |
---|
246 | ranlux3 rl3; |
---|
247 | check_pseudo_random(&rl3); |
---|
248 | |
---|
249 | std::tr1::xor_combine<pseudo_random_generator_architype, 0, pseudo_random_generator_architype, 1> xorc; |
---|
250 | check_pseudo_random(&xorc); |
---|
251 | verify_return_type(xorc.base1(), pseudo_random_generator_architype()); |
---|
252 | verify_return_type(xorc.base2(), pseudo_random_generator_architype()); |
---|
253 | |
---|
254 | #ifndef __SUNPRO_CC |
---|
255 | // we don't normally allow workarounds in here, but this |
---|
256 | // class is unsupported on this platform. |
---|
257 | std::tr1::random_device d; |
---|
258 | check_uniform(&d); |
---|
259 | verify_return_type(d.entropy(), double(0)); |
---|
260 | #endif |
---|
261 | |
---|
262 | uniform_random_generator_architype& gen = uniform_random_generator_architype::get(); |
---|
263 | std::tr1::uniform_int<unsigned long> ui; |
---|
264 | check_random_distribution(&ui); |
---|
265 | typedef std::tr1::uniform_int<unsigned long>::result_type ui_r_t; |
---|
266 | verify_return_type((ui.min)(), ui_r_t()); |
---|
267 | verify_return_type((ui.max)(), ui_r_t()); |
---|
268 | //verify_return_type(ui(gen, ui_r_t()), ui_r_t()); |
---|
269 | |
---|
270 | std::tr1::bernoulli_distribution bd; |
---|
271 | verify_return_type(bd.p(), double(0)); |
---|
272 | check_random_distribution(&bd); |
---|
273 | |
---|
274 | std::tr1::geometric_distribution<> gd; |
---|
275 | verify_return_type(gd.p(), double(0)); |
---|
276 | check_random_distribution(&gd); |
---|
277 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::geometric_distribution<>::result_type, int>::value)); |
---|
278 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::geometric_distribution<>::input_type, double>::value)); |
---|
279 | std::tr1::geometric_distribution<long, double> gd2(0.5); |
---|
280 | verify_return_type(gd2.p(), double(0)); |
---|
281 | check_random_distribution(&gd2); |
---|
282 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::geometric_distribution<long, double>::result_type, long>::value)); |
---|
283 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::geometric_distribution<long, double>::input_type, double>::value)); |
---|
284 | |
---|
285 | std::tr1::poisson_distribution<> pd; |
---|
286 | verify_return_type(pd.mean(), double(0)); |
---|
287 | check_random_distribution(&pd); |
---|
288 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::poisson_distribution<>::result_type, int>::value)); |
---|
289 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::poisson_distribution<>::input_type, double>::value)); |
---|
290 | std::tr1::poisson_distribution<long, double> pd2(0.5); |
---|
291 | verify_return_type(pd2.mean(), double(0)); |
---|
292 | check_random_distribution(&pd2); |
---|
293 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::poisson_distribution<long, double>::result_type, long>::value)); |
---|
294 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::poisson_distribution<long, double>::input_type, double>::value)); |
---|
295 | |
---|
296 | std::tr1::binomial_distribution<> bind; |
---|
297 | verify_return_type(bind.p(), double(0)); |
---|
298 | verify_return_type(bind.t(), int(0)); |
---|
299 | check_random_distribution(&bind); |
---|
300 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::binomial_distribution<>::result_type, int>::value)); |
---|
301 | //BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::binomial_distribution<>::input_type, double>::value)); |
---|
302 | std::tr1::binomial_distribution<long, double> bind2(1, 0.5); |
---|
303 | verify_return_type(bind2.t(), long(0)); |
---|
304 | check_random_distribution(&bind2); |
---|
305 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::binomial_distribution<long, double>::result_type, long>::value)); |
---|
306 | //BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::binomial_distribution<long, double>::input_type, double>::value)); |
---|
307 | |
---|
308 | std::tr1::uniform_real<> urd; |
---|
309 | check_random_distribution(&urd); |
---|
310 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::uniform_real<>::result_type, double>::value)); |
---|
311 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::uniform_real<>::input_type, double>::value)); |
---|
312 | std::tr1::uniform_real<long double> urd2(0.5L, 1.5L); |
---|
313 | verify_return_type((urd2.min)(), (long double)(0)); |
---|
314 | verify_return_type((urd2.max)(), (long double)(0)); |
---|
315 | check_random_distribution(&urd2); |
---|
316 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::uniform_real<long double>::result_type, long double>::value)); |
---|
317 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::uniform_real<long double>::input_type, long double>::value)); |
---|
318 | |
---|
319 | std::tr1::exponential_distribution<> exd; |
---|
320 | check_random_distribution(&exd); |
---|
321 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::exponential_distribution<>::result_type, double>::value)); |
---|
322 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::exponential_distribution<>::input_type, double>::value)); |
---|
323 | std::tr1::exponential_distribution<long double> exd2(0.5L); |
---|
324 | verify_return_type(exd2.lambda(), (long double)(0)); |
---|
325 | check_random_distribution(&exd2); |
---|
326 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::exponential_distribution<long double>::result_type, long double>::value)); |
---|
327 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::exponential_distribution<long double>::input_type, long double>::value)); |
---|
328 | |
---|
329 | std::tr1::normal_distribution<> normd; |
---|
330 | check_random_distribution(&normd); |
---|
331 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::normal_distribution<>::result_type, double>::value)); |
---|
332 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::normal_distribution<>::input_type, double>::value)); |
---|
333 | std::tr1::normal_distribution<long double> normd2(0.5L, 0.1L); |
---|
334 | verify_return_type(normd2.mean(), (long double)(0)); |
---|
335 | verify_return_type(normd2.sigma(), (long double)(0)); |
---|
336 | check_random_distribution(&normd2); |
---|
337 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::normal_distribution<long double>::result_type, long double>::value)); |
---|
338 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::normal_distribution<long double>::input_type, long double>::value)); |
---|
339 | |
---|
340 | std::tr1::gamma_distribution<> gammad; |
---|
341 | check_random_distribution(&gammad); |
---|
342 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::gamma_distribution<>::result_type, double>::value)); |
---|
343 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::gamma_distribution<>::input_type, double>::value)); |
---|
344 | std::tr1::gamma_distribution<long double> gammad2(0.5L); |
---|
345 | verify_return_type(gammad2.alpha(), (long double)(0)); |
---|
346 | check_random_distribution(&gammad2); |
---|
347 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::gamma_distribution<long double>::result_type, long double>::value)); |
---|
348 | BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::gamma_distribution<long double>::input_type, long double>::value)); |
---|
349 | |
---|
350 | // |
---|
351 | // variate_generator: |
---|
352 | // |
---|
353 | std::tr1::variate_generator<uniform_random_generator_architype&, random_distribution_architype> vg1(uniform_random_generator_architype::get(), random_distribution_architype()); |
---|
354 | check_generator(&vg1); |
---|
355 | std::tr1::variate_generator<uniform_random_generator_architype&, std::tr1::uniform_int<> > vg2(uniform_random_generator_architype::get(), std::tr1::uniform_int<>()); |
---|
356 | check_generator_extended(&vg2); |
---|
357 | std::tr1::variate_generator<uniform_random_generator_architype*, std::tr1::uniform_int<> > vg3(&uniform_random_generator_architype::get(), std::tr1::uniform_int<>()); |
---|
358 | check_generator_extended(&vg3); |
---|
359 | return 0; |
---|
360 | } |
---|
361 | |
---|
362 | |
---|
363 | |
---|