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