From a4c264d8db2f02e7d7bc433e22f571b65450aba1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 17 Oct 2023 14:54:27 -0400 Subject: [PATCH] randomgen: distribution + related concepts --- include/xo/randomgen/distribution_concept.hpp | 35 +++++++++++++ include/xo/randomgen/generator.hpp | 49 +++++++++++++++++++ include/xo/randomgen/normalgen.hpp | 14 ++++++ 3 files changed, 98 insertions(+) create mode 100644 include/xo/randomgen/distribution_concept.hpp create mode 100644 include/xo/randomgen/generator.hpp create mode 100644 include/xo/randomgen/normalgen.hpp diff --git a/include/xo/randomgen/distribution_concept.hpp b/include/xo/randomgen/distribution_concept.hpp new file mode 100644 index 00000000..61c764e0 --- /dev/null +++ b/include/xo/randomgen/distribution_concept.hpp @@ -0,0 +1,35 @@ +/* @file distribution_concept.hpp */ + +#pragma once + +#include + +namespace xo { + namespace rng { + template + concept distribution_concept = requires(Distribution dist, typename Distribution::param_type p) { + typename Distribution::result_type; + typename Distribution::param_type; + { Distribution() }; + { Distribution(p) }; + { dist.reset() }; + { dist.param() }; + { dist.param(p) }; + // { dist(g) }; // generator g satisfying engine_concept + // { dist(g, p) }; + { dist.min() }; + { dist.max() }; + { dist == dist }; + { dist != dist }; + // os << dist + // is >> dist + + } && std::copyable + && std::copyable + && std::equality_comparable; + } /*namespace rng*/ + +} /*namespace xo*/ + + +/* end distribution_concept.hpp */ diff --git a/include/xo/randomgen/generator.hpp b/include/xo/randomgen/generator.hpp new file mode 100644 index 00000000..f35c0994 --- /dev/null +++ b/include/xo/randomgen/generator.hpp @@ -0,0 +1,49 @@ +/* @file generator.hpp */ + +#pragma once + +#include "engine_concept.hpp" +#include "distribution_concept.hpp" +#include + +namespace xo { + namespace rng { + /* Engine: uniform integer random number generator, e.g. xoshiro256ss + * Distribution: random number distribution, e.g. std::normal_distribution + */ + template requires engine_concept && distribution_concept + class generator { + public: + using result_type = typename Distribution::result_type; + using engine_type = Engine; + + public: + generator(Engine & e, Distribution const & d) + : engine_{e}, + distribution_{d} {} + generator(Engine && e, Distribution && d) + : engine_{std::move(e)}, + distribution_{std::move(d)} {} + + static generator make(Engine e, Distribution d) { + return generator(e, d); + } + + result_type operator()() { return this->distribution_(this->engine_); } + + private: + /* random number generator; generates uniformly-distributed integers */ + Engine engine_; + /* distribution object */ + Distribution distribution_; + }; /*generator*/ + + template + generator make_generator(Engine e, Distribution d) { + return generator::make(std::move(e), + std::move(d)); + } /*make_generator*/ + } /*namespace rng*/ +} /*namespace xo*/ + +/* end generator.hpp */ diff --git a/include/xo/randomgen/normalgen.hpp b/include/xo/randomgen/normalgen.hpp new file mode 100644 index 00000000..dad04328 --- /dev/null +++ b/include/xo/randomgen/normalgen.hpp @@ -0,0 +1,14 @@ +/* @file normalgen.hpp */ + +#pragma once + +#include "generator.hpp" +#include + +namespace xo { + namespace rng { + /* Engine: e.g. xo::rng::xoshiro256 or std::mt19937 */ + template + using normalgen = generator>; + } /*namespace rng*/ +} /*namespace xo*/