123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- //===----------------------------------------------------------------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is dual licensed under the MIT and the University of Illinois Open
- // Source Licenses. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // REQUIRES: long_tests
- // <random>
- // template<class IntType = int>
- // class binomial_distribution
- // template<class _URNG> result_type operator()(_URNG& g);
- #include <random>
- #include <numeric>
- #include <vector>
- #include <cassert>
- template <class T>
- inline
- T
- sqr(T x)
- {
- return x * x;
- }
- void
- test1()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937_64 G;
- G g;
- D d(5, .75);
- const int N = 1000000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- double dev = std::sqrt(var);
- skew /= u.size() * dev * var;
- kurtosis /= u.size() * var * var;
- kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(std::abs((mean - x_mean) / x_mean) < 0.01);
- assert(std::abs((var - x_var) / x_var) < 0.01);
- assert(std::abs((skew - x_skew) / x_skew) < 0.01);
- assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.04);
- }
- void
- test2()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(30, .03125);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- double dev = std::sqrt(var);
- skew /= u.size() * dev * var;
- kurtosis /= u.size() * var * var;
- kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(std::abs((mean - x_mean) / x_mean) < 0.01);
- assert(std::abs((var - x_var) / x_var) < 0.01);
- assert(std::abs((skew - x_skew) / x_skew) < 0.01);
- assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
- }
- void
- test3()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(40, .25);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- double dev = std::sqrt(var);
- skew /= u.size() * dev * var;
- kurtosis /= u.size() * var * var;
- kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(std::abs((mean - x_mean) / x_mean) < 0.01);
- assert(std::abs((var - x_var) / x_var) < 0.01);
- assert(std::abs((skew - x_skew) / x_skew) < 0.03);
- assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.3);
- }
- void
- test4()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(40, 0);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- //double dev = std::sqrt(var);
- // In this case:
- // skew computes to 0./0. == nan
- // kurtosis computes to 0./0. == nan
- // x_skew == inf
- // x_kurtosis == inf
- // These tests are commented out because UBSan warns about division by 0
- // skew /= u.size() * dev * var;
- // kurtosis /= u.size() * var * var;
- // kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- // double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- // double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(mean == x_mean);
- assert(var == x_var);
- // assert(skew == x_skew);
- // assert(kurtosis == x_kurtosis);
- }
- void
- test5()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(40, 1);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- // double dev = std::sqrt(var);
- // In this case:
- // skew computes to 0./0. == nan
- // kurtosis computes to 0./0. == nan
- // x_skew == -inf
- // x_kurtosis == inf
- // These tests are commented out because UBSan warns about division by 0
- // skew /= u.size() * dev * var;
- // kurtosis /= u.size() * var * var;
- // kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- // double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- // double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(mean == x_mean);
- assert(var == x_var);
- // assert(skew == x_skew);
- // assert(kurtosis == x_kurtosis);
- }
- void
- test6()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(400, 0.5);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- double dev = std::sqrt(var);
- skew /= u.size() * dev * var;
- kurtosis /= u.size() * var * var;
- kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(std::abs((mean - x_mean) / x_mean) < 0.01);
- assert(std::abs((var - x_var) / x_var) < 0.01);
- assert(std::abs(skew - x_skew) < 0.01);
- assert(std::abs(kurtosis - x_kurtosis) < 0.01);
- }
- void
- test7()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(1, 0.5);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- double dev = std::sqrt(var);
- skew /= u.size() * dev * var;
- kurtosis /= u.size() * var * var;
- kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(std::abs((mean - x_mean) / x_mean) < 0.01);
- assert(std::abs((var - x_var) / x_var) < 0.01);
- assert(std::abs(skew - x_skew) < 0.01);
- assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
- }
- void
- test8()
- {
- const int N = 100000;
- std::mt19937 gen1;
- std::mt19937 gen2;
- std::binomial_distribution<> dist1(5, 0.1);
- std::binomial_distribution<unsigned> dist2(5, 0.1);
- for(int i = 0; i < N; ++i) {
- int r1 = dist1(gen1);
- unsigned r2 = dist2(gen2);
- assert(r1 >= 0);
- assert(static_cast<unsigned>(r1) == r2);
- }
- }
- void
- test9()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(0, 0.005);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- // double dev = std::sqrt(var);
- // In this case:
- // skew computes to 0./0. == nan
- // kurtosis computes to 0./0. == nan
- // x_skew == inf
- // x_kurtosis == inf
- // These tests are commented out because UBSan warns about division by 0
- // skew /= u.size() * dev * var;
- // kurtosis /= u.size() * var * var;
- // kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- // double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- // double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(mean == x_mean);
- assert(var == x_var);
- // assert(skew == x_skew);
- // assert(kurtosis == x_kurtosis);
- }
- void
- test10()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(0, 0);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- // double dev = std::sqrt(var);
- // In this case:
- // skew computes to 0./0. == nan
- // kurtosis computes to 0./0. == nan
- // x_skew == inf
- // x_kurtosis == inf
- // These tests are commented out because UBSan warns about division by 0
- // skew /= u.size() * dev * var;
- // kurtosis /= u.size() * var * var;
- // kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- // double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- // double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(mean == x_mean);
- assert(var == x_var);
- // assert(skew == x_skew);
- // assert(kurtosis == x_kurtosis);
- }
- void
- test11()
- {
- typedef std::binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(0, 1);
- const int N = 100000;
- std::vector<D::result_type> u;
- for (int i = 0; i < N; ++i)
- {
- D::result_type v = d(g);
- assert(d.min() <= v && v <= d.max());
- u.push_back(v);
- }
- double mean = std::accumulate(u.begin(), u.end(),
- double(0)) / u.size();
- double var = 0;
- double skew = 0;
- double kurtosis = 0;
- for (unsigned i = 0; i < u.size(); ++i)
- {
- double dbl = (u[i] - mean);
- double d2 = sqr(dbl);
- var += d2;
- skew += dbl * d2;
- kurtosis += d2 * d2;
- }
- var /= u.size();
- // double dev = std::sqrt(var);
- // In this case:
- // skew computes to 0./0. == nan
- // kurtosis computes to 0./0. == nan
- // x_skew == -inf
- // x_kurtosis == inf
- // These tests are commented out because UBSan warns about division by 0
- // skew /= u.size() * dev * var;
- // kurtosis /= u.size() * var * var;
- // kurtosis -= 3;
- double x_mean = d.t() * d.p();
- double x_var = x_mean*(1-d.p());
- // double x_skew = (1-2*d.p()) / std::sqrt(x_var);
- // double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var;
- assert(mean == x_mean);
- assert(var == x_var);
- // assert(skew == x_skew);
- // assert(kurtosis == x_kurtosis);
- }
- int main()
- {
- test1();
- test2();
- test3();
- test4();
- test5();
- test6();
- test7();
- test8();
- test9();
- test10();
- test11();
- }
|