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