core: (fixes #2513) - Deprecates Mean attribute in ParetoRandomVariable
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Tue, 08 Nov 2016 01:42:06 +0100
changeset 12397 6572761077e5
parent 12396 d15839ef113c
child 12398 f09101df7e5c
core: (fixes #2513) - Deprecates Mean attribute in ParetoRandomVariable
CHANGES.html
RELEASE_NOTES
src/core/examples/main-random-variable-stream.cc
src/core/examples/main-random-variable.cc
src/core/model/random-variable-stream.cc
src/core/model/random-variable-stream.h
src/core/test/random-variable-stream-test-suite.cc
src/core/test/rng-test-suite.cc
--- a/CHANGES.html	Mon Nov 07 22:58:13 2016 +0100
+++ b/CHANGES.html	Tue Nov 08 01:42:06 2016 +0100
@@ -61,6 +61,11 @@
 </ul>
 <h2>Changes to existing API:</h2>
 <ul>
+<li><b>ParetoRandomVariable</b> "Mean" attribute has been deprecated, 
+    the "Scale" Attribute have to be used instead.
+    Changing the Mean attribute has no more an effect on the distribution.
+    See the documentation for the relationship between Mean, Scale and Shape. 
+</li>
 </ul>
 <h2>Changes to build system:</h2>
 <ul>
--- a/RELEASE_NOTES	Mon Nov 07 22:58:13 2016 +0100
+++ b/RELEASE_NOTES	Tue Nov 08 01:42:06 2016 +0100
@@ -28,6 +28,7 @@
 - Bug 2450 - LogDistancePropagationLossModel is not continuous
 - Bug 2492 - uan: Make use of RxGain attribute in UanPhyGen class
 - Bug 2511 - HT Greenfield is not working
+- Bug 2513 - ParetoRandomVariable needs a "scale", not a "mean" attribute.
 - Bug 2521 - Include ipv6-option.h in wscript
 - Bug 2527 - PrintRoutingTable extended to add an optional Time::Units parameter
 - Bug 2530 - Rename aodv::SetBalckListTimeout to aodv::SetBlackListTimeout
--- a/src/core/examples/main-random-variable-stream.cc	Mon Nov 07 22:58:13 2016 +0100
+++ b/src/core/examples/main-random-variable-stream.cc	Tue Nov 08 01:42:06 2016 +0100
@@ -138,25 +138,25 @@
     plot.AppendExtra ("set xrange [0:2]");
 
     Ptr<ParetoRandomVariable> x1 = CreateObject<ParetoRandomVariable> ();
-    x1->SetAttribute ("Mean", DoubleValue (1.0));
+    x1->SetAttribute ("Scale", DoubleValue (1.0));
     x1->SetAttribute ("Shape", DoubleValue (1.5));
 
     plot.AddDataset ( Histogramm (x1, probes, precision,
-                                  "ParetoRandomVariable m=1.0 s=1.5") );
+                                  "ParetoRandomVariable scale=1.0 shape=1.5") );
 
     Ptr<ParetoRandomVariable> x2 = CreateObject<ParetoRandomVariable> ();
-    x2->SetAttribute ("Mean", DoubleValue (1.0));
+    x2->SetAttribute ("Scale", DoubleValue (1.0));
     x2->SetAttribute ("Shape", DoubleValue (2.0));
 
     plot.AddDataset ( Histogramm (x2, probes, precision,
-                                  "ParetoRandomVariable m=1.0 s=2.0") );
+                                  "ParetoRandomVariable scale=1.0 shape=2.0") );
 
     Ptr<ParetoRandomVariable> x3 = CreateObject<ParetoRandomVariable> ();
-    x3->SetAttribute ("Mean", DoubleValue (1.0));
+    x3->SetAttribute ("Scale", DoubleValue (1.0));
     x3->SetAttribute ("Shape", DoubleValue (2.5));
 
     plot.AddDataset ( Histogramm (x3, probes, precision,
-                                  "ParetoRandomVariable m=1.0 s=2.5") );
+                                  "ParetoRandomVariable scale=1.0 shape=2.5") );
 
     gnuplots.AddPlot (plot);
   }
