123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- //===----------------------------------------------------------------------===//
- //
- // 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 negative_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::negative_binomial_distribution<> D;
- typedef std::minstd_rand G;
- G g;
- D d(5, .25);
- 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.k() * (1 - d.p()) / d.p();
- double x_var = x_mean / d.p();
- double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p()));
- double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p()));
- 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.02);
- }
- void
- test2()
- {
- typedef std::negative_binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(30, .03125);
- 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.k() * (1 - d.p()) / d.p();
- double x_var = x_mean / d.p();
- double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p()));
- double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p()));
- 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::negative_binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(40, .25);
- 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.k() * (1 - d.p()) / d.p();
- double x_var = x_mean / d.p();
- double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p()));
- double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p()));
- 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.03);
- }
- void
- test4()
- {
- typedef std::negative_binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(40, 1);
- const int N = 1000;
- 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.k() * (1 - d.p()) / d.p();
- double x_var = x_mean / d.p();
- // double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p()));
- // double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p()));
- assert(mean == x_mean);
- assert(var == x_var);
- }
- void
- test5()
- {
- typedef std::negative_binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(400, 0.5);
- 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.k() * (1 - d.p()) / d.p();
- double x_var = x_mean / d.p();
- double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p()));
- double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p()));
- 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.04);
- assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05);
- }
- void
- test6()
- {
- typedef std::negative_binomial_distribution<> D;
- typedef std::mt19937 G;
- G g;
- D d(1, 0.05);
- 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.k() * (1 - d.p()) / d.p();
- double x_var = x_mean / d.p();
- double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p()));
- double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p()));
- 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.03);
- }
- int main()
- {
- test1();
- test2();
- test3();
- test4();
- test5();
- test6();
- }
|