A Discrete-Event Network Simulator
API
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 
50 using namespace ns3;
51 
59 void
61 {
62  std::cout << "------------------------------" << std::endl;
63  std::cout << "Sampling " << mode << std::endl;
64 
65  std::cout << std::endl;
66  std::cout << "Binned sample" << std::endl;
67  double value = erv->GetValue();
68  std::cout << "Binned sample: " << value << std::endl;
69  std::cout << std::endl;
70 
71  std::cout << "Interpolated sample" << std::endl;
72  erv->SetInterpolate(true);
73  value = erv->GetValue();
74  std::cout << "Interpolated sample:" << value << std::endl;
75  erv->SetInterpolate(false);
76 }
77 
88 void
89 PrintStatsLine(const double value, const long count, const long n, const long sum)
90 {
91  std::cout << std::fixed << std::setprecision(3) << std::setw(10) << std::right << value
92  << std::setw(10) << std::right << count << std::setw(10) << std::right
93  << count / static_cast<double>(n) * 100.0 << std::setw(10) << std::right
94  << sum / static_cast<double>(n) * 100.0 << std::endl;
95 }
96 
106 void
107 PrintSummary(long sum, long n, double weighted, double expected)
108 {
109  std::cout << std::endl;
110  std::cout << " --------" << std::endl;
111  std::cout << " Total " << std::setprecision(3) << std::fixed << std::setw(10)
112  << std::right << sum / static_cast<double>(n) * 100.0 << std::endl;
113  std::cout << " Average " << std::setprecision(3) << std::fixed << std::setw(6)
114  << std::right << weighted / n << std::endl;
115  std::cout << " Expected " << std::setprecision(3) << std::fixed << std::setw(6)
116  << std::right << expected << std::endl
117  << std::endl;
118 }
119 
128 void
129 RunBothModes(std::string mode, Ptr<EmpiricalRandomVariable> erv, long n)
130 {
131  std::cout << std::endl;
132  std::cout << "Sampling " << mode << std::endl;
133  std::map<double, int> counts;
134  counts[0] = 0;
135  for (long i = 0; i < n; ++i)
136  {
137  ++counts[erv->GetValue()];
138  }
139  long sum = 0;
140  double weighted = 0;
141  std::cout << std::endl;
142  std::cout << " Value Counts % % CDF" << std::endl;
143  std::cout << "---------- -------- -------- --------" << std::endl;
144  for (auto c : counts)
145  {
146  long count = c.second;
147  double value = c.first;
148  sum += count;
149  weighted += value * count;
150  PrintStatsLine(value, count, n, sum);
151  }
152  PrintSummary(sum, n, weighted, 0.8);
153 
154  std::cout << "Interpolating " << mode << std::endl;
155  erv->SetInterpolate(true);
156  Histogram h(0.1);
157  for (long i = 0; i < n; ++i)
158  {
159  h.AddValue(erv->GetValue());
160  // This could also be expressed as
161  // h.AddValue (erv->Interpolate ());
162  }
163  erv->SetInterpolate(false);
164  sum = 0;
165  weighted = 0;
166  std::cout << std::endl;
167  std::cout << " Bin Start Counts % % CDF" << std::endl;
168  std::cout << "---------- -------- -------- --------" << std::endl;
169  for (uint32_t i = 0; i < h.GetNBins(); ++i)
170  {
171  long count = h.GetBinCount(i);
172  double start = h.GetBinStart(i);
173  double value = start + h.GetBinWidth(i) / 2.;
174  sum += count;
175  weighted += count * value;
176  PrintStatsLine(start, count, n, sum);
177  }
178  PrintSummary(sum, n, weighted, 0.760);
179 }
180 
181 int
182 main(int argc, char* argv[])
183 {
184  long n = 1000000;
185  bool disableAnti = false;
186  bool single = false;
188  cmd.AddValue("count", "how many draws to make from the rng", n);
189  cmd.AddValue("antithetic", "disable antithetic sampling", disableAnti);
190  cmd.AddValue("single", "sample a single time", single);
191  cmd.Parse(argc, argv);
192  std::cout << std::endl;
193  std::cout << cmd.GetName() << std::endl;
194  if (!single)
195  {
196  std::cout << "Sample count: " << n << std::endl;
197  }
198  else
199  {
200  std::cout << "Sampling a single time" << std::endl;
201  }
202  if (disableAnti)
203  {
204  std::cout << "Antithetic sampling disabled" << std::endl;
205  }
206 
207  // Create the ERV in sampling mode
208  Ptr<EmpiricalRandomVariable> erv = CreateObject<EmpiricalRandomVariable>();
209 
210  // // Expectation for bin
211  erv->CDF(0.0, 0.0 / 15.0); // 0
212  erv->CDF(0.2, 1.0 / 15.0); // 0.2 1/15 = 2/150
213  erv->CDF(0.4, 3.0 / 15.0); // 0.4 2/15 = 8/150
214  erv->CDF(0.6, 4.0 / 15.0); // 0.6 1/15 = 6/150
215  erv->CDF(0.8, 7.0 / 15.0); // 0.8 3/15 = 24/150
216  erv->CDF(1.0, 9.0 / 15.0); // 1.0 2/15 = 20/150
217  erv->CDF(1.0, 15.0 / 15.0); // 1.0 6/15 = 60/150 <avg> = 120/150 = 0.8
218 
219  if (single)
220  {
221  RunSingleSample("normal", erv);
222  if (!disableAnti)
223  {
224  std::cout << std::endl;
225  std::cout << "Antithetic" << std::endl;
226  erv->SetAntithetic(true);
227  RunSingleSample("antithetic", erv);
228  erv->SetAntithetic(false);
229  }
230 
231  std::cout << std::endl;
232  return 0;
233  }
234 
235  RunBothModes("normal", erv, n);
236 
237  if (!disableAnti)
238  {
239  erv->SetAntithetic(true);
240  RunBothModes("antithetic", erv, n);
241  erv->SetAntithetic(false);
242  }
243 
244  return 0;
245 }
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.
cmd
Definition: second.py:40