@@ -171,21 +171,21 @@
     x1->SetAttribute ("Shape", DoubleValue (1.0));
 
     plot.AddDataset ( Histogramm (x1, probes, precision,
-                                  "WeibullRandomVariable m=1.0 s=1.0") );
+                                  "WeibullRandomVariable scale=1.0 shape=1.0") );
 
     Ptr<WeibullRandomVariable> x2 = CreateObject<WeibullRandomVariable> ();
     x2->SetAttribute ("Scale", DoubleValue (1.0));
     x2->SetAttribute ("Shape", DoubleValue (2.0));
 
     plot.AddDataset ( Histogramm (x2, probes, precision,
-                                  "WeibullRandomVariable m=1.0 s=2.0") );
+                                  "WeibullRandomVariable scale=1.0 shape=2.0") );
 
     Ptr<WeibullRandomVariable> x3 = CreateObject<WeibullRandomVariable> ();
     x3->SetAttribute ("Scale", DoubleValue (1.0));
     x3->SetAttribute ("Shape", DoubleValue (3.0));
 
     plot.AddDataset ( Histogramm (x3, probes, precision,
-                                  "WeibullRandomVariable m=1.0 s=3.0") );
+                                  "WeibullRandomVariable scale=1.0 shape=3.0") );
 
     gnuplots.AddPlot (plot);
   }
--- a/src/core/examples/main-random-variable.cc	Mon Nov 07 22:58:13 2016 +0100
+++ b/src/core/examples/main-random-variable.cc	Tue Nov 08 01:42:06 2016 +0100
@@ -138,25 +138,25 @@
     plot.AppendExtra ("set xrange [0:2]");
 
     Ptr<ParetoRandomVariable> x1 = CreateObject<ParetoRandomVariable> ();
-    x1->SetAttribute ("Mean", DoubleValue (1.0));
+    x1->SetAttribute ("Scale", DoubleValue (1.0));
     x1->SetAttribute ("Shape", DoubleValue (1.5));
 
     plot.AddDataset ( Histogramm (x1, probes, precision,
-                                  "ParetoRandomVariable m=1.0 s=1.5") );
+                                  "ParetoRandomVariable scale=1.0 shape=1.5") );
 
     Ptr<ParetoRandomVariable> x2 = CreateObject<ParetoRandomVariable> ();
-    x2->SetAttribute ("Mean", DoubleValue (1.0));
+    x2->SetAttribute ("Scale", DoubleValue (1.0));
     x2->SetAttribute ("Shape", DoubleValue (2.0));
 
     plot.AddDataset ( Histogramm (x2, probes, precision,
-                                  "ParetoRandomVariable m=1.0 s=2.0") );
+                                  "ParetoRandomVariable scale=1.0 shape=2.0") );
 
     Ptr<ParetoRandomVariable> x3 = CreateObject<ParetoRandomVariable> ();
-    x3->SetAttribute ("Mean", DoubleValue (1.0));
+    x3->SetAttribute ("Scale", DoubleValue (1.0));
     x3->SetAttribute ("Shape", DoubleValue (2.5));
 
     plot.AddDataset ( Histogramm (x3, probes, precision,
-                                  "ParetoRandomVariable m=1.0 s=2.5") );
+                                  "ParetoRandomVariable scale=1.0 shape=2.5") );
 
     gnuplots.AddPlot (plot);
   }
