1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// REQUIRES: long_tests
11
12// <random>
13
14// template<class _IntType = int>
15// class uniform_int_distribution
16
17// template<class _URNG> result_type operator()(_URNG& g);
18
19#include <random>
20#include <cassert>
21#include <vector>
22#include <numeric>
23#include <cstddef>
24
25template <class T>
26inline
27T
28sqr(T x)
29{
30    return x * x;
31}
32
33int main()
34{
35    {
36        typedef std::uniform_int_distribution<> D;
37        typedef std::minstd_rand0 G;
38        G g;
39        D d;
40        const int N = 100000;
41        std::vector<D::result_type> u;
42        for (int i = 0; i < N; ++i)
43        {
44            D::result_type v = d(g);
45            assert(d.a() <= v && v <= d.b());
46            u.push_back(v);
47        }
48        double mean = std::accumulate(u.begin(), u.end(),
49                                              double(0)) / u.size();
50        double var = 0;
51        double skew = 0;
52        double kurtosis = 0;
53        for (std::size_t i = 0; i < u.size(); ++i)
54        {
55            double dbl = (u[i] - mean);
56            double d2 = sqr(dbl);
57            var += d2;
58            skew += dbl * d2;
59            kurtosis += d2 * d2;
60        }
61        var /= u.size();
62        double dev = std::sqrt(var);
63        skew /= u.size() * dev * var;
64        kurtosis /= u.size() * var * var;
65        kurtosis -= 3;
66        double x_mean = ((double)d.a() + d.b()) / 2;
67        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
68        double x_skew = 0;
69        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
70                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
71        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
72        assert(std::abs((var - x_var) / x_var) < 0.01);
73        assert(std::abs(skew - x_skew) < 0.01);
74        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
75    }
76    {
77        typedef std::uniform_int_distribution<> D;
78        typedef std::minstd_rand G;
79        G g;
80        D d;
81        const int N = 100000;
82        std::vector<D::result_type> u;
83        for (int i = 0; i < N; ++i)
84        {
85            D::result_type v = d(g);
86            assert(d.a() <= v && v <= d.b());
87            u.push_back(v);
88        }
89        double mean = std::accumulate(u.begin(), u.end(),
90                                              double(0)) / u.size();
91        double var = 0;
92        double skew = 0;
93        double kurtosis = 0;
94        for (std::size_t i = 0; i < u.size(); ++i)
95        {
96            double dbl = (u[i] - mean);
97            double d2 = sqr(dbl);
98            var += d2;
99            skew += dbl * d2;
100            kurtosis += d2 * d2;
101        }
102        var /= u.size();
103        double dev = std::sqrt(var);
104        skew /= u.size() * dev * var;
105        kurtosis /= u.size() * var * var;
106        kurtosis -= 3;
107        double x_mean = ((double)d.a() + d.b()) / 2;
108        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
109        double x_skew = 0;
110        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
111                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
112        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
113        assert(std::abs((var - x_var) / x_var) < 0.01);
114        assert(std::abs(skew - x_skew) < 0.01);
115        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
116    }
117    {
118        typedef std::uniform_int_distribution<> D;
119        typedef std::mt19937 G;
120        G g;
121        D d;
122        const int N = 100000;
123        std::vector<D::result_type> u;
124        for (int i = 0; i < N; ++i)
125        {
126            D::result_type v = d(g);
127            assert(d.a() <= v && v <= d.b());
128            u.push_back(v);
129        }
130        double mean = std::accumulate(u.begin(), u.end(),
131                                              double(0)) / u.size();
132        double var = 0;
133        double skew = 0;
134        double kurtosis = 0;
135        for (std::size_t i = 0; i < u.size(); ++i)
136        {
137            double dbl = (u[i] - mean);
138            double d2 = sqr(dbl);
139            var += d2;
140            skew += dbl * d2;
141            kurtosis += d2 * d2;
142        }
143        var /= u.size();
144        double dev = std::sqrt(var);
145        skew /= u.size() * dev * var;
146        kurtosis /= u.size() * var * var;
147        kurtosis -= 3;
148        double x_mean = ((double)d.a() + d.b()) / 2;
149        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
150        double x_skew = 0;
151        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
152                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
153        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
154        assert(std::abs((var - x_var) / x_var) < 0.01);
155        assert(std::abs(skew - x_skew) < 0.01);
156        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
157    }
158    {
159        typedef std::uniform_int_distribution<> D;
160        typedef std::mt19937_64 G;
161        G g;
162        D d;
163        const int N = 100000;
164        std::vector<D::result_type> u;
165        for (int i = 0; i < N; ++i)
166        {
167            D::result_type v = d(g);
168            assert(d.a() <= v && v <= d.b());
169            u.push_back(v);
170        }
171        double mean = std::accumulate(u.begin(), u.end(),
172                                              double(0)) / u.size();
173        double var = 0;
174        double skew = 0;
175        double kurtosis = 0;
176        for (std::size_t i = 0; i < u.size(); ++i)
177        {
178            double dbl = (u[i] - mean);
179            double d2 = sqr(dbl);
180            var += d2;
181            skew += dbl * d2;
182            kurtosis += d2 * d2;
183        }
184        var /= u.size();
185        double dev = std::sqrt(var);
186        skew /= u.size() * dev * var;
187        kurtosis /= u.size() * var * var;
188        kurtosis -= 3;
189        double x_mean = ((double)d.a() + d.b()) / 2;
190        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
191        double x_skew = 0;
192        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
193                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
194        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
195        assert(std::abs((var - x_var) / x_var) < 0.01);
196        assert(std::abs(skew - x_skew) < 0.01);
197        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
198    }
199    {
200        typedef std::uniform_int_distribution<> D;
201        typedef std::ranlux24_base G;
202        G g;
203        D d;
204        const int N = 100000;
205        std::vector<D::result_type> u;
206        for (int i = 0; i < N; ++i)
207        {
208            D::result_type v = d(g);
209            assert(d.a() <= v && v <= d.b());
210            u.push_back(v);
211        }
212        double mean = std::accumulate(u.begin(), u.end(),
213                                              double(0)) / u.size();
214        double var = 0;
215        double skew = 0;
216        double kurtosis = 0;
217        for (std::size_t i = 0; i < u.size(); ++i)
218        {
219            double dbl = (u[i] - mean);
220            double d2 = sqr(dbl);
221            var += d2;
222            skew += dbl * d2;
223            kurtosis += d2 * d2;
224        }
225        var /= u.size();
226        double dev = std::sqrt(var);
227        skew /= u.size() * dev * var;
228        kurtosis /= u.size() * var * var;
229        kurtosis -= 3;
230        double x_mean = ((double)d.a() + d.b()) / 2;
231        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
232        double x_skew = 0;
233        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
234                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
235        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
236        assert(std::abs((var - x_var) / x_var) < 0.01);
237        assert(std::abs(skew - x_skew) < 0.01);
238        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
239    }
240    {
241        typedef std::uniform_int_distribution<> D;
242        typedef std::ranlux48_base G;
243        G g;
244        D d;
245        const int N = 100000;
246        std::vector<D::result_type> u;
247        for (int i = 0; i < N; ++i)
248        {
249            D::result_type v = d(g);
250            assert(d.a() <= v && v <= d.b());
251            u.push_back(v);
252        }
253        double mean = std::accumulate(u.begin(), u.end(),
254                                              double(0)) / u.size();
255        double var = 0;
256        double skew = 0;
257        double kurtosis = 0;
258        for (std::size_t i = 0; i < u.size(); ++i)
259        {
260            double dbl = (u[i] - mean);
261            double d2 = sqr(dbl);
262            var += d2;
263            skew += dbl * d2;
264            kurtosis += d2 * d2;
265        }
266        var /= u.size();
267        double dev = std::sqrt(var);
268        skew /= u.size() * dev * var;
269        kurtosis /= u.size() * var * var;
270        kurtosis -= 3;
271        double x_mean = ((double)d.a() + d.b()) / 2;
272        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
273        double x_skew = 0;
274        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
275                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
276        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
277        assert(std::abs((var - x_var) / x_var) < 0.01);
278        assert(std::abs(skew - x_skew) < 0.01);
279        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
280    }
281    {
282        typedef std::uniform_int_distribution<> D;
283        typedef std::ranlux24 G;
284        G g;
285        D d;
286        const int N = 100000;
287        std::vector<D::result_type> u;
288        for (int i = 0; i < N; ++i)
289        {
290            D::result_type v = d(g);
291            assert(d.a() <= v && v <= d.b());
292            u.push_back(v);
293        }
294        double mean = std::accumulate(u.begin(), u.end(),
295                                              double(0)) / u.size();
296        double var = 0;
297        double skew = 0;
298        double kurtosis = 0;
299        for (std::size_t i = 0; i < u.size(); ++i)
300        {
301            double dbl = (u[i] - mean);
302            double d2 = sqr(dbl);
303            var += d2;
304            skew += dbl * d2;
305            kurtosis += d2 * d2;
306        }
307        var /= u.size();
308        double dev = std::sqrt(var);
309        skew /= u.size() * dev * var;
310        kurtosis /= u.size() * var * var;
311        kurtosis -= 3;
312        double x_mean = ((double)d.a() + d.b()) / 2;
313        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
314        double x_skew = 0;
315        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
316                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
317        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
318        assert(std::abs((var - x_var) / x_var) < 0.01);
319        assert(std::abs(skew - x_skew) < 0.01);
320        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
321    }
322    {
323        typedef std::uniform_int_distribution<> D;
324        typedef std::ranlux48 G;
325        G g;
326        D d;
327        const int N = 100000;
328        std::vector<D::result_type> u;
329        for (int i = 0; i < N; ++i)
330        {
331            D::result_type v = d(g);
332            assert(d.a() <= v && v <= d.b());
333            u.push_back(v);
334        }
335        double mean = std::accumulate(u.begin(), u.end(),
336                                              double(0)) / u.size();
337        double var = 0;
338        double skew = 0;
339        double kurtosis = 0;
340        for (std::size_t i = 0; i < u.size(); ++i)
341        {
342            double dbl = (u[i] - mean);
343            double d2 = sqr(dbl);
344            var += d2;
345            skew += dbl * d2;
346            kurtosis += d2 * d2;
347        }
348        var /= u.size();
349        double dev = std::sqrt(var);
350        skew /= u.size() * dev * var;
351        kurtosis /= u.size() * var * var;
352        kurtosis -= 3;
353        double x_mean = ((double)d.a() + d.b()) / 2;
354        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
355        double x_skew = 0;
356        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
357                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
358        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
359        assert(std::abs((var - x_var) / x_var) < 0.01);
360        assert(std::abs(skew - x_skew) < 0.01);
361        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
362    }
363    {
364        typedef std::uniform_int_distribution<> D;
365        typedef std::knuth_b G;
366        G g;
367        D d;
368        const int N = 100000;
369        std::vector<D::result_type> u;
370        for (int i = 0; i < N; ++i)
371        {
372            D::result_type v = d(g);
373            assert(d.a() <= v && v <= d.b());
374            u.push_back(v);
375        }
376        double mean = std::accumulate(u.begin(), u.end(),
377                                              double(0)) / u.size();
378        double var = 0;
379        double skew = 0;
380        double kurtosis = 0;
381        for (std::size_t i = 0; i < u.size(); ++i)
382        {
383            double dbl = (u[i] - mean);
384            double d2 = sqr(dbl);
385            var += d2;
386            skew += dbl * d2;
387            kurtosis += d2 * d2;
388        }
389        var /= u.size();
390        double dev = std::sqrt(var);
391        skew /= u.size() * dev * var;
392        kurtosis /= u.size() * var * var;
393        kurtosis -= 3;
394        double x_mean = ((double)d.a() + d.b()) / 2;
395        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
396        double x_skew = 0;
397        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
398                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
399        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
400        assert(std::abs((var - x_var) / x_var) < 0.01);
401        assert(std::abs(skew - x_skew) < 0.01);
402        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
403    }
404    {
405        typedef std::uniform_int_distribution<> D;
406        typedef std::minstd_rand0 G;
407        G g;
408        D d(-6, 106);
409        for (int i = 0; i < 10000; ++i)
410        {
411            int u = d(g);
412            assert(-6 <= u && u <= 106);
413        }
414    }
415    {
416        typedef std::uniform_int_distribution<> D;
417        typedef std::minstd_rand G;
418        G g;
419        D d(5, 100);
420        const int N = 100000;
421        std::vector<D::result_type> u;
422        for (int i = 0; i < N; ++i)
423        {
424            D::result_type v = d(g);
425            assert(d.a() <= v && v <= d.b());
426            u.push_back(v);
427        }
428        double mean = std::accumulate(u.begin(), u.end(),
429                                              double(0)) / u.size();
430        double var = 0;
431        double skew = 0;
432        double kurtosis = 0;
433        for (std::size_t i = 0; i < u.size(); ++i)
434        {
435            double dbl = (u[i] - mean);
436            double d2 = sqr(dbl);
437            var += d2;
438            skew += dbl * d2;
439            kurtosis += d2 * d2;
440        }
441        var /= u.size();
442        double dev = std::sqrt(var);
443        skew /= u.size() * dev * var;
444        kurtosis /= u.size() * var * var;
445        kurtosis -= 3;
446        double x_mean = ((double)d.a() + d.b()) / 2;
447        double x_var = (sqr((double)d.b() - d.a() + 1) - 1) / 12;
448        double x_skew = 0;
449        double x_kurtosis = -6. * (sqr((double)d.b() - d.a() + 1) + 1) /
450                            (5. * (sqr((double)d.b() - d.a() + 1) - 1));
451        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
452        assert(std::abs((var - x_var) / x_var) < 0.01);
453        assert(std::abs(skew - x_skew) < 0.01);
454        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
455    }
456}
457