1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // <random> |
10 | |
11 | // template<class _IntType = int> |
12 | // class uniform_int_distribution |
13 | |
14 | // template<class _URNG> result_type operator()(_URNG& g, const param_type& parm); |
15 | |
16 | #include <random> |
17 | #include <cassert> |
18 | #include <vector> |
19 | #include <numeric> |
20 | #include <cstddef> |
21 | |
22 | #include "test_macros.h" |
23 | |
24 | template <class T> |
25 | inline |
26 | T |
27 | sqr(T x) |
28 | { |
29 | return x * x; |
30 | } |
31 | |
32 | int main(int, char**) |
33 | { |
34 | { |
35 | typedef std::uniform_int_distribution<> D; |
36 | typedef std::minstd_rand G; |
37 | typedef D::param_type P; |
38 | G g; |
39 | D d(5, 100); |
40 | P p(-10, 20); |
41 | const int N = 100000; |
42 | std::vector<D::result_type> u; |
43 | for (int i = 0; i < N; ++i) |
44 | { |
45 | D::result_type v = d(g, p); |
46 | assert(p.a() <= v && v <= p.b()); |
47 | u.push_back(v); |
48 | } |
49 | double mean = std::accumulate(u.begin(), u.end(), |
50 | double(0)) / u.size(); |
51 | double var = 0; |
52 | double skew = 0; |
53 | double kurtosis = 0; |
54 | for (std::size_t i = 0; i < u.size(); ++i) |
55 | { |
56 | double dbl = (u[i] - mean); |
57 | double d2 = sqr(dbl); |
58 | var += d2; |
59 | skew += dbl * d2; |
60 | kurtosis += d2 * d2; |
61 | } |
62 | var /= u.size(); |
63 | double dev = std::sqrt(x: var); |
64 | skew /= u.size() * dev * var; |
65 | kurtosis /= u.size() * var * var; |
66 | kurtosis -= 3; |
67 | double x_mean = ((double)p.a() + p.b()) / 2; |
68 | double x_var = (sqr((double)p.b() - p.a() + 1) - 1) / 12; |
69 | double x_skew = 0; |
70 | double x_kurtosis = -6. * (sqr((double)p.b() - p.a() + 1) + 1) / |
71 | (5. * (sqr((double)p.b() - p.a() + 1) - 1)); |
72 | assert(std::abs((mean - x_mean) / x_mean) < 0.01); |
73 | assert(std::abs((var - x_var) / x_var) < 0.01); |
74 | assert(std::abs(skew - x_skew) < 0.01); |
75 | assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); |
76 | } |
77 | |
78 | return 0; |
79 | } |
80 | |