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,22 +14,58 @@
// template<class _URNG> result_type operator()(_URNG& g);
#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 std::minstd_rand0 G;
typedef std::minstd_rand G;
G g;
D d(.75);
int count = 0;
for (int i = 0; i < 10000; ++i)
{
bool u = d(g);
if (u)
++count;
}
assert(count > 7400);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.p();
double x_var = d.p()*(1-d.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 std::minstd_rand G;
G g;
D d(.25);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.p();
double x_var = d.p()*(1-d.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
}

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);
}
}

View File

@@ -15,53 +15,218 @@
// template<class _URNG> result_type operator()(_URNG& g);
#include <random>
#include <numeric>
#include <vector>
#include <cassert>
template <class T>
inline
T
sqr(T x)
{
return x * x;
}
int main()
{
{
typedef std::binomial_distribution<> D;
typedef D::param_type P;
typedef std::minstd_rand0 G;
typedef std::minstd_rand G;
G g;
D d(16, .25);
int count = 0;
int r = 0;
for (int i = 0; i < 100; ++i)
{
D::result_type u = d(g);
r += u;
}
assert(int(r/100. + .5) == 4);
D d(5, .75);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
{
typedef std::binomial_distribution<> D;
typedef D::param_type P;
typedef std::minstd_rand0 G;
typedef std::minstd_rand G;
G g;
D d(16, .5);
int count = 0;
int r = 0;
for (int i = 0; i < 100; ++i)
{
D::result_type u = d(g);
r += u;
}
assert(int(r/100. + .5) == 8);
D d(30, .03125);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
{
typedef std::binomial_distribution<> D;
typedef D::param_type P;
typedef std::minstd_rand0 G;
typedef std::minstd_rand G;
G g;
D d(16, .75);
int count = 0;
int r = 0;
for (int i = 0; i < 100; ++i)
{
D::result_type u = d(g);
r += u;
}
assert(int(r/100. + .5) == 12);
D d(40, .25);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
{
typedef std::binomial_distribution<> D;
typedef std::minstd_rand G;
G g;
D d(40, 0);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(mean == x_mean);
assert(var == x_var);
}
{
typedef std::binomial_distribution<> D;
typedef std::minstd_rand G;
G g;
D d(40, 1);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(mean == x_mean);
assert(var == x_var);
}
{
typedef std::binomial_distribution<> D;
typedef std::minstd_rand G;
G g;
D d(400, 0.5);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
{
typedef std::binomial_distribution<> D;
typedef std::minstd_rand G;
G g;
D d(1, 0.5);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
{
typedef std::binomial_distribution<> D;
typedef std::minstd_rand G;
G g;
D d(0, 0.005);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(mean == x_mean);
assert(var == x_var);
}
{
typedef std::binomial_distribution<> D;
typedef std::minstd_rand G;
G g;
D d(0, 0);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(mean == x_mean);
assert(var == x_var);
}
{
typedef std::binomial_distribution<> D;
typedef std::minstd_rand G;
G g;
D d(0, 1);
const int N = 100000;
std::vector<D::result_type> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));
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 = d.t() * d.p();
double x_var = x_mean*(1-d.p());
assert(mean == x_mean);
assert(var == x_var);
}
}

View File

@@ -15,56 +15,84 @@
// 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::binomial_distribution<> D;
typedef D::param_type P;
typedef std::minstd_rand0 G;
typedef std::minstd_rand G;
G g;
D d(16, .75);
P p(16, .25);
int count = 0;
int r = 0;
for (int i = 0; i < 100; ++i)
{
D::result_type u = d(g, p);
r += u;
}
assert(int(r/100. + .5) == 4);
P p(5, .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.t() * p.p();
double x_var = x_mean*(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::binomial_distribution<> D;
typedef D::param_type P;
typedef std::minstd_rand0 G;
typedef std::minstd_rand G;
G g;
D d(16, .75);
P p(16, .5);
int count = 0;
int r = 0;
for (int i = 0; i < 100; ++i)
{
D::result_type u = d(g, p);
r += u;
}
assert(int(r/100. + .5) == 8);
P p(30, .03125);
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.t() * p.p();
double x_var = x_mean*(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::binomial_distribution<> D;
typedef D::param_type P;
typedef std::minstd_rand0 G;
typedef std::minstd_rand G;
G g;
D d(16, .75);
P p(16, .75);
int count = 0;
int r = 0;
for (int i = 0; i < 100; ++i)
{
D::result_type u = d(g, p);
r += u;
}
assert(int(r/100. + .5) == 12);
P p(40, .25);
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.t() * p.p();
double x_var = x_mean*(1-p.p());
assert(std::abs(mean - x_mean) / x_mean < 0.01);
assert(std::abs(var - x_var) / x_var < 0.01);
}
}

View File

@@ -72,7 +72,7 @@ int main()
typedef std::minstd_rand G;
G g;
D d(20);
const int N = 10000;
const int N = 100000;
std::vector<double> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g));

View File

@@ -78,7 +78,7 @@ int main()
G g;
D d(2);
P p(20);
const int N = 10000;
const int N = 100000;
std::vector<double> u;
for (int i = 0; i < N; ++i)
u.push_back(d(g, p));