core: Add largest extreme value random distribution

This commit is contained in:
Sébastien Deronne
2024-01-31 07:58:06 +01:00
committed by Sébastien Deronne
parent 287ae60ae3
commit 73474d22dc
3 changed files with 226 additions and 0 deletions

View File

@@ -264,6 +264,7 @@ can also create their own custom random variables by deriving from class
* class :cpp:class:`BinomialRandomVariable`
* class :cpp:class:`BernoulliRandomVariable`
* class :cpp:class:`LaplacianRandomVariable`
* class :cpp:class:`LargestExtremeValueRandomVariable`
Semantics of RandomVariableStream objects
*****************************************

View File

@@ -38,6 +38,7 @@
#include <algorithm> // upper_bound
#include <cmath>
#include <iostream>
#include <numbers>
/**
* \file
@@ -1979,4 +1980,106 @@ LaplacianRandomVariable::GetVariance() const
return GetVariance(m_scale);
}
NS_OBJECT_ENSURE_REGISTERED(LargestExtremeValueRandomVariable);
TypeId
LargestExtremeValueRandomVariable::GetTypeId()
{
static TypeId tid =
TypeId("ns3::LargestExtremeValueRandomVariable")
.SetParent<RandomVariableStream>()
.SetGroupName("Core")
.AddConstructor<LargestExtremeValueRandomVariable>()
.AddAttribute("Location",
"The location parameter for the Largest Extreme Value distribution "
"returned by this RNG stream.",
DoubleValue(0.0),
MakeDoubleAccessor(&LargestExtremeValueRandomVariable::m_location),
MakeDoubleChecker<double>())
.AddAttribute("Scale",
"The scale parameter for the Largest Extreme Value distribution "
"returned by this RNG stream.",
DoubleValue(1.0),
MakeDoubleAccessor(&LargestExtremeValueRandomVariable::m_scale),
MakeDoubleChecker<double>());
return tid;
}
LargestExtremeValueRandomVariable::LargestExtremeValueRandomVariable()
{
NS_LOG_FUNCTION(this);
}
double
LargestExtremeValueRandomVariable::GetLocation() const
{
return m_location;
}
double
LargestExtremeValueRandomVariable::GetScale() const
{
return m_scale;
}
double
LargestExtremeValueRandomVariable::GetValue(double location, double scale)
{
NS_LOG_FUNCTION(this << location << scale);
NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
// Get a uniform random variable in [0,1].
auto v = Peek()->RandU01();
if (IsAntithetic())
{
v = (1 - v);
}
// Calculate the largest extreme value random variable.
const auto t = std::log(v) * (-1.0);
const auto r = location - (scale * std::log(t));
return r;
}
uint32_t
LargestExtremeValueRandomVariable::GetInteger(uint32_t location, uint32_t scale)
{
NS_LOG_FUNCTION(this << location << scale);
return static_cast<uint32_t>(GetValue(location, scale));
}
double
LargestExtremeValueRandomVariable::GetValue()
{
NS_LOG_FUNCTION(this);
return GetValue(m_location, m_scale);
}
double
LargestExtremeValueRandomVariable::GetMean(double location, double scale)
{
NS_LOG_FUNCTION(location << scale);
return (location + (scale * std::numbers::egamma));
}
double
LargestExtremeValueRandomVariable::GetMean() const
{
return GetMean(m_location, m_scale);
}
double
LargestExtremeValueRandomVariable::GetVariance(double scale)
{
NS_LOG_FUNCTION(scale);
return std::pow((scale * std::numbers::pi), 2) / 6.0;
}
double
LargestExtremeValueRandomVariable::GetVariance() const
{
return GetVariance(m_scale);
}
} // namespace ns3

View File

@@ -2390,6 +2390,128 @@ class LaplacianRandomVariable : public RandomVariableStream
}; // class LaplacianRandomVariable
/**
* \ingroup randomvariable
* \brief The Largest Extreme Value distribution Random Number Generator (RNG).
*
* This class supports the creation of objects that return random numbers from a fixed Largest
* Extreme Value distribution. This corresponds to the type-I Generalized Extreme Value
* distribution, also known as Gumbel distribution
* (https://en.wikipedia.org/wiki/Gumbel_distribution).
*
* The probability density function of a Largest Extreme Value variable
* is defined as:
*
* \f[
* P(x; \mu, \beta) dx = \frac{1}{\beta} e^{\frac{- \frac{x - \mu}}{\beta}} e^{-e^{\frac{-
* \frac{x - \mu}}{\beta}}} dx \f]
*
* where \f$\mu\f$ is the \c Location configurable attribute and \f$\beta\f$
* is the \c Scale configurable attribute.
*
* The Largest Extreme Value RNG value \f$x\f$ is generated by
*
* \f[
* x = \mu - \beta \log(-\log(u))
* \f]
*
* where \f$u\f$ is a uniform random variable on [0,1).
*
* The mean of the distribution is:
*
* \f[
* E = \mu + y \beta
* \f]
*
* where \f$y\f$ is the Euler-Mascheroni constant.
*
* The variance of the distribution is
*
* \f[
* \sigma^2 = 6 \pi^2 \beta^2
* \f]
*/
class LargestExtremeValueRandomVariable : public RandomVariableStream
{
public:
/**
* \brief Register this type.
* \return The object TypeId.
*/
static TypeId GetTypeId();
/**
* \brief Creates a Largest Extreme Value distribution RNG with the default
* values for the location and the scale.
*/
LargestExtremeValueRandomVariable();
/**
* \brief Get the configured location value of this RNG.
*
* \return The configured location value.
*/
double GetLocation() const;
/**
* \brief Get the configured scale value of this RNG.
*
* \return The configured scale value.
*/
double GetScale() const;
/**
* \copydoc GetValue()
* \param [in] location location value of the Largest Extreme Value distribution.
* \param [in] scale scale value of the Largest Extreme Value distribution.
*/
double GetValue(double location, double scale);
/** \copydoc GetValue(double,double) */
uint32_t GetInteger(uint32_t location, uint32_t scale);
// Inherited
double GetValue() override;
using RandomVariableStream::GetInteger;
/**
* \brief Returns the mean value for the Largest Extreme Value distribution returned by this RNG
* stream.
* \return The mean value for the Largest Extreme Value distribution returned by this
* RNG stream.
*/
double GetMean() const;
/**
* \copydoc GetMean()
* \param [in] location location value of the Largest Extreme Value distribution.
* \param [in] scale scale value of the Largest Extreme Value distribution.
*/
static double GetMean(double location, double scale);
/**
* \brief Returns the variance value for the Largest Extreme Value distribution returned by this
* RNG stream.
* \return The variance value for the Largest Extreme Value distribution returned by
* this RNG stream.
*/
double GetVariance() const;
/**
* \copydoc GetVariance()
* \param [in] scale scale value of the Largest Extreme Value distribution.
*/
static double GetVariance(double scale);
private:
/** The location value of the Largest Extreme Value distribution. */
double m_location;
/** The scale value of the Largest Extreme Value distribution. */
double m_scale;
}; // class LargestExtremeValueRandomVariable
} // namespace ns3
#endif /* RANDOM_VARIABLE_STREAM_H */