From 89eaea24bca2c33ae10703bb332d8456fe56f41b Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Mon, 17 May 2010 00:09:38 +0000 Subject: [PATCH] [rand.dist.bern.negbin] llvm-svn: 103916 --- libcxx/include/random | 173 ++++++++++- .../rand.dist.bern.bin/eval.pass.cpp | 2 - .../rand.dist.bern.negbin/assign.pass.cpp | 34 +++ .../rand.dist.bern.negbin/copy.pass.cpp | 32 +++ .../ctor_int_double.pass.cpp | 40 +++ .../rand.dist.bern.negbin/ctor_param.pass.cpp | 30 ++ .../rand.dist.bern.negbin/eq.pass.cpp | 43 +++ .../rand.dist.bern.negbin/eval.pass.cpp | 270 ++++++++++++++++++ .../rand.dist.bern.negbin/eval_param.pass.cpp | 158 ++++++++++ .../rand.dist.bern.negbin/get_param.pass.cpp | 29 ++ .../rand.dist.bern.negbin/io.pass.cpp | 41 +++ .../rand.dist.bern.negbin/max.pass.cpp | 27 ++ .../rand.dist.bern.negbin/min.pass.cpp | 27 ++ .../param_assign.pass.cpp | 32 +++ .../rand.dist.bern.negbin/param_copy.pass.cpp | 31 ++ .../rand.dist.bern.negbin/param_ctor.pass.cpp | 44 +++ .../rand.dist.bern.negbin/param_eq.pass.cpp | 37 +++ .../param_types.pass.cpp | 28 ++ .../rand.dist.bern.negbin/set_param.pass.cpp | 30 ++ .../rand.dist.bern.negbin/types.pass.cpp | 32 +++ .../generate_canonical.pass.cpp | 2 - 21 files changed, 1137 insertions(+), 5 deletions(-) create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/assign.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/copy.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_param.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eq.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval_param.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/get_param.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/max.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/min.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_assign.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_copy.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_ctor.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_eq.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_types.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/set_param.pass.cpp create mode 100644 libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/types.pass.cpp diff --git a/libcxx/include/random b/libcxx/include/random index 6d17c2c36d2b..3298cd34f0ac 100644 --- a/libcxx/include/random +++ b/libcxx/include/random @@ -669,7 +669,62 @@ template class geometric_distribution; template - class negative_binomial_distribution; +class negative_binomial_distribution +{ +public: + // types + typedef IntType result_type; + + class param_type + { + public: + typedef negative_binomial_distribution distribution_type; + + explicit param_type(result_type k = 1, double p = 0.5); + + result_type k() const; + double p() const; + + friend bool operator==(const param_type& x, const param_type& y); + friend bool operator!=(const param_type& x, const param_type& y); + }; + + // constructor and reset functions + explicit negative_binomial_distribution(result_type k = 1, double p = 0.5); + explicit negative_binomial_distribution(const param_type& parm); + void reset(); + + // generating functions + template result_type operator()(URNG& g); + template result_type operator()(URNG& g, const param_type& parm); + + // property functions + result_type k() const; + double p() const; + + param_type param() const; + void param(const param_type& parm); + + result_type min() const; + result_type max() const; + + friend bool operator==(const negative_binomial_distribution& x, + const negative_binomial_distribution& y); + friend bool operator!=(const negative_binomial_distribution& x, + const negative_binomial_distribution& y); + + template + friend + basic_ostream& + operator<<(basic_ostream& os, + const negative_binomial_distribution& x); + + template + friend + basic_istream& + operator>>(basic_istream& is, + negative_binomial_distribution& x); +}; template class poisson_distribution @@ -4098,6 +4153,122 @@ operator>>(basic_istream<_CharT, _Traits>& __is, return __is; } +// negative_binomial_distribution + +template +class negative_binomial_distribution +{ +public: + // types + typedef _IntType result_type; + + class param_type + { + result_type __k_; + double __p_; + public: + typedef negative_binomial_distribution distribution_type; + + explicit param_type(result_type __k = 1, double __p = 0.5) + : __k_(__k), __p_(__p) {} + + result_type k() const {return __k_;} + double p() const {return __p_;} + + friend bool operator==(const param_type& __x, const param_type& __y) + {return __x.__k_ == __y.__k_ && __x.__p_ == __y.__p_;} + friend bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructor and reset functions + explicit negative_binomial_distribution(result_type __k = 1, double __p = 0.5) + : __p_(__k, __p) {} + explicit negative_binomial_distribution(const param_type& __p) : __p_(__p) {} + void reset() {} + + // generating functions + template result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + result_type k() const {return __p_.k();} + double p() const {return __p_.p();} + + param_type param() const {return __p_;} + void param(const param_type& __p) {__p_ = __p;} + + result_type min() const {return 0;} + result_type max() const {return numeric_limits::max();} + + friend bool operator==(const negative_binomial_distribution& __x, + const negative_binomial_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend bool operator!=(const negative_binomial_distribution& __x, + const negative_binomial_distribution& __y) + {return !(__x == __y);} +}; + +template +template +_IntType +negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr) +{ + result_type __k = __pr.k(); + double __p = __pr.p(); + if (__k <= 21 * __p) + { + bernoulli_distribution __gen(__p); + result_type __f = 0; + result_type __s = 0; + while (__s < __k) + { + if (__gen(__urng)) + ++__s; + else + ++__f; + } + return __f; + } + return poisson_distribution(gamma_distribution + (__k, (1-__p)/__p)(__urng))(__urng); +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const negative_binomial_distribution<_IntType>& __x) +{ + __save_flags<_CharT, _Traits> _(__os); + __os.flags(ios_base::dec | ios_base::left); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + return __os << __x.k() << __sp << __x.p(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + negative_binomial_distribution<_IntType>& __x) +{ + typedef negative_binomial_distribution<_IntType> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> _(__is); + __is.flags(ios_base::dec | ios_base::skipws); + result_type __k; + double __p; + __is >> __k >> __p; + if (!__is.fail()) + __x.param(param_type(__k, __p)); + return __is; +} + // chi_squared_distribution template diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp index 7ff25d546704..71bbf198b5ed 100644 --- a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp @@ -14,8 +14,6 @@ // template result_type operator()(_URNG& g); -#include - #include #include #include diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/assign.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/assign.pass.cpp new file mode 100644 index 000000000000..edf7436c1324 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/assign.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// negative_binomial_distribution& operator=(const negative_binomial_distribution&); + +#include +#include + +void +test1() +{ + typedef std::negative_binomial_distribution<> D; + D d1(2, 0.75); + D d2; + assert(d1 != d2); + d2 = d1; + assert(d1 == d2); +} + +int main() +{ + test1(); +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/copy.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/copy.pass.cpp new file mode 100644 index 000000000000..d1dadb908b9f --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/copy.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// negative_binomial_distribution(const negative_binomial_distribution&); + +#include +#include + +void +test1() +{ + typedef std::negative_binomial_distribution<> D; + D d1(2, 0.75); + D d2 = d1; + assert(d1 == d2); +} + +int main() +{ + test1(); +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp new file mode 100644 index 000000000000..601d575148c6 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// explicit negative_binomial_distribution(IntType t = 1, double p = 0.5); + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + D d; + assert(d.k() == 1); + assert(d.p() == 0.5); + } + { + typedef std::negative_binomial_distribution<> D; + D d(3); + assert(d.k() == 3); + assert(d.p() == 0.5); + } + { + typedef std::negative_binomial_distribution<> D; + D d(3, 0.75); + assert(d.k() == 3); + assert(d.p() == 0.75); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_param.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_param.pass.cpp new file mode 100644 index 000000000000..37bd125e8b59 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_param.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// explicit negative_binomial_distribution(const param_type& parm); + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type P; + P p(5, 0.25); + D d(p); + assert(d.k() == 5); + assert(d.p() == 0.25); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eq.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eq.pass.cpp new file mode 100644 index 000000000000..9c264cf76e64 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eq.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// bool operator=(const negative_binomial_distribution& x, +// const negative_binomial_distribution& y); +// bool operator!(const negative_binomial_distribution& x, +// const negative_binomial_distribution& y); + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + D d1(3, .25); + D d2(3, .25); + assert(d1 == d2); + } + { + typedef std::negative_binomial_distribution<> D; + D d1(3, .28); + D d2(3, .25); + assert(d1 != d2); + } + { + typedef std::negative_binomial_distribution<> D; + D d1(3, .25); + D d2(4, .25); + assert(d1 != d2); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval.pass.cpp new file mode 100644 index 000000000000..96b4c1802614 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval.pass.cpp @@ -0,0 +1,270 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// template result_type operator()(_URNG& g); + +#include +#include +#include +#include + +template +inline +T +sqr(T x) +{ + return x * x; +} + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef std::minstd_rand G; + G g; + D d(5, .25); + const int N = 1000000; + std::vector 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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); + } + { + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(30, .03125); + const int N = 1000000; + std::vector 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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); + } + { + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(40, .25); + const int N = 1000000; + std::vector 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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); + } + { + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(40, 1); + const int N = 1000; + std::vector 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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); + } + { + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(400, 0.5); + const int N = 1000000; + std::vector 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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); + } + { + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(1, 0.05); + const int N = 1000000; + std::vector 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval_param.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval_param.pass.cpp new file mode 100644 index 000000000000..b8906721e618 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval_param.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// template result_type operator()(_URNG& g, const param_type& parm); + +#include +#include +#include +#include + +template +inline +T +sqr(T x) +{ + return x * x; +} + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type P; + typedef std::minstd_rand G; + G g; + D d(16, .75); + P p(5, .75); + const int N = 1000000; + std::vector u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g, p); + 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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 = p.k() * (1 - p.p()) / p.p(); + double x_var = x_mean / p.p(); + double x_skew = (2 - p.p()) / std::sqrt(p.k() * (1 - p.p())); + double x_kurtosis = 6. / p.k() + sqr(p.p()) / (p.k() * (1 - p.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); + } + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(16, .75); + P p(30, .03125); + const int N = 1000000; + std::vector u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g, p); + 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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 = p.k() * (1 - p.p()) / p.p(); + double x_var = x_mean / p.p(); + double x_skew = (2 - p.p()) / std::sqrt(p.k() * (1 - p.p())); + double x_kurtosis = 6. / p.k() + sqr(p.p()) / (p.k() * (1 - p.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); + } + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(16, .75); + P p(40, .25); + const int N = 1000000; + std::vector u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g, p); + 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 (int i = 0; i < u.size(); ++i) + { + double d = (u[i] - mean); + double d2 = sqr(d); + var += d2; + skew += d * 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 = p.k() * (1 - p.p()) / p.p(); + double x_var = x_mean / p.p(); + double x_skew = (2 - p.p()) / std::sqrt(p.k() * (1 - p.p())); + double x_kurtosis = 6. / p.k() + sqr(p.p()) / (p.k() * (1 - p.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); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/get_param.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/get_param.pass.cpp new file mode 100644 index 000000000000..8ea477095752 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/get_param.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// param_type param() const; + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type P; + P p(5, .125); + D d(p); + assert(d.param() == p); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp new file mode 100644 index 000000000000..ed72ff12a488 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// template +// basic_ostream& +// operator<<(basic_ostream& os, +// const negative_binomial_distribution& x); +// +// template +// basic_istream& +// operator>>(basic_istream& is, +// negative_binomial_distribution& x); + +#include +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + D d1(7, .25); + std::ostringstream os; + os << d1; + std::istringstream is(os.str()); + D d2; + is >> d2; + assert(d1 == d2); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/max.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/max.pass.cpp new file mode 100644 index 000000000000..558ea8d77ce5 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/max.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// result_type max() const; + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + D d(4, .25); + assert(d.max() == std::numeric_limits::max()); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/min.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/min.pass.cpp new file mode 100644 index 000000000000..139c51cd1ea5 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/min.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// result_type min() const; + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + D d(4, .5); + assert(d.min() == 0); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_assign.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_assign.pass.cpp new file mode 100644 index 000000000000..f01485284fae --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_assign.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution +// { +// class param_type; + +#include +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type param_type; + param_type p0(6, .7); + param_type p; + p = p0; + assert(p.k() == 6); + assert(p.p() == .7); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_copy.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_copy.pass.cpp new file mode 100644 index 000000000000..a4af47b83379 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_copy.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution +// { +// class param_type; + +#include +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type param_type; + param_type p0(10, .125); + param_type p = p0; + assert(p.k() == 10); + assert(p.p() == .125); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_ctor.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_ctor.pass.cpp new file mode 100644 index 000000000000..9b657b4d607b --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_ctor.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution +// { +// class param_type; + +#include +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type param_type; + param_type p; + assert(p.k() == 1); + assert(p.p() == 0.5); + } + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type param_type; + param_type p(10); + assert(p.k() == 10); + assert(p.p() == 0.5); + } + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type param_type; + param_type p(10, 0.25); + assert(p.k() == 10); + assert(p.p() == 0.25); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_eq.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_eq.pass.cpp new file mode 100644 index 000000000000..0d1fe9fd19f4 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_eq.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution +// { +// class param_type; + +#include +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type param_type; + param_type p1(3, 0.75); + param_type p2(3, 0.75); + assert(p1 == p2); + } + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type param_type; + param_type p1(3, 0.75); + param_type p2(3, 0.5); + assert(p1 != p2); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_types.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_types.pass.cpp new file mode 100644 index 000000000000..85ab987e8182 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/param_types.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution +// { +// class param_type; + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type param_type; + typedef param_type::distribution_type distribution_type; + static_assert((std::is_same::value), ""); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/set_param.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/set_param.pass.cpp new file mode 100644 index 000000000000..fec8aeace214 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/set_param.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution + +// void param(const param_type& parm); + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::param_type P; + P p(10, 0.25); + D d(8, 0.75); + d.param(p); + assert(d.param() == p); + } +} diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/types.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/types.pass.cpp new file mode 100644 index 000000000000..fc4062f251b2 --- /dev/null +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/types.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class negative_binomial_distribution +// { +// typedef bool result_type; + +#include +#include + +int main() +{ + { + typedef std::negative_binomial_distribution<> D; + typedef D::result_type result_type; + static_assert((std::is_same::value), ""); + } + { + typedef std::negative_binomial_distribution D; + typedef D::result_type result_type; + static_assert((std::is_same::value), ""); + } +} diff --git a/libcxx/test/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp b/libcxx/test/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp index afeeeb242ccd..44cf901d007a 100644 --- a/libcxx/test/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp +++ b/libcxx/test/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp @@ -15,8 +15,6 @@ #include #include -#include - int main() { {