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> |
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.001); |
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.001); |
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.001); |
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.001); |
294 | else |
295 | assert(u[i] == 0); |
296 | } |
297 | } |
298 | |
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 | |