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