From 73986c315bdf126a2100869878790dcfbab6bd82 Mon Sep 17 00:00:00 2001 From: Michele Pezzutti Date: Sun, 24 Dec 2017 23:08:52 +0100 Subject: [PATCH] re PR libstdc++/83237 (Values returned by std::poisson_distribution are not distributed correctly) 2017-12-24 Michele Pezzutti PR libstdc++/83237 * include/bits/random.tcc (poisson_distribution<>::operator()): Fix __x = 1 case - see updated Errata of Devroye's treatise. * testsuite/26_numerics/random/poisson_distribution/operators/ values.cc: Add test. * testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error line number. From-SVN: r255993 --- libstdc++-v3/ChangeLog | 10 ++++++++++ libstdc++-v3/include/bits/random.tcc | 8 +++++++- .../random/poisson_distribution/operators/values.cc | 6 ++++++ .../testsuite/26_numerics/random/pr60037-neg.cc | 2 +- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c94e77169a2..bc523a0f056 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2017-12-24 Michele Pezzutti + + PR libstdc++/83237 + * include/bits/random.tcc (poisson_distribution<>::operator()): + Fix __x = 1 case - see updated Errata of Devroye's treatise. + * testsuite/26_numerics/random/poisson_distribution/operators/ + values.cc: Add test. + * testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error + line number. + 2017-12-24 Jonathan Wakely PR libstdc++/83450 diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc index 95bcf0a163e..c1ee0835249 100644 --- a/libstdc++-v3/include/bits/random.tcc +++ b/libstdc++-v3/include/bits/random.tcc @@ -1301,6 +1301,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const double __c2 = __param._M_c2b + __c1; const double __c3 = __c2 + 1; const double __c4 = __c3 + 1; + // 1 / 78 + const double __178 = 0.0128205128205128205128205128205128L; // e^(1 / 78) const double __e178 = 1.0129030479320018583185514777512983L; const double __c5 = __c4 + __e178; @@ -1340,7 +1342,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else if (__u <= __c4) __x = 0; else if (__u <= __c5) - __x = 1; + { + __x = 1; + // Only in the Errata, see libstdc++/83237. + __w = __178; + } else { const double __v = -std::log(1.0 - __aurng()); diff --git a/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/operators/values.cc b/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/operators/values.cc index 0039b7dbd0a..9655c405b29 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/operators/values.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/poisson_distribution/operators/values.cc @@ -42,6 +42,12 @@ void test01() std::poisson_distribution<> pd3(30.0); auto bpd3 = std::bind(pd3, eng); testDiscreteDist(bpd3, [](int n) { return poisson_pdf(n, 30.0); } ); + + // libstdc++/83237 + std::poisson_distribution<> pd4(37.17); + auto bpd4 = std::bind(pd4, eng); + testDiscreteDist<100, 2000000>(bpd4, [](int n) + { return poisson_pdf(n, 37.17); } ); } int main() diff --git a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc index 22485222f28..13c052daef8 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc @@ -11,4 +11,4 @@ auto x = std::generate_canonical