321 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: long_tests10// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME11 12// <random>13 14// template<class IntType = int>15// class discrete_distribution16 17// template<class _URNG> result_type operator()(_URNG& g);18 19#include <cassert>20#include <cstdint>21#include <cstdlib>22#include <random>23#include <vector>24 25#include "test_macros.h"26 27template <class T>28void tests() {29 typedef long long Frequency;30 {31 typedef std::discrete_distribution<T> D;32 typedef std::minstd_rand G;33 G g;34 D d;35 const int N = 100;36 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));37 assert(u.max_size() > static_cast<unsigned long long>(d.max()));38 for (int i = 0; i < N; ++i)39 {40 typename D::result_type v = d(g);41 assert(d.min() <= v && v <= d.max());42 u[static_cast<std::size_t>(v)]++;43 }44 std::vector<double> prob = d.probabilities();45 for (unsigned i = 0; i < u.size(); ++i)46 assert((double)u[i]/N == prob[i]);47 }48 {49 typedef std::discrete_distribution<T> D;50 typedef std::minstd_rand G;51 G g;52 double p0[] = {.3};53 D d(p0, p0+1);54 const int N = 100;55 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));56 assert(u.max_size() > static_cast<unsigned long long>(d.max()));57 for (int i = 0; i < N; ++i)58 {59 typename D::result_type v = d(g);60 assert(d.min() <= v && v <= d.max());61 u[static_cast<std::size_t>(v)]++;62 }63 std::vector<double> prob = d.probabilities();64 for (unsigned i = 0; i < u.size(); ++i)65 assert((double)u[i]/N == prob[i]);66 }67 {68 typedef std::discrete_distribution<T> D;69 typedef std::minstd_rand G;70 G g;71 double p0[] = {.75, .25};72 D d(p0, p0+2);73 const int N = 1000000;74 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));75 assert(u.max_size() > static_cast<unsigned long long>(d.max()));76 for (int i = 0; i < N; ++i)77 {78 typename D::result_type v = d(g);79 assert(d.min() <= v && v <= d.max());80 u[static_cast<std::size_t>(v)]++;81 }82 std::vector<double> prob = d.probabilities();83 for (unsigned i = 0; i < u.size(); ++i)84 assert(std::abs((double)u[i] / N - prob[i]) / prob[i] < 0.0013);85 }86 {87 typedef std::discrete_distribution<T> D;88 typedef std::minstd_rand G;89 G g;90 double p0[] = {0, 1};91 D d(p0, p0+2);92 const int N = 1000000;93 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));94 assert(u.max_size() > static_cast<unsigned long long>(d.max()));95 for (int i = 0; i < N; ++i)96 {97 typename D::result_type v = d(g);98 assert(d.min() <= v && v <= d.max());99 u[static_cast<std::size_t>(v)]++;100 }101 std::vector<double> prob = d.probabilities();102 assert((double)u[0]/N == prob[0]);103 assert((double)u[1]/N == prob[1]);104 }105 {106 typedef std::discrete_distribution<T> D;107 typedef std::minstd_rand G;108 G g;109 double p0[] = {1, 0};110 D d(p0, p0+2);111 const int N = 1000000;112 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));113 assert(u.max_size() > static_cast<unsigned long long>(d.max()));114 for (int i = 0; i < N; ++i)115 {116 typename D::result_type v = d(g);117 assert(d.min() <= v && v <= d.max());118 u[static_cast<std::size_t>(v)]++;119 }120 std::vector<double> prob = d.probabilities();121 assert((double)u[0]/N == prob[0]);122 assert((double)u[1]/N == prob[1]);123 }124 {125 typedef std::discrete_distribution<T> D;126 typedef std::minstd_rand G;127 G g;128 double p0[] = {.3, .1, .6};129 D d(p0, p0+3);130 const int N = 10000000;131 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));132 assert(u.max_size() > static_cast<unsigned long long>(d.max()));133 for (int i = 0; i < N; ++i)134 {135 typename D::result_type v = d(g);136 assert(d.min() <= v && v <= d.max());137 u[static_cast<std::size_t>(v)]++;138 }139 std::vector<double> prob = d.probabilities();140 for (unsigned i = 0; i < u.size(); ++i)141 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);142 }143 {144 typedef std::discrete_distribution<T> D;145 typedef std::minstd_rand G;146 G g;147 double p0[] = {0, 25, 75};148 D d(p0, p0+3);149 const int N = 1000000;150 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));151 assert(u.max_size() > static_cast<unsigned long long>(d.max()));152 for (int i = 0; i < N; ++i)153 {154 typename D::result_type v = d(g);155 assert(d.min() <= v && v <= d.max());156 u[static_cast<std::size_t>(v)]++;157 }158 std::vector<double> prob = d.probabilities();159 for (unsigned i = 0; i < u.size(); ++i)160 if (prob[i] != 0)161 assert(std::abs((double)u[i] / N - prob[i]) / prob[i] < 0.0013);162 else163 assert(u[i] == 0);164 }165 {166 typedef std::discrete_distribution<T> D;167 typedef std::minstd_rand G;168 G g;169 double p0[] = {25, 0, 75};170 D d(p0, p0+3);171 const int N = 1000000;172 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));173 assert(u.max_size() > static_cast<unsigned long long>(d.max()));174 for (int i = 0; i < N; ++i)175 {176 typename D::result_type v = d(g);177 assert(d.min() <= v && v <= d.max());178 u[static_cast<std::size_t>(v)]++;179 }180 std::vector<double> prob = d.probabilities();181 for (unsigned i = 0; i < u.size(); ++i)182 if (prob[i] != 0)183 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);184 else185 assert(u[i] == 0);186 }187 {188 typedef std::discrete_distribution<T> D;189 typedef std::minstd_rand G;190 G g;191 double p0[] = {25, 75, 0};192 D d(p0, p0+3);193 const int N = 1000000;194 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));195 assert(u.max_size() > static_cast<unsigned long long>(d.max()));196 for (int i = 0; i < N; ++i)197 {198 typename D::result_type v = d(g);199 assert(d.min() <= v && v <= d.max());200 u[static_cast<std::size_t>(v)]++;201 }202 std::vector<double> prob = d.probabilities();203 for (unsigned i = 0; i < u.size(); ++i)204 if (prob[i] != 0)205 assert(std::abs((double)u[i] / N - prob[i]) / prob[i] < 0.0013);206 else207 assert(u[i] == 0);208 }209 {210 typedef std::discrete_distribution<T> D;211 typedef std::minstd_rand G;212 G g;213 double p0[] = {0, 0, 1};214 D d(p0, p0+3);215 const int N = 100;216 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));217 assert(u.max_size() > static_cast<unsigned long long>(d.max()));218 for (int i = 0; i < N; ++i)219 {220 typename D::result_type v = d(g);221 assert(d.min() <= v && v <= d.max());222 u[static_cast<std::size_t>(v)]++;223 }224 std::vector<double> prob = d.probabilities();225 for (unsigned i = 0; i < u.size(); ++i)226 if (prob[i] != 0)227 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);228 else229 assert(u[i] == 0);230 }231 {232 typedef std::discrete_distribution<T> D;233 typedef std::minstd_rand G;234 G g;235 double p0[] = {0, 1, 0};236 D d(p0, p0+3);237 const int N = 100;238 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));239 assert(u.max_size() > static_cast<unsigned long long>(d.max()));240 for (int i = 0; i < N; ++i)241 {242 typename D::result_type v = d(g);243 assert(d.min() <= v && v <= d.max());244 u[static_cast<std::size_t>(v)]++;245 }246 std::vector<double> prob = d.probabilities();247 for (unsigned i = 0; i < u.size(); ++i)248 if (prob[i] != 0)249 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);250 else251 assert(u[i] == 0);252 }253 {254 typedef std::discrete_distribution<T> D;255 typedef std::minstd_rand G;256 G g;257 double p0[] = {1, 0, 0};258 D d(p0, p0+3);259 const int N = 100;260 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));261 assert(u.max_size() > static_cast<unsigned long long>(d.max()));262 for (int i = 0; i < N; ++i)263 {264 typename D::result_type v = d(g);265 assert(d.min() <= v && v <= d.max());266 u[static_cast<std::size_t>(v)]++;267 }268 std::vector<double> prob = d.probabilities();269 for (unsigned i = 0; i < u.size(); ++i)270 if (prob[i] != 0)271 assert(std::abs((double)u[i]/N - prob[i]) / prob[i] < 0.001);272 else273 assert(u[i] == 0);274 }275 {276 typedef std::discrete_distribution<T> D;277 typedef std::minstd_rand G;278 G g;279 double p0[] = {33, 0, 0, 67};280 D d(p0, p0+3);281 const int N = 1000000;282 std::vector<Frequency> u(static_cast<std::size_t>(d.max()+1));283 assert(u.max_size() > static_cast<unsigned long long>(d.max()));284 for (int i = 0; i < N; ++i)285 {286 typename D::result_type v = d(g);287 assert(d.min() <= v && v <= d.max());288 u[static_cast<std::size_t>(v)]++;289 }290 std::vector<double> prob = d.probabilities();291 for (unsigned i = 0; i < u.size(); ++i)292 if (prob[i] != 0)293 assert(std::abs((double)u[i] / N - prob[i]) / prob[i] < 0.0013);294 else295 assert(u[i] == 0);296 }297}298 299int main(int, char**) {300 tests<short>();301 tests<int>();302 tests<long>();303 tests<long long>();304 305 tests<unsigned short>();306 tests<unsigned int>();307 tests<unsigned long>();308 tests<unsigned long long>();309 310#if defined(_LIBCPP_VERSION) // extension311 tests<std::int8_t>();312 tests<std::uint8_t>();313#if !defined(TEST_HAS_NO_INT128)314 tests<__int128_t>();315 tests<__uint128_t>();316#endif317#endif318 319 return 0;320}321