A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
random-variable.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 //
3 // Copyright (c) 2006 Georgia Tech Research Corporation
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: Rajib Bhattacharjea<raj.b@gatech.edu>
19 // Author: Hadi Arbabi<marbabi@cs.odu.edu>
20 //
21 
22 #include <iostream>
23 #include <cmath>
24 #include <cstdlib>
25 #include <sys/time.h> // for gettimeofday
26 #include <unistd.h>
27 #include <iostream>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <sstream>
32 #include <vector>
33 
34 #include "assert.h"
35 #include "random-variable.h"
36 #include "rng-seed-manager.h"
37 #include "rng-stream.h"
38 #include "fatal-error.h"
39 #include "log.h"
40 
41 namespace ns3 {
42 
43 // -----------------------------------------------------------------------------
44 // -----------------------------------------------------------------------------
45 // RandomVariableBase methods
46 
47 NS_LOG_COMPONENT_DEFINE ("RandomVariable");
48 
50 {
51 public:
54  virtual ~RandomVariableBase ();
55  virtual double GetValue () = 0;
56  virtual uint32_t GetInteger ();
57  virtual RandomVariableBase* Copy (void) const = 0;
58  RngStream *GetStream(void);
59 private:
60  RngStream* m_generator; // underlying generator being wrapped
61 };
62 
63 RandomVariableBase::RandomVariableBase ()
64  : m_generator (0)
65 {
66  NS_LOG_FUNCTION (this);
67 }
68 
69 RandomVariableBase::RandomVariableBase (const RandomVariableBase& r)
70  : m_generator (0)
71 {
72  NS_LOG_FUNCTION (this << &r);
73  if (r.m_generator != 0)
74  {
75  m_generator = new RngStream (RngSeedManager::GetSeed (),
76  RngSeedManager::GetNextStreamIndex (),
78  }
79 }
80 
81 RandomVariableBase::~RandomVariableBase ()
82 {
83  NS_LOG_FUNCTION (this);
84  delete m_generator;
85 }
86 
87 uint32_t RandomVariableBase::GetInteger ()
88 {
89  NS_LOG_FUNCTION (this);
90  return (uint32_t)GetValue ();
91 }
92 
93 RngStream *
94 RandomVariableBase::GetStream (void)
95 {
96  NS_LOG_FUNCTION (this);
97  if (m_generator == 0)
98  {
99  m_generator = new RngStream (RngSeedManager::GetSeed (),
100  RngSeedManager::GetNextStreamIndex (),
102  }
103  return m_generator;
104 }
105 
106 // -------------------------------------------------------
107 
108 RandomVariable::RandomVariable ()
109  : m_variable (0)
110 {
111  NS_LOG_FUNCTION (this);
112 }
113 RandomVariable::RandomVariable (const RandomVariable&o)
114  : m_variable (o.m_variable->Copy ())
115 {
116 }
117 RandomVariable::RandomVariable (const RandomVariableBase &variable)
118  : m_variable (variable.Copy ())
119 {
120 }
121 RandomVariable &
122 RandomVariable::operator = (const RandomVariable &o)
123 {
124  if (&o == this)
125  {
126  return *this;
127  }
128  delete m_variable;
129  m_variable = o.m_variable->Copy ();
130  return *this;
131 }
132 RandomVariable::~RandomVariable ()
133 {
134  NS_LOG_FUNCTION (this);
135  delete m_variable;
136 }
137 double
139 {
140  NS_LOG_FUNCTION (this);
141  return m_variable->GetValue ();
142 }
143 
144 uint32_t
146 {
147  NS_LOG_FUNCTION (this);
148  return m_variable->GetInteger ();
149 }
150 
152 RandomVariable::Peek (void) const
153 {
154  NS_LOG_FUNCTION (this);
155  return m_variable;
156 }
157 
158 
159 ATTRIBUTE_VALUE_IMPLEMENT (RandomVariable);
160 ATTRIBUTE_CHECKER_IMPLEMENT (RandomVariable);
161 
162 // -----------------------------------------------------------------------------
163 // -----------------------------------------------------------------------------
164 // UniformVariableImpl
165 
167 {
168 public:
174 
180  UniformVariableImpl (double s, double l);
181 
183 
184  double GetMin (void) const;
185  double GetMax (void) const;
186 
190  virtual double GetValue ();
191 
195  virtual double GetValue (double s, double l);
196 
197  virtual RandomVariableBase* Copy (void) const;
198 
199 private:
200  double m_min;
201  double m_max;
202 };
203 
205  : m_min (0),
206  m_max (1.0)
207 {
208  NS_LOG_FUNCTION (this);
209 }
210 
212  : m_min (s),
213  m_max (l)
214 {
215  NS_LOG_FUNCTION (this << s << l);
216 }
217 
219  : RandomVariableBase (c),
220  m_min (c.m_min),
221  m_max (c.m_max)
222 {
223  NS_LOG_FUNCTION (this << &c);
224 }
225 
226 double
227 UniformVariableImpl::GetMin (void) const
228 {
229  NS_LOG_FUNCTION (this);
230  return m_min;
231 }
232 double
233 UniformVariableImpl::GetMax (void) const
234 {
235  NS_LOG_FUNCTION (this);
236  return m_max;
237 }
238 
239 
241 {
242  NS_LOG_FUNCTION (this);
243  RngStream *generator = GetStream ();
244  return m_min + generator->RandU01 () * (m_max - m_min);
245 }
246 
247 double UniformVariableImpl::GetValue (double s, double l)
248 {
249  NS_LOG_FUNCTION (this << s << l);
250  RngStream *generator = GetStream ();
251  return s + generator->RandU01 () * (l - s);
252 }
253 
254 RandomVariableBase* UniformVariableImpl::Copy () const
255 {
256  NS_LOG_FUNCTION (this);
257  return new UniformVariableImpl (*this);
258 }
259 
262 {
263  NS_LOG_FUNCTION (this);
264 }
267 {
268  NS_LOG_FUNCTION (this << s << l);
269 }
270 
271 double UniformVariable::GetValue (void) const
272 {
273  NS_LOG_FUNCTION (this);
274  return this->RandomVariable::GetValue ();
275 }
276 
277 double UniformVariable::GetValue (double s, double l)
278 {
279  NS_LOG_FUNCTION (this << s << l);
280  return ((UniformVariableImpl*)Peek ())->GetValue (s,l);
281 }
282 
283 uint32_t UniformVariable::GetInteger (uint32_t s, uint32_t l)
284 {
285  NS_LOG_FUNCTION (this << s << l);
286  NS_ASSERT (s <= l);
287  return static_cast<uint32_t> ( GetValue (s, l + 1) );
288 }
289 
290 // -----------------------------------------------------------------------------
291 // -----------------------------------------------------------------------------
292 // ConstantVariableImpl methods
293 
295 {
296 
297 public:
302 
308  ConstantVariableImpl (double c);
309 
310 
312 
317  void NewConstant (double c);
318 
322  virtual double GetValue ();
323  virtual uint32_t GetInteger ();
324  virtual RandomVariableBase* Copy (void) const;
325 private:
326  double m_const;
327 };
328 
330  : m_const (0)
331 {
332  NS_LOG_FUNCTION (this);
333 }
334 
336  : m_const (c)
337 {
338  NS_LOG_FUNCTION (this << c);
339 }
340 
342  : RandomVariableBase (c),
343  m_const (c.m_const)
344 {
345  NS_LOG_FUNCTION (this << &c);
346 }
347 
349 {
350  NS_LOG_FUNCTION (this << c);
351  m_const = c;
352 }
353 
355 {
356  NS_LOG_FUNCTION (this);
357  return m_const;
358 }
359 
360 uint32_t ConstantVariableImpl::GetInteger ()
361 {
362  NS_LOG_FUNCTION (this);
363  return (uint32_t)m_const;
364 }
365 
366 RandomVariableBase* ConstantVariableImpl::Copy () const
367 {
368  NS_LOG_FUNCTION (this);
369  return new ConstantVariableImpl (*this);
370 }
371 
374 {
375  NS_LOG_FUNCTION (this);
376 }
379 {
380  NS_LOG_FUNCTION (this << c);
381 }
382 void
384 {
385  NS_LOG_FUNCTION (this << c);
386  *this = ConstantVariable (c);
387 }
388 
389 // -----------------------------------------------------------------------------
390 // -----------------------------------------------------------------------------
391 // SequentialVariableImpl methods
392 
393 
395 {
396 
397 public:
409  SequentialVariableImpl (double f, double l, double i = 1, uint32_t c = 1);
410 
421  SequentialVariableImpl (double f, double l, const RandomVariable& i, uint32_t c = 1);
422 
424 
429  virtual double GetValue ();
430  virtual RandomVariableBase* Copy (void) const;
431 private:
432  double m_min;
433  double m_max;
434  RandomVariable m_increment;
435  uint32_t m_consecutive;
436  double m_current;
437  uint32_t m_currentConsecutive;
438 };
439 
440 SequentialVariableImpl::SequentialVariableImpl (double f, double l, double i, uint32_t c)
441  : m_min (f),
442  m_max (l),
443  m_increment (ConstantVariable (i)),
444  m_consecutive (c),
445  m_current (f),
446  m_currentConsecutive (0)
447 {
448  NS_LOG_FUNCTION (this << f << l << i << c);
449 }
450 
451 SequentialVariableImpl::SequentialVariableImpl (double f, double l, const RandomVariable& i, uint32_t c)
452  : m_min (f),
453  m_max (l),
454  m_increment (i),
455  m_consecutive (c),
456  m_current (f),
457  m_currentConsecutive (0)
458 {
459  NS_LOG_FUNCTION (this << f << l << i << c);
460 }
461 
463  : RandomVariableBase (c),
464  m_min (c.m_min),
465  m_max (c.m_max),
466  m_increment (c.m_increment),
467  m_consecutive (c.m_consecutive),
468  m_current (c.m_current),
469  m_currentConsecutive (c.m_currentConsecutive)
470 {
471  NS_LOG_FUNCTION (this << &c);
472 }
473 
474 SequentialVariableImpl::~SequentialVariableImpl ()
475 {
476  NS_LOG_FUNCTION (this);
477 }
478 
480 { // Return a sequential series of values
481  NS_LOG_FUNCTION (this);
482  double r = m_current;
483  if (++m_currentConsecutive == m_consecutive)
484  { // Time to advance to next
485  m_currentConsecutive = 0;
486  m_current += m_increment.GetValue ();
487  if (m_current >= m_max)
488  {
489  m_current = m_min + (m_current - m_max);
490  }
491  }
492  return r;
493 }
494 
495 RandomVariableBase* SequentialVariableImpl::Copy () const
496 {
497  NS_LOG_FUNCTION (this);
498  return new SequentialVariableImpl (*this);
499 }
500 
501 SequentialVariable::SequentialVariable (double f, double l, double i, uint32_t c)
502  : RandomVariable (SequentialVariableImpl (f, l, i, c))
503 {
504  NS_LOG_FUNCTION (this << f << l << i << c);
505 }
506 SequentialVariable::SequentialVariable (double f, double l, const RandomVariable& i, uint32_t c)
507  : RandomVariable (SequentialVariableImpl (f, l, i, c))
508 {
509  NS_LOG_FUNCTION (this << f << l << i << c);
510 }
511 
512 // -----------------------------------------------------------------------------
513 // -----------------------------------------------------------------------------
514 // ExponentialVariableImpl methods
515 
517 {
518 public:
524 
530  explicit ExponentialVariableImpl (double m);
531 
543  ExponentialVariableImpl (double m, double b);
544 
546 
550  virtual double GetValue ();
551  virtual RandomVariableBase* Copy (void) const;
552 
553 private:
554  double m_mean; // Mean value of RV
555  double m_bound; // Upper bound on value (if non-zero)
556 };
557 
559  : m_mean (1.0),
560  m_bound (0)
561 {
562  NS_LOG_FUNCTION (this);
563 }
564 
566  : m_mean (m),
567  m_bound (0)
568 {
569  NS_LOG_FUNCTION (this << m);
570 }
571 
573  : m_mean (m),
574  m_bound (b)
575 {
576  NS_LOG_FUNCTION (this << m << b);
577 }
578 
580  : RandomVariableBase (c),
581  m_mean (c.m_mean),
582  m_bound (c.m_bound)
583 {
584  NS_LOG_FUNCTION (this << &c);
585 }
586 
588 {
589  NS_LOG_FUNCTION (this);
590  RngStream *generator = GetStream ();
591  while (1)
592  {
593  double r = -m_mean*std::log (generator->RandU01 ());
594  if (m_bound == 0 || r <= m_bound)
595  {
596  return r;
597  }
598  // otherwise, try again
599  }
600 }
601 
602 RandomVariableBase* ExponentialVariableImpl::Copy () const
603 {
604  NS_LOG_FUNCTION (this);
605  return new ExponentialVariableImpl (*this);
606 }
607 
610 {
611  NS_LOG_FUNCTION (this);
612 }
615 {
616  NS_LOG_FUNCTION (this << m);
617 }
620 {
621  NS_LOG_FUNCTION (this << m << b);
622 }
623 
624 // -----------------------------------------------------------------------------
625 // -----------------------------------------------------------------------------
626 // ParetoVariableImpl methods
628 {
629 public:
635 
642  explicit ParetoVariableImpl (double m);
643 
651  ParetoVariableImpl (double m, double s);
652 
665  ParetoVariableImpl (double m, double s, double b);
666 
673  ParetoVariableImpl (std::pair<double, double> params);
674 
687  ParetoVariableImpl (std::pair<double, double> params, double b);
688 
690 
694  virtual double GetValue ();
695  virtual RandomVariableBase* Copy () const;
696 
697 private:
698  double m_scale; // Scale value of RV
699  double m_shape; // Shape parameter
700  double m_bound; // Upper bound on value (if non-zero)
701 };
702 
704  : m_scale (0.5 / 1.5),
705  m_shape (1.5),
706  m_bound (0)
707 {
708  NS_LOG_FUNCTION (this);
709 }
710 
712  : m_scale (m * 0.5 / 1.5),
713  m_shape (1.5),
714  m_bound (0)
715 {
716  NS_LOG_FUNCTION (this << m);
717 }
718 
720  : m_scale (m * (s - 1.0) / s),
721  m_shape (s),
722  m_bound (0)
723 {
724  NS_LOG_FUNCTION (this << m << s);
725 }
726 
727 ParetoVariableImpl::ParetoVariableImpl (double m, double s, double b)
728  : m_scale (m * (s - 1.0) / s),
729  m_shape (s),
730  m_bound (b)
731 {
732  NS_LOG_FUNCTION (this << m << s << b);
733 }
734 
735 ParetoVariableImpl::ParetoVariableImpl (std::pair<double, double> params)
736  : m_scale (params.first),
737  m_shape (params.second),
738  m_bound (0)
739 {
740  NS_LOG_FUNCTION (this << &params);
741 }
742 
743 ParetoVariableImpl::ParetoVariableImpl (std::pair<double, double> params, double b)
744  : m_scale (params.first),
745  m_shape (params.second),
746  m_bound (b)
747 {
748  NS_LOG_FUNCTION (this << &params << b);
749 }
750 
752  : RandomVariableBase (c),
753  m_scale (c.m_scale),
754  m_shape (c.m_shape),
755  m_bound (c.m_bound)
756 {
757  NS_LOG_FUNCTION (this << &c);
758 }
759 
761 {
762  NS_LOG_FUNCTION (this);
763  RngStream *generator = GetStream ();
764  while (1)
765  {
766  double r = (m_scale * ( 1.0 / std::pow (generator->RandU01 (), 1.0 / m_shape)));
767  if (m_bound == 0 || r <= m_bound)
768  {
769  return r;
770  }
771  // otherwise, try again
772  }
773 }
774 
775 RandomVariableBase* ParetoVariableImpl::Copy () const
776 {
777  NS_LOG_FUNCTION (this);
778  return new ParetoVariableImpl (*this);
779 }
780 
783 {
784  NS_LOG_FUNCTION (this);
785 }
788 {
789  NS_LOG_FUNCTION (this << m);
790 }
791 ParetoVariable::ParetoVariable (double m, double s)
793 {
794  NS_LOG_FUNCTION (this << m << s);
795 }
796 ParetoVariable::ParetoVariable (double m, double s, double b)
797  : RandomVariable (ParetoVariableImpl (m, s, b))
798 {
799  NS_LOG_FUNCTION (this << m << s << b);
800 }
801 ParetoVariable::ParetoVariable (std::pair<double, double> params)
803 {
804  NS_LOG_FUNCTION (this << &params);
805 }
806 ParetoVariable::ParetoVariable (std::pair<double, double> params, double b)
807  : RandomVariable (ParetoVariableImpl (params, b))
808 {
809  NS_LOG_FUNCTION (this << &params << b);
810 }
811 
812 // -----------------------------------------------------------------------------
813 // -----------------------------------------------------------------------------
814 // WeibullVariableImpl methods
815 
817 {
818 public:
824 
825 
831  WeibullVariableImpl (double m);
832 
839  WeibullVariableImpl (double m, double s);
840 
852  WeibullVariableImpl (double m, double s, double b);
853 
855 
859  virtual double GetValue ();
860  virtual RandomVariableBase* Copy (void) const;
861 
862 private:
863  double m_mean; // Mean value of RV
864  double m_alpha; // Shape parameter
865  double m_bound; // Upper bound on value (if non-zero)
866 };
867 
869  m_alpha (1),
870  m_bound (0)
871 {
872  NS_LOG_FUNCTION (this);
873 }
875  : m_mean (m),
876  m_alpha (1),
877  m_bound (0)
878 {
879  NS_LOG_FUNCTION (this << m);
880 }
882  : m_mean (m),
883  m_alpha (s),
884  m_bound (0)
885 {
886  NS_LOG_FUNCTION (this << m << s);
887 }
888 WeibullVariableImpl::WeibullVariableImpl (double m, double s, double b)
889  : m_mean (m),
890  m_alpha (s),
891  m_bound (b)
892 {
893  NS_LOG_FUNCTION (this << m << s << b);
894 }
896  : RandomVariableBase (c),
897  m_mean (c.m_mean),
898  m_alpha (c.m_alpha),
899  m_bound (c.m_bound)
900 {
901  NS_LOG_FUNCTION (this << &c);
902 }
903 
905 {
906  NS_LOG_FUNCTION (this);
907  RngStream *generator = GetStream ();
908  double exponent = 1.0 / m_alpha;
909  while (1)
910  {
911  double r = m_mean * std::pow ( -std::log (generator->RandU01 ()), exponent);
912  if (m_bound == 0 || r <= m_bound)
913  {
914  return r;
915  }
916  // otherwise, try again
917  }
918 }
919 
920 RandomVariableBase* WeibullVariableImpl::Copy () const
921 {
922  NS_LOG_FUNCTION (this);
923  return new WeibullVariableImpl (*this);
924 }
925 
928 {
929  NS_LOG_FUNCTION (this);
930 }
933 {
934  NS_LOG_FUNCTION (this << m);
935 }
938 {
939  NS_LOG_FUNCTION (this << m << s);
940 }
941 WeibullVariable::WeibullVariable (double m, double s, double b)
942  : RandomVariable (WeibullVariableImpl (m, s, b))
943 {
944  NS_LOG_FUNCTION (this << m << s << b);
945 }
946 
947 // -----------------------------------------------------------------------------
948 // -----------------------------------------------------------------------------
949 // NormalVariableImpl methods
950 
951 class NormalVariableImpl : public RandomVariableBase // Normally Distributed random var
952 
953 {
954 public:
955  static const double INFINITE_VALUE;
961 
968  NormalVariableImpl (double m, double v, double b = INFINITE_VALUE);
969 
971 
975  virtual double GetValue ();
976  virtual RandomVariableBase* Copy (void) const;
977 
978  double GetMean (void) const;
979  double GetVariance (void) const;
980  double GetBound (void) const;
981 
982 private:
983  double m_mean; // Mean value of RV
984  double m_variance; // Mean value of RV
985  double m_bound; // Bound on value's difference from the mean (absolute value)
986  bool m_nextValid; // True if next valid
987  double m_next; // The algorithm produces two values at a time
988 };
989 
990 const double NormalVariableImpl::INFINITE_VALUE = 1e307;
991 
993  : m_mean (0.0),
994  m_variance (1.0),
995  m_bound (INFINITE_VALUE),
996  m_nextValid (false)
997 {
998  NS_LOG_FUNCTION (this);
999 }
1000 
1001 NormalVariableImpl::NormalVariableImpl (double m, double v, double b)
1002  : m_mean (m),
1003  m_variance (v),
1004  m_bound (b),
1005  m_nextValid (false)
1006 {
1007  NS_LOG_FUNCTION (this << m << v << b);
1008 }
1009 
1011  : RandomVariableBase (c),
1012  m_mean (c.m_mean),
1013  m_variance (c.m_variance),
1014  m_bound (c.m_bound),
1015  m_nextValid (false)
1016 {
1017  NS_LOG_FUNCTION (this << &c);
1018 }
1019 
1021 {
1022  NS_LOG_FUNCTION (this);
1023  RngStream *generator = GetStream ();
1024  if (m_nextValid)
1025  { // use previously generated
1026  m_nextValid = false;
1027  return m_next;
1028  }
1029  while (1)
1030  { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1031  // for algorithm; basically a Box-Muller transform:
1032  // http://en.wikipedia.org/wiki/Box-Muller_transform
1033  double u1 = generator->RandU01 ();
1034  double u2 = generator->RandU01 ();
1035  double v1 = 2 * u1 - 1;
1036  double v2 = 2 * u2 - 1;
1037  double w = v1 * v1 + v2 * v2;
1038  if (w <= 1.0)
1039  { // Got good pair
1040  double y = std::sqrt ((-2 * std::log (w)) / w);
1041  m_next = m_mean + v2 * y * std::sqrt (m_variance);
1042  // if next is in bounds, it is valid
1043  m_nextValid = std::fabs (m_next - m_mean) <= m_bound;
1044  double x1 = m_mean + v1 * y * std::sqrt (m_variance);
1045  // if x1 is in bounds, return it
1046  if (std::fabs (x1 - m_mean) <= m_bound)
1047  {
1048  return x1;
1049  }
1050  // otherwise try and return m_next if it is valid
1051  else if (m_nextValid)
1052  {
1053  m_nextValid = false;
1054  return m_next;
1055  }
1056  // otherwise, just run this loop again
1057  }
1058  }
1059 }
1060 
1061 RandomVariableBase* NormalVariableImpl::Copy () const
1062 {
1063  NS_LOG_FUNCTION (this);
1064  return new NormalVariableImpl (*this);
1065 }
1066 
1067 double
1068 NormalVariableImpl::GetMean (void) const
1069 {
1070  NS_LOG_FUNCTION (this);
1071  return m_mean;
1072 }
1073 
1074 double
1075 NormalVariableImpl::GetVariance (void) const
1076 {
1077  NS_LOG_FUNCTION (this);
1078  return m_variance;
1079 }
1080 
1081 double
1082 NormalVariableImpl::GetBound (void) const
1083 {
1084  NS_LOG_FUNCTION (this);
1085  return m_bound;
1086 }
1087 
1090 {
1091  NS_LOG_FUNCTION (this);
1092 }
1095 {
1096  NS_LOG_FUNCTION (this << m << v);
1097 }
1098 NormalVariable::NormalVariable (double m, double v, double b)
1099  : RandomVariable (NormalVariableImpl (m, v, b))
1100 {
1101  NS_LOG_FUNCTION (this << m << v << b);
1102 }
1103 
1104 // -----------------------------------------------------------------------------
1105 // -----------------------------------------------------------------------------
1107 {
1108 public:
1112  explicit EmpiricalVariableImpl ();
1113 
1114  virtual ~EmpiricalVariableImpl ();
1119  virtual double GetValue ();
1120  virtual RandomVariableBase* Copy (void) const;
1126  virtual void CDF (double v, double c); // Value, prob <= Value
1127 
1128 private:
1129  class ValueCDF
1130  {
1131 public:
1132  ValueCDF ();
1133  ValueCDF (double v, double c);
1134  ValueCDF (const ValueCDF& c);
1135  double value;
1136  double cdf;
1137  };
1138  virtual void Validate (); // Insure non-decreasing emiprical values
1139  virtual double Interpolate (double, double, double, double, double);
1140  bool validated; // True if non-decreasing validated
1141  std::vector<ValueCDF> emp; // Empicical CDF
1142 };
1143 
1144 
1145 // ValueCDF methods
1146 EmpiricalVariableImpl::ValueCDF::ValueCDF ()
1147  : value (0.0),
1148  cdf (0.0)
1149 {
1150  NS_LOG_FUNCTION (this);
1151 }
1152 EmpiricalVariableImpl::ValueCDF::ValueCDF (double v, double c)
1153  : value (v),
1154  cdf (c)
1155 {
1156  NS_LOG_FUNCTION (this << v << c);
1157 }
1158 EmpiricalVariableImpl::ValueCDF::ValueCDF (const ValueCDF& c)
1159  : value (c.value),
1160  cdf (c.cdf)
1161 {
1162  NS_LOG_FUNCTION (this << &c);
1163 }
1164 
1165 // -----------------------------------------------------------------------------
1166 // -----------------------------------------------------------------------------
1167 // EmpiricalVariableImpl methods
1169  : validated (false)
1170 {
1171  NS_LOG_FUNCTION (this);
1172 }
1173 
1175  : RandomVariableBase (c),
1176  validated (c.validated),
1177  emp (c.emp)
1178 {
1179  NS_LOG_FUNCTION (this << &c);
1180 }
1181 
1182 EmpiricalVariableImpl::~EmpiricalVariableImpl ()
1183 {
1184  NS_LOG_FUNCTION (this);
1185 }
1186 
1188 { // Return a value from the empirical distribution
1189  // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1190  NS_LOG_FUNCTION (this);
1191  RngStream *generator = GetStream ();
1192  if (emp.size () == 0)
1193  {
1194  return 0.0; // HuH? No empirical data
1195  }
1196  if (!validated)
1197  {
1198  Validate (); // Insure in non-decreasing
1199  }
1200  double r = generator->RandU01 ();
1201  if (r <= emp.front ().cdf)
1202  {
1203  return emp.front ().value; // Less than first
1204  }
1205  if (r >= emp.back ().cdf)
1206  {
1207  return emp.back ().value; // Greater than last
1208  }
1209  // Binary search
1210  std::vector<ValueCDF>::size_type bottom = 0;
1211  std::vector<ValueCDF>::size_type top = emp.size () - 1;
1212  while (1)
1213  {
1214  std::vector<ValueCDF>::size_type c = (top + bottom) / 2;
1215  if (r >= emp[c].cdf && r < emp[c + 1].cdf)
1216  { // Found it
1217  return Interpolate (emp[c].cdf, emp[c + 1].cdf,
1218  emp[c].value, emp[c + 1].value,
1219  r);
1220  }
1221  // Not here, adjust bounds
1222  if (r < emp[c].cdf)
1223  {
1224  top = c - 1;
1225  }
1226  else
1227  {
1228  bottom = c + 1;
1229  }
1230  }
1231 }
1232 
1233 RandomVariableBase* EmpiricalVariableImpl::Copy () const
1234 {
1235  NS_LOG_FUNCTION (this);
1236  return new EmpiricalVariableImpl (*this);
1237 }
1238 
1239 void EmpiricalVariableImpl::CDF (double v, double c)
1240 { // Add a new empirical datapoint to the empirical cdf
1241  // NOTE. These MUST be inserted in non-decreasing order
1242  NS_LOG_FUNCTION (this << v << c);
1243  emp.push_back (ValueCDF (v, c));
1244 }
1245 
1246 void EmpiricalVariableImpl::Validate ()
1247 {
1248  NS_LOG_FUNCTION (this);
1249  ValueCDF prior;
1250  for (std::vector<ValueCDF>::size_type i = 0; i < emp.size (); ++i)
1251  {
1252  ValueCDF& current = emp[i];
1253  if (current.value < prior.value || current.cdf < prior.cdf)
1254  { // Error
1255  std::cerr << "Empirical Dist error,"
1256  << " current value " << current.value
1257  << " prior value " << prior.value
1258  << " current cdf " << current.cdf
1259  << " prior cdf " << prior.cdf << std::endl;
1260  NS_FATAL_ERROR ("Empirical Dist error");
1261  }
1262  prior = current;
1263  }
1264  validated = true;
1265 }
1266 
1267 double EmpiricalVariableImpl::Interpolate (double c1, double c2,
1268  double v1, double v2, double r)
1269 { // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1270  NS_LOG_FUNCTION (this << c1 << c2 << v1 << v2 << r);
1271  return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1272 }
1273 
1276 {
1277  NS_LOG_FUNCTION (this);
1278 }
1280  : RandomVariable (variable)
1281 {
1282  NS_LOG_FUNCTION (this << &variable);
1283 }
1284 void
1285 EmpiricalVariable::CDF (double v, double c)
1286 {
1287  NS_LOG_FUNCTION (this << v << c);
1288  EmpiricalVariableImpl *impl = dynamic_cast<EmpiricalVariableImpl *> (Peek ());
1289  NS_ASSERT (impl);
1290  impl->CDF (v, c);
1291 }
1292 
1293 
1294 // -----------------------------------------------------------------------------
1295 // -----------------------------------------------------------------------------
1296 // IntegerValue EmpiricalVariableImpl methods
1298 {
1299 public:
1301 
1302  virtual RandomVariableBase* Copy (void) const;
1306  virtual uint32_t GetInteger ();
1307 private:
1308  virtual double Interpolate (double, double, double, double, double);
1309 };
1310 
1311 
1312 IntEmpiricalVariableImpl::IntEmpiricalVariableImpl ()
1313 {
1314  NS_LOG_FUNCTION (this);
1315 }
1316 
1318 {
1319  NS_LOG_FUNCTION (this);
1320  return (uint32_t)GetValue ();
1321 }
1322 
1323 RandomVariableBase* IntEmpiricalVariableImpl::Copy () const
1324 {
1325  NS_LOG_FUNCTION (this);
1326  return new IntEmpiricalVariableImpl (*this);
1327 }
1328 
1329 double IntEmpiricalVariableImpl::Interpolate (double c1, double c2,
1330  double v1, double v2, double r)
1331 { // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1332  NS_LOG_FUNCTION (this << c1 << c2 << v1 << v2 << r);
1333  return std::ceil (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1334 }
1335 
1336 IntEmpiricalVariable::IntEmpiricalVariable ()
1337  : EmpiricalVariable (IntEmpiricalVariableImpl ())
1338 {
1339  NS_LOG_FUNCTION (this);
1340 }
1341 
1342 // -----------------------------------------------------------------------------
1343 // -----------------------------------------------------------------------------
1344 // DeterministicVariableImpl
1346 {
1347 
1348 public:
1360  explicit DeterministicVariableImpl (double* d, uint32_t c);
1361 
1362  virtual ~DeterministicVariableImpl ();
1366  virtual double GetValue ();
1367  virtual RandomVariableBase* Copy (void) const;
1368 private:
1369  uint32_t count;
1370  uint32_t next;
1371  double* data;
1372 };
1373 
1375  : count (c),
1376  next (c),
1377  data (d)
1378 { // Nothing else needed
1379  NS_LOG_FUNCTION (this << d << c);
1380 }
1381 
1382 DeterministicVariableImpl::~DeterministicVariableImpl ()
1383 {
1384  NS_LOG_FUNCTION (this);
1385 }
1386 
1388 {
1389  NS_LOG_FUNCTION (this);
1390  if (next == count)
1391  {
1392  next = 0;
1393  }
1394  return data[next++];
1395 }
1396 
1397 RandomVariableBase* DeterministicVariableImpl::Copy () const
1398 {
1399  NS_LOG_FUNCTION (this);
1400  return new DeterministicVariableImpl (*this);
1401 }
1402 
1405 {
1406  NS_LOG_FUNCTION (this << d << c);
1407 }
1408 
1409 // -----------------------------------------------------------------------------
1410 // -----------------------------------------------------------------------------
1411 // LogNormalVariableImpl
1413 {
1414 public:
1419  LogNormalVariableImpl (double mu, double sigma);
1420 
1424  virtual double GetValue ();
1425  virtual RandomVariableBase* Copy (void) const;
1426 
1427 private:
1428  double m_mu;
1429  double m_sigma;
1430 };
1431 
1432 
1433 RandomVariableBase* LogNormalVariableImpl::Copy () const
1434 {
1435  NS_LOG_FUNCTION (this);
1436  return new LogNormalVariableImpl (*this);
1437 }
1438 
1440  : m_mu (mu),
1441  m_sigma (sigma)
1442 {
1443  NS_LOG_FUNCTION (this << mu << sigma);
1444 }
1445 
1446 // The code from this function was adapted from the GNU Scientific
1447 // Library 1.8:
1448 /* randist/lognormal.c
1449  *
1450  * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
1451  *
1452  * This program is free software; you can redistribute it and/or modify
1453  * it under the terms of the GNU General Public License as published by
1454  * the Free Software Foundation; either version 2 of the License, or (at
1455  * your option) any later version.
1456  *
1457  * This program is distributed in the hope that it will be useful, but
1458  * WITHOUT ANY WARRANTY; without even the implied warranty of
1459  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1460  * General Public License for more details.
1461  *
1462  * You should have received a copy of the GNU General Public License
1463  * along with this program; if not, write to the Free Software
1464  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1465  */
1466 /* The lognormal distribution has the form
1467 
1468  p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
1469 
1470  for x > 0. Lognormal random numbers are the exponentials of
1471  gaussian random numbers */
1472 double
1474 {
1475  NS_LOG_FUNCTION (this);
1476  RngStream *generator = GetStream ();
1477  double u, v, r2, normal, z;
1478 
1479  do
1480  {
1481  /* choose x,y in uniform square (-1,-1) to (+1,+1) */
1482 
1483  u = -1 + 2 * generator->RandU01 ();
1484  v = -1 + 2 * generator->RandU01 ();
1485 
1486  /* see if it is in the unit circle */
1487  r2 = u * u + v * v;
1488  }
1489  while (r2 > 1.0 || r2 == 0);
1490 
1491  normal = u * std::sqrt (-2.0 * std::log (r2) / r2);
1492 
1493  z = std::exp (m_sigma * normal + m_mu);
1494 
1495  return z;
1496 }
1497 
1498 LogNormalVariable::LogNormalVariable (double mu, double sigma)
1499  : RandomVariable (LogNormalVariableImpl (mu, sigma))
1500 {
1501  NS_LOG_FUNCTION (this << mu << sigma);
1502 }
1503 
1504 // -----------------------------------------------------------------------------
1505 // -----------------------------------------------------------------------------
1506 // GammaVariableImpl
1508 {
1509 public:
1514  GammaVariableImpl (double alpha, double beta);
1515 
1519  virtual double GetValue ();
1520 
1525  double GetValue (double alpha, double beta);
1526 
1527  virtual RandomVariableBase* Copy (void) const;
1528 
1529 private:
1530  double m_alpha;
1531  double m_beta;
1532  NormalVariable m_normal;
1533 };
1534 
1535 
1536 RandomVariableBase* GammaVariableImpl::Copy () const
1537 {
1538  NS_LOG_FUNCTION (this);
1539  return new GammaVariableImpl (m_alpha, m_beta);
1540 }
1541 
1542 GammaVariableImpl::GammaVariableImpl (double alpha, double beta)
1543  : m_alpha (alpha),
1544  m_beta (beta)
1545 {
1546  NS_LOG_FUNCTION (this << alpha << beta);
1547 }
1548 
1549 double
1551 {
1552  NS_LOG_FUNCTION (this);
1553  return GetValue (m_alpha, m_beta);
1554 }
1555 
1556 /*
1557  The code for the following generator functions was adapted from ns-2
1558  tools/ranvar.cc
1559 
1560  Originally the algorithm was devised by Marsaglia in 2000:
1561  G. Marsaglia, W. W. Tsang: A simple method for gereating Gamma variables
1562  ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
1563 
1564  The Gamma distribution density function has the form
1565 
1566  x^(alpha-1) * exp(-x/beta)
1567  p(x; alpha, beta) = ----------------------------
1568  beta^alpha * Gamma(alpha)
1569 
1570  for x > 0.
1571 */
1572 double
1573 GammaVariableImpl::GetValue (double alpha, double beta)
1574 {
1575  NS_LOG_FUNCTION (this << alpha << beta);
1576  RngStream *generator = GetStream ();
1577 
1578  if (alpha < 1)
1579  {
1580  double u = generator->RandU01 ();
1581  return GetValue (1.0 + alpha, beta) * std::pow (u, 1.0 / alpha);
1582  }
1583 
1584  double x, v, u;
1585  double d = alpha - 1.0 / 3.0;
1586  double c = (1.0 / 3.0) / std::sqrt (d);
1587 
1588  while (1)
1589  {
1590  do
1591  {
1592  x = m_normal.GetValue ();
1593  v = 1.0 + c * x;
1594  }
1595  while (v <= 0);
1596 
1597  v = v * v * v;
1598  u = generator->RandU01 ();
1599  if (u < 1 - 0.0331 * x * x * x * x)
1600  {
1601  break;
1602  }
1603  if (std::log (u) < 0.5 * x * x + d * (1 - v + std::log (v)))
1604  {
1605  break;
1606  }
1607  }
1608 
1609  return beta * d * v;
1610 }
1611 
1613  : RandomVariable (GammaVariableImpl (1.0, 1.0))
1614 {
1615  NS_LOG_FUNCTION (this);
1616 }
1617 
1618 GammaVariable::GammaVariable (double alpha, double beta)
1619  : RandomVariable (GammaVariableImpl (alpha, beta))
1620 {
1621  NS_LOG_FUNCTION (this << alpha << beta);
1622 }
1623 
1624 double GammaVariable::GetValue (void) const
1625 {
1626  NS_LOG_FUNCTION (this);
1627  return this->RandomVariable::GetValue ();
1628 }
1629 
1630 double GammaVariable::GetValue (double alpha, double beta) const
1631 {
1632  NS_LOG_FUNCTION (this << alpha << beta);
1633  return ((GammaVariableImpl*)Peek ())->GetValue (alpha, beta);
1634 }
1635 
1636 // -----------------------------------------------------------------------------
1637 // -----------------------------------------------------------------------------
1638 // ErlangVariableImpl
1639 
1641 {
1642 public:
1647  ErlangVariableImpl (unsigned int k, double lambda);
1648 
1652  virtual double GetValue ();
1653 
1658  double GetValue (unsigned int k, double lambda);
1659 
1660  virtual RandomVariableBase* Copy (void) const;
1661 
1662 private:
1663  unsigned int m_k;
1664  double m_lambda;
1665 };
1666 
1667 
1668 RandomVariableBase* ErlangVariableImpl::Copy () const
1669 {
1670  NS_LOG_FUNCTION (this);
1671  return new ErlangVariableImpl (m_k, m_lambda);
1672 }
1673 
1674 ErlangVariableImpl::ErlangVariableImpl (unsigned int k, double lambda)
1675  : m_k (k),
1676  m_lambda (lambda)
1677 {
1678  NS_LOG_FUNCTION (this << k << lambda);
1679 }
1680 
1681 double
1683 {
1684  NS_LOG_FUNCTION (this);
1685  return GetValue (m_k, m_lambda);
1686 }
1687 
1688 /*
1689  The code for the following generator functions was adapted from ns-2
1690  tools/ranvar.cc
1691 
1692  The Erlang distribution density function has the form
1693 
1694  x^(k-1) * exp(-x/lambda)
1695  p(x; k, lambda) = ---------------------------
1696  lambda^k * (k-1)!
1697 
1698  for x > 0.
1699 */
1700 double
1701 ErlangVariableImpl::GetValue (unsigned int k, double lambda)
1702 {
1703  // XXX: Fixme: do not create a new
1704  // RNG stream every time the function is called !
1705  NS_LOG_FUNCTION (this << k << lambda);
1706  ExponentialVariable exponential (lambda);
1707 
1708  double result = 0;
1709  for (unsigned int i = 0; i < k; ++i)
1710  {
1711  result += exponential.GetValue ();
1712  }
1713 
1714  return result;
1715 }
1716 
1718  : RandomVariable (ErlangVariableImpl (1, 1.0))
1719 {
1720  NS_LOG_FUNCTION (this);
1721 }
1722 
1723 ErlangVariable::ErlangVariable (unsigned int k, double lambda)
1724  : RandomVariable (ErlangVariableImpl (k, lambda))
1725 {
1726  NS_LOG_FUNCTION (this << k << lambda);
1727 }
1728 
1729 double ErlangVariable::GetValue (void) const
1730 {
1731  NS_LOG_FUNCTION (this);
1732  return this->RandomVariable::GetValue ();
1733 }
1734 
1735 double ErlangVariable::GetValue (unsigned int k, double lambda) const
1736 {
1737  NS_LOG_FUNCTION (this << k << lambda);
1738  return ((ErlangVariableImpl*)Peek ())->GetValue (k, lambda);
1739 }
1740 
1741 // -----------------------------------------------------------------------------
1742 // -----------------------------------------------------------------------------
1743 // TriangularVariableImpl methods
1745 {
1746 public:
1752 
1760  TriangularVariableImpl (double s, double l, double mean);
1761 
1763 
1767  virtual double GetValue ();
1768  virtual RandomVariableBase* Copy (void) const;
1769 
1770 private:
1771  double m_min;
1772  double m_max;
1773  double m_mode; // easier to work with the mode internally instead of the mean
1774  // they are related by the simple: mean = (min+max+mode)/3
1775 };
1776 
1778  : m_min (0),
1779  m_max (1),
1780  m_mode (0.5)
1781 {
1782  NS_LOG_FUNCTION (this);
1783 }
1784 
1785 TriangularVariableImpl::TriangularVariableImpl (double s, double l, double mean)
1786  : m_min (s),
1787  m_max (l),
1788  m_mode (3.0 * mean - s - l)
1789 {
1790  NS_LOG_FUNCTION (this << s << l << mean);
1791 }
1792 
1794  : RandomVariableBase (c),
1795  m_min (c.m_min),
1796  m_max (c.m_max),
1797  m_mode (c.m_mode)
1798 {
1799  NS_LOG_FUNCTION (this << &c);
1800 }
1801 
1803 {
1804  NS_LOG_FUNCTION (this);
1805  RngStream *generator = GetStream ();
1806  double u = generator->RandU01 ();
1807  if (u <= (m_mode - m_min) / (m_max - m_min) )
1808  {
1809  return m_min + std::sqrt (u * (m_max - m_min) * (m_mode - m_min) );
1810  }
1811  else
1812  {
1813  return m_max - std::sqrt ( (1 - u) * (m_max - m_min) * (m_max - m_mode) );
1814  }
1815 }
1816 
1817 RandomVariableBase* TriangularVariableImpl::Copy () const
1818 {
1819  NS_LOG_FUNCTION (this);
1820  return new TriangularVariableImpl (*this);
1821 }
1822 
1825 {
1826  NS_LOG_FUNCTION (this);
1827 }
1828 TriangularVariable::TriangularVariable (double s, double l, double mean)
1829  : RandomVariable (TriangularVariableImpl (s,l,mean))
1830 {
1831  NS_LOG_FUNCTION (this << s << l << mean);
1832 }
1833 
1834 // -----------------------------------------------------------------------------
1835 // -----------------------------------------------------------------------------
1836 // ZipfVariableImpl
1838 {
1839 public:
1844  ZipfVariableImpl (long n, double alpha);
1845 
1849  ZipfVariableImpl ();
1850 
1854  virtual double GetValue ();
1855  virtual RandomVariableBase* Copy (void) const;
1856 
1857 private:
1858  long m_n;
1859  double m_alpha;
1860  double m_c; // the normalization constant
1861 };
1862 
1863 
1864 RandomVariableBase* ZipfVariableImpl::Copy () const
1865 {
1866  NS_LOG_FUNCTION (this);
1867  return new ZipfVariableImpl (m_n, m_alpha);
1868 }
1869 
1871  : m_n (1),
1872  m_alpha (0),
1873  m_c (1)
1874 {
1875  NS_LOG_FUNCTION (this);
1876 }
1877 
1878 
1880  : m_n (n),
1881  m_alpha (alpha),
1882  m_c (0)
1883 {
1884  // calculate the normalization constant c
1885  NS_LOG_FUNCTION (this << n << alpha);
1886  for (int i = 1; i <= n; i++)
1887  {
1888  m_c += (1.0 / std::pow ((double)i, alpha));
1889  }
1890  m_c = 1.0 / m_c;
1891 }
1892 
1893 double
1895 {
1896  NS_LOG_FUNCTION (this);
1897  RngStream *generator = GetStream ();
1898 
1899  double u = generator->RandU01 ();
1900  double sum_prob = 0,zipf_value = 0;
1901  for (int i = 1; i <= m_n; i++)
1902  {
1903  sum_prob += m_c / std::pow ((double)i, m_alpha);
1904  if (sum_prob > u)
1905  {
1906  zipf_value = i;
1907  break;
1908  }
1909  }
1910  return zipf_value;
1911 }
1912 
1915 {
1916  NS_LOG_FUNCTION (this);
1917 }
1918 
1919 ZipfVariable::ZipfVariable (long n, double alpha)
1920  : RandomVariable (ZipfVariableImpl (n, alpha))
1921 {
1922  NS_LOG_FUNCTION (this << n << alpha);
1923 }
1924 
1925 
1926 // -----------------------------------------------------------------------------
1927 // -----------------------------------------------------------------------------
1928 // ZetaVariableImpl
1930 {
1931 public:
1935  ZetaVariableImpl (double alpha);
1936 
1940  ZetaVariableImpl ();
1941 
1945  virtual double GetValue ();
1946  virtual RandomVariableBase* Copy (void) const;
1947 
1948 private:
1949  double m_alpha;
1950  double m_b; // just for calculus simplifications
1951 };
1952 
1953 
1954 RandomVariableBase* ZetaVariableImpl::Copy () const
1955 {
1956  NS_LOG_FUNCTION (this);
1957  return new ZetaVariableImpl (m_alpha);
1958 }
1959 
1961  : m_alpha (3.14),
1962  m_b (std::pow (2.0, 2.14))
1963 {
1964  NS_LOG_FUNCTION (this);
1965 }
1966 
1967 
1969  : m_alpha (alpha),
1970  m_b (std::pow (2.0, alpha - 1.0))
1971 {
1972  NS_LOG_FUNCTION (this << alpha);
1973 }
1974 
1975 /*
1976  The code for the following generator functions is borrowed from:
1977  L. Devroye: Non-Uniform Random Variate Generation, Springer-Verlag, New York, 1986.
1978  page 551
1979  */
1980 double
1982 {
1983  NS_LOG_FUNCTION (this);
1984  RngStream *generator = GetStream ();
1985 
1986  double u, v;
1987  double X, T;
1988  double test;
1989 
1990  do
1991  {
1992  u = generator->RandU01 ();
1993  v = generator->RandU01 ();
1994  X = floor (std::pow (u, -1.0 / (m_alpha - 1.0)));
1995  T = std::pow (1.0 + 1.0 / X, m_alpha - 1.0);
1996  test = v * X * (T - 1.0) / (m_b - 1.0);
1997  }
1998  while ( test > (T / m_b) );
1999 
2000  return X;
2001 }
2002 
2005 {
2006  NS_LOG_FUNCTION (this);
2007 }
2008 
2010  : RandomVariable (ZetaVariableImpl (alpha))
2011 {
2012  NS_LOG_FUNCTION (this << alpha);
2013 }
2014 
2015 
2016 std::ostream & operator << (std::ostream &os, const RandomVariable &var)
2017 {
2018  RandomVariableBase *base = var.Peek ();
2019  ConstantVariableImpl *constant = dynamic_cast<ConstantVariableImpl *> (base);
2020  if (constant != 0)
2021  {
2022  os << "Constant:" << constant->GetValue ();
2023  return os;
2024  }
2025  UniformVariableImpl *uniform = dynamic_cast<UniformVariableImpl *> (base);
2026  if (uniform != 0)
2027  {
2028  os << "Uniform:" << uniform->GetMin () << ":" << uniform->GetMax ();
2029  return os;
2030  }
2031  NormalVariableImpl *normal = dynamic_cast<NormalVariableImpl *> (base);
2032  if (normal != 0)
2033  {
2034  os << "Normal:" << normal->GetMean () << ":" << normal->GetVariance ();
2035  double bound = normal->GetBound ();
2036  if (bound != NormalVariableImpl::INFINITE_VALUE)
2037  {
2038  os << ":" << bound;
2039  }
2040  return os;
2041  }
2042  // XXX: support other distributions
2043  os.setstate (std::ios_base::badbit);
2044  return os;
2045 }
2046 std::istream & operator >> (std::istream &is, RandomVariable &var)
2047 {
2048  std::string value;
2049  is >> value;
2050  std::string::size_type tmp;
2051  tmp = value.find (":");
2052  if (tmp == std::string::npos)
2053  {
2054  is.setstate (std::ios_base::badbit);
2055  return is;
2056  }
2057  std::string type = value.substr (0, tmp);
2058  value = value.substr (tmp + 1, value.npos);
2059  if (type == "Constant")
2060  {
2061  std::istringstream iss (value);
2062  double constant;
2063  iss >> constant;
2064  var = ConstantVariable (constant);
2065  }
2066  else if (type == "Uniform")
2067  {
2068  if (value.size () == 0)
2069  {
2070  var = UniformVariable ();
2071  }
2072  else
2073  {
2074  tmp = value.find (":");
2075  if (tmp == value.npos)
2076  {
2077  NS_FATAL_ERROR ("bad Uniform value: " << value);
2078  }
2079  std::istringstream issA (value.substr (0, tmp));
2080  std::istringstream issB (value.substr (tmp + 1, value.npos));
2081  double a, b;
2082  issA >> a;
2083  issB >> b;
2084  var = UniformVariable (a, b);
2085  }
2086  }
2087  else if (type == "Normal")
2088  {
2089  if (value.size () == 0)
2090  {
2091  var = NormalVariable ();
2092  }
2093  else
2094  {
2095  tmp = value.find (":");
2096  if (tmp == value.npos)
2097  {
2098  NS_FATAL_ERROR ("bad Normal value: " << value);
2099  }
2100  std::string::size_type tmp2;
2101  std::string sub = value.substr (tmp + 1, value.npos);
2102  tmp2 = sub.find (":");
2103  if (tmp2 == value.npos)
2104  {
2105  std::istringstream issA (value.substr (0, tmp));
2106  std::istringstream issB (sub);
2107  double a, b;
2108  issA >> a;
2109  issB >> b;
2110  var = NormalVariable (a, b);
2111  }
2112  else
2113  {
2114  std::istringstream issA (value.substr (0, tmp));
2115  std::istringstream issB (sub.substr (0, tmp2));
2116  std::istringstream issC (sub.substr (tmp2 + 1, value.npos));
2117  double a, b, c;
2118  issA >> a;
2119  issB >> b;
2120  issC >> c;
2121  var = NormalVariable (a, b, c);
2122  }
2123  }
2124  }
2125  else
2126  {
2127  NS_FATAL_ERROR ("RandomVariable deserialization not implemented for " << type);
2128  // XXX: support other distributions.
2129  }
2130  return is;
2131 }
2132 
2133 } // namespace ns3
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:49
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
A random variable that returns a constantClass ConstantVariable defines a random number generator tha...
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual double GetValue()
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
static uint64_t GetRun(void)
void NewConstant(double c)
Specify a new constant RNG for this generator.
Class NormalVariable defines a random variable with a normal (Gaussian) distribution.This class supports the creation of objects that return random numbers from a fixed normal distribution. It also supports the generation of single random numbers from various normal distributions.
Combined Multiple-Recursive Generator MRG32k3a.
Definition: rng-stream.h:39
#define ATTRIBUTE_VALUE_IMPLEMENT(type)
SequentialVariableImpl(double f, double l, double i=1, uint32_t c=1)
Constructor for the SequentialVariableImpl RNG.
DeterministicVariable(double *d, uint32_t c)
Constructor.
LogNormalVariableImpl(double mu, double sigma)
double GetValue(void) const
call RandomVariable::GetValue
double GetValue(void) const
call RandomVariable::GetValue
SequentialVariable(double f, double l, double i=1, uint32_t c=1)
Constructor for the SequentialVariable RNG.
ErlangVariableImpl(unsigned int k, double lambda)
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:43
LogNormalVariable(double mu, double sigma)
virtual void CDF(double v, double c)
Specifies a point in the empirical distribution.
virtual double GetValue()
Exponentially Distributed random varThis class supports the creation of objects that return random nu...
double RandU01(void)
Definition: rng-stream.cc:262
static uint32_t GetSeed(void)
Get the seed value.
double GetValue(void) const
call RandomVariable::GetValue
void CDF(double v, double c)
Specifies a point in the empirical distribution.
virtual double GetValue()
virtual double GetValue()
GammaVariableImpl(double alpha, double beta)
DeterministicVariableImpl(double *d, uint32_t c)
Constructor.
The basic RNG for NS-3.Note: The underlying random number generation method used by NS-3 is the RngSt...
double GetValue(void) const
Returns a random double from the underlying distribution.
uint32_t GetInteger(void) const
Returns a random integer integer from the underlying distribution.
void SetConstant(double c)
Specify a new constant RNG for this generator.
ParetoVariable()
Constructs a pareto random variable with a mean of 1 and a shape parameter of 1.5.
#define ATTRIBUTE_CHECKER_IMPLEMENT(type)