diff --git a/src/core/examples/empirical-random-variable-example.cc b/src/core/examples/empirical-random-variable-example.cc new file mode 100644 index 000000000..c8bd663f8 --- /dev/null +++ b/src/core/examples/empirical-random-variable-example.cc @@ -0,0 +1,215 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Lawrence Livermore National Laboratory + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Peter D. Barnes, Jr. + */ + +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/command-line.h" +#include "ns3/random-variable-stream.h" +#include "ns3/histogram.h" +#include "ns3/ptr.h" + +#include +#include +#include + +/** + * \file + * \ingroup core-examples + * \ingroup randomvariable + * Example program illustrating use of ns3::EmpiricalRandomVariable + * + * This example illustrates + * + * * Creating an EmpiricalRandomVariable instance. + * * Switching the mode. + * * Using the sampling mode + * * Switching modes + * * Using the interpolating mode + * + * Consult the ns-3 manual for more information about the use of the + * random number generator + */ + +using namespace ns3; + +void +RunSingleSample (std::string mode, Ptr erv) +{ + std::cout << "------------------------------" << std::endl; + std::cout << "Sampling " << mode << std::endl; + + std::cout << std::endl; + std::cout << "Binned sample" << std::endl; + double value = erv->GetValue (); + std::cout << "Binned sample: " << value << std::endl; + std::cout << std::endl; + + std::cout << "Interpolated sample" << std::endl; + erv->SetInterpolate (true); + value = erv->GetValue (); + std::cout << "Interpolated sample:" << value << std::endl; + erv->SetInterpolate (false); +} + +void +PrintStatsLine (const double value, const long count, const long n) +{ + std::cout << std::fixed << std::setprecision (3) + << std::setw (10) << std::right << value + << std::setw (10) << std::right << count + << std::setw (10) << std::right + << count / static_cast (n) * 100.0 + << std::endl; +} + +void +PrintSummary (long sum, long n, double weighted, double expected) +{ + std::cout << std::endl; + std::cout << " --------" << std::endl; + std::cout << " Total " + << std::setprecision (3) << std::fixed + << std::setw (10) << std::right + << sum / static_cast (n) * 100.0 + << std::endl; + std::cout << " Average " + << std::setprecision (3) << std::fixed + << std::setw (6) << std::right << weighted / n + << std::endl; + std::cout << " Expected " + << std::setprecision (3) << std::fixed + << std::setw (6) << std::right << expected + << std::endl + << std::endl; +} + +void +RunBothModes (std::string mode, Ptr erv, long n) +{ + std::cout << std::endl; + std::cout << "Sampling " << mode << std::endl; + std::map counts; + counts[0] = 0; + for (long i = 0; i < n; ++i) + { + ++counts[erv->GetValue ()]; + } + long sum = 0; + double weighted = 0; + std::cout << std::endl; + std::cout << " Value Counts %" << std::endl; + std::cout << "---------- -------- --------" << std::endl; + for (auto c : counts) + { + long count = c.second; + double value = c.first; + sum += count; + weighted += value * count; + PrintStatsLine (value, count, n); + } + PrintSummary (sum, n, weighted, 8.75); + + std::cout << "Interpolating " << mode << std::endl; + erv->SetInterpolate (true); + Histogram h (0.5); + for (long i = 0; i < n; ++i) + { + h.AddValue (erv->GetValue ()); + // This could also be expressed as + // h.AddValue (erv->Interpolate ()); + } + erv->SetInterpolate (false); + sum = 0; + weighted = 0; + std::cout << std::endl; + std::cout << " Bin Start Counts %" << std::endl; + std::cout << "---------- -------- --------" << std::endl; + for (uint32_t i = 0; i < h.GetNBins (); ++i) + { + long count = h.GetBinCount (i); + double start = h.GetBinStart (i); + double value = start + h.GetBinWidth (i) / 2.; + sum += count; + weighted += count * value; + PrintStatsLine (start, count, n); + } + PrintSummary (sum, n, weighted, 6.25); +} + + +int main (int argc, char *argv[]) +{ + long n = 1000000; + bool disableAnti = false; + bool single = false; + CommandLine cmd; + cmd.AddValue ("count", "how many draws to make from the rng", n); + cmd.AddValue ("antithetic", "disable antithetic sampling", disableAnti); + cmd.AddValue ("single", "sample a single time", single); + cmd.Parse (argc, argv); + std::cout << std::endl; + std::cout << cmd.GetName () << std::endl; + if (!single) + { + std::cout << "Sample count: " << n << std::endl; + } + else + { + std::cout << "Sampling a single time" << std::endl; + } + if (disableAnti) + { + std::cout << "Antithetic sampling disabled" << std::endl; + } + + // Create the ERV in sampling mode + Ptr erv = CreateObject (); + erv->SetInterpolate (false); + erv->CDF ( 0.0, 0.0); + erv->CDF ( 5.0, 0.25); + erv->CDF (10.0, 1.0); + + if (single) + { + RunSingleSample ("normal", erv); + if (!disableAnti) + { + std::cout << std::endl; + std::cout << "Antithetic" << std::endl; + erv->SetAntithetic (true); + RunSingleSample ("antithetic", erv); + erv->SetAntithetic (false); + } + + std::cout << std::endl; + return 0; + } + + RunBothModes ("normal", erv, n); + + if (!disableAnti) + { + erv->SetAntithetic (true); + RunBothModes ("antithetic", erv, n); + erv->SetAntithetic (false); + } + + return 0; +} diff --git a/src/core/examples/wscript b/src/core/examples/wscript index 13879618c..6a34452ef 100644 --- a/src/core/examples/wscript +++ b/src/core/examples/wscript @@ -44,6 +44,9 @@ def build(bld): ['core']) obj.source = 'sample-show-progress.cc' + obj = bld.create_ns3_program('empirical-random-variable-example', ['core', 'flow-monitor']) + obj.source = 'empirical-random-variable-example.cc' + if bld.env['ENABLE_THREADING'] and bld.env["ENABLE_REAL_TIME"]: obj = bld.create_ns3_program('main-test-sync', ['network']) obj.source = 'main-test-sync.cc' diff --git a/src/core/model/random-variable-stream.cc b/src/core/model/random-variable-stream.cc index b6947fc37..dd877c41d 100644 --- a/src/core/model/random-variable-stream.cc +++ b/src/core/model/random-variable-stream.cc @@ -1518,12 +1518,13 @@ DeterministicRandomVariable::GetInteger (void) NS_OBJECT_ENSURE_REGISTERED (EmpiricalRandomVariable); // ValueCDF methods -EmpiricalRandomVariable::ValueCDF::ValueCDF () +EmpiricalRandomVariable::ValueCDF::ValueCDF (void) : value (0.0), cdf (0.0) { NS_LOG_FUNCTION (this); } + EmpiricalRandomVariable::ValueCDF::ValueCDF (double v, double c) : value (v), cdf (c) @@ -1531,11 +1532,12 @@ EmpiricalRandomVariable::ValueCDF::ValueCDF (double v, double c) NS_LOG_FUNCTION (this << v << c); NS_ASSERT (c >= 0.0 && c <= 1.0); } -EmpiricalRandomVariable::ValueCDF::ValueCDF (const ValueCDF& c) - : value (c.value), - cdf (c.cdf) + +bool +operator < (EmpiricalRandomVariable::ValueCDF a, + EmpiricalRandomVariable::ValueCDF b) { - NS_LOG_FUNCTION (this << &c); + return a.cdf < b.cdf; } TypeId @@ -1545,18 +1547,39 @@ EmpiricalRandomVariable::GetTypeId (void) .SetParent() .SetGroupName ("Core") .AddConstructor () + .AddAttribute ("Interpolate", + "Treat the CDF as a smooth distribution and interpolate, " + "default is to treat the CDF as a histogram and sample.", + BooleanValue (false), + MakeBooleanAccessor (&EmpiricalRandomVariable::m_interpolate), + MakeBooleanChecker ()) ; return tid; } -EmpiricalRandomVariable::EmpiricalRandomVariable () - : - m_validated (false) +EmpiricalRandomVariable::EmpiricalRandomVariable (void) + : m_validated (false) { NS_LOG_FUNCTION (this); } -double -EmpiricalRandomVariable::GetValue (void) +bool +EmpiricalRandomVariable::SetInterpolate (bool interpolate) +{ + NS_LOG_FUNCTION (this << interpolate); + bool prev = m_interpolate; + m_interpolate = interpolate; + return prev; +} + +uint32_t +EmpiricalRandomVariable::GetInteger (void) +{ + NS_LOG_FUNCTION (this); + return static_cast (GetValue ()); +} + +bool +EmpiricalRandomVariable::PreSample (double & value) { NS_LOG_FUNCTION (this); @@ -1564,29 +1587,61 @@ EmpiricalRandomVariable::GetValue (void) { Validate (); } - - // Get a uniform random variable in [0,1]. + + // Get a uniform random variable in [0, 1]. double r = Peek ()->RandU01 (); if (IsAntithetic ()) { r = (1 - r); } - + + value = r; + bool valid = false; + // check extrema if (r <= m_emp.front ().cdf) { - return m_emp.front ().value; // Less than first + value = m_emp.front ().value; // Less than first + valid = true; } - if (r >= m_emp.back ().cdf) + else if (r >= m_emp.back ().cdf) { - return m_emp.back ().value; // Greater than last + value = m_emp.back ().value; // Greater than last + valid = true; + } + return valid; +} + +double +EmpiricalRandomVariable::GetValue (void) +{ + NS_LOG_FUNCTION (this); + + double value; + if (PreSample (value)) + { + return value; } - // Binary search - auto bound = std::upper_bound (m_emp.begin (), m_emp.end (), r, - [] (double p, ValueCDF &it) - { - return p < it.cdf; - }); + // value now has the (unused) URNG selector + if (m_interpolate) + { + value = DoInterpolate (value); + } + else + { + value = DoSampleCDF (value); + } + return value; +} + +double +EmpiricalRandomVariable::DoSampleCDF (double r) +{ + NS_LOG_FUNCTION (this << r); + + ValueCDF selector (0, r); + auto bound = std::upper_bound (m_emp.begin (), m_emp.end (), selector); + return bound->value; } @@ -1595,52 +1650,55 @@ EmpiricalRandomVariable::Interpolate (void) { NS_LOG_FUNCTION (this); - if (!m_validated) + double value; + if (PreSample (value)) { - Validate (); - } - - // Get a uniform random variable in [0, 1]. - double r = Peek ()->RandU01 (); - if (IsAntithetic ()) - { - r = (1 - r); + return value; } - if (r <= m_emp.front ().cdf) - { - return m_emp.front ().value; // Less than first - } - if (r >= m_emp.back ().cdf) - { - return m_emp.back ().value; // Greater than last - } - - // Binary search - auto bound = std::upper_bound (m_emp.begin (), m_emp.end (), r, - [] (double p, ValueCDF &it) - { - return p < it.cdf; - }); - auto next = std::next(bound, 1); - return DoInterpolate (bound->cdf, next->cdf, bound->value, next->value, r); + // value now has the (unused) URNG selector + value = DoInterpolate (value); + return value; } -uint32_t -EmpiricalRandomVariable::GetInteger (void) +double +EmpiricalRandomVariable::DoInterpolate (double r) { - NS_LOG_FUNCTION (this); - return (uint32_t)GetValue (); + NS_LOG_FUNCTION (this << r); + + // Return a value from the empirical distribution + // This code based (loosely) on code by Bruce Mah (Thanks Bruce!) + + // search + ValueCDF selector (0, r); + auto upper = std::upper_bound (m_emp.begin (), m_emp.end (), selector); + auto lower = std::prev (upper, 1); + if (upper == m_emp.begin ()) + { + lower = upper; + } + + // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2) + double c1 = lower->cdf; + double c2 = upper->cdf; + double v1 = lower->value; + double v2 = upper->value; + + double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1)); + return value; } -void EmpiricalRandomVariable::CDF (double v, double c) -{ // Add a new empirical datapoint to the empirical cdf +void +EmpiricalRandomVariable::CDF (double v, double c) +{ + // Add a new empirical datapoint to the empirical cdf // NOTE. These MUST be inserted in non-decreasing order NS_LOG_FUNCTION (this << v << c); m_emp.push_back (ValueCDF (v, c)); } -void EmpiricalRandomVariable::Validate () +void +EmpiricalRandomVariable::Validate (void) { NS_LOG_FUNCTION (this); if (m_emp.empty ()) @@ -1648,9 +1706,8 @@ void EmpiricalRandomVariable::Validate () NS_FATAL_ERROR ("CDF is not initialized"); } ValueCDF prior = m_emp[0]; - for (std::vector::size_type i = 0; i < m_emp.size (); ++i) + for (auto current : m_emp) { - ValueCDF& current = m_emp[i]; if (current.value < prior.value || current.cdf < prior.cdf) { // Error std::cerr << "Empirical Dist error," @@ -1669,11 +1726,4 @@ void EmpiricalRandomVariable::Validate () m_validated = true; } -double EmpiricalRandomVariable::DoInterpolate (double c1, double c2, - double v1, double v2, double r) -{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2) - NS_LOG_FUNCTION (this << c1 << c2 << v1 << v2 << r); - return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1)); -} - } // namespace ns3 diff --git a/src/core/model/random-variable-stream.h b/src/core/model/random-variable-stream.h index ccc56b8a7..354d90fca 100644 --- a/src/core/model/random-variable-stream.h +++ b/src/core/model/random-variable-stream.h @@ -2403,34 +2403,70 @@ private: /** * \ingroup randomvariable - * \brief The Random Number Generator (RNG) that has a specified empirical distribution. + * \brief The Random Number Generator (RNG) that has a specified + * empirical distribution. * * Defines a random variable that has a specified, empirical * distribution. The distribution is specified by a - * series of calls to the CDF member function, specifying a + * series of calls to the CDF() member function, specifying a * value and the probability that the function value is less than - * the specified value. When values are requested, + * the specified value. When random values are requested, * a uniform random variable is used to select a probability, - * and the return value is interpreted linearly between the - * two appropriate points in the CDF. The method is known + * and the return value is chosen from the largest input value with CDF + * less than the random value. The method is known * as inverse transform sampling: * (http://en.wikipedia.org/wiki/Inverse_transform_sampling). * - * Here is an example of how to use this class: - * \code - * // Create the RNG with a uniform distribution between 0 and 10. - * Ptr x = CreateObject (); - * x->CDF ( 0.0, 0.0); - * x->CDF ( 5.0, 0.5); - * x->CDF (10.0, 1.0); + * This generator has two modes: *sampling* and *interpolating*. + * In *sampling* mode this random variable generator + * treats the CDF as an exact histogram and returns + * one of the histogram inputs exactly. This is appropriate + * when the configured CDF represents the exact probability + * distribution, for a categorical variable, for example. * - * // The expected value for the mean of the values returned by this - * // empirical distribution is the midpoint of the distribution - * // - * // E[value] = 5 . - * // - * double value = x->GetValue (); - * \endcode + * In *interpolating* mode this random variable generator linearly + * interpolates between the CDF values defining the histogram bins. + * This is appropriate when the configured CDF is an approximation + * to a continuous underlying probability distribution. + * + * For historical reasons the default is interpolating. + * To switch modes use the \c Interpolate Attribute, or call SetInterpolate(). + * You can change modes at any time. + * + * If you find yourself switching frequently it could be simpler to + * set the mode to sampling, then use the GetValue() function for + * sampled values, and Interpolate() function for interpolated values. + * + * Here is an example of how to use this class: + * + * // Create the RNG with a non-uniform distribution between 0 and 10. + * // in sampling mode. + * Ptr x = CreateObject (); + * x->SetInterpolate (false); + * x->CDF ( 0.0, 0.0); + * x->CDF ( 5.0, 0.25); + * x->CDF (10.0, 1.0); + * + * double value = x->GetValue (); + * + * The expected values and probabilities returned by GetValue are + * + * Value | Probability + * ----: | ----------: + * 0.0 | 0 + * 5.0 | 25% + * 10.0 | 75% + * + * The only two values ever returned are 5 and 10, with unequal probability. + * + * If instead you want linear interpolation between the points of the CDF + * use the Interpolate() function: + * + * double interp = x->Interpolate (); + * + * This will return continuous values on the range [0,1). + * + * See empirical-random-variable-example.cc for an example. */ class EmpiricalRandomVariable : public RandomVariableStream { @@ -2443,14 +2479,16 @@ public: /** * \brief Creates an empirical RNG that has a specified, empirical - * distribution. + * distribution, and configured for interpolating mode. */ - EmpiricalRandomVariable (); + EmpiricalRandomVariable (void); /** * \brief Specifies a point in the empirical distribution + * \note These *MUST* be inserted in ascending order of \p c + * * \param [in] v The function value for this point - * \param [in] c Probability that the function is less than or equal to v + * \param [in] c Probability that the function is less than or equal to \p v */ void CDF (double v, double c); // Value, prob <= Value @@ -2460,6 +2498,7 @@ public: * * Note that this does not interpolate the CDF, but treats it as a * stepwise continuous function. + * * Also note that antithetic values are being generated if m_isAntithetic * is equal to true. If \f$u\f$ is a uniform variable over [0,1] * and \f$x\f$ is a value that would be returned normally, then @@ -2485,39 +2524,44 @@ public: virtual uint32_t GetInteger (void); /** - * \brief Returns the next value in the empirical distribution using linear interpolation. - * \return The floating point next value in the empirical distribution using linear interpolation. + * \brief Returns the next value in the empirical distribution using + * linear interpolation. + * \return The floating point next value in the empirical distribution + * using linear interpolation. */ virtual double Interpolate (void); + /** + * \brief Switch the mode between sampling the CDF and interpolating. + * The default mode is sampling. + * \param [in] interpolate If \c true set to interpolation, otherwise sampling. + * \returns The previous interpolate flag value. + */ + bool SetInterpolate (bool interpolate); + private: - /** Helper to hold one point of the CDF. */ + /** \brief Helper to hold one point of the CDF. */ class ValueCDF { public: - /** Constructor. */ - ValueCDF (); + /** \brief Constructor. */ + ValueCDF (void); /** - * Construct from values. + * \brief Construct from values. * * \param [in] v The argument value. * \param [in] c The CDF at the argument value \pname{v} */ ValueCDF (double v, double c); - /** - * Copy constructor. - * - * \param [in] c The other ValueCDF. - */ - ValueCDF (const ValueCDF& c); /** The argument value. */ double value; /** The CDF at \pname{value} */ double cdf; - }; + }; // class ValueCDF + /** - * Check that the CDF is valid. + * \brief Check that the CDF is valid. * * A valid CDF has * @@ -2526,25 +2570,54 @@ private: * * It is a fatal error to fail validation. */ - virtual void Validate (); + void Validate (void); + /** + * \brief Do the initial rng draw and check against the extrema. + * + * If the extrema apply, \c value will have the extremal value + * and the return will be \c true. + * + * If the extrema do not apply \c value will have the URNG value + * and the return will be \c false. + * + * \param [out] value The extremal value, or the URNG. + * \returns \c true if \p value is the extremal result, + * or \c false if \p value is the URNG value. + */ + bool PreSample (double & value); /** - * Linear interpolation between two points on the CDF to estimate + * \brief Sample the CDF as a histogram (without interpolation). + * \param [in] r The CDF value at which to sample the CDF. + * \return The bin value corresponding to \c r. + */ + double DoSampleCDF (double r); + /** + * \brief Linear interpolation between two points on the CDF to estimate * the value at \p r. * - * \param [in] c1 The first argument value. - * \param [in] c2 The second argument value. - * \param [in] v1 The first CDF value. - * \param [in] v2 The second CDF value. * \param [in] r The argument value to interpolate to. * \returns The interpolated CDF at \pname{r} */ - virtual double DoInterpolate (double c1, double c2, - double v1, double v2, double r); + double DoInterpolate (double r); + + /** + * \brief Comparison operator, for use by std::upper_bound + * \param a [in] the first value + * \param b [in] the second value + * \returns \c true if \c a.cdf < \c b.cdf + */ + friend + bool operator < (ValueCDF a, ValueCDF b); /** \c true once the CDF has been validated. */ bool m_validated; /** The vector of CDF points. */ std::vector m_emp; + /** + * If \c true GetValue will interpolate, + * otherwise treat CDF as normal histogram. + */ + bool m_interpolate; }; // class EmpiricalRandomVariable diff --git a/src/core/test/random-variable-stream-test-suite.cc b/src/core/test/random-variable-stream-test-suite.cc index e36916cae..0d37fc594 100644 --- a/src/core/test/random-variable-stream-test-suite.cc +++ b/src/core/test/random-variable-stream-test-suite.cc @@ -2741,26 +2741,39 @@ RandomVariableStreamEmpiricalTestCase::DoRun (void) // Create the RNG with a uniform distribution between 0 and 10. Ptr x = CreateObject (); + x->SetInterpolate (false); x->CDF ( 0.0, 0.0); - x->CDF ( 5.0, 0.5); + x->CDF ( 5.0, 0.25); x->CDF (10.0, 1.0); - // Calculate the mean of these values. - double sum = 0.0; - double value; + // Check that only the correct values are returned for (uint32_t i = 0; i < N_MEASUREMENTS; ++i) { - value = x->GetValue (); + double value = x->GetValue (); + NS_TEST_EXPECT_MSG_EQ ( (value == 5) || (value == 10), true, + "Incorrect value returned, expected only 5 or 10."); + } + + // Calculate the mean of the interpolated values. + double sum = 0.0; + for (uint32_t i = 0; i < N_MEASUREMENTS; ++i) + { + double value = x->Interpolate (); sum += value; } double valueMean = sum / N_MEASUREMENTS; + // The expected distribution (with interpolation) is + // Domain Probability + // [0, 5) 25% + // [5, 10) 75% + // // The expected value for the mean of the values returned by this - // empirical distribution is the midpoint of the distribution + // empirical distribution is // - // E[value] = 5 . + // E[value] = 2.5 * 25% + 7.5 * 75% = 6.25 // - double expectedMean = 5.0; + double expectedMean = 6.25; // Test that values have approximately the right mean value. double TOLERANCE = expectedMean * 1e-2; @@ -2768,6 +2781,7 @@ RandomVariableStreamEmpiricalTestCase::DoRun (void) // Bug 2082: Create the RNG with a uniform distribution between -1 and 1. Ptr y = CreateObject (); + y->SetInterpolate (false); y->CDF (-1.0, 0.0); y->CDF (0.0, 0.5); y->CDF (1.0, 1.0); @@ -2803,29 +2817,38 @@ RandomVariableStreamEmpiricalAntitheticTestCase::DoRun (void) // Create the RNG with a uniform distribution between 0 and 10. Ptr x = CreateObject (); + x->SetInterpolate (false); x->CDF ( 0.0, 0.0); - x->CDF ( 5.0, 0.5); + x->CDF ( 5.0, 0.25); x->CDF (10.0, 1.0); // Make this generate antithetic values. x->SetAttribute ("Antithetic", BooleanValue (true)); + // Check that only the correct values are returned + for (uint32_t i = 0; i < N_MEASUREMENTS; ++i) + { + double value = x->GetValue (); + NS_TEST_EXPECT_MSG_EQ ( (value == 5) || (value == 10), true, + "Incorrect value returned, expected only 5 or 10."); + } + // Calculate the mean of these values. double sum = 0.0; double value; for (uint32_t i = 0; i < N_MEASUREMENTS; ++i) { - value = x->GetValue (); + value = x->Interpolate (); sum += value; } double valueMean = sum / N_MEASUREMENTS; // The expected value for the mean of the values returned by this - // empirical distribution is the midpoint of the distribution + // empirical distribution is // - // E[value] = 5 . + // E[value] = 2.5 * 25% + 7.5 * 75% = 6.25 // - double expectedMean = 5.0; + double expectedMean = 6.25; // Test that values have approximately the right mean value. double TOLERANCE = expectedMean * 1e-2; @@ -2841,41 +2864,41 @@ public: RandomVariableStreamTestSuite::RandomVariableStreamTestSuite () : TestSuite ("random-variable-stream-generators", UNIT) { - AddTestCase (new RandomVariableStreamUniformTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamUniformAntitheticTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamConstantTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamSequentialTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamNormalTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamNormalAntitheticTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamExponentialTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamExponentialAntitheticTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamParetoTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamParetoAntitheticTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamWeibullTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamWeibullAntitheticTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamLogNormalTestCase, TestCase::QUICK); + AddTestCase (new RandomVariableStreamUniformTestCase); + AddTestCase (new RandomVariableStreamUniformAntitheticTestCase); + AddTestCase (new RandomVariableStreamConstantTestCase); + AddTestCase (new RandomVariableStreamSequentialTestCase); + AddTestCase (new RandomVariableStreamNormalTestCase); + AddTestCase (new RandomVariableStreamNormalAntitheticTestCase); + AddTestCase (new RandomVariableStreamExponentialTestCase); + AddTestCase (new RandomVariableStreamExponentialAntitheticTestCase); + AddTestCase (new RandomVariableStreamParetoTestCase); + AddTestCase (new RandomVariableStreamParetoAntitheticTestCase); + AddTestCase (new RandomVariableStreamWeibullTestCase); + AddTestCase (new RandomVariableStreamWeibullAntitheticTestCase); + AddTestCase (new RandomVariableStreamLogNormalTestCase); /// \todo This test is currently disabled because it fails sometimes. /// A possible reason for the failure is that the antithetic code is /// not implemented properly for this log-normal case. /* - AddTestCase (new RandomVariableStreamLogNormalAntitheticTestCase, TestCase::QUICK); + AddTestCase (new RandomVariableStreamLogNormalAntitheticTestCase); */ - AddTestCase (new RandomVariableStreamGammaTestCase, TestCase::QUICK); + AddTestCase (new RandomVariableStreamGammaTestCase); /// \todo This test is currently disabled because it fails sometimes. /// A possible reason for the failure is that the antithetic code is /// not implemented properly for this gamma case. /* - AddTestCase (new RandomVariableStreamGammaAntitheticTestCase, TestCase::QUICK); + AddTestCase (new RandomVariableStreamGammaAntitheticTestCase); */ - AddTestCase (new RandomVariableStreamErlangTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamErlangAntitheticTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamZipfTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamZipfAntitheticTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamZetaTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamZetaAntitheticTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamDeterministicTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamEmpiricalTestCase, TestCase::QUICK); - AddTestCase (new RandomVariableStreamEmpiricalAntitheticTestCase, TestCase::QUICK); + AddTestCase (new RandomVariableStreamErlangTestCase); + AddTestCase (new RandomVariableStreamErlangAntitheticTestCase); + AddTestCase (new RandomVariableStreamZipfTestCase); + AddTestCase (new RandomVariableStreamZipfAntitheticTestCase); + AddTestCase (new RandomVariableStreamZetaTestCase); + AddTestCase (new RandomVariableStreamZetaAntitheticTestCase); + AddTestCase (new RandomVariableStreamDeterministicTestCase); + AddTestCase (new RandomVariableStreamEmpiricalTestCase); + AddTestCase (new RandomVariableStreamEmpiricalAntitheticTestCase); } static RandomVariableStreamTestSuite randomVariableStreamTestSuite;