generators_test.cc (5848B)
1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <cstddef> 16 #include <cstdint> 17 #include <random> 18 #include <vector> 19 20 #include "gtest/gtest.h" 21 #include "absl/random/distributions.h" 22 #include "absl/random/random.h" 23 24 namespace { 25 26 template <typename URBG> 27 void TestUniform(URBG* gen) { 28 // [a, b) default-semantics, inferred types. 29 absl::Uniform(*gen, 0, 100); // int 30 absl::Uniform(*gen, 0, 1.0); // Promoted to double 31 absl::Uniform(*gen, 0.0f, 1.0); // Promoted to double 32 absl::Uniform(*gen, 0.0, 1.0); // double 33 absl::Uniform(*gen, -1, 1L); // Promoted to long 34 35 // Roll a die. 36 absl::Uniform(absl::IntervalClosedClosed, *gen, 1, 6); 37 38 // Get a fraction. 39 absl::Uniform(absl::IntervalOpenOpen, *gen, 0.0, 1.0); 40 41 // Assign a value to a random element. 42 std::vector<int> elems = {10, 20, 30, 40, 50}; 43 elems[absl::Uniform(*gen, 0u, elems.size())] = 5; 44 elems[absl::Uniform<size_t>(*gen, 0, elems.size())] = 3; 45 46 // Choose some epsilon around zero. 47 absl::Uniform(absl::IntervalOpenOpen, *gen, -1.0, 1.0); 48 49 // (a, b) semantics, inferred types. 50 absl::Uniform(absl::IntervalOpenOpen, *gen, 0, 1.0); // Promoted to double 51 52 // Explicit overriding of types. 53 absl::Uniform<int>(*gen, 0, 100); 54 absl::Uniform<int8_t>(*gen, 0, 100); 55 absl::Uniform<int16_t>(*gen, 0, 100); 56 absl::Uniform<uint16_t>(*gen, 0, 100); 57 absl::Uniform<int32_t>(*gen, 0, 1 << 10); 58 absl::Uniform<uint32_t>(*gen, 0, 1 << 10); 59 absl::Uniform<int64_t>(*gen, 0, 1 << 10); 60 absl::Uniform<uint64_t>(*gen, 0, 1 << 10); 61 62 absl::Uniform<float>(*gen, 0.0, 1.0); 63 absl::Uniform<float>(*gen, 0, 1); 64 absl::Uniform<float>(*gen, -1, 1); 65 absl::Uniform<double>(*gen, 0.0, 1.0); 66 67 absl::Uniform<float>(*gen, -1.0, 0); 68 absl::Uniform<double>(*gen, -1.0, 0); 69 70 // Tagged 71 absl::Uniform<double>(absl::IntervalClosedClosed, *gen, 0, 1); 72 absl::Uniform<double>(absl::IntervalClosedOpen, *gen, 0, 1); 73 absl::Uniform<double>(absl::IntervalOpenOpen, *gen, 0, 1); 74 absl::Uniform<double>(absl::IntervalOpenClosed, *gen, 0, 1); 75 absl::Uniform<double>(absl::IntervalClosedClosed, *gen, 0, 1); 76 absl::Uniform<double>(absl::IntervalOpenOpen, *gen, 0, 1); 77 78 absl::Uniform<int>(absl::IntervalClosedClosed, *gen, 0, 100); 79 absl::Uniform<int>(absl::IntervalClosedOpen, *gen, 0, 100); 80 absl::Uniform<int>(absl::IntervalOpenOpen, *gen, 0, 100); 81 absl::Uniform<int>(absl::IntervalOpenClosed, *gen, 0, 100); 82 absl::Uniform<int>(absl::IntervalClosedClosed, *gen, 0, 100); 83 absl::Uniform<int>(absl::IntervalOpenOpen, *gen, 0, 100); 84 85 // With *generator as an R-value reference. 86 absl::Uniform<int>(URBG(), 0, 100); 87 absl::Uniform<double>(URBG(), 0.0, 1.0); 88 } 89 90 template <typename URBG> 91 void TestExponential(URBG* gen) { 92 absl::Exponential<float>(*gen); 93 absl::Exponential<double>(*gen); 94 absl::Exponential<double>(URBG()); 95 } 96 97 template <typename URBG> 98 void TestPoisson(URBG* gen) { 99 // [rand.dist.pois] Indicates that the std::poisson_distribution 100 // is parameterized by IntType, however MSVC does not allow 8-bit 101 // types. 102 absl::Poisson<int>(*gen); 103 absl::Poisson<int16_t>(*gen); 104 absl::Poisson<uint16_t>(*gen); 105 absl::Poisson<int32_t>(*gen); 106 absl::Poisson<uint32_t>(*gen); 107 absl::Poisson<int64_t>(*gen); 108 absl::Poisson<uint64_t>(*gen); 109 absl::Poisson<uint64_t>(URBG()); 110 absl::Poisson<absl::int128>(*gen); 111 absl::Poisson<absl::uint128>(*gen); 112 } 113 114 template <typename URBG> 115 void TestBernoulli(URBG* gen) { 116 absl::Bernoulli(*gen, 0.5); 117 absl::Bernoulli(*gen, 0.5); 118 } 119 120 template <typename URBG> 121 void TestZipf(URBG* gen) { 122 absl::Zipf<int>(*gen, 100); 123 absl::Zipf<int8_t>(*gen, 100); 124 absl::Zipf<int16_t>(*gen, 100); 125 absl::Zipf<uint16_t>(*gen, 100); 126 absl::Zipf<int32_t>(*gen, 1 << 10); 127 absl::Zipf<uint32_t>(*gen, 1 << 10); 128 absl::Zipf<int64_t>(*gen, 1 << 10); 129 absl::Zipf<uint64_t>(*gen, 1 << 10); 130 absl::Zipf<uint64_t>(URBG(), 1 << 10); 131 absl::Zipf<absl::int128>(*gen, 1 << 10); 132 absl::Zipf<absl::uint128>(*gen, 1 << 10); 133 } 134 135 template <typename URBG> 136 void TestGaussian(URBG* gen) { 137 absl::Gaussian<float>(*gen, 1.0, 1.0); 138 absl::Gaussian<double>(*gen, 1.0, 1.0); 139 absl::Gaussian<double>(URBG(), 1.0, 1.0); 140 } 141 142 template <typename URBG> 143 void TestLogNormal(URBG* gen) { 144 absl::LogUniform<int>(*gen, 0, 100); 145 absl::LogUniform<int8_t>(*gen, 0, 100); 146 absl::LogUniform<int16_t>(*gen, 0, 100); 147 absl::LogUniform<uint16_t>(*gen, 0, 100); 148 absl::LogUniform<int32_t>(*gen, 0, 1 << 10); 149 absl::LogUniform<uint32_t>(*gen, 0, 1 << 10); 150 absl::LogUniform<int64_t>(*gen, 0, 1 << 10); 151 absl::LogUniform<uint64_t>(*gen, 0, 1 << 10); 152 absl::LogUniform<uint64_t>(URBG(), 0, 1 << 10); 153 absl::LogUniform<absl::int128>(*gen, 0, 1 << 10); 154 absl::LogUniform<absl::uint128>(*gen, 0, 1 << 10); 155 } 156 157 template <typename URBG> 158 void CompatibilityTest() { 159 URBG gen; 160 161 TestUniform(&gen); 162 TestExponential(&gen); 163 TestPoisson(&gen); 164 TestBernoulli(&gen); 165 TestZipf(&gen); 166 TestGaussian(&gen); 167 TestLogNormal(&gen); 168 } 169 170 TEST(std_mt19937_64, Compatibility) { 171 // Validate with std::mt19937_64 172 CompatibilityTest<std::mt19937_64>(); 173 } 174 175 TEST(BitGen, Compatibility) { 176 // Validate with absl::BitGen 177 CompatibilityTest<absl::BitGen>(); 178 } 179 180 TEST(InsecureBitGen, Compatibility) { 181 // Validate with absl::InsecureBitGen 182 CompatibilityTest<absl::InsecureBitGen>(); 183 } 184 185 } // namespace