m = static_cast<IntType>((t+1)*p);
if(use_inversion()) {
- q_n = pow((1 - p), static_cast<RealType>(t));
+ _u.q_n = pow((1 - p), static_cast<RealType>(t));
} else {
- btrd.r = p/(1-p);
- btrd.nr = (t+1)*btrd.r;
- btrd.npq = t*p*(1-p);
- RealType sqrt_npq = sqrt(btrd.npq);
- btrd.b = 1.15 + 2.53 * sqrt_npq;
- btrd.a = -0.0873 + 0.0248*btrd.b + 0.01*p;
- btrd.c = t*p + 0.5;
- btrd.alpha = (2.83 + 5.1/btrd.b) * sqrt_npq;
- btrd.v_r = 0.92 - 4.2/btrd.b;
- btrd.u_rv_r = 0.86*btrd.v_r;
+ _u.btrd.r = p/(1-p);
+ _u.btrd.nr = (t+1)*_u.btrd.r;
+ _u.btrd.npq = t*p*(1-p);
+ RealType sqrt_npq = sqrt(_u.btrd.npq);
+ _u.btrd.b = 1.15 + 2.53 * sqrt_npq;
+ _u.btrd.a = -0.0873 + 0.0248*_u.btrd.b + 0.01*p;
+ _u.btrd.c = t*p + 0.5;
+ _u.btrd.alpha = (2.83 + 5.1/_u.btrd.b) * sqrt_npq;
+ _u.btrd.v_r = 0.92 - 4.2/_u.btrd.b;
+ _u.btrd.u_rv_r = 0.86*_u.btrd.v_r;
}
}
while(true) {
RealType u;
RealType v = uniform_01<RealType>()(urng);
- if(v <= btrd.u_rv_r) {
- u = v/btrd.v_r - 0.43;
+ if(v <= _u.btrd.u_rv_r) {
+ u = v/_u.btrd.v_r - 0.43;
return static_cast<IntType>(floor(
- (2*btrd.a/(0.5 - abs(u)) + btrd.b)*u + btrd.c));
+ (2*_u.btrd.a/(0.5 - abs(u)) + _u.btrd.b)*u + _u.btrd.c));
}
- if(v >= btrd.v_r) {
+ if(v >= _u.btrd.v_r) {
u = uniform_01<RealType>()(urng) - 0.5;
} else {
- u = v/btrd.v_r - 0.93;
+ u = v/_u.btrd.v_r - 0.93;
u = ((u < 0)? -0.5 : 0.5) - u;
- v = uniform_01<RealType>()(urng) * btrd.v_r;
+ v = uniform_01<RealType>()(urng) * _u.btrd.v_r;
}
RealType us = 0.5 - abs(u);
- IntType k = static_cast<IntType>(floor((2*btrd.a/us + btrd.b)*u + btrd.c));
+ IntType k = static_cast<IntType>(floor((2*_u.btrd.a/us + _u.btrd.b)*u + _u.btrd.c));
if(k < 0 || k > _t) continue;
- v = v*btrd.alpha/(btrd.a/(us*us) + btrd.b);
+ v = v*_u.btrd.alpha/(_u.btrd.a/(us*us) + _u.btrd.b);
RealType km = abs(k - m);
if(km <= 15) {
RealType f = 1;
IntType i = m;
do {
++i;
- f = f*(btrd.nr/i - btrd.r);
+ f = f*(_u.btrd.nr/i - _u.btrd.r);
} while(i != k);
} else if(m > k) {
IntType i = k;
do {
++i;
- v = v*(btrd.nr/i - btrd.r);
+ v = v*(_u.btrd.nr/i - _u.btrd.r);
} while(i != m);
}
if(v <= f) return k;
// final acceptance/rejection
v = log(v);
RealType rho =
- (km/btrd.npq)*(((km/3. + 0.625)*km + 1./6)/btrd.npq + 0.5);
- RealType t = -km*km/(2*btrd.npq);
+ (km/_u.btrd.npq)*(((km/3. + 0.625)*km + 1./6)/_u.btrd.npq + 0.5);
+ RealType t = -km*km/(2*_u.btrd.npq);
if(v < t - rho) return k;
if(v > t + rho) continue;
IntType nm = _t - m + 1;
- RealType h = (m + 0.5)*log((m + 1)/(btrd.r*nm))
+ RealType h = (m + 0.5)*log((m + 1)/(_u.btrd.r*nm))
+ fc(m) + fc(_t - m);
IntType nk = _t - k + 1;
if(v <= h + (_t+1)*log(static_cast<RealType>(nm)/nk)
- + (k + 0.5)*log(nk*btrd.r/(k+1))
+ + (k + 0.5)*log(nk*_u.btrd.r/(k+1))
- fc(k)
- fc(_t - k))
{
RealType q = 1 - p;
RealType s = p / q;
RealType a = (t + 1) * s;
- RealType r = q_n;
+ RealType r = _u.q_n;
RealType u = uniform_01<RealType>()(urng);
IntType x = 0;
while(u > r) {
} btrd;
// for inversion
RealType q_n;
- };
+ } _u;
/// @endcond
};
using std::exp;
if(use_inversion()) {
- _exp_mean = exp(-_mean);
+ _u._exp_mean = exp(-_mean);
} else {
- _ptrd.smu = sqrt(_mean);
- _ptrd.b = 0.931 + 2.53 * _ptrd.smu;
- _ptrd.a = -0.059 + 0.02483 * _ptrd.b;
- _ptrd.inv_alpha = 1.1239 + 1.1328 / (_ptrd.b - 3.4);
- _ptrd.v_r = 0.9277 - 3.6224 / (_ptrd.b - 2);
+ _u._ptrd.smu = sqrt(_mean);
+ _u._ptrd.b = 0.931 + 2.53 * _u._ptrd.smu;
+ _u._ptrd.a = -0.059 + 0.02483 * _u._ptrd.b;
+ _u._ptrd.inv_alpha = 1.1239 + 1.1328 / (_u._ptrd.b - 3.4);
+ _u._ptrd.v_r = 0.9277 - 3.6224 / (_u._ptrd.b - 2);
}
}
while(true) {
RealType u;
RealType v = uniform_01<RealType>()(urng);
- if(v <= 0.86 * _ptrd.v_r) {
- u = v / _ptrd.v_r - 0.43;
+ if(v <= 0.86 * _u._ptrd.v_r) {
+ u = v / _u._ptrd.v_r - 0.43;
return static_cast<IntType>(floor(
- (2*_ptrd.a/(0.5-abs(u)) + _ptrd.b)*u + _mean + 0.445));
+ (2*_u._ptrd.a/(0.5-abs(u)) + _u._ptrd.b)*u + _mean + 0.445));
}
- if(v >= _ptrd.v_r) {
+ if(v >= _u._ptrd.v_r) {
u = uniform_01<RealType>()(urng) - 0.5;
} else {
- u = v/_ptrd.v_r - 0.93;
+ u = v/_u._ptrd.v_r - 0.93;
u = ((u < 0)? -0.5 : 0.5) - u;
- v = uniform_01<RealType>()(urng) * _ptrd.v_r;
+ v = uniform_01<RealType>()(urng) * _u._ptrd.v_r;
}
RealType us = 0.5 - abs(u);
continue;
}
- RealType k = floor((2*_ptrd.a/us + _ptrd.b)*u+_mean+0.445);
- v = v*_ptrd.inv_alpha/(_ptrd.a/(us*us) + _ptrd.b);
+ RealType k = floor((2*_u._ptrd.a/us + _u._ptrd.b)*u+_mean+0.445);
+ v = v*_u._ptrd.inv_alpha/(_u._ptrd.a/(us*us) + _u._ptrd.b);
RealType log_sqrt_2pi = 0.91893853320467267;
if(k >= 10) {
- if(log(v*_ptrd.smu) <= (k + 0.5)*log(_mean/k)
+ if(log(v*_u._ptrd.smu) <= (k + 0.5)*log(_mean/k)
- _mean
- log_sqrt_2pi
+ k
template<class URNG>
IntType invert(URNG& urng) const
{
- RealType p = _exp_mean;
+ RealType p = _u._exp_mean;
IntType x = 0;
RealType u = uniform_01<RealType>()(urng);
while(u > p) {
} _ptrd;
// for inversion
RealType _exp_mean;
- };
+ } _u;
/// @endcond
};