RandomLib  1.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
InverseEProb.hpp
Go to the documentation of this file.
1 /**
2  * \file InverseEProb.hpp
3  * \brief Header for InverseEProb
4  *
5  * Return true with probabililty 1/\e e.
6  *
7  * Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
8  * the MIT/X11 License. For more information, see
9  * http://randomlib.sourceforge.net/
10  **********************************************************************/
11 
12 #if !defined(RANDOMLIB_INVERSEEPROB_HPP)
13 #define RANDOMLIB_INVERSEEPROB_HPP 1
14 
15 #include <vector>
16 #include <RandomLib/Random.hpp>
17 
18 namespace RandomLib {
19 
20  /**
21  * \brief Return true with probability 1/\e e = exp(&minus;1).
22  *
23  * InverseEProb p; p(Random& r) returns true with prob 1/\e e using von
24  * Neumann's rejection method. It consumes 4.572 bits per call on average.
25  *
26  * This class illustrates how to return an exact result using coin tosses
27  * only. A more efficient way of returning an exact result would be to use
28  * ExponentialProb p; p(r, 1.0f);
29  **********************************************************************/
30  class InverseEProb {
31  private:
32  mutable std::vector<bool> _p;
33  template<class Random> bool exph(Random& r) {
34  // Return true with prob 1/sqrt(e).
35  if (r.Boolean()) return true;
36  _p.clear(); // vector of bits in p
37  _p.push_back(false);
38  for (bool s = false; ; s = !s) { // s is a parity
39  for (size_t i = 0; ; ++i) { // Compare bits of p and q
40  if (i == _p.size())
41  _p.push_back(r.Boolean()); // Generate next bit of p if necessary
42  if (r.Boolean()) { // Half the time the bits differ
43  if (_p[i]) { // p's bit is 1, so q is smaller, update p
44  _p[i] = false; // Last bit of q 0
45  if (++i < _p.size()) _p.resize(i); // p = q
46  break;
47  } else
48  return s; // p's bit is 0, so q is bigger, return parity
49  } // The other half of the time the bits match, so go to next bit
50  }
51  }
52  }
53  public:
54  /**
55  * Return true with probability 1/\e e.
56  *
57  * @tparam Random the type of the random generator.
58  * @param[in,out] r a random generator.
59  * @return true with probability 1/\e e.
60  **********************************************************************/
61  template<class Random> bool operator()(Random& r)
62  { return exph(r) && exph(r); }
63  };
64 
65 } // namespace RandomLib
66 
67 #endif // RANDOMLIB_INVERSEEPROB_HPP
Return true with probability 1/e = exp(−1).
Generate random integers, reals, and booleans.
Header for Random, RandomGenerator.
bool operator()(Random &r)