Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(EXPONENTIALPROB_HPP)
00012 #define EXPONENTIALPROB_HPP "$Id: ExponentialProb.hpp 6723 2010-01-11 14:20:10Z ckarney $"
00013
00014 #include <vector>
00015 #include <limits>
00016
00017 namespace RandomLib {
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 class ExponentialProb {
00048 private:
00049 typedef unsigned word;
00050 public:
00051
00052 ExponentialProb() : _v(std::vector<word>(alloc_incr)) {}
00053
00054
00055
00056
00057
00058 template<typename RealType, class Random>
00059 bool operator()(Random& r, RealType p) const throw(std::bad_alloc);
00060
00061 private:
00062
00063
00064
00065 template<typename RealType, class Random>
00066 bool ExpFraction(Random& r, RealType p) const throw(std::bad_alloc);
00067
00068
00069
00070 mutable std::vector<word> _v;
00071
00072
00073
00074 static const unsigned alloc_incr = 16;
00075 };
00076
00077 template<typename RealType, class Random>
00078 inline bool ExponentialProb::operator()(Random& r, RealType p) const
00079 throw(std::bad_alloc) {
00080 return p <= 0 ||
00081
00082 p < RealType(1)/std::numeric_limits<RealType>::epsilon() &&
00083
00084 ExpFraction(r, p < RealType(1) ? p : RealType(1)) &&
00085 ( p <= RealType(1) || operator()(r, p - RealType(1)) );
00086 }
00087
00088 template<typename RealType, class Random>
00089 inline bool ExponentialProb::ExpFraction(Random& r, RealType p) const
00090 throw(std::bad_alloc) {
00091
00092 const int c =
00093 std::numeric_limits<word>::digits <
00094 std::numeric_limits<RealType>::digits ?
00095 std::numeric_limits<word>::digits :
00096 std::numeric_limits<RealType>::digits;
00097
00098 unsigned m = 0, l = _v.size();
00099 if (p < RealType(1))
00100 while (true) {
00101 if (p <= RealType(0))
00102 return true;
00103
00104 if (l == m)
00105 _v.resize(l += alloc_incr);
00106 _v[m++] = r.template Integer<word, c>();
00107 p *= pow(RealType(2), c);
00108 word w = word(p);
00109 if (_v[m - 1] > w)
00110 return true;
00111 else if (_v[m - 1] < w)
00112 break;
00113 else
00114 p -= RealType(w);
00115 }
00116
00117
00118 for (unsigned s = 0; ; s ^= 1) {
00119 for (size_t j = 0; ; ++j) {
00120 if (j == m) {
00121
00122 if (l == m)
00123 _v.resize(l += alloc_incr);
00124 _v[m++] = r.template Integer<word, c>();
00125 }
00126 word w = r.template Integer<word, c>();
00127 if (w > _v[j])
00128 return s;
00129 else if (w < _v[j]) {
00130 _v[j] = w;
00131 m = j + 1;
00132 break;
00133 }
00134
00135 }
00136 }
00137 }
00138 }
00139 #endif // EXPONENTIALPROB_HPP