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