diff --git a/include/xo/randomgen/bernoulligen.hpp b/include/xo/randomgen/bernoulligen.hpp new file mode 100644 index 00000000..9de59300 --- /dev/null +++ b/include/xo/randomgen/bernoulligen.hpp @@ -0,0 +1,29 @@ +/* @file bernoulligen.hpp */ + +#pragma once + +#include "generator.hpp" +#include + +namespace xo { + namespace rng { + /* Engine: e.g. xo::rng::xoshiro256ss or std::mt19937 */ + template + class bernoulligen : public generator> { + public: + using generator_type = generator>; + + template + static generator_type make(Engine engine, double prob) { + return generator_type::make(std::move(engine), + std::bernoulli_distribution(prob)); + } + + template + static generator_type conflip(Engine engine) { + return generator_type::make(std::move(engine), + std::bernoulli_distribution(0.5)); + } + }; + } /*namespace rng*/ + } /*namespace xo*/ diff --git a/include/xo/randomgen/exponentialgen.hpp b/include/xo/randomgen/exponentialgen.hpp new file mode 100644 index 00000000..35945f5b --- /dev/null +++ b/include/xo/randomgen/exponentialgen.hpp @@ -0,0 +1,21 @@ +/* @file exponentialgen.hpp */ + +#pragma once + +#include "generator.hpp" +#include + +namespace xo { + namespace rng { + template + class exponentialgen : public generator> { + public: + using generator_type = generator>; + + template + static generator_type make(Engine eng, double lambda) { + return make_generator(std::move(eng), std::exponential_distribution(lambda)); + } + }; + } /*namespace rng*/ +} /*namespace xo*/ diff --git a/include/xo/randomgen/gaussianpairgen.hpp b/include/xo/randomgen/gaussianpairgen.hpp new file mode 100644 index 00000000..d5cc4699 --- /dev/null +++ b/include/xo/randomgen/gaussianpairgen.hpp @@ -0,0 +1,108 @@ +/* @file gaussianpairgen.hpp */ + +#pragma once + +#include "generator.hpp" +#include +#include + +namespace xo { + namespace random { + /* editor bait: 2d normal, normal xy + * + * if + * N1 ~ N(0,1) + * N2 ~ N(0,1) + * are two indepenent, normally-distributed r.v's with + * mean 0 and variance 1, then + * let + * A = | 1 0 | X = | N1 | + * | r q | | N2 | + * + * with r^2 + q^2 = 1 + * + * and consider + * A.X = | N1 | := | Y1 | + * | r.N1 + q.N2 | | Y2 | + * + * Y1, Y2 both have mean 0, + * since both are linear combination of 0-mean N(0,1) variables + * + * Var(Y1) = 1 + * Var(Y2) = r^2.Var(N1) + q^2.Var(N2) + * = r^2 + q^2 + * = 1 + * + * (since N1,N2 indept, and Var(N1)=Var(N2)=1) + * + * Cov(Y1,Y2) = r.Cov(N1,N1) + q.Cov(N1,N2) + * = r.Var(N1) + * = r + * + * (since Cov(N1,N2)=0) + * + * we have correlation coefficient for Y1,Y2: + * + * Cov(Y1,Y2) + * p(Y1,Y2) = -------------------- + * sqrt(Var(Y1).Var(Y2)) + * + * = r + */ + template + class gaussianpair_dist { + public: + using result_type = std::array; + + public: + /* generate pairs of gaussian N(0,1) random numbers, + * with correlation coefficient rho + * + * Require: + * - rho in the interval [-1, +1] + */ + explicit gaussianpair_dist(FloatType rho) + : r_(rho), q_(std::sqrt(1.0 - rho*rho)) {} + + template + result_type operator()(Engine & engine) { + FloatType n1 = this->ndist_(engine); + FloatType n2 = this->ndist_(engine); + + FloatType y1 = n1; + FloatType y2 = this->r_ * n1 + this->q_ * n2; + + return {y1, y2}; + } /*operator()*/ + + private: + /* correlation coefficient r + * 2nd random variable Y2 in each pair will be constructed by + * r.N1 + sqrt(1-r^2).N2 + */ + FloatType r_; + /* q := sqrt(1-r^2) */ + FloatType q_; + + /* state for generating indept normally-distributed r.v's */ + std::normal_distribution ndist_; + }; /*gaussianpair_dist*/ + + /* generate pairs of correlated gaussian random variables */ + template + class gaussianpairgen { + public: + using engine_type = Engine; + using generator_type = generator>; + + template + static generator_type make(Engine eng, + double rho) { + return generator_type::make(std::move(eng), + gaussianpair_dist(rho)); + } + }; /*GaussianPairGen*/ + } /*namespace random*/ +} /*namespace xo*/ + +/* end gaussianpairgen.hpp */ diff --git a/include/xo/randomgen/uniformgen.hpp b/include/xo/randomgen/uniformgen.hpp new file mode 100644 index 00000000..d1c4d62b --- /dev/null +++ b/include/xo/randomgen/uniformgen.hpp @@ -0,0 +1,25 @@ +/* @file uniformgen.hpp */ + +#pragma once + +#include "generator.hpp" +#include + +namespace xo { + namespace rng { + template + class uniformgen : public generator> { + public: + using generator_type = generator>; + + template + static generator_type unit(Engine eng) { + return make_generator(std::move(eng), + std::uniform_real_distribution(0.0, 1.0)); + } + }; + } /*namespace rng*/ +} /*namespace xo*/ + + +/* end uniformgen.hpp */