From 2bdfcc4fbb425d9ad6af0da3de5aa1562abf1d5c Mon Sep 17 00:00:00 2001 From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu> Date: Tue, 15 Jan 2019 13:23:18 +0100 Subject: [PATCH] added ExponentialDistribution --- Framework/Random/CMakeLists.txt | 1 + Framework/Random/ExponentialDistribution.h | 38 ++++++++++++++++++++++ Framework/Random/UniformRealDistribution.h | 5 ++- Framework/Random/testRandom.cc | 24 ++++++++++++++ 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 Framework/Random/ExponentialDistribution.h diff --git a/Framework/Random/CMakeLists.txt b/Framework/Random/CMakeLists.txt index 3607b585..84479e12 100644 --- a/Framework/Random/CMakeLists.txt +++ b/Framework/Random/CMakeLists.txt @@ -8,6 +8,7 @@ set ( CORSIKArandom_HEADERS RNGManager.h UniformRealDistribution.h + ExponentialDistribution.h ) set ( diff --git a/Framework/Random/ExponentialDistribution.h b/Framework/Random/ExponentialDistribution.h new file mode 100644 index 00000000..248d785a --- /dev/null +++ b/Framework/Random/ExponentialDistribution.h @@ -0,0 +1,38 @@ +/** + * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu + * + * See file AUTHORS for a list of contributors. + * + * This software is distributed under the terms of the GNU General Public + * Licence version 3 (GPL Version 3). See file LICENSE for a full version of + * the license. + */ + +#ifndef _include_ExponentialDistribution_h +#define _include_ExponentialDistribution_h + +#include <corsika/units/PhysicalUnits.h> +#include <random> + +namespace corsika::random { + + template <class TQuantity> + class ExponentialDistribution { + using RealType = typename TQuantity::value_type; + std::exponential_distribution<RealType> dist{1.}; + + TQuantity const fBeta; + + public: + ExponentialDistribution(TQuantity beta) + : fBeta(beta) {} + + template <class Generator> + TQuantity operator()(Generator& g) { + return fBeta * dist(g); + } + }; + +} // namespace corsika::random + +#endif diff --git a/Framework/Random/UniformRealDistribution.h b/Framework/Random/UniformRealDistribution.h index 73872928..fd501ab3 100644 --- a/Framework/Random/UniformRealDistribution.h +++ b/Framework/Random/UniformRealDistribution.h @@ -1,4 +1,3 @@ - /** * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu * @@ -9,8 +8,8 @@ * the license. */ -#ifndef _include_random_distributions_h -#define _include_random_distributions_h +#ifndef _include_UniformRealDistribution_h +#define _include_UniformRealDistribution_h #include <corsika/units/PhysicalUnits.h> #include <random> diff --git a/Framework/Random/testRandom.cc b/Framework/Random/testRandom.cc index 56d8157a..97923eb0 100644 --- a/Framework/Random/testRandom.cc +++ b/Framework/Random/testRandom.cc @@ -14,10 +14,12 @@ #include <corsika/random/RNGManager.h> #include <corsika/random/UniformRealDistribution.h> +#include <corsika/random/ExponentialDistribution.h> #include <corsika/units/PhysicalUnits.h> #include <iostream> #include <limits> #include <random> +#include <type_traits> using namespace corsika::random; @@ -83,3 +85,25 @@ TEST_CASE("UniformRealDistribution") { CHECK(max / 18_cm == Approx(1.)); } } + +TEST_CASE("ExponentialDistribution") { + using namespace corsika::units::si; + std::mt19937 rng; + + auto const beta = 15_m; + + corsika::random::ExponentialDistribution dist(beta); + + SECTION("mean") { + std::remove_const<decltype(beta)>::type mean = beta * 0; + + int constexpr N = 1'000'000; + + for (int i{0}; i < N; ++i) { + decltype(beta) x = dist(rng); + mean += x / N; + } + + CHECK(mean / beta == Approx(1).margin(1e-2)); + } +} -- GitLab