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