1eb1c5037SNikolas Klauser //===----------------------------------------------------------------------===// 2eb1c5037SNikolas Klauser // 3eb1c5037SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4eb1c5037SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5eb1c5037SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6eb1c5037SNikolas Klauser // 7eb1c5037SNikolas Klauser //===----------------------------------------------------------------------===// 8eb1c5037SNikolas Klauser 9eb1c5037SNikolas Klauser // <random> 10eb1c5037SNikolas Klauser 11eb1c5037SNikolas Klauser // class bernoulli_distribution 12eb1c5037SNikolas Klauser 13eb1c5037SNikolas Klauser // template<class _URNG> result_type operator()(_URNG& g); 14eb1c5037SNikolas Klauser 15eb1c5037SNikolas Klauser #include <random> 16*09e3a360SLouis Dionne #include <cassert> 17*09e3a360SLouis Dionne #include <cmath> 18*09e3a360SLouis Dionne #include <cstddef> 19eb1c5037SNikolas Klauser #include <numeric> 20eb1c5037SNikolas Klauser #include <vector> 21eb1c5037SNikolas Klauser 22eb1c5037SNikolas Klauser #include "test_macros.h" 23eb1c5037SNikolas Klauser 24eb1c5037SNikolas Klauser template <class T> 25eb1c5037SNikolas Klauser inline 26eb1c5037SNikolas Klauser T 27eb1c5037SNikolas Klauser sqr(T x) 28eb1c5037SNikolas Klauser { 29eb1c5037SNikolas Klauser return x * x; 30eb1c5037SNikolas Klauser } 31eb1c5037SNikolas Klauser 32eb1c5037SNikolas Klauser int main(int, char**) 33eb1c5037SNikolas Klauser { 34eb1c5037SNikolas Klauser { 35eb1c5037SNikolas Klauser typedef std::bernoulli_distribution D; 36eb1c5037SNikolas Klauser typedef std::minstd_rand G; 37eb1c5037SNikolas Klauser G g; 38eb1c5037SNikolas Klauser D d(.75); 39eb1c5037SNikolas Klauser const int N = 100000; 40eb1c5037SNikolas Klauser std::vector<D::result_type> u; 41eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 42eb1c5037SNikolas Klauser u.push_back(d(g)); 43eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 44eb1c5037SNikolas Klauser double(0)) / u.size(); 45eb1c5037SNikolas Klauser double var = 0; 46eb1c5037SNikolas Klauser double skew = 0; 47eb1c5037SNikolas Klauser double kurtosis = 0; 48eb1c5037SNikolas Klauser for (std::size_t i = 0; i < u.size(); ++i) 49eb1c5037SNikolas Klauser { 50eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 51eb1c5037SNikolas Klauser double d2 = sqr(dbl); 52eb1c5037SNikolas Klauser var += d2; 53eb1c5037SNikolas Klauser skew += dbl * d2; 54eb1c5037SNikolas Klauser kurtosis += d2 * d2; 55eb1c5037SNikolas Klauser } 56eb1c5037SNikolas Klauser var /= u.size(); 57eb1c5037SNikolas Klauser double dev = std::sqrt(var); 58eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 59eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 60eb1c5037SNikolas Klauser kurtosis -= 3; 61eb1c5037SNikolas Klauser double x_mean = d.p(); 62eb1c5037SNikolas Klauser double x_var = d.p()*(1-d.p()); 63eb1c5037SNikolas Klauser double x_skew = (1 - 2 * d.p())/std::sqrt(x_var); 64eb1c5037SNikolas Klauser double x_kurtosis = (6 * sqr(d.p()) - 6 * d.p() + 1)/x_var; 65eb1c5037SNikolas Klauser assert(std::abs((mean - x_mean) / x_mean) < 0.01); 66eb1c5037SNikolas Klauser assert(std::abs((var - x_var) / x_var) < 0.01); 6776aa042dSMatt Stephanson assert(std::abs((skew - x_skew) / x_skew) < 0.02); 6876aa042dSMatt Stephanson assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05); 69eb1c5037SNikolas Klauser } 70eb1c5037SNikolas Klauser { 71eb1c5037SNikolas Klauser typedef std::bernoulli_distribution D; 72eb1c5037SNikolas Klauser typedef std::minstd_rand G; 73eb1c5037SNikolas Klauser G g; 74eb1c5037SNikolas Klauser D d(.25); 75eb1c5037SNikolas Klauser const int N = 100000; 76eb1c5037SNikolas Klauser std::vector<D::result_type> u; 77eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 78eb1c5037SNikolas Klauser u.push_back(d(g)); 79eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 80eb1c5037SNikolas Klauser double(0)) / u.size(); 81eb1c5037SNikolas Klauser double var = 0; 82eb1c5037SNikolas Klauser double skew = 0; 83eb1c5037SNikolas Klauser double kurtosis = 0; 84eb1c5037SNikolas Klauser for (std::size_t i = 0; i < u.size(); ++i) 85eb1c5037SNikolas Klauser { 86eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 87eb1c5037SNikolas Klauser double d2 = sqr(dbl); 88eb1c5037SNikolas Klauser var += d2; 89eb1c5037SNikolas Klauser skew += dbl * d2; 90eb1c5037SNikolas Klauser kurtosis += d2 * d2; 91eb1c5037SNikolas Klauser } 92eb1c5037SNikolas Klauser var /= u.size(); 93eb1c5037SNikolas Klauser double dev = std::sqrt(var); 94eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 95eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 96eb1c5037SNikolas Klauser kurtosis -= 3; 97eb1c5037SNikolas Klauser double x_mean = d.p(); 98eb1c5037SNikolas Klauser double x_var = d.p()*(1-d.p()); 99eb1c5037SNikolas Klauser double x_skew = (1 - 2 * d.p())/std::sqrt(x_var); 100eb1c5037SNikolas Klauser double x_kurtosis = (6 * sqr(d.p()) - 6 * d.p() + 1)/x_var; 101eb1c5037SNikolas Klauser assert(std::abs((mean - x_mean) / x_mean) < 0.01); 102eb1c5037SNikolas Klauser assert(std::abs((var - x_var) / x_var) < 0.01); 10376aa042dSMatt Stephanson assert(std::abs((skew - x_skew) / x_skew) < 0.02); 10476aa042dSMatt Stephanson assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05); 105eb1c5037SNikolas Klauser } 106eb1c5037SNikolas Klauser 107eb1c5037SNikolas Klauser return 0; 108eb1c5037SNikolas Klauser } 109