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 // REQUIRES: long_tests 10eb1c5037SNikolas Klauser 11eb1c5037SNikolas Klauser // <random> 12eb1c5037SNikolas Klauser 13eb1c5037SNikolas Klauser // template<class IntType = int> 14eb1c5037SNikolas Klauser // class binomial_distribution 15eb1c5037SNikolas Klauser 16eb1c5037SNikolas Klauser // template<class _URNG> result_type operator()(_URNG& g); 17eb1c5037SNikolas Klauser 18eb1c5037SNikolas Klauser #include <cassert> 19*09e3a360SLouis Dionne #include <cmath> 200a4aa8a1SNikolas Klauser #include <cstdint> 210a4aa8a1SNikolas Klauser #include <numeric> 220a4aa8a1SNikolas Klauser #include <random> 230a4aa8a1SNikolas Klauser #include <type_traits> 240a4aa8a1SNikolas Klauser #include <vector> 25eb1c5037SNikolas Klauser 2607e984bcSLouis Dionne #include "test_macros.h" 2707e984bcSLouis Dionne 28eb1c5037SNikolas Klauser template <class T> 2907e984bcSLouis Dionne T sqr(T x) { 30eb1c5037SNikolas Klauser return x * x; 31eb1c5037SNikolas Klauser } 32eb1c5037SNikolas Klauser 3307e984bcSLouis Dionne template <class T> 3407e984bcSLouis Dionne void test1() { 3507e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 36eb1c5037SNikolas Klauser typedef std::mt19937_64 G; 37eb1c5037SNikolas Klauser G g; 38eb1c5037SNikolas Klauser D d(5, .75); 39eb1c5037SNikolas Klauser const int N = 1000000; 4007e984bcSLouis Dionne std::vector<typename D::result_type> u; 41eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 42eb1c5037SNikolas Klauser { 4307e984bcSLouis Dionne typename D::result_type v = d(g); 44eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 45eb1c5037SNikolas Klauser u.push_back(v); 46eb1c5037SNikolas Klauser } 47eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 48eb1c5037SNikolas Klauser double(0)) / u.size(); 49eb1c5037SNikolas Klauser double var = 0; 50eb1c5037SNikolas Klauser double skew = 0; 51eb1c5037SNikolas Klauser double kurtosis = 0; 52eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 53eb1c5037SNikolas Klauser { 54eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 55eb1c5037SNikolas Klauser double d2 = sqr(dbl); 56eb1c5037SNikolas Klauser var += d2; 57eb1c5037SNikolas Klauser skew += dbl * d2; 58eb1c5037SNikolas Klauser kurtosis += d2 * d2; 59eb1c5037SNikolas Klauser } 60eb1c5037SNikolas Klauser var /= u.size(); 61eb1c5037SNikolas Klauser double dev = std::sqrt(var); 62eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 63eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 64eb1c5037SNikolas Klauser kurtosis -= 3; 65eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 66eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 67eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 68eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 69eb1c5037SNikolas Klauser assert(std::abs((mean - x_mean) / x_mean) < 0.01); 70eb1c5037SNikolas Klauser assert(std::abs((var - x_var) / x_var) < 0.01); 71eb1c5037SNikolas Klauser assert(std::abs((skew - x_skew) / x_skew) < 0.01); 7276aa042dSMatt Stephanson assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.08); 73eb1c5037SNikolas Klauser } 74eb1c5037SNikolas Klauser 7507e984bcSLouis Dionne template <class T> 7607e984bcSLouis Dionne void test2() { 7707e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 78eb1c5037SNikolas Klauser typedef std::mt19937 G; 79eb1c5037SNikolas Klauser G g; 80eb1c5037SNikolas Klauser D d(30, .03125); 81eb1c5037SNikolas Klauser const int N = 100000; 8207e984bcSLouis Dionne std::vector<typename D::result_type> u; 83eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 84eb1c5037SNikolas Klauser { 8507e984bcSLouis Dionne typename D::result_type v = d(g); 86eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 87eb1c5037SNikolas Klauser u.push_back(v); 88eb1c5037SNikolas Klauser } 89eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 90eb1c5037SNikolas Klauser double(0)) / u.size(); 91eb1c5037SNikolas Klauser double var = 0; 92eb1c5037SNikolas Klauser double skew = 0; 93eb1c5037SNikolas Klauser double kurtosis = 0; 94eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 95eb1c5037SNikolas Klauser { 96eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 97eb1c5037SNikolas Klauser double d2 = sqr(dbl); 98eb1c5037SNikolas Klauser var += d2; 99eb1c5037SNikolas Klauser skew += dbl * d2; 100eb1c5037SNikolas Klauser kurtosis += d2 * d2; 101eb1c5037SNikolas Klauser } 102eb1c5037SNikolas Klauser var /= u.size(); 103eb1c5037SNikolas Klauser double dev = std::sqrt(var); 104eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 105eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 106eb1c5037SNikolas Klauser kurtosis -= 3; 107eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 108eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 109eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 110eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 111eb1c5037SNikolas Klauser assert(std::abs((mean - x_mean) / x_mean) < 0.01); 112eb1c5037SNikolas Klauser assert(std::abs((var - x_var) / x_var) < 0.01); 11376aa042dSMatt Stephanson assert(std::abs((skew - x_skew) / x_skew) < 0.02); 11476aa042dSMatt Stephanson assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.08); 115eb1c5037SNikolas Klauser } 116eb1c5037SNikolas Klauser 11707e984bcSLouis Dionne template <class T> 11807e984bcSLouis Dionne void test3() { 11907e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 120eb1c5037SNikolas Klauser typedef std::mt19937 G; 121eb1c5037SNikolas Klauser G g; 122eb1c5037SNikolas Klauser D d(40, .25); 123eb1c5037SNikolas Klauser const int N = 100000; 12407e984bcSLouis Dionne std::vector<typename D::result_type> u; 125eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 126eb1c5037SNikolas Klauser { 12707e984bcSLouis Dionne typename D::result_type v = d(g); 128eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 129eb1c5037SNikolas Klauser u.push_back(v); 130eb1c5037SNikolas Klauser } 131eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 132eb1c5037SNikolas Klauser double(0)) / u.size(); 133eb1c5037SNikolas Klauser double var = 0; 134eb1c5037SNikolas Klauser double skew = 0; 135eb1c5037SNikolas Klauser double kurtosis = 0; 136eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 137eb1c5037SNikolas Klauser { 138eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 139eb1c5037SNikolas Klauser double d2 = sqr(dbl); 140eb1c5037SNikolas Klauser var += d2; 141eb1c5037SNikolas Klauser skew += dbl * d2; 142eb1c5037SNikolas Klauser kurtosis += d2 * d2; 143eb1c5037SNikolas Klauser } 144eb1c5037SNikolas Klauser var /= u.size(); 145eb1c5037SNikolas Klauser double dev = std::sqrt(var); 146eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 147eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 148eb1c5037SNikolas Klauser kurtosis -= 3; 149eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 150eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 151eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 152eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 153eb1c5037SNikolas Klauser assert(std::abs((mean - x_mean) / x_mean) < 0.01); 154eb1c5037SNikolas Klauser assert(std::abs((var - x_var) / x_var) < 0.01); 15576aa042dSMatt Stephanson assert(std::abs((skew - x_skew) / x_skew) < 0.07); 15676aa042dSMatt Stephanson assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 2.0); 157eb1c5037SNikolas Klauser } 158eb1c5037SNikolas Klauser 15907e984bcSLouis Dionne template <class T> 16007e984bcSLouis Dionne void test4() { 16107e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 162eb1c5037SNikolas Klauser typedef std::mt19937 G; 163eb1c5037SNikolas Klauser G g; 164eb1c5037SNikolas Klauser D d(40, 0); 165eb1c5037SNikolas Klauser const int N = 100000; 16607e984bcSLouis Dionne std::vector<typename D::result_type> u; 167eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 168eb1c5037SNikolas Klauser { 16907e984bcSLouis Dionne typename D::result_type v = d(g); 170eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 171eb1c5037SNikolas Klauser u.push_back(v); 172eb1c5037SNikolas Klauser } 173eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 174eb1c5037SNikolas Klauser double(0)) / u.size(); 175eb1c5037SNikolas Klauser double var = 0; 176eb1c5037SNikolas Klauser double skew = 0; 177eb1c5037SNikolas Klauser double kurtosis = 0; 178eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 179eb1c5037SNikolas Klauser { 180eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 181eb1c5037SNikolas Klauser double d2 = sqr(dbl); 182eb1c5037SNikolas Klauser var += d2; 183eb1c5037SNikolas Klauser skew += dbl * d2; 184eb1c5037SNikolas Klauser kurtosis += d2 * d2; 185eb1c5037SNikolas Klauser } 186eb1c5037SNikolas Klauser var /= u.size(); 187eb1c5037SNikolas Klauser double dev = std::sqrt(var); 188eb1c5037SNikolas Klauser // In this case: 189eb1c5037SNikolas Klauser // skew computes to 0./0. == nan 190eb1c5037SNikolas Klauser // kurtosis computes to 0./0. == nan 191eb1c5037SNikolas Klauser // x_skew == inf 192eb1c5037SNikolas Klauser // x_kurtosis == inf 193eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 194eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 195eb1c5037SNikolas Klauser kurtosis -= 3; 196eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 197eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 198eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 199eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 200eb1c5037SNikolas Klauser assert(mean == x_mean); 201eb1c5037SNikolas Klauser assert(var == x_var); 202eb1c5037SNikolas Klauser // assert(skew == x_skew); 203eb1c5037SNikolas Klauser (void)skew; (void)x_skew; 204eb1c5037SNikolas Klauser // assert(kurtosis == x_kurtosis); 205eb1c5037SNikolas Klauser (void)kurtosis; (void)x_kurtosis; 206eb1c5037SNikolas Klauser } 207eb1c5037SNikolas Klauser 20807e984bcSLouis Dionne template <class T> 20907e984bcSLouis Dionne void test5() { 21007e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 211eb1c5037SNikolas Klauser typedef std::mt19937 G; 212eb1c5037SNikolas Klauser G g; 213eb1c5037SNikolas Klauser D d(40, 1); 214eb1c5037SNikolas Klauser const int N = 100000; 21507e984bcSLouis Dionne std::vector<typename D::result_type> u; 216eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 217eb1c5037SNikolas Klauser { 21807e984bcSLouis Dionne typename D::result_type v = d(g); 219eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 220eb1c5037SNikolas Klauser u.push_back(v); 221eb1c5037SNikolas Klauser } 222eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 223eb1c5037SNikolas Klauser double(0)) / u.size(); 224eb1c5037SNikolas Klauser double var = 0; 225eb1c5037SNikolas Klauser double skew = 0; 226eb1c5037SNikolas Klauser double kurtosis = 0; 227eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 228eb1c5037SNikolas Klauser { 229eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 230eb1c5037SNikolas Klauser double d2 = sqr(dbl); 231eb1c5037SNikolas Klauser var += d2; 232eb1c5037SNikolas Klauser skew += dbl * d2; 233eb1c5037SNikolas Klauser kurtosis += d2 * d2; 234eb1c5037SNikolas Klauser } 235eb1c5037SNikolas Klauser var /= u.size(); 236eb1c5037SNikolas Klauser double dev = std::sqrt(var); 237eb1c5037SNikolas Klauser // In this case: 238eb1c5037SNikolas Klauser // skew computes to 0./0. == nan 239eb1c5037SNikolas Klauser // kurtosis computes to 0./0. == nan 240eb1c5037SNikolas Klauser // x_skew == -inf 241eb1c5037SNikolas Klauser // x_kurtosis == inf 242eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 243eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 244eb1c5037SNikolas Klauser kurtosis -= 3; 245eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 246eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 247eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 248eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 249eb1c5037SNikolas Klauser assert(mean == x_mean); 250eb1c5037SNikolas Klauser assert(var == x_var); 251eb1c5037SNikolas Klauser // assert(skew == x_skew); 252eb1c5037SNikolas Klauser (void)skew; (void)x_skew; 253eb1c5037SNikolas Klauser // assert(kurtosis == x_kurtosis); 254eb1c5037SNikolas Klauser (void)kurtosis; (void)x_kurtosis; 255eb1c5037SNikolas Klauser } 256eb1c5037SNikolas Klauser 25707e984bcSLouis Dionne template <class T> 25807e984bcSLouis Dionne void test6() { 25907e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 260eb1c5037SNikolas Klauser typedef std::mt19937 G; 261eb1c5037SNikolas Klauser G g; 26207e984bcSLouis Dionne D d(127, 0.5); 263eb1c5037SNikolas Klauser const int N = 100000; 26407e984bcSLouis Dionne std::vector<typename D::result_type> u; 265eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 266eb1c5037SNikolas Klauser { 26707e984bcSLouis Dionne typename D::result_type v = d(g); 268eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 269eb1c5037SNikolas Klauser u.push_back(v); 270eb1c5037SNikolas Klauser } 271eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 272eb1c5037SNikolas Klauser double(0)) / u.size(); 273eb1c5037SNikolas Klauser double var = 0; 274eb1c5037SNikolas Klauser double skew = 0; 275eb1c5037SNikolas Klauser double kurtosis = 0; 276eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 277eb1c5037SNikolas Klauser { 278eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 279eb1c5037SNikolas Klauser double d2 = sqr(dbl); 280eb1c5037SNikolas Klauser var += d2; 281eb1c5037SNikolas Klauser skew += dbl * d2; 282eb1c5037SNikolas Klauser kurtosis += d2 * d2; 283eb1c5037SNikolas Klauser } 284eb1c5037SNikolas Klauser var /= u.size(); 285eb1c5037SNikolas Klauser double dev = std::sqrt(var); 286eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 287eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 288eb1c5037SNikolas Klauser kurtosis -= 3; 289eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 290eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 291eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 292eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 293eb1c5037SNikolas Klauser assert(std::abs((mean - x_mean) / x_mean) < 0.01); 294eb1c5037SNikolas Klauser assert(std::abs((var - x_var) / x_var) < 0.01); 29507e984bcSLouis Dionne assert(std::abs(skew - x_skew) < 0.02); 29676aa042dSMatt Stephanson assert(std::abs(kurtosis - x_kurtosis) < 0.03); 297eb1c5037SNikolas Klauser } 298eb1c5037SNikolas Klauser 29907e984bcSLouis Dionne template <class T> 30007e984bcSLouis Dionne void test7() { 30107e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 302eb1c5037SNikolas Klauser typedef std::mt19937 G; 303eb1c5037SNikolas Klauser G g; 304eb1c5037SNikolas Klauser D d(1, 0.5); 305eb1c5037SNikolas Klauser const int N = 100000; 30607e984bcSLouis Dionne std::vector<typename D::result_type> u; 307eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 308eb1c5037SNikolas Klauser { 30907e984bcSLouis Dionne typename D::result_type v = d(g); 310eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 311eb1c5037SNikolas Klauser u.push_back(v); 312eb1c5037SNikolas Klauser } 313eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 314eb1c5037SNikolas Klauser double(0)) / u.size(); 315eb1c5037SNikolas Klauser double var = 0; 316eb1c5037SNikolas Klauser double skew = 0; 317eb1c5037SNikolas Klauser double kurtosis = 0; 318eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 319eb1c5037SNikolas Klauser { 320eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 321eb1c5037SNikolas Klauser double d2 = sqr(dbl); 322eb1c5037SNikolas Klauser var += d2; 323eb1c5037SNikolas Klauser skew += dbl * d2; 324eb1c5037SNikolas Klauser kurtosis += d2 * d2; 325eb1c5037SNikolas Klauser } 326eb1c5037SNikolas Klauser var /= u.size(); 327eb1c5037SNikolas Klauser double dev = std::sqrt(var); 328eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 329eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 330eb1c5037SNikolas Klauser kurtosis -= 3; 331eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 332eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 333eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 334eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 335eb1c5037SNikolas Klauser assert(std::abs((mean - x_mean) / x_mean) < 0.01); 336eb1c5037SNikolas Klauser assert(std::abs((var - x_var) / x_var) < 0.01); 337eb1c5037SNikolas Klauser assert(std::abs(skew - x_skew) < 0.01); 338eb1c5037SNikolas Klauser assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); 339eb1c5037SNikolas Klauser } 340eb1c5037SNikolas Klauser 34107e984bcSLouis Dionne template <class T> 34207e984bcSLouis Dionne void test8() { 343eb1c5037SNikolas Klauser const int N = 100000; 344eb1c5037SNikolas Klauser std::mt19937 gen1; 345eb1c5037SNikolas Klauser std::mt19937 gen2; 346eb1c5037SNikolas Klauser 34707e984bcSLouis Dionne using UnsignedT = typename std::make_unsigned<T>::type; 34807e984bcSLouis Dionne std::binomial_distribution<T> dist1(5, 0.1); 34907e984bcSLouis Dionne std::binomial_distribution<UnsignedT> dist2(5, 0.1); 350eb1c5037SNikolas Klauser 351eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) { 35207e984bcSLouis Dionne T r1 = dist1(gen1); 35307e984bcSLouis Dionne UnsignedT r2 = dist2(gen2); 354eb1c5037SNikolas Klauser assert(r1 >= 0); 35507e984bcSLouis Dionne assert(static_cast<UnsignedT>(r1) == r2); 356eb1c5037SNikolas Klauser } 357eb1c5037SNikolas Klauser } 358eb1c5037SNikolas Klauser 35907e984bcSLouis Dionne template <class T> 36007e984bcSLouis Dionne void test9() { 36107e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 362eb1c5037SNikolas Klauser typedef std::mt19937 G; 363eb1c5037SNikolas Klauser G g; 364eb1c5037SNikolas Klauser D d(0, 0.005); 365eb1c5037SNikolas Klauser const int N = 100000; 36607e984bcSLouis Dionne std::vector<typename D::result_type> u; 367eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 368eb1c5037SNikolas Klauser { 36907e984bcSLouis Dionne typename D::result_type v = d(g); 370eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 371eb1c5037SNikolas Klauser u.push_back(v); 372eb1c5037SNikolas Klauser } 373eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 374eb1c5037SNikolas Klauser double(0)) / u.size(); 375eb1c5037SNikolas Klauser double var = 0; 376eb1c5037SNikolas Klauser double skew = 0; 377eb1c5037SNikolas Klauser double kurtosis = 0; 378eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 379eb1c5037SNikolas Klauser { 380eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 381eb1c5037SNikolas Klauser double d2 = sqr(dbl); 382eb1c5037SNikolas Klauser var += d2; 383eb1c5037SNikolas Klauser skew += dbl * d2; 384eb1c5037SNikolas Klauser kurtosis += d2 * d2; 385eb1c5037SNikolas Klauser } 386eb1c5037SNikolas Klauser var /= u.size(); 387eb1c5037SNikolas Klauser double dev = std::sqrt(var); 388eb1c5037SNikolas Klauser // In this case: 389eb1c5037SNikolas Klauser // skew computes to 0./0. == nan 390eb1c5037SNikolas Klauser // kurtosis computes to 0./0. == nan 391eb1c5037SNikolas Klauser // x_skew == inf 392eb1c5037SNikolas Klauser // x_kurtosis == inf 393eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 394eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 395eb1c5037SNikolas Klauser kurtosis -= 3; 396eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 397eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 398eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 399eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 400eb1c5037SNikolas Klauser assert(mean == x_mean); 401eb1c5037SNikolas Klauser assert(var == x_var); 402eb1c5037SNikolas Klauser // assert(skew == x_skew); 403eb1c5037SNikolas Klauser (void)skew; (void)x_skew; 404eb1c5037SNikolas Klauser // assert(kurtosis == x_kurtosis); 405eb1c5037SNikolas Klauser (void)kurtosis; (void)x_kurtosis; 406eb1c5037SNikolas Klauser } 407eb1c5037SNikolas Klauser 40807e984bcSLouis Dionne template <class T> 40907e984bcSLouis Dionne void test10() { 41007e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 411eb1c5037SNikolas Klauser typedef std::mt19937 G; 412eb1c5037SNikolas Klauser G g; 413eb1c5037SNikolas Klauser D d(0, 0); 414eb1c5037SNikolas Klauser const int N = 100000; 41507e984bcSLouis Dionne std::vector<typename D::result_type> u; 416eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 417eb1c5037SNikolas Klauser { 41807e984bcSLouis Dionne typename D::result_type v = d(g); 419eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 420eb1c5037SNikolas Klauser u.push_back(v); 421eb1c5037SNikolas Klauser } 422eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 423eb1c5037SNikolas Klauser double(0)) / u.size(); 424eb1c5037SNikolas Klauser double var = 0; 425eb1c5037SNikolas Klauser double skew = 0; 426eb1c5037SNikolas Klauser double kurtosis = 0; 427eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 428eb1c5037SNikolas Klauser { 429eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 430eb1c5037SNikolas Klauser double d2 = sqr(dbl); 431eb1c5037SNikolas Klauser var += d2; 432eb1c5037SNikolas Klauser skew += dbl * d2; 433eb1c5037SNikolas Klauser kurtosis += d2 * d2; 434eb1c5037SNikolas Klauser } 435eb1c5037SNikolas Klauser var /= u.size(); 436eb1c5037SNikolas Klauser double dev = std::sqrt(var); 437eb1c5037SNikolas Klauser // In this case: 438eb1c5037SNikolas Klauser // skew computes to 0./0. == nan 439eb1c5037SNikolas Klauser // kurtosis computes to 0./0. == nan 440eb1c5037SNikolas Klauser // x_skew == inf 441eb1c5037SNikolas Klauser // x_kurtosis == inf 442eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 443eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 444eb1c5037SNikolas Klauser kurtosis -= 3; 445eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 446eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 447eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 448eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 449eb1c5037SNikolas Klauser assert(mean == x_mean); 450eb1c5037SNikolas Klauser assert(var == x_var); 451eb1c5037SNikolas Klauser // assert(skew == x_skew); 452eb1c5037SNikolas Klauser (void)skew; (void)x_skew; 453eb1c5037SNikolas Klauser // assert(kurtosis == x_kurtosis); 454eb1c5037SNikolas Klauser (void)kurtosis; (void)x_kurtosis; 455eb1c5037SNikolas Klauser } 456eb1c5037SNikolas Klauser 45707e984bcSLouis Dionne template <class T> 45807e984bcSLouis Dionne void test11() { 45907e984bcSLouis Dionne typedef std::binomial_distribution<T> D; 460eb1c5037SNikolas Klauser typedef std::mt19937 G; 461eb1c5037SNikolas Klauser G g; 462eb1c5037SNikolas Klauser D d(0, 1); 463eb1c5037SNikolas Klauser const int N = 100000; 46407e984bcSLouis Dionne std::vector<typename D::result_type> u; 465eb1c5037SNikolas Klauser for (int i = 0; i < N; ++i) 466eb1c5037SNikolas Klauser { 46707e984bcSLouis Dionne typename D::result_type v = d(g); 468eb1c5037SNikolas Klauser assert(d.min() <= v && v <= d.max()); 469eb1c5037SNikolas Klauser u.push_back(v); 470eb1c5037SNikolas Klauser } 471eb1c5037SNikolas Klauser double mean = std::accumulate(u.begin(), u.end(), 472eb1c5037SNikolas Klauser double(0)) / u.size(); 473eb1c5037SNikolas Klauser double var = 0; 474eb1c5037SNikolas Klauser double skew = 0; 475eb1c5037SNikolas Klauser double kurtosis = 0; 476eb1c5037SNikolas Klauser for (unsigned i = 0; i < u.size(); ++i) 477eb1c5037SNikolas Klauser { 478eb1c5037SNikolas Klauser double dbl = (u[i] - mean); 479eb1c5037SNikolas Klauser double d2 = sqr(dbl); 480eb1c5037SNikolas Klauser var += d2; 481eb1c5037SNikolas Klauser skew += dbl * d2; 482eb1c5037SNikolas Klauser kurtosis += d2 * d2; 483eb1c5037SNikolas Klauser } 484eb1c5037SNikolas Klauser var /= u.size(); 485eb1c5037SNikolas Klauser double dev = std::sqrt(var); 486eb1c5037SNikolas Klauser // In this case: 487eb1c5037SNikolas Klauser // skew computes to 0./0. == nan 488eb1c5037SNikolas Klauser // kurtosis computes to 0./0. == nan 489eb1c5037SNikolas Klauser // x_skew == -inf 490eb1c5037SNikolas Klauser // x_kurtosis == inf 491eb1c5037SNikolas Klauser skew /= u.size() * dev * var; 492eb1c5037SNikolas Klauser kurtosis /= u.size() * var * var; 493eb1c5037SNikolas Klauser kurtosis -= 3; 494eb1c5037SNikolas Klauser double x_mean = d.t() * d.p(); 495eb1c5037SNikolas Klauser double x_var = x_mean*(1-d.p()); 496eb1c5037SNikolas Klauser double x_skew = (1-2*d.p()) / std::sqrt(x_var); 497eb1c5037SNikolas Klauser double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; 498eb1c5037SNikolas Klauser assert(mean == x_mean); 499eb1c5037SNikolas Klauser assert(var == x_var); 500eb1c5037SNikolas Klauser // assert(skew == x_skew); 501eb1c5037SNikolas Klauser (void)skew; (void)x_skew; 502eb1c5037SNikolas Klauser // assert(kurtosis == x_kurtosis); 503eb1c5037SNikolas Klauser (void)kurtosis; (void)x_kurtosis; 504eb1c5037SNikolas Klauser } 505eb1c5037SNikolas Klauser 50607e984bcSLouis Dionne template <class T> 50707e984bcSLouis Dionne void tests() { 50807e984bcSLouis Dionne test1<T>(); 50907e984bcSLouis Dionne test2<T>(); 51007e984bcSLouis Dionne test3<T>(); 51107e984bcSLouis Dionne test4<T>(); 51207e984bcSLouis Dionne test5<T>(); 51307e984bcSLouis Dionne test6<T>(); 51407e984bcSLouis Dionne test7<T>(); 51507e984bcSLouis Dionne test8<T>(); 51607e984bcSLouis Dionne test9<T>(); 51707e984bcSLouis Dionne test10<T>(); 51807e984bcSLouis Dionne test11<T>(); 51907e984bcSLouis Dionne } 52007e984bcSLouis Dionne 52107e984bcSLouis Dionne int main(int, char**) { 52207e984bcSLouis Dionne tests<short>(); 52307e984bcSLouis Dionne tests<int>(); 52407e984bcSLouis Dionne tests<long>(); 52507e984bcSLouis Dionne tests<long long>(); 52607e984bcSLouis Dionne 52707e984bcSLouis Dionne tests<unsigned short>(); 52807e984bcSLouis Dionne tests<unsigned int>(); 52907e984bcSLouis Dionne tests<unsigned long>(); 53007e984bcSLouis Dionne tests<unsigned long long>(); 53107e984bcSLouis Dionne 53207e984bcSLouis Dionne #if defined(_LIBCPP_VERSION) // extension 533bd5d0feeSMark de Wever tests<std::int8_t>(); 534bd5d0feeSMark de Wever tests<std::uint8_t>(); 53507e984bcSLouis Dionne #if !defined(TEST_HAS_NO_INT128) 53607e984bcSLouis Dionne tests<__int128_t>(); 53707e984bcSLouis Dionne tests<__uint128_t>(); 53807e984bcSLouis Dionne #endif 53907e984bcSLouis Dionne #endif 540eb1c5037SNikolas Klauser 541eb1c5037SNikolas Klauser return 0; 542eb1c5037SNikolas Klauser } 543