@@ -171,21 +171,21 @@
     x1->SetAttribute ("Shape", DoubleValue (1.0));
 
     plot.AddDataset ( Histogramm (x1, probes, precision,
-                                  "WeibullRandomVariable m=1.0 s=1.0") );
+                                  "WeibullRandomVariable scale=1.0 shape=1.0") );
 
     Ptr<WeibullRandomVariable> x2 = CreateObject<WeibullRandomVariable> ();
     x2->SetAttribute ("Scale", DoubleValue (1.0));
     x2->SetAttribute ("Shape", DoubleValue (2.0));
 
     plot.AddDataset ( Histogramm (x2, probes, precision,
-                                  "WeibullRandomVariable m=1.0 s=2.0") );
+                                  "WeibullRandomVariable scale=1.0 shape=2.0") );
 
     Ptr<WeibullRandomVariable> x3 = CreateObject<WeibullRandomVariable> ();
     x3->SetAttribute ("Scale", DoubleValue (1.0));
     x3->SetAttribute ("Shape", DoubleValue (3.0));
 
     plot.AddDataset ( Histogramm (x3, probes, precision,
-                                  "WeibullRandomVariable m=1.0 s=3.0") );
+                                  "WeibullRandomVariable scale=1.0 shape=3.0") );
 
     gnuplots.AddPlot (plot);
   }
--- a/src/core/model/random-variable-stream.cc	Mon Nov 07 22:58:13 2016 +0100
+++ b/src/core/model/random-variable-stream.cc	Tue Nov 08 01:42:06 2016 +0100
@@ -33,6 +33,7 @@
 #include "log.h"
 #include "rng-stream.h"
 #include "rng-seed-manager.h"
+#include "unused.h"
 #include <cmath>
 #include <iostream>
 
@@ -455,9 +456,15 @@
     .SetGroupName ("Core")
     .AddConstructor<ParetoRandomVariable> ()
     .AddAttribute("Mean", "The mean parameter for the Pareto distribution returned by this RNG stream.",
-		  DoubleValue(1.0),
-		  MakeDoubleAccessor(&ParetoRandomVariable::m_mean),
-		  MakeDoubleChecker<double>())
+      DoubleValue(0.0),
+      MakeDoubleAccessor(&ParetoRandomVariable::m_mean),
+      MakeDoubleChecker<double>(),
+      TypeId::DEPRECATED,
+      "Not anymore used. Use 'Scale' instead - changing this attribute has no effect.")
+    .AddAttribute("Scale", "The scale parameter for the Pareto distribution returned by this RNG stream.",
+      DoubleValue(1.0),
+      MakeDoubleAccessor(&ParetoRandomVariable::m_scale),
+      MakeDoubleChecker<double>())
     .AddAttribute("Shape", "The shape parameter for the Pareto distribution returned by this RNG stream.",
 		  DoubleValue(2.0),
 		  MakeDoubleAccessor(&ParetoRandomVariable::m_shape),
@@ -471,23 +478,34 @@
 }
 ParetoRandomVariable::ParetoRandomVariable ()
 {
-  // m_mean, m_shape, and m_bound are initialized after constructor
+  // m_shape, m_shape, and m_bound are initialized after constructor
   // by attributes
   NS_LOG_FUNCTION (this);
+  NS_UNUSED (m_mean);
 }
 
 double 
 ParetoRandomVariable::GetMean (void) const
 {
   NS_LOG_FUNCTION (this);
-  return m_mean;
+
+  double mean = std::numeric_limits<double>::infinity();
+
+  if (m_shape > 1)
+    {
+      mean = m_shape * m_scale / (m_shape -1);
+    }
+
+  return mean;
 }
+
 double 
 ParetoRandomVariable::GetShape (void) const
 {
   NS_LOG_FUNCTION (this);
   return m_shape;
 }
+
 double 
 ParetoRandomVariable::GetBound (void) const
 {
@@ -496,11 +514,10 @@
 }
 
 double 
-ParetoRandomVariable::GetValue (double mean, double shape, double bound)
+ParetoRandomVariable::GetValue (double scale, double shape, double bound)
 {
   // Calculate the scale parameter.
-  NS_LOG_FUNCTION (this << mean << shape << bound);
-  double scale = mean * (shape - 1.0) / shape;
+  NS_LOG_FUNCTION (this << scale << shape << bound);
 
   while (1)
     {
@@ -522,23 +539,23 @@
     }
 }
 uint32_t 
