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//===----------------------------------------------------------------------===//
9d9144e8d1783617b279146f397a6ab3defefefc4Jonathan Roelofs//
10d9144e8d1783617b279146f397a6ab3defefefc4Jonathan Roelofs// 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>
23a9bcd3dae859f02ab496d175d50840f43a2d4ed2Stephan T. Lavavej#include <cstddef>
2497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant
2597dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnanttemplate <class T>
2697dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnantinline
2797dc2f35c3d0d797ece43f5598023c6952144f37Howard HinnantT
2897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnantsqr(T x)
2997dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant{
3097dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    return x * x;
3197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant}
3297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant
3397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnantint main()
3497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant{
3597dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    {
3697dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef std::chi_squared_distribution<> D;
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;
52a9bcd3dae859f02ab496d175d50840f43a2d4ed2Stephan T. Lavavej        for (std::size_t i = 0; i < u.size(); ++i)
53df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
54d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            double dbl = (u[i] - mean);
55d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            double d2 = sqr(dbl);
56df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            var += d2;
57d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            skew += dbl * 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 std::minstd_rand G;
7797dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        G g;
7897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        D d(1);
79df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        const int N = 1000000;
8097dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        std::vector<D::result_type> u;
8197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        for (int i = 0; i < N; ++i)
82df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
83df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            D::result_type v = d(g);
84df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            assert(d.min() < v);
85df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            u.push_back(v);
86df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
87df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
88df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double var = 0;
89df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double skew = 0;
90df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double kurtosis = 0;
91a9bcd3dae859f02ab496d175d50840f43a2d4ed2Stephan T. Lavavej        for (std::size_t i = 0; i < u.size(); ++i)
92df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
93d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            double dbl = (u[i] - mean);
94d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            double d2 = sqr(dbl);
95df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            var += d2;
96d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            skew += dbl * d2;
97df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            kurtosis += d2 * d2;
98df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
9997dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        var /= u.size();
100df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double dev = std::sqrt(var);
101df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        skew /= u.size() * dev * var;
102df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis /= u.size() * var * var;
103df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis -= 3;
104df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_mean = d.n();
105df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_var = 2 * d.n();
106df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_skew = std::sqrt(8 / d.n());
107df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_kurtosis = 12 / d.n();
108d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
109d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((var - x_var) / x_var) < 0.01);
110d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((skew - x_skew) / x_skew) < 0.01);
111d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
11297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    }
11397dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    {
11497dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        typedef std::chi_squared_distribution<> D;
115df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        typedef std::mt19937 G;
11697dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        G g;
11797dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        D d(2);
118df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        const int N = 1000000;
11997dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        std::vector<D::result_type> u;
12097dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        for (int i = 0; i < N; ++i)
121df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
122df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            D::result_type v = d(g);
123df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            assert(d.min() < v);
124df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            u.push_back(v);
125df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
126df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
127df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double var = 0;
128df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double skew = 0;
129df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double kurtosis = 0;
130a9bcd3dae859f02ab496d175d50840f43a2d4ed2Stephan T. Lavavej        for (std::size_t i = 0; i < u.size(); ++i)
131df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        {
132d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            double dbl = (u[i] - mean);
133d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            double d2 = sqr(dbl);
134df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            var += d2;
135d6c0cf0ebdfd1d237fe7e07ab3732467dbd14c91Eric Fiselier            skew += dbl * d2;
136df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant            kurtosis += d2 * d2;
137df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        }
13897dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant        var /= u.size();
139df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double dev = std::sqrt(var);
140df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        skew /= u.size() * dev * var;
141df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis /= u.size() * var * var;
142df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        kurtosis -= 3;
143df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_mean = d.n();
144df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_var = 2 * d.n();
145df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_skew = std::sqrt(8 / d.n());
146df40dc6c1a8ca0bf00fb6aec030f69042f61d974Howard Hinnant        double x_kurtosis = 12 / d.n();
147d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((mean - x_mean) / x_mean) < 0.01);
148d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((var - x_var) / x_var) < 0.01);
149d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((skew - x_skew) / x_skew) < 0.01);
150d6d1171f2c3f254582ae1d5b9e14cea0ea8e701bHoward Hinnant        assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
15197dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant    }
15297dc2f35c3d0d797ece43f5598023c6952144f37Howard Hinnant}
153