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 // REQUIRES: long_tests
10 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
11 
12 // <random>
13 
14 // template<class IntType = int>
15 // class discrete_distribution
16 
17 // template<class _URNG> result_type operator()(_URNG& g);
18 
19 #include <cassert>
20 #include <cstdint>
21 #include <cstdlib>
22 #include <random>
23 #include <vector>
24 
25 #include "test_macros.h"
26 
27 template <class T>
tests()28 void tests() {
29     typedef long long Frequency;
30     {
31         typedef std::discrete_distribution<T> D;
32         typedef std::minstd_rand G;
33         G g;
34         D d;
35         const int N = 100;
36         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
37         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
38         for (int i = 0; i < N; ++i)
39         {
40             typename D::result_type v = d(g);
41             assert(d.min() <= v && v <= d.max());
42             u[static_cast<std::size_t>(v)]++;
43         }
44         std::vector<double> prob = d.probabilities();
45         for (unsigned i = 0; i < u.size(); ++i)
46             assert((double)u[i]/N == prob[i]);
47     }
48     {
49         typedef std::discrete_distribution<T> D;
50         typedef std::minstd_rand G;
51         G g;
52         double p0[] = {.3};
53         D d(p0, p0+1);
54         const int N = 100;
55         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
56         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
57         for (int i = 0; i < N; ++i)
58         {
59             typename D::result_type v = d(g);
60             assert(d.min() <= v && v <= d.max());
61             u[static_cast<std::size_t>(v)]++;
62         }
63         std::vector<double> prob = d.probabilities();
64         for (unsigned i = 0; i < u.size(); ++i)
65             assert((double)u[i]/N == prob[i]);
66     }
67     {
68         typedef std::discrete_distribution<T> D;
69         typedef std::minstd_rand G;
70         G g;
71         double p0[] = {.75, .25};
72         D d(p0, p0+2);
73         const int N = 1000000;
74         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
75         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
76         for (int i = 0; i < N; ++i)
77         {
78             typename D::result_type v = d(g);
79             assert(d.min() <= v && v <= d.max());
80             u[static_cast<std::size_t>(v)]++;
81         }
82         std::vector<double> prob = d.probabilities();
83         for (unsigned i = 0; i < u.size(); ++i)
84           assert(std::abs((double)u[i] / N - prob[i]) / prob[i] < 0.0013);
85     }
86     {
87         typedef std::discrete_distribution<T> D;
88         typedef std::minstd_rand G;
89         G g;
90         double p0[] = {0, 1};
91         D d(p0, p0+2);
92         const int N = 1000000;
93         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
94         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
95         for (int i = 0; i < N; ++i)
96         {
97             typename D::result_type v = d(g);
98             assert(d.min() <= v && v <= d.max());
99             u[static_cast<std::size_t>(v)]++;
100         }
101         std::vector<double> prob = d.probabilities();
102         assert((double)u[0]/N == prob[0]);
103         assert((double)u[1]/N == prob[1]);
104     }
105     {
106         typedef std::discrete_distribution<T> D;
107         typedef std::minstd_rand G;
108         G g;
109         double p0[] = {1, 0};
110         D d(p0, p0+2);
111         const int N = 1000000;
112         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
113         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
114         for (int i = 0; i < N; ++i)
115         {
116             typename D::result_type v = d(g);
117             assert(d.min() <= v && v <= d.max());
118             u[static_cast<std::size_t>(v)]++;
119         }
120         std::vector<double> prob = d.probabilities();
121         assert((double)u[0]/N == prob[0]);
122         assert((double)u[1]/N == prob[1]);
123     }
124     {
125         typedef std::discrete_distribution<T> D;
126         typedef std::minstd_rand G;
127         G g;
128         double p0[] = {.3, .1, .6};
129         D d(p0, p0+3);
130         const int N = 10000000;
131         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
132         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
133         for (int i = 0; i < N; ++i)
134         {
135             typename D::result_type v = d(g);
136             assert(d.min() <= v && v <= d.max());
137             u[static_cast<std::size_t>(v)]++;
138         }
139         std::vector<double> prob = d.probabilities();
140         for (unsigned i = 0; i < u.size(); ++i)
141             assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);
142     }
143     {
144         typedef std::discrete_distribution<T> D;
145         typedef std::minstd_rand G;
146         G g;
147         double p0[] = {0, 25, 75};
148         D d(p0, p0+3);
149         const int N = 1000000;
150         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
151         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
152         for (int i = 0; i < N; ++i)
153         {
154             typename D::result_type v = d(g);
155             assert(d.min() <= v && v <= d.max());
156             u[static_cast<std::size_t>(v)]++;
157         }
158         std::vector<double> prob = d.probabilities();
159         for (unsigned i = 0; i < u.size(); ++i)
160             if (prob[i] != 0)
161               assert(std::abs((double)u[i] / N - prob[i]) / prob[i] < 0.0013);
162             else
163                 assert(u[i] == 0);
164     }
165     {
166         typedef std::discrete_distribution<T> D;
167         typedef std::minstd_rand G;
168         G g;
169         double p0[] = {25, 0, 75};
170         D d(p0, p0+3);
171         const int N = 1000000;
172         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
173         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
174         for (int i = 0; i < N; ++i)
175         {
176             typename D::result_type v = d(g);
177             assert(d.min() <= v && v <= d.max());
178             u[static_cast<std::size_t>(v)]++;
179         }
180         std::vector<double> prob = d.probabilities();
181         for (unsigned i = 0; i < u.size(); ++i)
182             if (prob[i] != 0)
183                 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);
184             else
185                 assert(u[i] == 0);
186     }
187     {
188         typedef std::discrete_distribution<T> D;
189         typedef std::minstd_rand G;
190         G g;
191         double p0[] = {25, 75, 0};
192         D d(p0, p0+3);
193         const int N = 1000000;
194         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
195         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
196         for (int i = 0; i < N; ++i)
197         {
198             typename D::result_type v = d(g);
199             assert(d.min() <= v && v <= d.max());
200             u[static_cast<std::size_t>(v)]++;
201         }
202         std::vector<double> prob = d.probabilities();
203         for (unsigned i = 0; i < u.size(); ++i)
204             if (prob[i] != 0)
205               assert(std::abs((double)u[i] / N - prob[i]) / prob[i] < 0.0013);
206             else
207                 assert(u[i] == 0);
208     }
209     {
210         typedef std::discrete_distribution<T> D;
211         typedef std::minstd_rand G;
212         G g;
213         double p0[] = {0, 0, 1};
214         D d(p0, p0+3);
215         const int N = 100;
216         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
217         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
218         for (int i = 0; i < N; ++i)
219         {
220             typename D::result_type v = d(g);
221             assert(d.min() <= v && v <= d.max());
222             u[static_cast<std::size_t>(v)]++;
223         }
224         std::vector<double> prob = d.probabilities();
225         for (unsigned i = 0; i < u.size(); ++i)
226             if (prob[i] != 0)
227                 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);
228             else
229                 assert(u[i] == 0);
230     }
231     {
232         typedef std::discrete_distribution<T> D;
233         typedef std::minstd_rand G;
234         G g;
235         double p0[] = {0, 1, 0};
236         D d(p0, p0+3);
237         const int N = 100;
238         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
239         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
240         for (int i = 0; i < N; ++i)
241         {
242             typename D::result_type v = d(g);
243             assert(d.min() <= v && v <= d.max());
244             u[static_cast<std::size_t>(v)]++;
245         }
246         std::vector<double> prob = d.probabilities();
247         for (unsigned i = 0; i < u.size(); ++i)
248             if (prob[i] != 0)
249                 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);
250             else
251                 assert(u[i] == 0);
252     }
253     {
254         typedef std::discrete_distribution<T> D;
255         typedef std::minstd_rand G;
256         G g;
257         double p0[] = {1, 0, 0};
258         D d(p0, p0+3);
259         const int N = 100;
260         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
261         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
262         for (int i = 0; i < N; ++i)
263         {
264             typename D::result_type v = d(g);
265             assert(d.min() <= v && v <= d.max());
266             u[static_cast<std::size_t>(v)]++;
267         }
268         std::vector<double> prob = d.probabilities();
269         for (unsigned i = 0; i < u.size(); ++i)
270             if (prob[i] != 0)
271                 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);
272             else
273                 assert(u[i] == 0);
274     }
275     {
276         typedef std::discrete_distribution<T> D;
277         typedef std::minstd_rand G;
278         G g;
279         double p0[] = {33, 0, 0, 67};
280         D d(p0, p0+3);
281         const int N = 1000000;
282         std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));
283         assert(u.max_size() > static_cast<unsigned long long>(d.max()));
284         for (int i = 0; i < N; ++i)
285         {
286             typename D::result_type v = d(g);
287             assert(d.min() <= v && v <= d.max());
288             u[static_cast<std::size_t>(v)]++;
289         }
290         std::vector<double> prob = d.probabilities();
291         for (unsigned i = 0; i < u.size(); ++i)
292             if (prob[i] != 0)
293               assert(std::abs((double)u[i] / N - prob[i]) / prob[i] < 0.0013);
294             else
295                 assert(u[i] == 0);
296     }
297 }
298 
main(int,char **)299 int main(int, char**) {
300     tests<short>();
301     tests<int>();
302     tests<long>();
303     tests<long long>();
304 
305     tests<unsigned short>();
306     tests<unsigned int>();
307     tests<unsigned long>();
308     tests<unsigned long long>();
309 
310 #if defined(_LIBCPP_VERSION) // extension
311     tests<std::int8_t>();
312     tests<std::uint8_t>();
313 #if !defined(TEST_HAS_NO_INT128)
314     tests<__int128_t>();
315     tests<__uint128_t>();
316 #endif
317 #endif
318 
319     return 0;
320 }
321