-ParetoRandomVariable::GetInteger (uint32_t mean, uint32_t shape, uint32_t bound)
+ParetoRandomVariable::GetInteger (uint32_t scale, uint32_t shape, uint32_t bound)
 {
-  NS_LOG_FUNCTION (this << mean << shape << bound);
-  return static_cast<uint32_t> ( GetValue (mean, shape, bound) );
+  NS_LOG_FUNCTION (this << scale << shape << bound);
+  return static_cast<uint32_t> ( GetValue (scale, shape, bound) );
 }
 
 double 
 ParetoRandomVariable::GetValue (void)
 {
   NS_LOG_FUNCTION (this);
-  return GetValue (m_mean, m_shape, m_bound);
+  return GetValue (m_scale, m_shape, m_bound);
 }
 uint32_t 
 ParetoRandomVariable::GetInteger (void)
 {
   NS_LOG_FUNCTION (this);
-  return (uint32_t)GetValue (m_mean, m_shape, m_bound);
+  return (uint32_t)GetValue (m_scale, m_shape, m_bound);
 }
 
 NS_OBJECT_ENSURE_REGISTERED(WeibullRandomVariable);
--- a/src/core/model/random-variable-stream.h	Mon Nov 07 22:58:13 2016 +0100
+++ b/src/core/model/random-variable-stream.h	Tue Nov 08 01:42:06 2016 +0100
@@ -576,7 +576,7 @@
   /**
    * \brief Get the next random value, as an unsigned integer from
    * the exponential distribution with the specified mean and upper bound.
-   * \param [in] mean Mean value of the unbounded exponential distributuion.
+   * \param [in] mean Mean value of the unbounded exponential distribution.
    * \param [in] bound Upper bound on values returned.
    * \return A random unsigned integer value.
    */
@@ -607,9 +607,9 @@
  * The probability density function of a Pareto variable is defined
  * over the range [\f$x_m\f$,\f$+\infty\f$) as: \f$ k \frac{x_m^k}{x^{k+1}}\f$
  * where \f$x_m > 0\f$ is called the scale parameter and \f$ k > 0\f$
- * is called the pareto index or shape.
+ * is called the Pareto index or shape.
  *
- * The parameter \f$ x_m \f$ can be infered from the mean and the parameter \f$ k \f$
+ * The parameter \f$ x_m \f$ can be inferred from the mean and the parameter \f$ k \f$
  * with the equation \f$ x_m = mean \frac{k-1}{k},  k > 1\f$.
  *
  * Since Pareto distributions can theoretically return unbounded values,
@@ -619,11 +619,11 @@
  *
  * Here is an example of how to use this class:
  * \code
- *   double mean = 5.0;
+ *   double scale = 5.0;
  *   double shape = 2.0;
  * 
  *   Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
- *   x->SetAttribute ("Mean", DoubleValue (mean));
+ *   x->SetAttribute ("Scale", DoubleValue (scale));
  *   x->SetAttribute ("Shape", DoubleValue (shape));
  * 
  *   // The expected value for the mean of the values returned by a
@@ -632,11 +632,7 @@
  *   //                   shape * scale
  *   //     E[value]  =  ---------------  ,
  *   //                     shape - 1
- *   // 
- *   // where
- *   // 
- *   //     scale  =  mean * (shape - 1.0) / shape .
- *   //
+ *
  *   double value = x->GetValue ();
  * \endcode
  */
@@ -659,9 +655,16 @@
    * \brief Returns the mean parameter for the Pareto distribution returned by this RNG stream.
    * \return The mean parameter for the Pareto distribution returned by this RNG stream.
    */
+  NS_DEPRECATED
   double GetMean (void) const;
 
   /**
+   * \brief Returns the scale parameter for the Pareto distribution returned by this RNG stream.
+   * \return The scale parameter for the Pareto distribution returned by this RNG stream.
+   */
+  double GetScale (void) const;
+
+  /**
    * \brief Returns the shape parameter for the Pareto distribution returned by this RNG stream.
    * \return The shape parameter for the Pareto distribution returned by this RNG stream.
    */
