A Discrete-Event Network Simulator
API
empirical-random-variable-example.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Lawrence Livermore National Laboratory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
19  */
20 
21 #include "ns3/simulator.h"
22 #include "ns3/nstime.h"
23 #include "ns3/command-line.h"
24 #include "ns3/random-variable-stream.h"
25 #include "ns3/histogram.h"
26 #include "ns3/ptr.h"
27 
28 #include <iomanip>
29 #include <iostream>
30 #include <map>
31 
50 using namespace ns3;
51 
52 void
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 void
72 PrintStatsLine (const double value, const long count, const long n)
73 {
74  std::cout << std::fixed << std::setprecision (3)
75  << std::setw (10) << std::right << value
76  << std::setw (10) << std::right << count
77  << std::setw (10) << std::right
78  << count / static_cast<double> (n) * 100.0
79  << std::endl;
80 }
81 
82 void
83 PrintSummary (long sum, long n, double weighted, double expected)
84 {
85  std::cout << std::endl;
86  std::cout << " --------" << std::endl;
87  std::cout << " Total "
88  << std::setprecision (3) << std::fixed
89  << std::setw (10) << std::right
90  << sum / static_cast<double> (n) * 100.0
91  << std::endl;
92  std::cout << " Average "
93  << std::setprecision (3) << std::fixed
94  << std::setw (6) << std::right << weighted / n
95  << std::endl;
96  std::cout << " Expected "
97  << std::setprecision (3) << std::fixed
98  << std::setw (6) << std::right << expected
99  << std::endl
100  << std::endl;
101 }
102 
103 void
104 RunBothModes (std::string mode, Ptr<EmpiricalRandomVariable> erv, long n)
105 {
106  std::cout << std::endl;
107  std::cout << "Sampling " << mode << std::endl;
108  std::map <double, int> counts;
109  counts[0] = 0;
110  for (long i = 0; i < n; ++i)
111  {
112  ++counts[erv->GetValue ()];
113  }
114  long sum = 0;
115  double weighted = 0;
116  std::cout << std::endl;
117  std::cout << " Value Counts %" << std::endl;
118  std::cout << "---------- -------- --------" << std::endl;
119  for (auto c : counts)
120  {
121  long count = c.second;
122  double value = c.first;
123  sum += count;
124  weighted += value * count;
125  PrintStatsLine (value, count, n);
126  }
127  PrintSummary (sum, n, weighted, 8.75);
128 
129  std::cout << "Interpolating " << mode << std::endl;
130  erv->SetInterpolate (true);
131  Histogram h (0.5);
132  for (long i = 0; i < n; ++i)
133  {
134  h.AddValue (erv->GetValue ());
135  // This could also be expressed as
136  // h.AddValue (erv->Interpolate ());
137  }
138  erv->SetInterpolate (false);
139  sum = 0;
140  weighted = 0;
141  std::cout << std::endl;
142  std::cout << " Bin Start Counts %" << std::endl;
143  std::cout << "---------- -------- --------" << std::endl;
144  for (uint32_t i = 0; i < h.GetNBins (); ++i)
145  {
146  long count = h.GetBinCount (i);
147  double start = h.GetBinStart (i);
148  double value = start + h.GetBinWidth (i) / 2.;
149  sum += count;
150  weighted += count * value;
151  PrintStatsLine (start, count, n);
152  }
153  PrintSummary (sum, n, weighted, 6.25);
154 }
155 
156 
157 int main (int argc, char *argv[])
158 {
159  long n = 1000000;
160  bool disableAnti = false;
161  bool single = false;
163  cmd.AddValue ("count", "how many draws to make from the rng", n);
164  cmd.AddValue ("antithetic", "disable antithetic sampling", disableAnti);
165  cmd.AddValue ("single", "sample a single time", single);
166  cmd.Parse (argc, argv);
167  std::cout << std::endl;
168  std::cout << cmd.GetName () << std::endl;
169  if (!single)
170  {
171  std::cout << "Sample count: " << n << std::endl;
172  }
173  else
174  {
175  std::cout << "Sampling a single time" << std::endl;
176  }
177  if (disableAnti)
178  {
179  std::cout << "Antithetic sampling disabled" << std::endl;
180  }
181 
182  // Create the ERV in sampling mode
183  Ptr<EmpiricalRandomVariable> erv = CreateObject<EmpiricalRandomVariable> ();
184  erv->SetInterpolate (false);
185  erv->CDF ( 0.0, 0.0);
186  erv->CDF ( 5.0, 0.25);
187  erv->CDF (10.0, 1.0);
188 
189  if (single)
190  {
191  RunSingleSample ("normal", erv);
192  if (!disableAnti)
193  {
194  std::cout << std::endl;
195  std::cout << "Antithetic" << std::endl;
196  erv->SetAntithetic (true);
197  RunSingleSample ("antithetic", erv);
198  erv->SetAntithetic (false);
199  }
200 
201  std::cout << std::endl;
202  return 0;
203  }
204 
205  RunBothModes ("normal", erv, n);
206 
207  if (!disableAnti)
208  {
209  erv->SetAntithetic (true);
210  RunBothModes ("antithetic", erv, n);
211  erv->SetAntithetic (false);
212  }
213 
214  return 0;
215 }
void PrintStatsLine(const double value, const long count, const long n)
void SetAntithetic(bool isAntithetic)
Specify whether antithetic values should be generated.
virtual double GetValue(void)
Returns the next value in the empirical distribution.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
def start()
Definition: core.py:1855
uint32_t GetNBins() const
Returns the number of bins in the histogram.
Definition: histogram.cc:42
cmd
Definition: second.py:35
void RunSingleSample(std::string mode, Ptr< EmpiricalRandomVariable > erv)
void CDF(double v, double c)
Specifies a point in the empirical distribution.
Parse command-line arguments.
Definition: command-line.h:227
bool SetInterpolate(bool interpolate)
Switch the mode between sampling the CDF and interpolating.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void RunBothModes(std::string mode, Ptr< EmpiricalRandomVariable > erv, long n)
uint32_t GetBinCount(uint32_t index)
Get the number of data added to the bin.
Definition: histogram.cc:73
double GetBinWidth(uint32_t index) const
Returns the bin width.
Definition: histogram.cc:60
double GetBinStart(uint32_t index)
Returns the bin start, i.e., index*binWidth.
Definition: histogram.cc:48
void PrintSummary(long sum, long n, double weighted, double expected)
void AddValue(double value)
Add a value to the histogram.
Definition: histogram.cc:80
Class used to store data and make an histogram of the data frequency.
Definition: histogram.h:45