IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 570a0266 authored by Maximilian Reininghaus's avatar Maximilian Reininghaus :vulcan:
Browse files

basic interface for RNG

parent 57fe46ab
No related branches found
No related tags found
No related merge requests found
...@@ -6,3 +6,4 @@ add_subdirectory (Logging) ...@@ -6,3 +6,4 @@ add_subdirectory (Logging)
add_subdirectory (StackInterface) add_subdirectory (StackInterface)
add_subdirectory (ProcessSequence) add_subdirectory (ProcessSequence)
add_subdirectory (Cascade) add_subdirectory (Cascade)
add_subdirectory (Random)
set (
CORSIKArandom_SOURCES
RNGManager.cc
)
set (
CORSIKArandom_HEADERS
RNGManager.h
)
set (
CORSIKArandom_NAMESPACE
corsika/random
)
add_library (CORSIKArandom STATIC ${CORSIKArandom_SOURCES})
CORSIKA_COPY_HEADERS_TO_NAMESPACE (CORSIKArandom ${CORSIKArandom_NAMESPACE} ${CORSIKArandom_HEADERS})
target_include_directories (
CORSIKArandom
PUBLIC
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include/>
)
# target dependencies on other libraries (also the header onlys)
# none
install (
TARGETS CORSIKArandom
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include/${CORSIKArandom_NAMESPACE}
)
# --------------------
# code unit testing
add_executable (testRandom testRandom.cc)
target_link_libraries (
testRandom
CORSIKArandom
CORSIKAthirdparty # for catch2
)
add_test (NAME testRandom COMMAND testRandom)
#include <corsika/random/RNGManager.h>
void corsika::random::RNGManager::RegisterRandomStream(std::string const& pStreamName) {
corsika::random::RNG rng;
if (auto const& it = seeds.find(pStreamName); it != seeds.end()) {
rng.seed(it->second);
}
rngs[pStreamName] = std::move(rng);
}
corsika::random::RNG& corsika::random::RNGManager::GetRandomStream(std::string const& pStreamName) {
return rngs.at(pStreamName);
}
std::stringstream corsika::random::RNGManager::dumpState() const {
std::stringstream buffer;
for (auto const& [streamName, rng] : rngs) {
buffer << '"' << streamName << "\" = \"" << rng << '"' << std::endl;
}
return buffer;
}
#ifndef _include_RNGManager_h_
#define _include_RNGManager_h_
#include <map>
#include <random>
#include <sstream>
#include <string>
/*!
* With this class modules can register streams of random numbers.
*/
namespace corsika::random {
using RNG = std::mt19937; //!< the actual RNG type that will be used
class RNGManager {
std::map<std::string, RNG> rngs;
std::map<std::string, std::seed_seq> seeds;
public:
/*!
* This function is to be called by a module requiring a random-number
* stream during its initialization.
*
* \throws sth. when stream \a pModuleName is already registered
*/
void RegisterRandomStream(std::string const& pStreamName);
/*!
* returns the pre-stored stream of given name \a pStreamName if
* available
*/
RNG& GetRandomStream(std::string const& pStreamName);
/*!
* dumps the names and states of all registered random-number streams
* into a std::stringstream.
*/
std::stringstream dumpState() const;
};
} // namespace Random
#endif
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one
// cpp file
#include <catch2/catch.hpp>
#include <corsika/random/RNGManager.h>
#include <iostream>
using namespace corsika::random;
SCENARIO("random-number streams can be registered and retrieved") {
GIVEN("a RNGManager") {
RNGManager rngManager;
WHEN("a sequence is registered by name") {
rngManager.RegisterRandomStream("stream_A");
THEN("the sequence can be retrieved") {
REQUIRE_NOTHROW(rngManager.GetRandomStream("stream_A"));
}
THEN("an unknown sequence cannot be retrieved") {
REQUIRE_THROWS(rngManager.GetRandomStream("stream_UNKNOWN"));
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment