Revisited [rand.dist.bern.bin] and [rand.dist.pois.poisson] with better algorithms

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@103886 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant
2010-05-15 21:36:23 +00:00
parent 4ff556cf62
commit 6add8ddfef
7 changed files with 766 additions and 383 deletions

View File

@@ -14,24 +14,62 @@
// template<class _URNG> result_type operator()(_URNG& g, const param_type& parm);
#include <random>
#include <numeric>
#include <vector>
#include <cassert>
template <class T>
inline
T
sqr(T x)
{
return x * x;
}
int main()
{
{
typedef std::bernoulli_distribution D;
typedef D::param_type P;
typedef std::minstd_rand0 G;
typedef std::minstd_rand G;
G g;
D d(.75);
P p(.25);
int count = 0;
for (int i = 0; i < 10000; ++i)
{
bool u = d(g, p);
if (u)
++count;
}
assert(count < 2600);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g, p));
double mean = std::accumulate(u.begin(), u.end(),
double(0)) / u.size();
double var = 0;
for (int i = 0; i < u.size(); ++i)
var += sqr(u[i] - mean);
var /= u.size();
double x_mean = p.p();
double x_var = p.p()*(1-p.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
{
typedef std::bernoulli_distribution D;
typedef D::param_type P;
typedef std::minstd_rand G;
G g;
D d(.25);
P p(.75);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g, p));
double mean = std::accumulate(u.begin(), u.end(),
double(0)) / u.size();
double var = 0;
for (int i = 0; i < u.size(); ++i)
var += sqr(u[i] - mean);
var /= u.size();
double x_mean = p.p();
double x_var = p.p()*(1-p.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
}