A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
empirical-random-variable-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Lawrence Livermore National Laboratory
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
7 */
8
9#include "ns3/command-line.h"
10#include "ns3/histogram.h"
11#include "ns3/nstime.h"
12#include "ns3/ptr.h"
13#include "ns3/random-variable-stream.h"
14#include "ns3/simulator.h"
15
16#include <iomanip>
17#include <iostream>
18#include <map>
19
20/**
21 * \defgroup empirical-rng-example Core example: Empirical random variables use.
22 * \ingroup core-examples randomvariable
23 */
24
25/**
26 * \file
27 * \ingroup empirical-rng-example
28 *
29 * Example program illustrating use of ns3::EmpiricalRandomVariable
30 *
31 * This example illustrates
32 *
33 * * Creating an EmpiricalRandomVariable instance.
34 * * Switching the mode.
35 * * Using the sampling mode
36 * * Switching modes
37 * * Using the interpolating mode
38 *
39 * Consult the ns-3 manual for more information about the use of the
40 * random number generator
41 */
42
43using namespace ns3;
44
45/**
46 * \ingroup empirical-rng-example
47 *
48 * \brief Sample the random variable only once.
49 * \param mode Rng mode (Normal or Antithetic).
50 * \param erv The empirical random variable.
51 */
52void
54{
55 std::cout << "------------------------------" << std::endl;
56 std::cout << "Sampling " << mode << std::endl;
57
58 std::cout << std::endl;
59 std::cout << "Binned sample" << std::endl;
60 double value = erv->GetValue();
61 std::cout << "Binned sample: " << value << std::endl;
62 std::cout << std::endl;
63
64 std::cout << "Interpolated sample" << std::endl;
65 erv->SetInterpolate(true);
66 value = erv->GetValue();
67 std::cout << "Interpolated sample:" << value << std::endl;
68 erv->SetInterpolate(false);
69}
70
71/**
72 * \ingroup empirical-rng-example
73 *
74 * \brief Prints a stat line.
75 * \param value The value to print.
76 * \param count The number of times that value has been sampled.
77 * \param n The total number of random values sampled.
78 * \param sum The sum of the counts seen up to \p value, used to show
79 * the CDF for \p value.
80 */
81void
82PrintStatsLine(const double value, const long count, const long n, const long sum)
83{
84 std::cout << std::fixed << std::setprecision(3) << std::setw(10) << std::right << value
85 << std::setw(10) << std::right << count << std::setw(10) << std::right
86 << count / static_cast<double>(n) * 100.0 << std::setw(10) << std::right
87 << sum / static_cast<double>(n) * 100.0 << std::endl;
88}
89
90/**
91 * \ingroup empirical-rng-example
92 *
93 * \brief Prints the summary.
94 * \param sum The number of sampled values.
95 * \param n The total number of random values to be drawn.
96 * \param weighted The average of the sample.
97 * \param expected The expected average of the sample.
98 */
99void
100PrintSummary(long sum, long n, double weighted, double expected)
101{
102 std::cout << std::endl;
103 std::cout << " --------" << std::endl;
104 std::cout << " Total " << std::setprecision(3) << std::fixed << std::setw(10)
105 << std::right << sum / static_cast<double>(n) * 100.0 << std::endl;
106 std::cout << " Average " << std::setprecision(3) << std::fixed << std::setw(6)
107 << std::right << weighted / n << std::endl;
108 std::cout << " Expected " << std::setprecision(3) << std::fixed << std::setw(6)
109 << std::right << expected << std::endl
110 << std::endl;
111}
112
113/**
114 * \ingroup empirical-rng-example
115 *
116 * \brief Sample the random variable.
117 * \param mode Rng mode (Normal or Antithetic).
118 * \param erv The empirical random variable.
119 * \param n Number of samples to draw.
120 */
121void
122RunBothModes(std::string mode, Ptr<EmpiricalRandomVariable> erv, long n)
123{
124 std::cout << std::endl;
125 std::cout << "Sampling " << mode << std::endl;
126 std::map<double, int> counts;
127 counts[0] = 0;
128 for (long i = 0; i < n; ++i)
129 {
130 ++counts[erv->GetValue()];
131 }
132 long sum = 0;
133 double weighted = 0;
134 std::cout << std::endl;
135 std::cout << " Value Counts % % CDF" << std::endl;
136 std::cout << "---------- -------- -------- --------" << std::endl;
137 for (auto c : counts)
138 {
139 long count = c.second;
140 double value = c.first;
141 sum += count;
142 weighted += value * count;
143 PrintStatsLine(value, count, n, sum);
144 }
145 PrintSummary(sum, n, weighted, 0.8);
146
147 std::cout << "Interpolating " << mode << std::endl;
148 erv->SetInterpolate(true);
149 Histogram h(0.1);
150 for (long i = 0; i < n; ++i)
151 {
152 h.AddValue(erv->GetValue());
153 // This could also be expressed as
154 // h.AddValue (erv->Interpolate ());
155 }
156 erv->SetInterpolate(false);
157 sum = 0;
158 weighted = 0;
159 std::cout << std::endl;
160 std::cout << " Bin Start Counts % % CDF" << std::endl;
161 std::cout << "---------- -------- -------- --------" << std::endl;
162 for (uint32_t i = 0; i < h.GetNBins(); ++i)
163 {
164 long count = h.GetBinCount(i);
165 double start = h.GetBinStart(i);
166 double value = start + h.GetBinWidth(i) / 2.;
167 sum += count;
168 weighted += count * value;
169 PrintStatsLine(start, count, n, sum);
170 }
171 PrintSummary(sum, n, weighted, 0.760);
172}
173
174int
175main(int argc, char* argv[])
176{
177 long n = 1000000;
178 bool disableAnti = false;
179 bool single = false;
181 cmd.AddValue("count", "how many draws to make from the rng", n);
182 cmd.AddValue("antithetic", "disable antithetic sampling", disableAnti);
183 cmd.AddValue("single", "sample a single time", single);
184 cmd.Parse(argc, argv);
185 std::cout << std::endl;
186 std::cout << cmd.GetName() << std::endl;
187 if (!single)
188 {
189 std::cout << "Sample count: " << n << std::endl;
190 }
191 else
192 {
193 std::cout << "Sampling a single time" << std::endl;
194 }
195 if (disableAnti)
196 {
197 std::cout << "Antithetic sampling disabled" << std::endl;
198 }
199
200 // Create the ERV in sampling mode
202
203 // // Expectation for bin
204 erv->CDF(0.0, 0.0 / 15.0); // 0
205 erv->CDF(0.2, 1.0 / 15.0); // 0.2 1/15 = 2/150
206 erv->CDF(0.4, 3.0 / 15.0); // 0.4 2/15 = 8/150
207 erv->CDF(0.6, 4.0 / 15.0); // 0.6 1/15 = 6/150
208 erv->CDF(0.8, 7.0 / 15.0); // 0.8 3/15 = 24/150
209 erv->CDF(1.0, 9.0 / 15.0); // 1.0 2/15 = 20/150
210 erv->CDF(1.0, 15.0 / 15.0); // 1.0 6/15 = 60/150 <avg> = 120/150 = 0.8
211
212 if (single)
213 {
214 RunSingleSample("normal", erv);
215 if (!disableAnti)
216 {
217 std::cout << std::endl;
218 std::cout << "Antithetic" << std::endl;
219 erv->SetAntithetic(true);
220 RunSingleSample("antithetic", erv);
221 erv->SetAntithetic(false);
222 }
223
224 std::cout << std::endl;
225 return 0;
226 }
227
228 RunBothModes("normal", erv, n);
229
230 if (!disableAnti)
231 {
232 erv->SetAntithetic(true);
233 RunBothModes("antithetic", erv, n);
234 erv->SetAntithetic(false);
235 }
236
237 return 0;
238}
Parse command-line arguments.
Class used to store data and make an histogram of the data frequency.
Definition histogram.h:35
double GetBinWidth(uint32_t index) const
Returns the bin width.
Definition histogram.cc:50
uint32_t GetBinCount(uint32_t index) const
Get the number of data added to the bin.
Definition histogram.cc:63
uint32_t GetNBins() const
Returns the number of bins in the histogram.
Definition histogram.cc:32
void AddValue(double value)
Add a value to the histogram.
Definition histogram.cc:70
double GetBinStart(uint32_t index) const
Returns the bin start, i.e., index*binWidth.
Definition histogram.cc:38
Smart pointer class similar to boost::intrusive_ptr.
void PrintSummary(long sum, long n, double weighted, double expected)
Prints the summary.
void RunBothModes(std::string mode, Ptr< EmpiricalRandomVariable > erv, long n)
Sample the random variable.
void RunSingleSample(std::string mode, Ptr< EmpiricalRandomVariable > erv)
Sample the random variable only once.
void PrintStatsLine(const double value, const long count, const long n, const long sum)
Prints a stat line.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Every class exported by the ns3 library is enclosed in the ns3 namespace.