12 #if !defined(RANDOMLIB_EXACTNORMAL_HPP)
13 #define RANDOMLIB_EXACTNORMAL_HPP 1
20 # pragma warning (push)
21 # pragma warning (disable: 4127)
181 template<
class Random>
bool ExpProbH(
Random& r)
const;
192 template<
class Random>
bool ExpProb(
Random& r,
unsigned n)
const;
201 template<
class Random>
unsigned ExpProbN(
Random& r)
const;
207 template<
class Random>
static bool Boolean(
Random& r) {
233 template<
class Random>
static int Choose(
Random& r,
int k) {
235 const int b = bits > 15 ? 15 : bits;
236 const unsigned mask = (1u << b) - 1;
237 const int m = 2 * k + 2;
238 int n1 = m - 2, n2 = m - 1;
245 n1 = (std::max)((n1 << b) - d, 0);
246 if (n1 >= m)
return 1;
247 n2 = (std::min)((n2 << b) - d, m);
248 if (n2 <= 0)
return -1;
249 if (n1 == 0 && n2 == m)
return 0;
258 template<
int bits>
template<
class Random>
280 if (_p.Digit(r, 0) >> (bits - 1))
return true;
282 _q.Init();
if (!_q.LessThan(r, _p))
return false;
283 _p.Init();
if (!_p.LessThan(r, _q))
return true;
287 template<
int bits>
template<
class Random>
288 bool ExactNormal<bits>::ExpProb(
Random& r,
unsigned n)
const {
294 while (n--) {
if (!ExpProbH(r))
return false; }
298 template<
int bits>
template<
class Random>
299 unsigned ExactNormal<bits>::ExpProbN(
Random& r)
const {
303 while (ExpProbH(r)) ++n;
307 template<
int bits>
template<
class Random> RandomNumber<bits>
333 unsigned k = ExpProbN(r);
334 if (ExpProb(r, (k - 1) * k)) {
358 for (
unsigned j = 0; j <= k; ++j) {
360 for (s = 1, first =
true; ; s ^= 1, first =
false) {
372 int y = Choose(r, k);
376 if (!_q.LessThan(r, _x))
break;
381 _p.Init();
if (!_x.GreaterPair(r, _q, _p))
break;
387 if (k == 0 && Boolean(r))
break;
389 _q.Init();
if (!_q.LessThan(r, _p))
break;
391 int y = k == 0 ? 0 : Choose(r, k);
395 _p.Init();
if (!_p.LessThan(r, _x))
break;
404 if (Boolean(r)) _x.Negate();
413 #if defined(_MSC_VER)
414 # pragma warning (pop)
417 #endif // RANDOMLIB_EXACTNORMAL_HPP
Generate random integers, reals, and booleans.
Infinite precision random numbers.
static unsigned RandomDigit(Random &r)
RandomCanonical< RandomGenerator > Random
Sample exactly from a normal distribution.
RandomNumber< bits > operator()(Random &r) const