template<class Random> bool binom(Random& r, int n) { // Probability of equal heads and tails on 2*n tosses // = binomial(2*n, n) / 2^(2*n) int d = 0; for (int k = n; k--; ) d += r.Boolean() ? 1 : -1; for (int k = n; k--; ) { d += r.Boolean() ? 1 : -1; // This optimization saves 0.1686 bit per call to operator() on average. if (std::abs(d) > k) return false; } return true; }
void coverage32() { typedef RandomLib::SRandom32 Random; { // Setting and examing the seed + seed management std::vector<unsigned long> v(Random::SeedVector()); unsigned long w = Random::SeedWord(); std::string s(Random::VectorToString(v)); { Random r(v); } { Random r(v.begin(), v.end()); } int a[] = {1, 2, 3, 4}; { Random r(a, a + 4); } { Random r(w); } { Random r(s); } { Random r; } Random r(0); r.Reseed(v); r.Reseed(v.begin(), v.end()); r.Reseed(w); r.Reseed(s); r.Reseed(); v = r.Seed(); s = r.SeedString(); r.Reseed(Random::VectorToString(v)); r.Reseed(Random::StringToVector(s)); } Random r; { // Functions returning random integers repeat r(); repeat r.Ran(); repeat r.Ran32(); repeat r.Ran64(); repeat r(52); repeat r.Integer<signed char, 3>(); repeat r.Integer<unsigned char, 3>(); repeat r.Integer<signed short, 3>(); repeat r.Integer<3>(); repeat r.Integer(); repeat r.Integer<signed short>(); repeat r.Integer<signed short>(52); repeat r.IntegerC<signed short>(51); repeat r.IntegerC<signed short>(1,52); repeat r.Integer(6u); repeat r.IntegerC(5u); repeat r.IntegerC(1u,6u); repeat r(); repeat r(52u); } { // Functions returning random reals repeat { r.Fixed <float, 16 >(); r.Fixed <float>(); r.Fixed (); } repeat { r.FixedU<float, 16 >(); r.FixedU<float>(); r.FixedU(); } repeat { r.FixedN<float, 16 >(); r.FixedN<float>(); r.FixedN(); } repeat { r.FixedW<float, 16 >(); r.FixedW<float>(); r.FixedW(); } repeat { r.FixedS<float, 16 >(); r.FixedS<float>(); r.FixedS(); } repeat { r.FixedO<float, 16 >(); r.FixedO<float>(); r.FixedO(); } repeat { r.Float <float, 4, 2>(); r.Float <float>(); r.Float (); } repeat { r.FloatU<float, 4, 2>(); r.FloatU<float>(); r.FloatU(); } repeat { r.FloatN<float, 4, 2>(); r.FloatN<float>(); r.FloatN(); } repeat { r.FloatW<float, 4, 2>(); r.FloatW<float>(); r.FloatW(); } repeat { r.Real<float>(); r.Real(); } } { // Functions returning other random results repeat r.Boolean(); repeat r.Prob(0.5f); repeat r.Prob(2.3, 7.0); repeat r.Prob(23, 70); repeat r.Bits< 5>(); repeat r.Bits<64>(); } { // Normal distribution RandomLib::NormalDistribution<float> nf; RandomLib::NormalDistribution<> nd; repeat nf(r); repeat nd(r, 1.0, 2.0); } { // Exponention distribution RandomLib::ExponentialDistribution<float> ef; RandomLib::ExponentialDistribution<> ed; repeat ef(r); repeat ed(r, 2.0); } { // Discrete probabilities unsigned w[] = { 0, 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1 }; std::vector<int> wi(13); std::vector<float> wf(13); for (int i = 0; i < 13; ++i) { wi[i] = int(w[i]); wf[i] = float(w[i]); } { RandomLib::RandomSelect<unsigned> sel; } { RandomLib::RandomSelect<unsigned> sel(w, w + 13); } { RandomLib::RandomSelect<unsigned> sel(wi.begin(), wi.end()); } { RandomLib::RandomSelect<unsigned> sel(wi); } { RandomLib::RandomSelect<> sel; } { RandomLib::RandomSelect<> sel(w, w + 13); } { RandomLib::RandomSelect<> sel(wi); } { RandomLib::RandomSelect<> sel(wf.begin(), wf.end()); } { RandomLib::RandomSelect<> sel(wf); } { RandomLib::RandomSelect<unsigned> sel; sel.Init(w, w + 13); sel.Init(wi.begin(), wi.end()); sel.Init(wi); repeat sel(r); sel.TotalWeight(); sel.MaxWeight(); sel.Weight(3); sel.Choices(); } { RandomLib::RandomSelect<> sel; sel.Init(w, w + 13); sel.Init(wi.begin(), wi.end()); sel.Init(wi); sel.Init(wf); repeat sel(r); sel.TotalWeight(); sel.MaxWeight(); sel.Weight(3); sel.Choices(); } // Other distributions { RandomLib::LeadingZeros lz; repeat lz(r); } { RandomLib::ExponentialProb ep; repeat ep(r, 1.5f); } { // Infinite precision random numbers { RandomLib::RandomNumber<1> n; n.Init(); n.Digit(r, 10); n.RawDigit(4); n.AddInteger(-2); n.Negate(); n.Sign(); n.Floor(); n.Ceiling(); n.Size(); n.Range(); n.Fraction<float>(r); n.Value<double>(r); RandomLib::RandomNumber<1> p; n.LessThan(r, p); std::ostringstream os; os << n; } { RandomLib::RandomNumber<32> n; n.Init(); n.Digit(r, 10); n.RawDigit(4); n.AddInteger(-2); n.Negate(); n.Sign(); n.Floor(); n.Ceiling(); n.Size(); n.Range(); n.Fraction<float>(r); n.Value<double>(r); RandomLib::RandomNumber<32> p; n.LessThan(r, p); std::ostringstream os; os << n; } { if (RandomLib::UniformInteger<char, 4>::Check(37, 7)) { RandomLib::UniformInteger<char, 4> u(r,37); u.Min(); u.Max(); u.Entropy(); u.Add(3); u.LessThan(r, 4, 1); u.LessThanEqual(r, 4, 1); u.GreaterThan(r, 60, 7); u.GreaterThanEqual(r, 60, 7); u.Negate(); std::ostringstream os; os << u; os << " " << u(r); } } { RandomLib::UniformInteger<short, 4> u(r,37); u.Min(); u.Max(); u.Entropy(); u.Add(3); u.LessThan(r, 4, 1); u.LessThanEqual(r, 4, 1); u.GreaterThan(r, 60, 7); u.GreaterThanEqual(r, 60, 7); u.Negate(); std::ostringstream os; os << u; os << " " << u(r); } { RandomLib::UniformInteger<int, 4> u(r,37); u.Min(); u.Max(); u.Entropy(); u.Add(3); u.LessThan(r, 4, 1); u.LessThanEqual(r, 4, 1); u.GreaterThan(r, 60, 7); u.GreaterThanEqual(r, 60, 7); u.Negate(); std::ostringstream os; os << u; os << " " << u(r); } { RandomLib::UniformInteger<long long, 32> u(r,37); u.Min(); u.Max(); u.Entropy(); u.Add(3); u.LessThan(r, 4, 1); u.LessThanEqual(r, 4, 1); u.GreaterThan(r, 60, 7); u.GreaterThanEqual(r, 60, 7); u.Negate(); std::ostringstream os; os << u; os << " " << u(r); } // Exact distributions { RandomLib::ExactExponential< 1> ed; repeat ed(r).Value<float >(r); } { RandomLib::ExactExponential<32> ed; repeat ed(r).Value<double>(r); } { RandomLib::ExactNormal< 1> ed; repeat ed(r).Value<float >(r); } { RandomLib::ExactNormal<32> ed; repeat ed(r).Value<double>(r); } { RandomLib::ExactPower< 1> pd; repeat pd(r,2).Value<float >(r); } { RandomLib::ExactPower<32> pd; repeat pd(r,3).Value<double>(r); } { RandomLib::DiscreteNormal<short> pd(7); repeat pd(r); } { RandomLib::DiscreteNormal<int> pd(7,1,1,2); repeat pd(r); } { RandomLib::DiscreteNormal<long> pd(7,1,1,2); repeat pd(r); } { RandomLib::DiscreteNormal<long long> pd(7); repeat pd(r); } { RandomLib::DiscreteNormalAlt<short,1> pd(7); repeat pd(r)(r); } { RandomLib::DiscreteNormalAlt<int,8> pd(7); repeat pd(r)(r); } { RandomLib::DiscreteNormalAlt<long,28> pd(7); repeat pd(r)(r); } { RandomLib::DiscreteNormalAlt<long long,32> pd(7); repeat pd(r)(r); } { RandomLib::InversePiProb pd; repeat pd(r); } { RandomLib::InverseEProb pd; repeat pd(r); } } } { // Setting position in sequence r.Count(); r.StepCount(1000); r.Reset(); r.SetCount(10000); r.SetStride(10,1); r.SetStride(5); r.GetStride(); r.SetStride(); } { // Other Random s(r); s = Random::Global; void(s == r); void(s != s); r.swap(s); std::swap(r, s); } }
template<class Random> int geom4(Random& r) { // Geom(1/4) int sum = 0; while (r.Boolean() && r.Boolean()) ++sum; return sum; }
template<class Random> bool prob59(Random& r) { // true with prob 5/9 = 0.1 000 111 000 111 000 111 ... (binary expansion) if (r.Boolean()) return true; for (bool res = false; ; res = !res) for (int i = 3; i--; ) if (r.Boolean()) return res; }