brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · 2ca213e Raw
138 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 11// <random>12 13// template<class _IntType = int>14// class uniform_int_distribution15 16// template<class _URNG> result_type operator()(_URNG& g);17 18#include <random>19#include <cassert>20#include <climits>21#include <cmath>22#include <cstddef>23#include <cstdint>24#include <limits>25#include <numeric>26#include <vector>27 28#include "test_macros.h"29 30template <class T>31T sqr(T x) {32    return x * x;33}34 35template <class ResultType, class EngineType>36void test_statistics(ResultType a, ResultType b) {37    ASSERT_SAME_TYPE(typename std::uniform_int_distribution<ResultType>::result_type, ResultType);38 39    EngineType g;40    std::uniform_int_distribution<ResultType> dist(a, b);41    assert(dist.a() == a);42    assert(dist.b() == b);43    std::vector<ResultType> u;44    for (int i = 0; i < 10000; ++i) {45        ResultType v = dist(g);46        assert(a <= v && v <= b);47        u.push_back(v);48    }49 50    // Quick check: The chance of getting *no* hits in any given tenth of the range51    // is (0.9)^10000, or "ultra-astronomically low."52    bool bottom_tenth = false;53    bool top_tenth = false;54    for (std::size_t i = 0; i < u.size(); ++i) {55        bottom_tenth = bottom_tenth || (u[i] <= (a + (b / 10) - (a / 10)));56        top_tenth = top_tenth || (u[i] >= (b - (b / 10) + (a / 10)));57    }58    assert(bottom_tenth);  // ...is populated59    assert(top_tenth);  // ...is populated60 61    // Now do some more involved statistical math.62    double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();63    double var = 0;64    double skew = 0;65    double kurtosis = 0;66    for (std::size_t i = 0; i < u.size(); ++i) {67        double dbl = (u[i] - mean);68        double d2 = dbl * dbl;69        var += d2;70        skew += dbl * d2;71        kurtosis += d2 * d2;72    }73    var /= u.size();74    double dev = std::sqrt(var);75    skew /= u.size() * dev * var;76    kurtosis /= u.size() * var * var;77 78    double expected_mean = double(a) + double(b)/2 - double(a)/2;79    double expected_var = (sqr(double(b) - double(a) + 1) - 1) / 12;80 81    double range = double(b) - double(a) + 1.0;82    assert(range > range / 10);  // i.e., it's not infinity83 84    assert(std::abs(mean - expected_mean) < range / 100);85    assert(std::abs(var - expected_var) < expected_var / 50);86    assert(-0.1 < skew && skew < 0.1);87    assert(1.6 < kurtosis && kurtosis < 2.0);88}89 90template <class ResultType, class EngineType>91void test_statistics() {92    test_statistics<ResultType, EngineType>(0, std::numeric_limits<ResultType>::max());93}94 95int main(int, char**)96{97    test_statistics<int, std::minstd_rand0>();98    test_statistics<int, std::minstd_rand>();99    test_statistics<int, std::mt19937>();100    test_statistics<int, std::mt19937_64>();101    test_statistics<int, std::ranlux24_base>();102    test_statistics<int, std::ranlux48_base>();103    test_statistics<int, std::ranlux24>();104    test_statistics<int, std::ranlux48>();105    test_statistics<int, std::knuth_b>();106    test_statistics<int, std::minstd_rand0>(-6, 106);107    test_statistics<int, std::minstd_rand>(5, 100);108 109    test_statistics<short, std::minstd_rand0>();110    test_statistics<int, std::minstd_rand0>();111    test_statistics<long, std::minstd_rand0>();112    test_statistics<long long, std::minstd_rand0>();113 114    test_statistics<unsigned short, std::minstd_rand0>();115    test_statistics<unsigned int, std::minstd_rand0>();116    test_statistics<unsigned long, std::minstd_rand0>();117    test_statistics<unsigned long long, std::minstd_rand0>();118 119    test_statistics<short, std::minstd_rand0>(SHRT_MIN, SHRT_MAX);120 121#if defined(_LIBCPP_VERSION) // extension122    test_statistics<std::int8_t, std::minstd_rand0>();123    test_statistics<std::uint8_t, std::minstd_rand0>();124 125#if !defined(TEST_HAS_NO_INT128)126    test_statistics<__int128_t, std::minstd_rand0>();127    test_statistics<__uint128_t, std::minstd_rand0>();128 129    test_statistics<__int128_t, std::minstd_rand0>(-100, 900);130    test_statistics<__int128_t, std::minstd_rand0>(0, UINT64_MAX);131    test_statistics<__int128_t, std::minstd_rand0>(std::numeric_limits<__int128_t>::min(), std::numeric_limits<__int128_t>::max());132    test_statistics<__uint128_t, std::minstd_rand0>(0, UINT64_MAX);133#endif134#endif135 136    return 0;137}138