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
27template <class T>
28void 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
299int 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

source code of libcxx/test/std/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.discrete/eval.pass.cpp