@@ -674,8 +677,8 @@
   double GetBound (void) const;
 
   /**
-   * \brief Returns a random double from a Pareto distribution with the specified mean, shape, and upper bound.
-   * \param [in] mean Mean parameter for the Pareto distribution.
+   * \brief Returns a random double from a Pareto distribution with the specified scale, shape, and upper bound.
+   * \param [in] scale Mean parameter for the Pareto distribution.
    * \param [in] shape Shape parameter for the Pareto distribution.
    * \param [in] bound Upper bound on values returned.
    * \return A floating point random value.
@@ -688,27 +691,22 @@
    *         x = \frac{scale}{u^{\frac{1}{shape}}}
    *    \f]
    *
-   * is a value that would be returned normally, where
-   *     
-   *    \f[
-   *         scale  =  mean * (shape - 1.0) / shape  .
-   *    \f]
+   * is a value that would be returned normally.
    *    
-   * Then \f$(1 - u\f$) is the distance that \f$u\f$ would be from
-   * \f$1\f$.  The value returned in the antithetic case, \f$x'\f$, is
+   * The value returned in the antithetic case, \f$x'\f$, is
    * calculated as
    *
    *    \f[
    *         x' = \frac{scale}{{(1 - u)}^{\frac{1}{shape}}} ,
    *    \f]
    *
-   * which now involves the distance \f$u\f$ is from 1 in the denonator.
+   * which now involves the distance \f$u\f$ is from 1 in the denominator.
    */
-  double GetValue (double mean, double shape, double bound);
+  double GetValue (double scale, double shape, double bound);
 
   /**
    * \brief Returns a random unsigned integer from a Pareto distribution with the specified mean, shape, and upper bound.
-   * \param [in] mean Mean parameter for the Pareto distribution.
+   * \param [in] scale Scale parameter for the Pareto distribution.
    * \param [in] shape Shape parameter for the Pareto distribution.
    * \param [in] bound Upper bound on values returned.
    * \return A random unsigned integer value.
@@ -721,23 +719,18 @@
    *         x = \frac{scale}{u^{\frac{1}{shape}}}
    *    \f]
    *
-   * is a value that would be returned normally, where
-   *     
-   *    \f[
-   *         scale  =  mean * (shape - 1.0) / shape  .
-   *    \f]
-   *    
-   * Then \f$(1 - u\f$) is the distance that \f$u\f$ would be from
-   * \f$1\f$.  The value returned in the antithetic case, \f$x'\f$, is
+   * is a value that would be returned normally.
+   *
+   * The value returned in the antithetic case, \f$x'\f$, is
    * calculated as
    *
    *    \f[
    *         x' = \frac{scale}{{(1 - u)}^{\frac{1}{shape}}} ,
    *    \f]
    *
-   * which now involves the distance \f$u\f$ is from 1 in the denonator.
+   * which now involves the distance \f$u\f$ is from 1 in the denominator.
    */
-  uint32_t GetInteger (uint32_t mean, uint32_t shape, uint32_t bound);
+  uint32_t GetInteger (uint32_t scale, uint32_t shape, uint32_t bound);
 
   /**
    * \brief Returns a random double from a Pareto distribution with the current mean, shape, and upper bound.
@@ -757,15 +750,14 @@
    *         scale  =  mean * (shape - 1.0) / shape  .
    *    \f]
    *    
-   * Then \f$(1 - u\f$) is the distance that \f$u\f$ would be from
-   * \f$1\f$.  The value returned in the antithetic case, \f$x'\f$, is
+   * The value returned in the antithetic case, \f$x'\f$, is
    * calculated as
    *
    *    \f[
    *         x' = \frac{scale}{{(1 - u)}^{\frac{1}{shape}}} ,
    *    \f]
    *
-   * which now involves the distance \f$u\f$ is from 1 in the denonator.
+   * which now involves the distance \f$u\f$ is from 1 in the denominator.
    *
    * Note that we have to re-implement this method here because the method is
    * overloaded above for the three-argument variant and the c++ name resolution
@@ -786,21 +778,16 @@
    *         x = \frac{scale}{u^{\frac{1}{shape}}}
    *    \f]
    *
-   * is a value that would be returned normally, where
-   *     
-   *    \f[
-   *         scale  =  mean * (shape - 1.0) / shape  .
-   *    \f]
-   *    
-   * Then \f$(1 - u\f$) is the distance that \f$u\f$ would be from
-   * \f$1\f$.  The value returned in the antithetic case, \f$x'\f$, is
+   * is a value that would be returned normally.
+   *
+   * The value returned in the antithetic case, \f$x'\f$, is
    * calculated as
    *
    *    \f[
    *         x' = \frac{scale}{{(1 - u)}^{\frac{1}{shape}}} ,
    *    \f]
    *
-   * which now involves the distance \f$u\f$ is from 1 in the denonator.
+   * which now involves the distance \f$u\f$ is from 1 in the denominator.
    */
   virtual uint32_t GetInteger (void);
 
