Skip to content

Commit

Permalink
core: (fixes #540) Add Bernoulli and Binomial Distributions
Browse files Browse the repository at this point in the history
- Add BernoulliRandomVariable and BinomialRandomVariable to the random-variable-stream model
- Add BernoulliRandomVariable and BinomialRandomVariable to random-variables.rst
- Add a stanza to main-random-variable-stream.cc for BernoulliRandomVariable and BinomialRandomVariable
- Add tests for BernoulliRandomVariable and BinomialRandomVariable in random-variable-stream-test-suite.cc
- Update RELEASE_NOTES.md and CHANGES.md
  • Loading branch information
AlessioBugetti committed Jan 26, 2024
1 parent 85d03d2 commit 567566c
Show file tree
Hide file tree
Showing 8 changed files with 663 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ Theodore Zhang ([email protected])
Dizhi Zhou ([email protected])
Tolik Zinovyev ([email protected])
Tommaso Zugno ([email protected])
Alessio Bugetti ([email protected])
hax0kartik (GCI 2019)
howie (GCI 2019)
InquisitivePenguin (GCI 2019)
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Changes from ns-3.40 to ns-3-dev

* (spectrum) `SpectrumSignalParameters` is extended to include two new members called: `spectrumChannelMatrix` and `precodingMatrix` which are the key information needed to support MIMO simulations.
* (wifi) Added new attribute `ChannelAccessManager:GenerateBackoffIfTxopWithoutTx` to invoke the backoff procedure when an AC gains the right to start a TXOP but it does not transmit any frame, provided that the queue is not actually empty. No transmission may occur,e.g., due to constraints associated with EMLSR operations. This possibility is specified by the current draft revision of the IEEE 802.11 standard.
* (core) Added `BernoulliRandomVariable` class implementing the bernoulli random variable, and `BinomialRandomVariable` class implementing the binomial random variable.

### Changes to existing API

Expand Down
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Release 3-dev
- (wifi) - Added EHT support for Ideal rate manager
- (wifi) - Reduce error rate model precision to fix infinite loop when Ideal rate manager is used with EHT
- (lr-wpan) !1794 - Group MAC primitives status enumerations into a single enumeration
- (core) !1802 - Added support for Bernoulli and Binomial random variables (`BernoulliRandomVariable`, `BinomialRandomVariable`)

### Bugs fixed

Expand Down
2 changes: 2 additions & 0 deletions doc/manual/source/random-variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ can also create their own custom random variables by deriving from class
* class :cpp:class:`ZetaRandomVariable`
* class :cpp:class:`DeterministicRandomVariable`
* class :cpp:class:`EmpiricalRandomVariable`
* class :cpp:class:`BinomialRandomVariable`
* class :cpp:class:`BernoulliRandomVariable`

Semantics of RandomVariableStream objects
*****************************************
Expand Down
31 changes: 31 additions & 0 deletions src/core/examples/main-random-variable-stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,37 @@ main(int argc, char* argv[])
std::cout << "done" << std::endl;
}

{
std::cout << "BinomialRandomVariable......." << std::flush;
Gnuplot plot;
plot.SetTitle("BinomialRandomVariable");
plot.AppendExtra("set yrange [0:10]");

auto x = CreateObject<BinomialRandomVariable>();
x->SetAttribute("Trials", IntegerValue(10));
x->SetAttribute("Probability", DoubleValue(0.5));

plot.AddDataset(Histogram(x, probes, precision, "BinomialRandomVariable n=10 p=0.5"));

gnuplots.AddPlot(plot);
std::cout << "done" << std::endl;
}

{
std::cout << "BernoulliRandomVariable......." << std::flush;
Gnuplot plot;
plot.SetTitle("BernoulliRandomVariable");
plot.AppendExtra("set yrange [0:1]");

auto x = CreateObject<BernoulliRandomVariable>();
x->SetAttribute("Probability", DoubleValue(0.5));

plot.AddDataset(Histogram(x, probes, precision, "BernoulliRandomVariable p=0.5"));

gnuplots.AddPlot(plot);
std::cout << "done" << std::endl;
}

{
std::string gnuFile = plotFile + ".plt";
std::cout << "Writing Gnuplot file: " << gnuFile << "..." << std::flush;
Expand Down
119 changes: 119 additions & 0 deletions src/core/model/random-variable-stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1738,4 +1738,123 @@ EmpiricalRandomVariable::Validate()
m_validated = true;
}

NS_OBJECT_ENSURE_REGISTERED(BinomialRandomVariable);

TypeId
BinomialRandomVariable::GetTypeId()
{
static TypeId tid =
TypeId("ns3::BinomialRandomVariable")
.SetParent<RandomVariableStream>()
.SetGroupName("Core")
.AddConstructor<BinomialRandomVariable>()
.AddAttribute("Trials",
"The number of trials.",
IntegerValue(10),
MakeIntegerAccessor(&BinomialRandomVariable::m_trials),
MakeIntegerChecker<uint32_t>(0))
.AddAttribute("Probability",
"The probability of success in each trial.",
DoubleValue(0.5),
MakeDoubleAccessor(&BinomialRandomVariable::m_probability),
MakeDoubleChecker<double>(0));
return tid;
}

BinomialRandomVariable::BinomialRandomVariable()
{
// m_trials and m_probability are initialized after constructor by attributes
NS_LOG_FUNCTION(this);
}

double
BinomialRandomVariable::GetValue(uint32_t trials, double probability)
{
NS_LOG_FUNCTION(this << trials << probability);

double successes = 0;

for (uint32_t i = 0; i < trials; ++i)
{
double v = Peek()->RandU01();
if (IsAntithetic())
{
v = (1 - v);
}

if (v <= probability)
{
successes += 1;
}
}

return successes;
}

uint32_t
BinomialRandomVariable::GetInteger(uint32_t trials, uint32_t probability)
{
NS_LOG_FUNCTION(this << trials << probability);
return static_cast<uint32_t>(GetValue(trials, probability));
}

double
BinomialRandomVariable::GetValue()
{
NS_LOG_FUNCTION(this);
return GetValue(m_trials, m_probability);
}

NS_OBJECT_ENSURE_REGISTERED(BernoulliRandomVariable);

TypeId
BernoulliRandomVariable::GetTypeId()
{
static TypeId tid =
TypeId("ns3::BernoulliRandomVariable")
.SetParent<RandomVariableStream>()
.SetGroupName("Core")
.AddConstructor<BernoulliRandomVariable>()
.AddAttribute("Probability",
"The probability of the random variable returning a value of 1.",
DoubleValue(0.5),
MakeDoubleAccessor(&BernoulliRandomVariable::m_probability),
MakeDoubleChecker<double>(0));
return tid;
}

BernoulliRandomVariable::BernoulliRandomVariable()
{
// m_probability is initialized after constructor by attributes
NS_LOG_FUNCTION(this);
}

double
BernoulliRandomVariable::GetValue(double probability)
{
NS_LOG_FUNCTION(this << probability);

double v = Peek()->RandU01();
if (IsAntithetic())
{
v = (1 - v);
}

return (v <= probability) ? 1.0 : 0.0;
}

uint32_t
BernoulliRandomVariable::GetInteger(uint32_t probability)
{
NS_LOG_FUNCTION(this << probability);
return static_cast<uint32_t>(GetValue(probability));
}

double
BernoulliRandomVariable::GetValue()
{
NS_LOG_FUNCTION(this);
return GetValue(m_probability);
}

} // namespace ns3
Loading

0 comments on commit 567566c

Please sign in to comment.