197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant//===----------------------------------------------------------------------===//
297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant//
397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant//                     The LLVM Compiler Infrastructure
497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant//
5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
797dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant//
897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant//===----------------------------------------------------------------------===//
906086258d3d8c48a916ec51c33e1ad8f46821b81Dan Albert//
1006086258d3d8c48a916ec51c33e1ad8f46821b81Dan Albert// REQUIRES: long_tests
1197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant
1297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant// <random>
1397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant
1497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant// template<class RealType = double>
1597dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant// class chi_squared_distribution
1697dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant
1797dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant// template<class _URNG> result_type operator()(_URNG& g);
1897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant
1997dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant#include <random>
2097dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant#include <cassert>
2197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant#include <vector>
2297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant#include <numeric>
2397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant
2497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnanttemplate <class T>
2597dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnantinline
2697dc2f35c3d0d797ece43f5598023c6952144f37Howard HinnantT
2797dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnantsqr(T x)
2897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant{
2997dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    return x * x;
3097dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant}
3197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant
3297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnantint main()
3397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant{
3497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    {
3597dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef std::chi_squared_distribution<> D;
3697dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef D::param_type P;
3797dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef std::minstd_rand G;
3897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        G g;
3997dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        D d(0.5);
40df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        const int N = 1000000;
4197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        std::vector<D::result_type> u;
4297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        for (int i = 0; i < N; ++i)
43df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
44df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            D::result_type v = d(g);
45df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            assert(d.min() < v);
46df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            u.push_back(v);
47df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
48df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
49df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double var = 0;
50df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double skew = 0;
51df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double kurtosis = 0;
5297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        for (int i = 0; i < u.size(); ++i)
53df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
54df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            double d = (u[i] - mean);
55df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            double d2 = sqr(d);
56df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            var += d2;
57df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            skew += d * d2;
58df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            kurtosis += d2 * d2;
59df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
6097dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        var /= u.size();
61df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double dev = std::sqrt(var);
62df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        skew /= u.size() * dev * var;
63df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis /= u.size() * var * var;
64df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis -= 3;
65df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_mean = d.n();
66df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_var = 2 * d.n();
67df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_skew = std::sqrt(8 / d.n());
68df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_kurtosis = 12 / d.n();
69d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
70d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((var - x_var) / x_var) < 0.01);
71d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((skew - x_skew) / x_skew) < 0.01);
72d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
7397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    }
7497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    {
7597dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef std::chi_squared_distribution<> D;
7697dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef D::param_type P;
7797dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef std::minstd_rand G;
7897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        G g;
7997dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        D d(1);
80df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        const int N = 1000000;
8197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        std::vector<D::result_type> u;
8297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        for (int i = 0; i < N; ++i)
83df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
84df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            D::result_type v = d(g);
85df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            assert(d.min() < v);
86df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            u.push_back(v);
87df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
88df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
89df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double var = 0;
90df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double skew = 0;
91df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double kurtosis = 0;
9297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        for (int i = 0; i < u.size(); ++i)
93df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
94df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            double d = (u[i] - mean);
95df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            double d2 = sqr(d);
96df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            var += d2;
97df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            skew += d * d2;
98df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            kurtosis += d2 * d2;
99df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
10097dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        var /= u.size();
101df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double dev = std::sqrt(var);
102df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        skew /= u.size() * dev * var;
103df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis /= u.size() * var * var;
104df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis -= 3;
105df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_mean = d.n();
106df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_var = 2 * d.n();
107df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_skew = std::sqrt(8 / d.n());
108df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_kurtosis = 12 / d.n();
109d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
110d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((var - x_var) / x_var) < 0.01);
111d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((skew - x_skew) / x_skew) < 0.01);
112d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
11397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    }
11497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    {
11597dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef std::chi_squared_distribution<> D;
11697dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef D::param_type P;
117df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        typedef std::mt19937 G;
11897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        G g;
11997dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        D d(2);
120df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        const int N = 1000000;
12197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        std::vector<D::result_type> u;
12297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        for (int i = 0; i < N; ++i)
123df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
124df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            D::result_type v = d(g);
125df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            assert(d.min() < v);
126df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            u.push_back(v);
127df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
128df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
129df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double var = 0;
130df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double skew = 0;
131df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double kurtosis = 0;
13297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        for (int i = 0; i < u.size(); ++i)
133df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
134df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            double d = (u[i] - mean);
135df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            double d2 = sqr(d);
136df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            var += d2;
137df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            skew += d * d2;
138df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            kurtosis += d2 * d2;
139df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
14097dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        var /= u.size();
141df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double dev = std::sqrt(var);
142df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        skew /= u.size() * dev * var;
143df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis /= u.size() * var * var;
144df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis -= 3;
145df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_mean = d.n();
146df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_var = 2 * d.n();
147df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_skew = std::sqrt(8 / d.n());
148df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_kurtosis = 12 / d.n();
149d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
150d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((var - x_var) / x_var) < 0.01);
151d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((skew - x_skew) / x_skew) < 0.01);
152d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
15397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    }
15497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant}
155