trick/trick_source/sim_services/MonteCarlo/StlRandomGenerator.cpp

297 lines
14 KiB
C++
Raw Normal View History

2015-02-26 15:02:31 +00:00
#include <stdexcept>
#include "trick/StlRandomGenerator.hh"
2015-02-26 15:02:31 +00:00
StlRandomGenerator::StlRandomGenerator(double in_param_a,
double in_param_b,
unsigned long in_seed,
StlDistribution in_dist_type,
StlEngine in_engine_type)
: initialSeed(in_seed),
engineEnum(in_engine_type),
distEnum(in_dist_type)
{
}
StlRandomGenerator::~StlRandomGenerator()
{
}
///@details return a pointer-to-base-class for a new StlRandomGeneratorSub object
/// of the input-specified type
StlRandomGenerator*
StlRandomGeneratorFactory::newGenerator(
double in_param_a,
double in_param_b,
unsigned long in_seed,
StlRandomGenerator::StlDistribution in_dist_type,
StlRandomGenerator::StlEngine in_engine_type)
{
#if (defined(_HAVE_TR1_RANDOM) || defined(_HAVE_STL_RANDOM))
#ifdef _HAVE_STL_RANDOM
#define UNIFORM_INT_DIST std::uniform_int_distribution
#define UNIFORM_REAL_DIST std::uniform_real_distribution
#define TRICK_DEFAULT_ENGINE_CLASS std::mt19937
#else
#define UNIFORM_INT_DIST std::uniform_int
#define UNIFORM_REAL_DIST std::uniform_real
#define TRICK_DEFAULT_ENGINE_CLASS std::ranlux_base_01 // because mt19937 doesnt return within canonical range for GCC 4.4.7
#endif
switch (in_engine_type * 1000 + in_dist_type) {
// ------------- TRICK_DEFAULT_ENGINE --------------------------------------
case StlRandomGenerator::TRICK_DEFAULT_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< TRICK_DEFAULT_ENGINE_CLASS, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::TRICK_DEFAULT_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< TRICK_DEFAULT_ENGINE_CLASS, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::TRICK_DEFAULT_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< TRICK_DEFAULT_ENGINE_CLASS, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
#ifdef _HAVE_TR1_RANDOM
// ------------- RANLUX_BASE_01_ENGINE ---------------------------------------------
case StlRandomGenerator::RANLUX_BASE_01_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux_base_01, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_BASE_01_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux_base_01, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_BASE_01_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux_base_01, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
// ------------- RANLUX_64_BASE_01_ENGINE ---------------------------------------------
case StlRandomGenerator::RANLUX_64_BASE_01_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux64_base_01, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_64_BASE_01_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux64_base_01, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_64_BASE_01_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux64_base_01, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
#else
// std::minstd_rand and mt19937 are not provided for TR1, because GCC 4.4.7 (at least)
// they return outside the canonical range 0 <= x < 1.
// This causes an infinite loop in std::normal_distribution
// ------------- MINSTD_RAND_ENGINE ---------------------------------------------
case StlRandomGenerator::MINSTD_RAND_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::minstd_rand, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::MINSTD_RAND_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::minstd_rand, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::MINSTD_RAND_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::minstd_rand, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
// ------------- MT19937_ENGINE ---------------------------------------------
case StlRandomGenerator::MT19937_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::mt19937, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::MT19937_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::mt19937, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::MT19937_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::mt19937, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
// these engines are all C++11 only
// ------------- MT19937_64_ENGINE ---------------------------------------------
case StlRandomGenerator::MT19937_64_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::mt19937_64, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::MT19937_64_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::mt19937_64, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::MT19937_64_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::mt19937_64, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
// ------------- RANLUX_24_BASE_ENGINE ---------------------------------------------
case StlRandomGenerator::RANLUX_24_BASE_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux24_base, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_24_BASE_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux24_base, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_24_BASE_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux24_base, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
// ------------- RANLUX_44_BASE_ENGINE ---------------------------------------------
case StlRandomGenerator::RANLUX_44_BASE_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux48_base, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_44_BASE_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux48_base, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_44_BASE_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux48_base, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
// ------------- RANLUX_24_ENGINE ---------------------------------------------
case StlRandomGenerator::RANLUX_24_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux24, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_24_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux24, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_24_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux24, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
// ------------- RANLUX_44_ENGINE ---------------------------------------------
case StlRandomGenerator::RANLUX_44_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux48, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_44_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux48, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::RANLUX_44_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::ranlux48, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
// ------------- KNUTH_B_ENGINE ---------------------------------------------
case StlRandomGenerator::KNUTH_B_ENGINE*1000 + StlRandomGenerator::GAUSSIAN:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::knuth_b, std::normal_distribution<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::KNUTH_B_ENGINE*1000 + StlRandomGenerator::FLAT:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::knuth_b, UNIFORM_REAL_DIST<double> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
case StlRandomGenerator::KNUTH_B_ENGINE*1000 + StlRandomGenerator::POISSON:
return static_cast< StlRandomGenerator* > (
new StlRandomGeneratorSub< std::knuth_b, std::poisson_distribution<STL_POISSON_TEMPLATE_TYPES> >
(in_param_a, in_param_b, in_seed, in_dist_type, in_engine_type)
);
break;
#endif
default:
throw std::invalid_argument(std::string("error: StlRandomGeneratorFactory::newGenerator called for unimplemented std::random (engine,distribution) combination."));
}
#else
// without either _HAVE_TR1_RANDOM or _HAVE_STL_RANDOM, return null pointer.
return 0; // ???? what was I thinking here static_cast< StlRandomGenerator* >( 0 );
#endif
}