@@ -808,6 +795,9 @@
   /** The mean parameter for the Pareto distribution returned by this RNG stream. */
   double m_mean;
 
+  /** The scale parameter for the Pareto distribution returned by this RNG stream. */
+  double m_scale;
+
   /** The shape parameter for the Pareto distribution returned by this RNG stream. */
   double m_shape;
 
--- a/src/core/test/random-variable-stream-test-suite.cc	Mon Nov 07 22:58:13 2016 +0100
+++ b/src/core/test/random-variable-stream-test-suite.cc	Tue Nov 08 01:42:06 2016 +0100
@@ -1036,11 +1036,8 @@
 
   double expected[N_BINS];
 
-  // Note that this assumes that p has mean equal to 1 and shape equal
-  // to 2, which are their default values for this distribution.
-  double mean = 1.0;
   double shape = 2.0;
-  double scale = mean * (shape - 1.0) / shape;
+  double scale = 1.0;
 
   for (uint32_t i = 0; i < N_BINS; ++i)
     {
@@ -1094,15 +1091,14 @@
 
   NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
 
-  double mean = 5.0;
   double shape = 2.0;
-  double scale = mean * (shape - 1.0) / shape;
+  double scale = 1.0;
   double value;
 
   // Create the RNG with the specified range.
   Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
-  x->SetAttribute ("Mean", DoubleValue (mean));
   x->SetAttribute ("Shape", DoubleValue (shape));
+  x->SetAttribute ("Scale", DoubleValue (scale));
 
   // Calculate the mean of these values.
   sum = 0.0;
@@ -1170,11 +1166,8 @@
 
   double expected[N_BINS];
 
-  // Note that this assumes that p has mean equal to 1 and shape equal
-  // to 2, which are their default values for this distribution.
-  double mean = 1.0;
   double shape = 2.0;
-  double scale = mean * (shape - 1.0) / shape;
+  double scale = 1.0;
 
   for (uint32_t i = 0; i < N_BINS; ++i)
     {
@@ -1232,15 +1225,14 @@
 
   NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
 
-  double mean = 5.0;
   double shape = 2.0;
-  double scale = mean * (shape - 1.0) / shape;
+  double scale = 1.0;
   double value;
 
   // Create the RNG with the specified range.
   Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
-  x->SetAttribute ("Mean", DoubleValue (mean));
   x->SetAttribute ("Shape", DoubleValue (shape));
+  x->SetAttribute ("Scale", DoubleValue (scale));
 
   // Make this generate antithetic values.
   x->SetAttribute ("Antithetic", BooleanValue (true));
--- a/src/core/test/rng-test-suite.cc	Mon Nov 07 22:58:13 2016 +0100
+++ b/src/core/test/rng-test-suite.cc	Tue Nov 08 01:42:06 2016 +0100
@@ -408,6 +408,7 @@
     {
       Ptr<ParetoRandomVariable> e = CreateObject<ParetoRandomVariable> ();
       e->SetAttribute ("Shape", DoubleValue (1.5));
+      e->SetAttribute ("Scale", DoubleValue (0.33333333));
       double result = ChiSquaredTest (e);
       sum += result;
     }