15 #ifndef ABSL_RANDOM_POISSON_DISTRIBUTION_H_
16 #define ABSL_RANDOM_POISSON_DISTRIBUTION_H_
23 #include <type_traits>
25 #include "absl/random/internal/fast_uniform_bits.h"
26 #include "absl/random/internal/fastmath.h"
27 #include "absl/random/internal/generate_real.h"
28 #include "absl/random/internal/iostream_state_saver.h"
53 template <
typename IntType =
int>
54 class poisson_distribution {
66 return a.mean_ ==
b.mean_;
84 "Class-template absl::poisson_distribution<> must be "
85 "parameterized using an integral type.");
97 template <
typename URBG>
102 template <
typename URBG>
104 const param_type&
p);
116 return a.param_ ==
b.param_;
120 return a.param_ !=
b.param_;
132 template <
typename IntType>
134 : mean_(mean), split_(0) {
140 assert(
mean <= 1e10);
144 emu_ = std::exp(-mean_);
145 }
else if (mean_ <= 50) {
147 split_ = 1 +
static_cast<int>(mean_ / 10.0);
148 emu_ = std::exp(-mean_ /
static_cast<double>(split_));
151 constexpr
double k2E = 0.7357588823428846;
152 constexpr
double kSA = 0.4494580810294493;
155 double a = mean_ + 0.5;
156 s_ = kSA + std::sqrt(k2E *
a);
157 const double mode = std::ceil(mean_) - 1;
162 template <
typename IntType>
163 template <
typename URBG>
167 const param_type&
p) {
168 using random_internal::GeneratePositiveTag;
170 using random_internal::GenerateSignedTag;
190 r *= GenerateRealFromBits<double, GeneratePositiveTag, true>(
193 }
while (
r >
p.emu_);
208 const double a =
p.mean_ + 0.5;
210 const double u = GenerateRealFromBits<double, GeneratePositiveTag, false>(
212 const double v = GenerateRealFromBits<double, GenerateSignedTag, false>(
215 const double x = std::floor(
p.s_ *
v /
u +
a);
217 const double rhs =
x *
p.lmu_;
219 double s = (
x <= 1.0) ? 0.0
220 : (
x == 2.0) ? 0.693147180559945
223 const double lhs = 2.0 *
std::log(
u) +
p.log_k_ +
s;
231 template <
typename CharT,
typename Traits,
typename IntType>
232 std::basic_ostream<CharT, Traits>&
operator<<(
233 std::basic_ostream<CharT, Traits>& os,
234 const poisson_distribution<IntType>&
x) {
241 template <
typename CharT,
typename Traits,
typename IntType>
242 std::basic_istream<CharT, Traits>&
operator>>(
243 std::basic_istream<CharT, Traits>& is,
244 poisson_distribution<IntType>&
x) {
245 using param_type =
typename poisson_distribution<IntType>::param_type;
248 double mean = random_internal::read_floating_point<double>(is);
250 x.param(param_type(mean));
258 #endif // ABSL_RANDOM_POISSON_DISTRIBUTION_H_