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 RealType = double>
14// class piecewise_constant_distribution
15
16// template<class _URNG> result_type operator()(_URNG& g);
17
18#include <random>
19#include <vector>
20#include <iterator>
21#include <numeric>
22#include <algorithm> // for sort
23#include <cassert>
24
25#include "test_macros.h"
26
27template <class T>
28inline
29T
30sqr(T x)
31{
32 return x*x;
33}
34
35void
36test1()
37{
38 typedef std::piecewise_constant_distribution<> D;
39 typedef std::mt19937_64 G;
40 G g;
41 double b[] = {10, 14, 16, 17};
42 double p[] = {25, 62.5, 12.5};
43 const std::size_t Np = sizeof(p) / sizeof(p[0]);
44 D d(b, b+Np+1, p);
45 const int N = 1000000;
46 std::vector<D::result_type> u;
47 for (int i = 0; i < N; ++i)
48 {
49 D::result_type v = d(g);
50 assert(d.min() <= v && v < d.max());
51 u.push_back(v);
52 }
53 std::vector<double> prob(std::begin(p), std::end(p));
54 double s = std::accumulate(prob.begin(), prob.end(), 0.0);
55 for (std::size_t i = 0; i < prob.size(); ++i)
56 prob[i] /= s;
57 std::sort(u.begin(), u.end());
58 for (std::size_t i = 0; i < Np; ++i)
59 {
60 typedef std::vector<D::result_type>::iterator I;
61 I lb = std::lower_bound(u.begin(), u.end(), b[i]);
62 I ub = std::lower_bound(u.begin(), u.end(), b[i+1]);
63 const std::size_t Ni = ub - lb;
64 if (prob[i] == 0)
65 assert(Ni == 0);
66 else
67 {
68 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
69 double mean = std::accumulate(lb, ub, 0.0) / Ni;
70 double var = 0;
71 double skew = 0;
72 double kurtosis = 0;
73 for (I j = lb; j != ub; ++j)
74 {
75 double dbl = (*j - mean);
76 double d2 = sqr(dbl);
77 var += d2;
78 skew += dbl * d2;
79 kurtosis += d2 * d2;
80 }
81 var /= Ni;
82 double dev = std::sqrt(x: var);
83 skew /= Ni * dev * var;
84 kurtosis /= Ni * var * var;
85 kurtosis -= 3;
86 double x_mean = (b[i+1] + b[i]) / 2;
87 double x_var = sqr(b[i+1] - b[i]) / 12;
88 double x_skew = 0;
89 double x_kurtosis = -6./5;
90 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
91 assert(std::abs((var - x_var) / x_var) < 0.01);
92 assert(std::abs(skew - x_skew) < 0.01);
93 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
94 }
95 }
96}
97
98void
99test2()
100{
101 typedef std::piecewise_constant_distribution<> D;
102 typedef std::mt19937_64 G;
103 G g;
104 double b[] = {10, 14, 16, 17};
105 double p[] = {0, 62.5, 12.5};
106 const std::size_t Np = sizeof(p) / sizeof(p[0]);
107 D d(b, b+Np+1, p);
108 const int N = 1000000;
109 std::vector<D::result_type> u;
110 for (int i = 0; i < N; ++i)
111 {
112 D::result_type v = d(g);
113 assert(d.min() <= v && v < d.max());
114 u.push_back(x: v);
115 }
116 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
117 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
118 for (std::size_t i = 0; i < prob.size(); ++i)
119 prob[i] /= s;
120 std::sort(first: u.begin(), last: u.end());
121 for (std::size_t i = 0; i < Np; ++i)
122 {
123 typedef std::vector<D::result_type>::iterator I;
124 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
125 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
126 const std::size_t Ni = ub - lb;
127 if (prob[i] == 0)
128 assert(Ni == 0);
129 else
130 {
131 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
132 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
133 double var = 0;
134 double skew = 0;
135 double kurtosis = 0;
136 for (I j = lb; j != ub; ++j)
137 {
138 double dbl = (*j - mean);
139 double d2 = sqr(x: dbl);
140 var += d2;
141 skew += dbl * d2;
142 kurtosis += d2 * d2;
143 }
144 var /= Ni;
145 double dev = std::sqrt(x: var);
146 skew /= Ni * dev * var;
147 kurtosis /= Ni * var * var;
148 kurtosis -= 3;
149 double x_mean = (b[i+1] + b[i]) / 2;
150 double x_var = sqr(x: b[i+1] - b[i]) / 12;
151 double x_skew = 0;
152 double x_kurtosis = -6./5;
153 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
154 assert(std::abs((var - x_var) / x_var) < 0.01);
155 assert(std::abs(skew - x_skew) < 0.01);
156 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
157 }
158 }
159}
160
161void
162test3()
163{
164 typedef std::piecewise_constant_distribution<> D;
165 typedef std::mt19937_64 G;
166 G g;
167 double b[] = {10, 14, 16, 17};
168 double p[] = {25, 0, 12.5};
169 const std::size_t Np = sizeof(p) / sizeof(p[0]);
170 D d(b, b+Np+1, p);
171 const int N = 1000000;
172 std::vector<D::result_type> u;
173 for (int i = 0; i < N; ++i)
174 {
175 D::result_type v = d(g);
176 assert(d.min() <= v && v < d.max());
177 u.push_back(x: v);
178 }
179 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
180 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
181 for (std::size_t i = 0; i < prob.size(); ++i)
182 prob[i] /= s;
183 std::sort(first: u.begin(), last: u.end());
184 for (std::size_t i = 0; i < Np; ++i)
185 {
186 typedef std::vector<D::result_type>::iterator I;
187 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
188 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
189 const std::size_t Ni = ub - lb;
190 if (prob[i] == 0)
191 assert(Ni == 0);
192 else
193 {
194 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
195 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
196 double var = 0;
197 double skew = 0;
198 double kurtosis = 0;
199 for (I j = lb; j != ub; ++j)
200 {
201 double dbl = (*j - mean);
202 double d2 = sqr(x: dbl);
203 var += d2;
204 skew += dbl * d2;
205 kurtosis += d2 * d2;
206 }
207 var /= Ni;
208 double dev = std::sqrt(x: var);
209 skew /= Ni * dev * var;
210 kurtosis /= Ni * var * var;
211 kurtosis -= 3;
212 double x_mean = (b[i+1] + b[i]) / 2;
213 double x_var = sqr(x: b[i+1] - b[i]) / 12;
214 double x_skew = 0;
215 double x_kurtosis = -6./5;
216 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
217 assert(std::abs((var - x_var) / x_var) < 0.01);
218 assert(std::abs(skew - x_skew) < 0.01);
219 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
220 }
221 }
222}
223
224void
225test4()
226{
227 typedef std::piecewise_constant_distribution<> D;
228 typedef std::mt19937_64 G;
229 G g;
230 double b[] = {10, 14, 16, 17};
231 double p[] = {25, 62.5, 0};
232 const std::size_t Np = sizeof(p) / sizeof(p[0]);
233 D d(b, b+Np+1, p);
234 const int N = 1000000;
235 std::vector<D::result_type> u;
236 for (int i = 0; i < N; ++i)
237 {
238 D::result_type v = d(g);
239 assert(d.min() <= v && v < d.max());
240 u.push_back(x: v);
241 }
242 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
243 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
244 for (std::size_t i = 0; i < prob.size(); ++i)
245 prob[i] /= s;
246 std::sort(first: u.begin(), last: u.end());
247 for (std::size_t i = 0; i < Np; ++i)
248 {
249 typedef std::vector<D::result_type>::iterator I;
250 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
251 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
252 const std::size_t Ni = ub - lb;
253 if (prob[i] == 0)
254 assert(Ni == 0);
255 else
256 {
257 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
258 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
259 double var = 0;
260 double skew = 0;
261 double kurtosis = 0;
262 for (I j = lb; j != ub; ++j)
263 {
264 double dbl = (*j - mean);
265 double d2 = sqr(x: dbl);
266 var += d2;
267 skew += dbl * d2;
268 kurtosis += d2 * d2;
269 }
270 var /= Ni;
271 double dev = std::sqrt(x: var);
272 skew /= Ni * dev * var;
273 kurtosis /= Ni * var * var;
274 kurtosis -= 3;
275 double x_mean = (b[i+1] + b[i]) / 2;
276 double x_var = sqr(x: b[i+1] - b[i]) / 12;
277 double x_skew = 0;
278 double x_kurtosis = -6./5;
279 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
280 assert(std::abs((var - x_var) / x_var) < 0.01);
281 assert(std::abs(skew - x_skew) < 0.01);
282 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
283 }
284 }
285}
286
287void
288test5()
289{
290 typedef std::piecewise_constant_distribution<> D;
291 typedef std::mt19937_64 G;
292 G g;
293 double b[] = {10, 14, 16, 17};
294 double p[] = {25, 0, 0};
295 const std::size_t Np = sizeof(p) / sizeof(p[0]);
296 D d(b, b+Np+1, p);
297 const int N = 100000;
298 std::vector<D::result_type> u;
299 for (int i = 0; i < N; ++i)
300 {
301 D::result_type v = d(g);
302 assert(d.min() <= v && v < d.max());
303 u.push_back(x: v);
304 }
305 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
306 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
307 for (std::size_t i = 0; i < prob.size(); ++i)
308 prob[i] /= s;
309 std::sort(first: u.begin(), last: u.end());
310 for (std::size_t i = 0; i < Np; ++i)
311 {
312 typedef std::vector<D::result_type>::iterator I;
313 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
314 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
315 const std::size_t Ni = ub - lb;
316 if (prob[i] == 0)
317 assert(Ni == 0);
318 else
319 {
320 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
321 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
322 double var = 0;
323 double skew = 0;
324 double kurtosis = 0;
325 for (I j = lb; j != ub; ++j)
326 {
327 double dbl = (*j - mean);
328 double d2 = sqr(x: dbl);
329 var += d2;
330 skew += dbl * d2;
331 kurtosis += d2 * d2;
332 }
333 var /= Ni;
334 double dev = std::sqrt(x: var);
335 skew /= Ni * dev * var;
336 kurtosis /= Ni * var * var;
337 kurtosis -= 3;
338 double x_mean = (b[i+1] + b[i]) / 2;
339 double x_var = sqr(x: b[i+1] - b[i]) / 12;
340 double x_skew = 0;
341 double x_kurtosis = -6./5;
342 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
343 assert(std::abs((var - x_var) / x_var) < 0.01);
344 assert(std::abs(skew - x_skew) < 0.01);
345 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
346 }
347 }
348}
349
350void
351test6()
352{
353 typedef std::piecewise_constant_distribution<> D;
354 typedef std::mt19937_64 G;
355 G g;
356 double b[] = {10, 14, 16, 17};
357 double p[] = {0, 25, 0};
358 const std::size_t Np = sizeof(p) / sizeof(p[0]);
359 D d(b, b+Np+1, p);
360 const int N = 100000;
361 std::vector<D::result_type> u;
362 for (int i = 0; i < N; ++i)
363 {
364 D::result_type v = d(g);
365 assert(d.min() <= v && v < d.max());
366 u.push_back(x: v);
367 }
368 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
369 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
370 for (std::size_t i = 0; i < prob.size(); ++i)
371 prob[i] /= s;
372 std::sort(first: u.begin(), last: u.end());
373 for (std::size_t i = 0; i < Np; ++i)
374 {
375 typedef std::vector<D::result_type>::iterator I;
376 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
377 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
378 const std::size_t Ni = ub - lb;
379 if (prob[i] == 0)
380 assert(Ni == 0);
381 else
382 {
383 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
384 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
385 double var = 0;
386 double skew = 0;
387 double kurtosis = 0;
388 for (I j = lb; j != ub; ++j)
389 {
390 double dbl = (*j - mean);
391 double d2 = sqr(x: dbl);
392 var += d2;
393 skew += dbl * d2;
394 kurtosis += d2 * d2;
395 }
396 var /= Ni;
397 double dev = std::sqrt(x: var);
398 skew /= Ni * dev * var;
399 kurtosis /= Ni * var * var;
400 kurtosis -= 3;
401 double x_mean = (b[i+1] + b[i]) / 2;
402 double x_var = sqr(x: b[i+1] - b[i]) / 12;
403 double x_skew = 0;
404 double x_kurtosis = -6./5;
405 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
406 assert(std::abs((var - x_var) / x_var) < 0.01);
407 assert(std::abs(skew - x_skew) < 0.01);
408 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
409 }
410 }
411}
412
413void
414test7()
415{
416 typedef std::piecewise_constant_distribution<> D;
417 typedef std::mt19937_64 G;
418 G g;
419 double b[] = {10, 14, 16, 17};
420 double p[] = {0, 0, 1};
421 const std::size_t Np = sizeof(p) / sizeof(p[0]);
422 D d(b, b+Np+1, p);
423 const int N = 100000;
424 std::vector<D::result_type> u;
425 for (int i = 0; i < N; ++i)
426 {
427 D::result_type v = d(g);
428 assert(d.min() <= v && v < d.max());
429 u.push_back(x: v);
430 }
431 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
432 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
433 for (std::size_t i = 0; i < prob.size(); ++i)
434 prob[i] /= s;
435 std::sort(first: u.begin(), last: u.end());
436 for (std::size_t i = 0; i < Np; ++i)
437 {
438 typedef std::vector<D::result_type>::iterator I;
439 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
440 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
441 const std::size_t Ni = ub - lb;
442 if (prob[i] == 0)
443 assert(Ni == 0);
444 else
445 {
446 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
447 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
448 double var = 0;
449 double skew = 0;
450 double kurtosis = 0;
451 for (I j = lb; j != ub; ++j)
452 {
453 double dbl = (*j - mean);
454 double d2 = sqr(x: dbl);
455 var += d2;
456 skew += dbl * d2;
457 kurtosis += d2 * d2;
458 }
459 var /= Ni;
460 double dev = std::sqrt(x: var);
461 skew /= Ni * dev * var;
462 kurtosis /= Ni * var * var;
463 kurtosis -= 3;
464 double x_mean = (b[i+1] + b[i]) / 2;
465 double x_var = sqr(x: b[i+1] - b[i]) / 12;
466 double x_skew = 0;
467 double x_kurtosis = -6./5;
468 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
469 assert(std::abs((var - x_var) / x_var) < 0.01);
470 assert(std::abs(skew - x_skew) < 0.01);
471 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
472 }
473 }
474}
475
476void
477test8()
478{
479 typedef std::piecewise_constant_distribution<> D;
480 typedef std::mt19937_64 G;
481 G g;
482 double b[] = {10, 14, 16};
483 double p[] = {75, 25};
484 const std::size_t Np = sizeof(p) / sizeof(p[0]);
485 D d(b, b+Np+1, p);
486 const int N = 100000;
487 std::vector<D::result_type> u;
488 for (int i = 0; i < N; ++i)
489 {
490 D::result_type v = d(g);
491 assert(d.min() <= v && v < d.max());
492 u.push_back(x: v);
493 }
494 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
495 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
496 for (std::size_t i = 0; i < prob.size(); ++i)
497 prob[i] /= s;
498 std::sort(first: u.begin(), last: u.end());
499 for (std::size_t i = 0; i < Np; ++i)
500 {
501 typedef std::vector<D::result_type>::iterator I;
502 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
503 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
504 const std::size_t Ni = ub - lb;
505 if (prob[i] == 0)
506 assert(Ni == 0);
507 else
508 {
509 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
510 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
511 double var = 0;
512 double skew = 0;
513 double kurtosis = 0;
514 for (I j = lb; j != ub; ++j)
515 {
516 double dbl = (*j - mean);
517 double d2 = sqr(x: dbl);
518 var += d2;
519 skew += dbl * d2;
520 kurtosis += d2 * d2;
521 }
522 var /= Ni;
523 double dev = std::sqrt(x: var);
524 skew /= Ni * dev * var;
525 kurtosis /= Ni * var * var;
526 kurtosis -= 3;
527 double x_mean = (b[i+1] + b[i]) / 2;
528 double x_var = sqr(x: b[i+1] - b[i]) / 12;
529 double x_skew = 0;
530 double x_kurtosis = -6./5;
531 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
532 assert(std::abs((var - x_var) / x_var) < 0.01);
533 assert(std::abs(skew - x_skew) < 0.01);
534 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
535 }
536 }
537}
538
539void
540test9()
541{
542 typedef std::piecewise_constant_distribution<> D;
543 typedef std::mt19937_64 G;
544 G g;
545 double b[] = {10, 14, 16};
546 double p[] = {0, 25};
547 const std::size_t Np = sizeof(p) / sizeof(p[0]);
548 D d(b, b+Np+1, p);
549 const int N = 100000;
550 std::vector<D::result_type> u;
551 for (int i = 0; i < N; ++i)
552 {
553 D::result_type v = d(g);
554 assert(d.min() <= v && v < d.max());
555 u.push_back(x: v);
556 }
557 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
558 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
559 for (std::size_t i = 0; i < prob.size(); ++i)
560 prob[i] /= s;
561 std::sort(first: u.begin(), last: u.end());
562 for (std::size_t i = 0; i < Np; ++i)
563 {
564 typedef std::vector<D::result_type>::iterator I;
565 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
566 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
567 const std::size_t Ni = ub - lb;
568 if (prob[i] == 0)
569 assert(Ni == 0);
570 else
571 {
572 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
573 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
574 double var = 0;
575 double skew = 0;
576 double kurtosis = 0;
577 for (I j = lb; j != ub; ++j)
578 {
579 double dbl = (*j - mean);
580 double d2 = sqr(x: dbl);
581 var += d2;
582 skew += dbl * d2;
583 kurtosis += d2 * d2;
584 }
585 var /= Ni;
586 double dev = std::sqrt(x: var);
587 skew /= Ni * dev * var;
588 kurtosis /= Ni * var * var;
589 kurtosis -= 3;
590 double x_mean = (b[i+1] + b[i]) / 2;
591 double x_var = sqr(x: b[i+1] - b[i]) / 12;
592 double x_skew = 0;
593 double x_kurtosis = -6./5;
594 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
595 assert(std::abs((var - x_var) / x_var) < 0.01);
596 assert(std::abs(skew - x_skew) < 0.01);
597 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
598 }
599 }
600}
601
602void
603test10()
604{
605 typedef std::piecewise_constant_distribution<> D;
606 typedef std::mt19937_64 G;
607 G g;
608 double b[] = {10, 14, 16};
609 double p[] = {1, 0};
610 const std::size_t Np = sizeof(p) / sizeof(p[0]);
611 D d(b, b+Np+1, p);
612 const int N = 100000;
613 std::vector<D::result_type> u;
614 for (int i = 0; i < N; ++i)
615 {
616 D::result_type v = d(g);
617 assert(d.min() <= v && v < d.max());
618 u.push_back(x: v);
619 }
620 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
621 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
622 for (std::size_t i = 0; i < prob.size(); ++i)
623 prob[i] /= s;
624 std::sort(first: u.begin(), last: u.end());
625 for (std::size_t i = 0; i < Np; ++i)
626 {
627 typedef std::vector<D::result_type>::iterator I;
628 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
629 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
630 const std::size_t Ni = ub - lb;
631 if (prob[i] == 0)
632 assert(Ni == 0);
633 else
634 {
635 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
636 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
637 double var = 0;
638 double skew = 0;
639 double kurtosis = 0;
640 for (I j = lb; j != ub; ++j)
641 {
642 double dbl = (*j - mean);
643 double d2 = sqr(x: dbl);
644 var += d2;
645 skew += dbl * d2;
646 kurtosis += d2 * d2;
647 }
648 var /= Ni;
649 double dev = std::sqrt(x: var);
650 skew /= Ni * dev * var;
651 kurtosis /= Ni * var * var;
652 kurtosis -= 3;
653 double x_mean = (b[i+1] + b[i]) / 2;
654 double x_var = sqr(x: b[i+1] - b[i]) / 12;
655 double x_skew = 0;
656 double x_kurtosis = -6./5;
657 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
658 assert(std::abs((var - x_var) / x_var) < 0.01);
659 assert(std::abs(skew - x_skew) < 0.01);
660 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
661 }
662 }
663}
664
665void
666test11()
667{
668 typedef std::piecewise_constant_distribution<> D;
669 typedef std::mt19937_64 G;
670 G g;
671 double b[] = {10, 14};
672 double p[] = {1};
673 const std::size_t Np = sizeof(p) / sizeof(p[0]);
674 D d(b, b+Np+1, p);
675 const int N = 100000;
676 std::vector<D::result_type> u;
677 for (int i = 0; i < N; ++i)
678 {
679 D::result_type v = d(g);
680 assert(d.min() <= v && v < d.max());
681 u.push_back(x: v);
682 }
683 std::vector<double> prob(std::begin(arr&: p), std::end(arr&: p));
684 double s = std::accumulate(first: prob.begin(), last: prob.end(), init: 0.0);
685 for (std::size_t i = 0; i < prob.size(); ++i)
686 prob[i] /= s;
687 std::sort(first: u.begin(), last: u.end());
688 for (std::size_t i = 0; i < Np; ++i)
689 {
690 typedef std::vector<D::result_type>::iterator I;
691 I lb = std::lower_bound(first: u.begin(), last: u.end(), val: b[i]);
692 I ub = std::lower_bound(first: u.begin(), last: u.end(), val: b[i+1]);
693 const std::size_t Ni = ub - lb;
694 if (prob[i] == 0)
695 assert(Ni == 0);
696 else
697 {
698 assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01);
699 double mean = std::accumulate(first: lb, last: ub, init: 0.0) / Ni;
700 double var = 0;
701 double skew = 0;
702 double kurtosis = 0;
703 for (I j = lb; j != ub; ++j)
704 {
705 double dbl = (*j - mean);
706 double d2 = sqr(x: dbl);
707 var += d2;
708 skew += dbl * d2;
709 kurtosis += d2 * d2;
710 }
711 var /= Ni;
712 double dev = std::sqrt(x: var);
713 skew /= Ni * dev * var;
714 kurtosis /= Ni * var * var;
715 kurtosis -= 3;
716 double x_mean = (b[i+1] + b[i]) / 2;
717 double x_var = sqr(x: b[i+1] - b[i]) / 12;
718 double x_skew = 0;
719 double x_kurtosis = -6./5;
720 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
721 assert(std::abs((var - x_var) / x_var) < 0.01);
722 assert(std::abs(skew - x_skew) < 0.01);
723 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
724 }
725 }
726}
727
728int main(int, char**)
729{
730 test1();
731 test2();
732 test3();
733 test4();
734 test5();
735 test6();
736 test7();
737 test8();
738 test9();
739 test10();
740 test11();
741
742 return 0;
743}
744

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