A Discrete-Event Network Simulator
API
random-variable-stream.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 Georgia Tech Research Corporation
3  * Copyright (c) 2011 Mathieu Lacage
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  * Authors: Rajib Bhattacharjea<raj.b@gatech.edu>
19  * Hadi Arbabi<marbabi@cs.odu.edu>
20  * Mathieu Lacage <mathieu.lacage@gmail.com>
21  *
22  * Modified by Mitch Watrous <watrous@u.washington.edu>
23  *
24  */
25 #include "random-variable-stream.h"
26 
27 #include "assert.h"
28 #include "boolean.h"
29 #include "double.h"
30 #include "integer.h"
31 #include "log.h"
32 #include "pointer.h"
33 #include "rng-seed-manager.h"
34 #include "rng-stream.h"
35 #include "string.h"
36 
37 #include <algorithm> // upper_bound
38 #include <cmath>
39 #include <iostream>
40 
47 namespace ns3
48 {
49 
50 NS_LOG_COMPONENT_DEFINE("RandomVariableStream");
51 
52 NS_OBJECT_ENSURE_REGISTERED(RandomVariableStream);
53 
54 TypeId
56 {
57  static TypeId tid = TypeId("ns3::RandomVariableStream")
58  .SetParent<Object>()
59  .SetGroupName("Core")
60  .AddAttribute("Stream",
61  "The stream number for this RNG stream. -1 means "
62  "\"allocate a stream automatically\". "
63  "Note that if -1 is set, Get will return -1 so that it "
64  "is not possible to know which "
65  "value was automatically allocated.",
66  IntegerValue(-1),
69  MakeIntegerChecker<int64_t>())
70  .AddAttribute("Antithetic",
71  "Set this RNG stream to generate antithetic values",
72  BooleanValue(false),
76  return tid;
77 }
78 
80  : m_rng(nullptr)
81 {
82  NS_LOG_FUNCTION(this);
83 }
84 
86 {
87  NS_LOG_FUNCTION(this);
88  delete m_rng;
89 }
90 
91 void
93 {
94  NS_LOG_FUNCTION(this << isAntithetic);
95  m_isAntithetic = isAntithetic;
96 }
97 
98 bool
100 {
101  NS_LOG_FUNCTION(this);
102  return m_isAntithetic;
103 }
104 
105 uint32_t
107 {
108  NS_LOG_FUNCTION(this);
109  return static_cast<uint32_t>(GetValue());
110 }
111 
112 void
114 {
115  NS_LOG_FUNCTION(this << stream);
116  // negative values are not legal.
117  NS_ASSERT(stream >= -1);
118  delete m_rng;
119  if (stream == -1)
120  {
121  // The first 2^63 streams are reserved for automatic stream
122  // number assignment.
123  uint64_t nextStream = RngSeedManager::GetNextStreamIndex();
124  NS_ASSERT(nextStream <= ((1ULL) << 63));
126  }
127  else
128  {
129  // The last 2^63 streams are reserved for deterministic stream
130  // number assignment.
131  uint64_t base = ((1ULL) << 63);
132  uint64_t target = base + stream;
134  }
135  m_stream = stream;
136 }
137 
138 int64_t
140 {
141  NS_LOG_FUNCTION(this);
142  return m_stream;
143 }
144 
145 RngStream*
147 {
148  NS_LOG_FUNCTION(this);
149  return m_rng;
150 }
151 
153 
154 TypeId
156 {
157  static TypeId tid =
158  TypeId("ns3::UniformRandomVariable")
160  .SetGroupName("Core")
161  .AddConstructor<UniformRandomVariable>()
162  .AddAttribute("Min",
163  "The lower bound on the values returned by this RNG stream.",
164  DoubleValue(0),
166  MakeDoubleChecker<double>())
167  .AddAttribute("Max",
168  "The upper bound on the values returned by this RNG stream.",
169  DoubleValue(1.0),
171  MakeDoubleChecker<double>());
172  return tid;
173 }
174 
176 {
177  // m_min and m_max are initialized after constructor by attributes
178  NS_LOG_FUNCTION(this);
179 }
180 
181 double
183 {
184  NS_LOG_FUNCTION(this);
185  return m_min;
186 }
187 
188 double
190 {
191  NS_LOG_FUNCTION(this);
192  return m_max;
193 }
194 
195 double
197 {
198  NS_LOG_FUNCTION(this << min << max);
199  double v = min + Peek()->RandU01() * (max - min);
200  if (IsAntithetic())
201  {
202  v = min + (max - v);
203  }
204  return v;
205 }
206 
207 uint32_t
209 {
210  NS_LOG_FUNCTION(this << min << max);
211  NS_ASSERT(min <= max);
212  return static_cast<uint32_t>(GetValue((double)(min), (double)(max) + 1.0));
213 }
214 
215 double
217 {
218  NS_LOG_FUNCTION(this);
219  return GetValue(m_min, m_max);
220 }
221 
222 uint32_t
224 {
225  NS_LOG_FUNCTION(this);
226  return static_cast<uint32_t>(GetValue(m_min, m_max + 1));
227 }
228 
230 
231 TypeId
233 {
234  static TypeId tid = TypeId("ns3::ConstantRandomVariable")
236  .SetGroupName("Core")
237  .AddConstructor<ConstantRandomVariable>()
238  .AddAttribute("Constant",
239  "The constant value returned by this RNG stream.",
240  DoubleValue(0),
242  MakeDoubleChecker<double>());
243  return tid;
244 }
245 
247 {
248  // m_constant is initialized after constructor by attributes
249  NS_LOG_FUNCTION(this);
250 }
251 
252 double
254 {
255  NS_LOG_FUNCTION(this);
256  return m_constant;
257 }
258 
259 double
261 {
262  NS_LOG_FUNCTION(this << constant);
263  return constant;
264 }
265 
266 uint32_t
268 {
269  NS_LOG_FUNCTION(this << constant);
270  return constant;
271 }
272 
273 double
275 {
276  NS_LOG_FUNCTION(this);
277  return GetValue(m_constant);
278 }
279 
281 
282 TypeId
284 {
285  static TypeId tid =
286  TypeId("ns3::SequentialRandomVariable")
288  .SetGroupName("Core")
289  .AddConstructor<SequentialRandomVariable>()
290  .AddAttribute("Min",
291  "The first value of the sequence.",
292  DoubleValue(0),
294  MakeDoubleChecker<double>())
295  .AddAttribute("Max",
296  "One more than the last value of the sequence.",
297  DoubleValue(0),
299  MakeDoubleChecker<double>())
300  .AddAttribute("Increment",
301  "The sequence random variable increment.",
302  StringValue("ns3::ConstantRandomVariable[Constant=1]"),
304  MakePointerChecker<RandomVariableStream>())
305  .AddAttribute("Consecutive",
306  "The number of times each member of the sequence is repeated.",
307  IntegerValue(1),
309  MakeIntegerChecker<uint32_t>());
310  return tid;
311 }
312 
314  : m_current(0),
315  m_currentConsecutive(0),
316  m_isCurrentSet(false)
317 {
318  // m_min, m_max, m_increment, and m_consecutive are initialized
319  // after constructor by attributes.
320  NS_LOG_FUNCTION(this);
321 }
322 
323 double
325 {
326  NS_LOG_FUNCTION(this);
327  return m_min;
328 }
329 
330 double
332 {
333  NS_LOG_FUNCTION(this);
334  return m_max;
335 }
336 
339 {
340  NS_LOG_FUNCTION(this);
341  return m_increment;
342 }
343 
344 uint32_t
346 {
347  NS_LOG_FUNCTION(this);
348  return m_consecutive;
349 }
350 
351 double
353 {
354  // Set the current sequence value if it hasn't been set.
355  NS_LOG_FUNCTION(this);
356  if (!m_isCurrentSet)
357  {
358  // Start the sequence at its minimum value.
359  m_current = m_min;
360  m_isCurrentSet = true;
361  }
362 
363  // Return a sequential series of values
364  double r = m_current;
366  { // Time to advance to next
369  if (m_current >= m_max)
370  {
371  m_current = m_min + (m_current - m_max);
372  }
373  }
374  return r;
375 }
376 
378 
379 TypeId
381 {
382  static TypeId tid =
383  TypeId("ns3::ExponentialRandomVariable")
385  .SetGroupName("Core")
386  .AddConstructor<ExponentialRandomVariable>()
387  .AddAttribute("Mean",
388  "The mean of the values returned by this RNG stream.",
389  DoubleValue(1.0),
391  MakeDoubleChecker<double>())
392  .AddAttribute("Bound",
393  "The upper bound on the values returned by this RNG stream.",
394  DoubleValue(0.0),
396  MakeDoubleChecker<double>());
397  return tid;
398 }
399 
401 {
402  // m_mean and m_bound are initialized after constructor by attributes
403  NS_LOG_FUNCTION(this);
404 }
405 
406 double
408 {
409  NS_LOG_FUNCTION(this);
410  return m_mean;
411 }
412 
413 double
415 {
416  NS_LOG_FUNCTION(this);
417  return m_bound;
418 }
419 
420 double
421 ExponentialRandomVariable::GetValue(double mean, double bound)
422 {
423  NS_LOG_FUNCTION(this << mean << bound);
424  while (true)
425  {
426  // Get a uniform random variable in [0,1].
427  double v = Peek()->RandU01();
428  if (IsAntithetic())
429  {
430  v = (1 - v);
431  }
432 
433  // Calculate the exponential random variable.
434  double r = -mean * std::log(v);
435 
436  // Use this value if it's acceptable.
437  if (bound == 0 || r <= bound)
438  {
439  return r;
440  }
441  }
442 }
443 
444 uint32_t
445 ExponentialRandomVariable::GetInteger(uint32_t mean, uint32_t bound)
446 {
447  NS_LOG_FUNCTION(this << mean << bound);
448  return static_cast<uint32_t>(GetValue(mean, bound));
449 }
450 
451 double
453 {
454  NS_LOG_FUNCTION(this);
455  return GetValue(m_mean, m_bound);
456 }
457 
459 
460 TypeId
462 {
463  static TypeId tid =
464  TypeId("ns3::ParetoRandomVariable")
466  .SetGroupName("Core")
467  .AddConstructor<ParetoRandomVariable>()
468  .AddAttribute(
469  "Scale",
470  "The scale parameter for the Pareto distribution returned by this RNG stream.",
471  DoubleValue(1.0),
473  MakeDoubleChecker<double>())
474  .AddAttribute(
475  "Shape",
476  "The shape parameter for the Pareto distribution returned by this RNG stream.",
477  DoubleValue(2.0),
479  MakeDoubleChecker<double>())
480  .AddAttribute(
481  "Bound",
482  "The upper bound on the values returned by this RNG stream (if non-zero).",
483  DoubleValue(0.0),
485  MakeDoubleChecker<double>());
486  return tid;
487 }
488 
490 {
491  // m_shape, m_shape, and m_bound are initialized after constructor
492  // by attributes
493  NS_LOG_FUNCTION(this);
494 }
495 
496 double
498 {
499  NS_LOG_FUNCTION(this);
500  return m_scale;
501 }
502 
503 double
505 {
506  NS_LOG_FUNCTION(this);
507  return m_shape;
508 }
509 
510 double
512 {
513  NS_LOG_FUNCTION(this);
514  return m_bound;
515 }
516 
517 double
518 ParetoRandomVariable::GetValue(double scale, double shape, double bound)
519 {
520  // Calculate the scale parameter.
521  NS_LOG_FUNCTION(this << scale << shape << bound);
522 
523  while (true)
524  {
525  // Get a uniform random variable in [0,1].
526  double v = Peek()->RandU01();
527  if (IsAntithetic())
528  {
529  v = (1 - v);
530  }
531 
532  // Calculate the Pareto random variable.
533  double r = (scale * (1.0 / std::pow(v, 1.0 / shape)));
534 
535  // Use this value if it's acceptable.
536  if (bound == 0 || r <= bound)
537  {
538  return r;
539  }
540  }
541 }
542 
543 uint32_t
544 ParetoRandomVariable::GetInteger(uint32_t scale, uint32_t shape, uint32_t bound)
545 {
546  NS_LOG_FUNCTION(this << scale << shape << bound);
547  return static_cast<uint32_t>(GetValue(scale, shape, bound));
548 }
549 
550 double
552 {
553  NS_LOG_FUNCTION(this);
554  return GetValue(m_scale, m_shape, m_bound);
555 }
556 
558 
559 TypeId
561 {
562  static TypeId tid =
563  TypeId("ns3::WeibullRandomVariable")
565  .SetGroupName("Core")
566  .AddConstructor<WeibullRandomVariable>()
567  .AddAttribute(
568  "Scale",
569  "The scale parameter for the Weibull distribution returned by this RNG stream.",
570  DoubleValue(1.0),
572  MakeDoubleChecker<double>())
573  .AddAttribute(
574  "Shape",
575  "The shape parameter for the Weibull distribution returned by this RNG stream.",
576  DoubleValue(1),
578  MakeDoubleChecker<double>())
579  .AddAttribute("Bound",
580  "The upper bound on the values returned by this RNG stream.",
581  DoubleValue(0.0),
583  MakeDoubleChecker<double>());
584  return tid;
585 }
586 
588 {
589  // m_scale, m_shape, and m_bound are initialized after constructor
590  // by attributes
591  NS_LOG_FUNCTION(this);
592 }
593 
594 double
596 {
597  NS_LOG_FUNCTION(this);
598  return m_scale;
599 }
600 
601 double
603 {
604  NS_LOG_FUNCTION(this);
605  return m_shape;
606 }
607 
608 double
610 {
611  NS_LOG_FUNCTION(this);
612  return m_bound;
613 }
614 
615 double
616 WeibullRandomVariable::GetValue(double scale, double shape, double bound)
617 {
618  NS_LOG_FUNCTION(this << scale << shape << bound);
619  double exponent = 1.0 / shape;
620  while (true)
621  {
622  // Get a uniform random variable in [0,1].
623  double v = Peek()->RandU01();
624  if (IsAntithetic())
625  {
626  v = (1 - v);
627  }
628 
629  // Calculate the Weibull random variable.
630  double r = scale * std::pow(-std::log(v), exponent);
631 
632  // Use this value if it's acceptable.
633  if (bound == 0 || r <= bound)
634  {
635  return r;
636  }
637  }
638 }
639 
640 uint32_t
641 WeibullRandomVariable::GetInteger(uint32_t scale, uint32_t shape, uint32_t bound)
642 {
643  NS_LOG_FUNCTION(this << scale << shape << bound);
644  return static_cast<uint32_t>(GetValue(scale, shape, bound));
645 }
646 
647 double
649 {
650  NS_LOG_FUNCTION(this);
651  return GetValue(m_scale, m_shape, m_bound);
652 }
653 
655 
656 const double NormalRandomVariable::INFINITE_VALUE = 1e307;
657 
658 TypeId
660 {
661  static TypeId tid =
662  TypeId("ns3::NormalRandomVariable")
664  .SetGroupName("Core")
665  .AddConstructor<NormalRandomVariable>()
666  .AddAttribute("Mean",
667  "The mean value for the normal distribution returned by this RNG stream.",
668  DoubleValue(0.0),
670  MakeDoubleChecker<double>())
671  .AddAttribute(
672  "Variance",
673  "The variance value for the normal distribution returned by this RNG stream.",
674  DoubleValue(1.0),
676  MakeDoubleChecker<double>())
677  .AddAttribute("Bound",
678  "The bound on the values returned by this RNG stream.",
681  MakeDoubleChecker<double>());
682  return tid;
683 }
684 
686  : m_nextValid(false)
687 {
688  // m_mean, m_variance, and m_bound are initialized after constructor
689  // by attributes
690  NS_LOG_FUNCTION(this);
691 }
692 
693 double
695 {
696  NS_LOG_FUNCTION(this);
697  return m_mean;
698 }
699 
700 double
702 {
703  NS_LOG_FUNCTION(this);
704  return m_variance;
705 }
706 
707 double
709 {
710  NS_LOG_FUNCTION(this);
711  return m_bound;
712 }
713 
714 double
715 NormalRandomVariable::GetValue(double mean, double variance, double bound)
716 {
717  NS_LOG_FUNCTION(this << mean << variance << bound);
718  if (m_nextValid)
719  { // use previously generated
720  m_nextValid = false;
721  double x2 = mean + m_v2 * m_y * std::sqrt(variance);
722  if (std::fabs(x2 - mean) <= bound)
723  {
724  return x2;
725  }
726  }
727  while (true)
728  { // See Simulation Modeling and Analysis p. 466 (Averill Law)
729  // for algorithm; basically a Box-Muller transform:
730  // http://en.wikipedia.org/wiki/Box-Muller_transform
731  double u1 = Peek()->RandU01();
732  double u2 = Peek()->RandU01();
733  if (IsAntithetic())
734  {
735  u1 = (1 - u1);
736  u2 = (1 - u2);
737  }
738  double v1 = 2 * u1 - 1;
739  double v2 = 2 * u2 - 1;
740  double w = v1 * v1 + v2 * v2;
741  if (w <= 1.0)
742  { // Got good pair
743  double y = std::sqrt((-2 * std::log(w)) / w);
744  double x1 = mean + v1 * y * std::sqrt(variance);
745  // if x1 is in bounds, return it, cache v2 and y
746  if (std::fabs(x1 - mean) <= bound)
747  {
748  m_nextValid = true;
749  m_y = y;
750  m_v2 = v2;
751  return x1;
752  }
753  // otherwise try and return the other if it is valid
754  double x2 = mean + v2 * y * std::sqrt(variance);
755  if (std::fabs(x2 - mean) <= bound)
756  {
757  m_nextValid = false;
758  return x2;
759  }
760  // otherwise, just run this loop again
761  }
762  }
763 }
764 
765 uint32_t
766 NormalRandomVariable::GetInteger(uint32_t mean, uint32_t variance, uint32_t bound)
767 {
768  NS_LOG_FUNCTION(this << mean << variance << bound);
769  return static_cast<uint32_t>(GetValue(mean, variance, bound));
770 }
771 
772 double
774 {
775  NS_LOG_FUNCTION(this);
776  return GetValue(m_mean, m_variance, m_bound);
777 }
778 
780 
781 TypeId
783 {
784  static TypeId tid =
785  TypeId("ns3::LogNormalRandomVariable")
787  .SetGroupName("Core")
788  .AddConstructor<LogNormalRandomVariable>()
789  .AddAttribute(
790  "Mu",
791  "The mu value for the log-normal distribution returned by this RNG stream.",
792  DoubleValue(0.0),
794  MakeDoubleChecker<double>())
795  .AddAttribute(
796  "Sigma",
797  "The sigma value for the log-normal distribution returned by this RNG stream.",
798  DoubleValue(1.0),
800  MakeDoubleChecker<double>());
801  return tid;
802 }
803 
805  : m_nextValid(false)
806 {
807  // m_mu and m_sigma are initialized after constructor by
808  // attributes
809  NS_LOG_FUNCTION(this);
810 }
811 
812 double
814 {
815  NS_LOG_FUNCTION(this);
816  return m_mu;
817 }
818 
819 double
821 {
822  NS_LOG_FUNCTION(this);
823  return m_sigma;
824 }
825 
826 // The code from this function was adapted from the GNU Scientific
827 // Library 1.8:
828 /* randist/lognormal.c
829  *
830  * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
831  *
832  * This program is free software; you can redistribute it and/or modify
833  * it under the terms of the GNU General Public License as published by
834  * the Free Software Foundation; either version 2 of the License, or (at
835  * your option) any later version.
836  *
837  * This program is distributed in the hope that it will be useful, but
838  * WITHOUT ANY WARRANTY; without even the implied warranty of
839  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
840  * General Public License for more details.
841  *
842  * You should have received a copy of the GNU General Public License
843  * along with this program; if not, write to the Free Software
844  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
845  */
846 /* The lognormal distribution has the form
847 
848  p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
849 
850  for x > 0. Lognormal random numbers are the exponentials of
851  gaussian random numbers */
852 double
854 {
855  if (m_nextValid)
856  { // use previously generated
857  m_nextValid = false;
858  double normal = m_v2 * m_normal;
859 
860  return std::exp(sigma * normal + mu);
861  }
862 
863  double v1;
864  double v2;
865  double r2;
866  double normal;
867  double x;
868 
869  NS_LOG_FUNCTION(this << mu << sigma);
870 
871  do
872  {
873  /* choose x,y in uniform square (-1,-1) to (+1,+1) */
874 
875  double u1 = Peek()->RandU01();
876  double u2 = Peek()->RandU01();
877  if (IsAntithetic())
878  {
879  u1 = (1 - u1);
880  u2 = (1 - u2);
881  }
882 
883  v1 = -1 + 2 * u1;
884  v2 = -1 + 2 * u2;
885 
886  /* see if it is in the unit circle */
887  r2 = v1 * v1 + v2 * v2;
888  } while (r2 > 1.0 || r2 == 0);
889 
890  m_normal = std::sqrt(-2.0 * std::log(r2) / r2);
891  normal = v1 * m_normal;
892  m_nextValid = true;
893  m_v2 = v2;
894 
895  x = std::exp(sigma * normal + mu);
896 
897  return x;
898 }
899 
900 uint32_t
902 {
903  NS_LOG_FUNCTION(this << mu << sigma);
904  return static_cast<uint32_t>(GetValue(mu, sigma));
905 }
906 
907 double
909 {
910  NS_LOG_FUNCTION(this);
911  return GetValue(m_mu, m_sigma);
912 }
913 
915 
916 TypeId
918 {
919  static TypeId tid =
920  TypeId("ns3::GammaRandomVariable")
922  .SetGroupName("Core")
923  .AddConstructor<GammaRandomVariable>()
924  .AddAttribute("Alpha",
925  "The alpha value for the gamma distribution returned by this RNG stream.",
926  DoubleValue(1.0),
928  MakeDoubleChecker<double>())
929  .AddAttribute("Beta",
930  "The beta value for the gamma distribution returned by this RNG stream.",
931  DoubleValue(1.0),
933  MakeDoubleChecker<double>());
934  return tid;
935 }
936 
938  : m_nextValid(false)
939 {
940  // m_alpha and m_beta are initialized after constructor by
941  // attributes
942  NS_LOG_FUNCTION(this);
943 }
944 
945 double
947 {
948  NS_LOG_FUNCTION(this);
949  return m_alpha;
950 }
951 
952 double
954 {
955  NS_LOG_FUNCTION(this);
956  return m_beta;
957 }
958 
959 /*
960  The code for the following generator functions was adapted from ns-2
961  tools/ranvar.cc
962 
963  Originally the algorithm was devised by Marsaglia in 2000:
964  G. Marsaglia, W. W. Tsang: A simple method for generating Gamma variables
965  ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
966 
967  The Gamma distribution density function has the form
968 
969  x^(alpha-1) * exp(-x/beta)
970  p(x; alpha, beta) = ----------------------------
971  beta^alpha * Gamma(alpha)
972 
973  for x > 0.
974 */
975 double
976 GammaRandomVariable::GetValue(double alpha, double beta)
977 {
978  NS_LOG_FUNCTION(this << alpha << beta);
979  if (alpha < 1)
980  {
981  double u = Peek()->RandU01();
982  if (IsAntithetic())
983  {
984  u = (1 - u);
985  }
986  return GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
987  }
988 
989  double x;
990  double v;
991  double u;
992  double d = alpha - 1.0 / 3.0;
993  double c = (1.0 / 3.0) / std::sqrt(d);
994 
995  while (true)
996  {
997  do
998  {
999  // Get a value from a normal distribution that has mean
1000  // zero, variance 1, and no bound.
1001  double mean = 0.0;
1002  double variance = 1.0;
1003  double bound = NormalRandomVariable::INFINITE_VALUE;
1004  x = GetNormalValue(mean, variance, bound);
1005 
1006  v = 1.0 + c * x;
1007  } while (v <= 0);
1008 
1009  v = v * v * v;
1010  u = Peek()->RandU01();
1011  if (IsAntithetic())
1012  {
1013  u = (1 - u);
1014  }
1015  if (u < 1 - 0.0331 * x * x * x * x)
1016  {
1017  break;
1018  }
1019  if (std::log(u) < 0.5 * x * x + d * (1 - v + std::log(v)))
1020  {
1021  break;
1022  }
1023  }
1024 
1025  return beta * d * v;
1026 }
1027 
1028 double
1030 {
1031  NS_LOG_FUNCTION(this);
1032  return GetValue(m_alpha, m_beta);
1033 }
1034 
1035 double
1036 GammaRandomVariable::GetNormalValue(double mean, double variance, double bound)
1037 {
1038  NS_LOG_FUNCTION(this << mean << variance << bound);
1039  if (m_nextValid)
1040  { // use previously generated
1041  m_nextValid = false;
1042  double x2 = mean + m_v2 * m_y * std::sqrt(variance);
1043  if (std::fabs(x2 - mean) <= bound)
1044  {
1045  return x2;
1046  }
1047  }
1048  while (true)
1049  { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1050  // for algorithm; basically a Box-Muller transform:
1051  // http://en.wikipedia.org/wiki/Box-Muller_transform
1052  double u1 = Peek()->RandU01();
1053  double u2 = Peek()->RandU01();
1054  if (IsAntithetic())
1055  {
1056  u1 = (1 - u1);
1057  u2 = (1 - u2);
1058  }
1059  double v1 = 2 * u1 - 1;
1060  double v2 = 2 * u2 - 1;
1061  double w = v1 * v1 + v2 * v2;
1062  if (w <= 1.0)
1063  { // Got good pair
1064  double y = std::sqrt((-2 * std::log(w)) / w);
1065  double x1 = mean + v1 * y * std::sqrt(variance);
1066  // if x1 is in bounds, return it, cache v2 an y
1067  if (std::fabs(x1 - mean) <= bound)
1068  {
1069  m_nextValid = true;
1070  m_y = y;
1071  m_v2 = v2;
1072  return x1;
1073  }
1074  // otherwise try and return the other if it is valid
1075  double x2 = mean + v2 * y * std::sqrt(variance);
1076  if (std::fabs(x2 - mean) <= bound)
1077  {
1078  m_nextValid = false;
1079  return x2;
1080  }
1081  // otherwise, just run this loop again
1082  }
1083  }
1084 }
1085 
1087 
1088 TypeId
1090 {
1091  static TypeId tid =
1092  TypeId("ns3::ErlangRandomVariable")
1094  .SetGroupName("Core")
1095  .AddConstructor<ErlangRandomVariable>()
1096  .AddAttribute("K",
1097  "The k value for the Erlang distribution returned by this RNG stream.",
1098  IntegerValue(1),
1100  MakeIntegerChecker<uint32_t>())
1101  .AddAttribute(
1102  "Lambda",
1103  "The lambda value for the Erlang distribution returned by this RNG stream.",
1104  DoubleValue(1.0),
1106  MakeDoubleChecker<double>());
1107  return tid;
1108 }
1109 
1111 {
1112  // m_k and m_lambda are initialized after constructor by attributes
1113  NS_LOG_FUNCTION(this);
1114 }
1115 
1116 uint32_t
1118 {
1119  NS_LOG_FUNCTION(this);
1120  return m_k;
1121 }
1122 
1123 double
1125 {
1126  NS_LOG_FUNCTION(this);
1127  return m_lambda;
1128 }
1129 
1130 /*
1131  The code for the following generator functions was adapted from ns-2
1132  tools/ranvar.cc
1133 
1134  The Erlang distribution density function has the form
1135 
1136  x^(k-1) * exp(-x/lambda)
1137  p(x; k, lambda) = ---------------------------
1138  lambda^k * (k-1)!
1139 
1140  for x > 0.
1141 */
1142 double
1143 ErlangRandomVariable::GetValue(uint32_t k, double lambda)
1144 {
1145  NS_LOG_FUNCTION(this << k << lambda);
1146  double mean = lambda;
1147  double bound = 0.0;
1148 
1149  double result = 0;
1150  for (unsigned int i = 0; i < k; ++i)
1151  {
1152  result += GetExponentialValue(mean, bound);
1153  }
1154 
1155  return result;
1156 }
1157 
1158 uint32_t
1159 ErlangRandomVariable::GetInteger(uint32_t k, uint32_t lambda)
1160 {
1161  NS_LOG_FUNCTION(this << k << lambda);
1162  return static_cast<uint32_t>(GetValue(k, lambda));
1163 }
1164 
1165 double
1167 {
1168  NS_LOG_FUNCTION(this);
1169  return GetValue(m_k, m_lambda);
1170 }
1171 
1172 double
1174 {
1175  NS_LOG_FUNCTION(this << mean << bound);
1176  while (true)
1177  {
1178  // Get a uniform random variable in [0,1].
1179  double v = Peek()->RandU01();
1180  if (IsAntithetic())
1181  {
1182  v = (1 - v);
1183  }
1184 
1185  // Calculate the exponential random variable.
1186  double r = -mean * std::log(v);
1187 
1188  // Use this value if it's acceptable.
1189  if (bound == 0 || r <= bound)
1190  {
1191  return r;
1192  }
1193  }
1194 }
1195 
1197 
1198 TypeId
1200 {
1201  static TypeId tid =
1202  TypeId("ns3::TriangularRandomVariable")
1204  .SetGroupName("Core")
1205  .AddConstructor<TriangularRandomVariable>()
1206  .AddAttribute(
1207  "Mean",
1208  "The mean value for the triangular distribution returned by this RNG stream.",
1209  DoubleValue(0.5),
1211  MakeDoubleChecker<double>())
1212  .AddAttribute("Min",
1213  "The lower bound on the values returned by this RNG stream.",
1214  DoubleValue(0.0),
1216  MakeDoubleChecker<double>())
1217  .AddAttribute("Max",
1218  "The upper bound on the values returned by this RNG stream.",
1219  DoubleValue(1.0),
1221  MakeDoubleChecker<double>());
1222  return tid;
1223 }
1224 
1226 {
1227  // m_mean, m_min, and m_max are initialized after constructor by
1228  // attributes
1229  NS_LOG_FUNCTION(this);
1230 }
1231 
1232 double
1234 {
1235  NS_LOG_FUNCTION(this);
1236  return m_mean;
1237 }
1238 
1239 double
1241 {
1242  NS_LOG_FUNCTION(this);
1243  return m_min;
1244 }
1245 
1246 double
1248 {
1249  NS_LOG_FUNCTION(this);
1250  return m_max;
1251 }
1252 
1253 double
1254 TriangularRandomVariable::GetValue(double mean, double min, double max)
1255 {
1256  // Calculate the mode.
1257  NS_LOG_FUNCTION(this << mean << min << max);
1258  double mode = 3.0 * mean - min - max;
1259 
1260  // Get a uniform random variable in [0,1].
1261  double u = Peek()->RandU01();
1262  if (IsAntithetic())
1263  {
1264  u = (1 - u);
1265  }
1266 
1267  // Calculate the triangular random variable.
1268  if (u <= (mode - min) / (max - min))
1269  {
1270  return min + std::sqrt(u * (max - min) * (mode - min));
1271  }
1272  else
1273  {
1274  return max - std::sqrt((1 - u) * (max - min) * (max - mode));
1275  }
1276 }
1277 
1278 uint32_t
1279 TriangularRandomVariable::GetInteger(uint32_t mean, uint32_t min, uint32_t max)
1280 {
1281  NS_LOG_FUNCTION(this << mean << min << max);
1282  return static_cast<uint32_t>(GetValue(mean, min, max));
1283 }
1284 
1285 double
1287 {
1288  NS_LOG_FUNCTION(this);
1289  return GetValue(m_mean, m_min, m_max);
1290 }
1291 
1293 
1294 TypeId
1296 {
1297  static TypeId tid =
1298  TypeId("ns3::ZipfRandomVariable")
1300  .SetGroupName("Core")
1301  .AddConstructor<ZipfRandomVariable>()
1302  .AddAttribute("N",
1303  "The n value for the Zipf distribution returned by this RNG stream.",
1304  IntegerValue(1),
1306  MakeIntegerChecker<uint32_t>())
1307  .AddAttribute("Alpha",
1308  "The alpha value for the Zipf distribution returned by this RNG stream.",
1309  DoubleValue(0.0),
1311  MakeDoubleChecker<double>());
1312  return tid;
1313 }
1314 
1316 {
1317  // m_n and m_alpha are initialized after constructor by attributes
1318  NS_LOG_FUNCTION(this);
1319 }
1320 
1321 uint32_t
1323 {
1324  NS_LOG_FUNCTION(this);
1325  return m_n;
1326 }
1327 
1328 double
1330 {
1331  NS_LOG_FUNCTION(this);
1332  return m_alpha;
1333 }
1334 
1335 double
1336 ZipfRandomVariable::GetValue(uint32_t n, double alpha)
1337 {
1338  NS_LOG_FUNCTION(this << n << alpha);
1339  // Calculate the normalization constant c.
1340  m_c = 0.0;
1341  for (uint32_t i = 1; i <= n; i++)
1342  {
1343  m_c += (1.0 / std::pow((double)i, alpha));
1344  }
1345  m_c = 1.0 / m_c;
1346 
1347  // Get a uniform random variable in [0,1].
1348  double u = Peek()->RandU01();
1349  if (IsAntithetic())
1350  {
1351  u = (1 - u);
1352  }
1353 
1354  double sum_prob = 0;
1355  double zipf_value = 0;
1356  for (uint32_t i = 1; i <= m_n; i++)
1357  {
1358  sum_prob += m_c / std::pow((double)i, m_alpha);
1359  if (sum_prob > u)
1360  {
1361  zipf_value = i;
1362  break;
1363  }
1364  }
1365  return zipf_value;
1366 }
1367 
1368 uint32_t
1369 ZipfRandomVariable::GetInteger(uint32_t n, uint32_t alpha)
1370 {
1371  NS_LOG_FUNCTION(this << n << alpha);
1372  return static_cast<uint32_t>(GetValue(n, alpha));
1373 }
1374 
1375 double
1377 {
1378  NS_LOG_FUNCTION(this);
1379  return GetValue(m_n, m_alpha);
1380 }
1381 
1383 
1384 TypeId
1386 {
1387  static TypeId tid =
1388  TypeId("ns3::ZetaRandomVariable")
1390  .SetGroupName("Core")
1391  .AddConstructor<ZetaRandomVariable>()
1392  .AddAttribute("Alpha",
1393  "The alpha value for the zeta distribution returned by this RNG stream.",
1394  DoubleValue(3.14),
1396  MakeDoubleChecker<double>());
1397  return tid;
1398 }
1399 
1401 {
1402  // m_alpha is initialized after constructor by attributes
1403  NS_LOG_FUNCTION(this);
1404 }
1405 
1406 double
1408 {
1409  NS_LOG_FUNCTION(this);
1410  return m_alpha;
1411 }
1412 
1413 double
1415 {
1416  NS_LOG_FUNCTION(this << alpha);
1417  m_b = std::pow(2.0, alpha - 1.0);
1418 
1419  double u;
1420  double v;
1421  double X;
1422  double T;
1423  double test;
1424 
1425  do
1426  {
1427  // Get a uniform random variable in [0,1].
1428  u = Peek()->RandU01();
1429  if (IsAntithetic())
1430  {
1431  u = (1 - u);
1432  }
1433 
1434  // Get a uniform random variable in [0,1].
1435  v = Peek()->RandU01();
1436  if (IsAntithetic())
1437  {
1438  v = (1 - v);
1439  }
1440 
1441  X = std::floor(std::pow(u, -1.0 / (m_alpha - 1.0)));
1442  T = std::pow(1.0 + 1.0 / X, m_alpha - 1.0);
1443  test = v * X * (T - 1.0) / (m_b - 1.0);
1444  } while (test > (T / m_b));
1445 
1446  return X;
1447 }
1448 
1449 uint32_t
1451 {
1452  NS_LOG_FUNCTION(this << alpha);
1453  return static_cast<uint32_t>(GetValue(alpha));
1454 }
1455 
1456 double
1458 {
1459  NS_LOG_FUNCTION(this);
1460  return GetValue(m_alpha);
1461 }
1462 
1464 
1465 TypeId
1467 {
1468  static TypeId tid = TypeId("ns3::DeterministicRandomVariable")
1470  .SetGroupName("Core")
1471  .AddConstructor<DeterministicRandomVariable>();
1472  return tid;
1473 }
1474 
1476  : m_count(0),
1477  m_next(0),
1478  m_data(nullptr)
1479 {
1480  NS_LOG_FUNCTION(this);
1481 }
1482 
1484 {
1485  // Delete any values currently set.
1486  NS_LOG_FUNCTION(this);
1487  if (m_data != nullptr)
1488  {
1489  delete[] m_data;
1490  }
1491 }
1492 
1493 void
1494 DeterministicRandomVariable::SetValueArray(const std::vector<double>& values)
1495 {
1496  SetValueArray(values.data(), values.size());
1497 }
1498 
1499 void
1500 DeterministicRandomVariable::SetValueArray(const double* values, std::size_t length)
1501 {
1502  NS_LOG_FUNCTION(this << values << length);
1503  // Delete any values currently set.
1504  if (m_data != nullptr)
1505  {
1506  delete[] m_data;
1507  }
1508 
1509  // Make room for the values being set.
1510  m_data = new double[length];
1511  m_count = length;
1512  m_next = length;
1513 
1514  // Copy the values.
1515  for (std::size_t i = 0; i < m_count; i++)
1516  {
1517  m_data[i] = values[i];
1518  }
1519 }
1520 
1521 double
1523 {
1524  NS_LOG_FUNCTION(this);
1525  // Make sure the array has been set.
1526  NS_ASSERT(m_count > 0);
1527 
1528  if (m_next == m_count)
1529  {
1530  m_next = 0;
1531  }
1532  return m_data[m_next++];
1533 }
1534 
1536 
1537 TypeId
1539 {
1540  static TypeId tid =
1541  TypeId("ns3::EmpiricalRandomVariable")
1543  .SetGroupName("Core")
1544  .AddConstructor<EmpiricalRandomVariable>()
1545  .AddAttribute("Interpolate",
1546  "Treat the CDF as a smooth distribution and interpolate, "
1547  "default is to treat the CDF as a histogram and sample.",
1548  BooleanValue(false),
1550  MakeBooleanChecker());
1551  return tid;
1552 }
1553 
1555  : m_validated(false)
1556 {
1557  NS_LOG_FUNCTION(this);
1558 }
1559 
1560 bool
1562 {
1563  NS_LOG_FUNCTION(this << interpolate);
1564  bool prev = m_interpolate;
1565  m_interpolate = interpolate;
1566  return prev;
1567 }
1568 
1569 bool
1571 {
1572  NS_LOG_FUNCTION(this);
1573 
1574  if (!m_validated)
1575  {
1576  Validate();
1577  }
1578 
1579  // Get a uniform random variable in [0, 1].
1580  double r = Peek()->RandU01();
1581  if (IsAntithetic())
1582  {
1583  r = (1 - r);
1584  }
1585 
1586  value = r;
1587  bool valid = false;
1588  // check extrema
1589  if (r <= m_empCdf.begin()->first)
1590  {
1591  value = m_empCdf.begin()->second; // Less than first
1592  valid = true;
1593  }
1594  else if (r >= m_empCdf.rbegin()->first)
1595  {
1596  value = m_empCdf.rbegin()->second; // Greater than last
1597  valid = true;
1598  }
1599  return valid;
1600 }
1601 
1602 double
1604 {
1605  NS_LOG_FUNCTION(this);
1606 
1607  double value;
1608  if (PreSample(value))
1609  {
1610  return value;
1611  }
1612 
1613  // value now has the (unused) URNG selector
1614  if (m_interpolate)
1615  {
1616  value = DoInterpolate(value);
1617  }
1618  else
1619  {
1620  value = DoSampleCDF(value);
1621  }
1622  return value;
1623 }
1624 
1625 double
1627 {
1628  NS_LOG_FUNCTION(this << r);
1629 
1630  // Find first CDF that is greater than r
1631  auto bound = m_empCdf.upper_bound(r);
1632 
1633  return bound->second;
1634 }
1635 
1636 double
1638 {
1639  NS_LOG_FUNCTION(this);
1640 
1641  double value;
1642  if (PreSample(value))
1643  {
1644  return value;
1645  }
1646 
1647  // value now has the (unused) URNG selector
1648  value = DoInterpolate(value);
1649  return value;
1650 }
1651 
1652 double
1654 {
1655  NS_LOG_FUNCTION(this << r);
1656 
1657  // Return a value from the empirical distribution
1658  // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1659 
1660  // search
1661  auto upper = m_empCdf.upper_bound(r);
1662  auto lower = std::prev(upper, 1);
1663 
1664  if (upper == m_empCdf.begin())
1665  {
1666  lower = upper;
1667  }
1668 
1669  // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1670  double c1 = lower->first;
1671  double c2 = upper->first;
1672  double v1 = lower->second;
1673  double v2 = upper->second;
1674 
1675  double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1676  return value;
1677 }
1678 
1679 void
1680 EmpiricalRandomVariable::CDF(double v, double c)
1681 {
1682  NS_LOG_FUNCTION(this << v << c);
1683 
1684  auto vPrevious = m_empCdf.find(c);
1685 
1686  if (vPrevious != m_empCdf.end())
1687  {
1688  NS_LOG_WARN("Empirical CDF already has a value " << vPrevious->second << " for CDF " << c
1689  << ". Overwriting it with value " << v
1690  << ".");
1691  }
1692 
1693  m_empCdf[c] = v;
1694 }
1695 
1696 void
1698 {
1699  NS_LOG_FUNCTION(this);
1700 
1701  if (m_empCdf.empty())
1702  {
1703  NS_FATAL_ERROR("CDF is not initialized");
1704  }
1705 
1706  double vPrev = m_empCdf.begin()->second;
1707 
1708  // Check if values are non-decreasing
1709  for (const auto& cdfPair : m_empCdf)
1710  {
1711  const auto& vCurr = cdfPair.second;
1712 
1713  if (vCurr < vPrev)
1714  {
1715  NS_FATAL_ERROR("Empirical distribution has decreasing CDF values. Current CDF: "
1716  << vCurr << ", prior CDF: " << vPrev);
1717  }
1718 
1719  vPrev = vCurr;
1720  }
1721 
1722  // Bounds check on CDF endpoints
1723  auto firstCdfPair = m_empCdf.begin();
1724  auto lastCdfPair = m_empCdf.rbegin();
1725 
1726  if (firstCdfPair->first < 0.0)
1727  {
1728  NS_FATAL_ERROR("Empirical distribution has invalid first CDF value. CDF: "
1729  << firstCdfPair->first << ", Value: " << firstCdfPair->second);
1730  }
1731 
1732  if (lastCdfPair->first > 1.0)
1733  {
1734  NS_FATAL_ERROR("Empirical distribution has invalid last CDF value. CDF: "
1735  << lastCdfPair->first << ", Value: " << lastCdfPair->second);
1736  }
1737 
1738  m_validated = true;
1739 }
1740 
1742 
1743 TypeId
1745 {
1746  static TypeId tid =
1747  TypeId("ns3::BinomialRandomVariable")
1749  .SetGroupName("Core")
1750  .AddConstructor<BinomialRandomVariable>()
1751  .AddAttribute("Trials",
1752  "The number of trials.",
1753  IntegerValue(10),
1755  MakeIntegerChecker<uint32_t>(0))
1756  .AddAttribute("Probability",
1757  "The probability of success in each trial.",
1758  DoubleValue(0.5),
1760  MakeDoubleChecker<double>(0));
1761  return tid;
1762 }
1763 
1765 {
1766  // m_trials and m_probability are initialized after constructor by attributes
1767  NS_LOG_FUNCTION(this);
1768 }
1769 
1770 double
1771 BinomialRandomVariable::GetValue(uint32_t trials, double probability)
1772 {
1773  NS_LOG_FUNCTION(this << trials << probability);
1774 
1775  double successes = 0;
1776 
1777  for (uint32_t i = 0; i < trials; ++i)
1778  {
1779  double v = Peek()->RandU01();
1780  if (IsAntithetic())
1781  {
1782  v = (1 - v);
1783  }
1784 
1785  if (v <= probability)
1786  {
1787  successes += 1;
1788  }
1789  }
1790 
1791  return successes;
1792 }
1793 
1794 uint32_t
1795 BinomialRandomVariable::GetInteger(uint32_t trials, uint32_t probability)
1796 {
1797  NS_LOG_FUNCTION(this << trials << probability);
1798  return static_cast<uint32_t>(GetValue(trials, probability));
1799 }
1800 
1801 double
1803 {
1804  NS_LOG_FUNCTION(this);
1805  return GetValue(m_trials, m_probability);
1806 }
1807 
1809 
1810 TypeId
1812 {
1813  static TypeId tid =
1814  TypeId("ns3::BernoulliRandomVariable")
1816  .SetGroupName("Core")
1817  .AddConstructor<BernoulliRandomVariable>()
1818  .AddAttribute("Probability",
1819  "The probability of the random variable returning a value of 1.",
1820  DoubleValue(0.5),
1822  MakeDoubleChecker<double>(0));
1823  return tid;
1824 }
1825 
1827 {
1828  // m_probability is initialized after constructor by attributes
1829  NS_LOG_FUNCTION(this);
1830 }
1831 
1832 double
1834 {
1835  NS_LOG_FUNCTION(this << probability);
1836 
1837  double v = Peek()->RandU01();
1838  if (IsAntithetic())
1839  {
1840  v = (1 - v);
1841  }
1842 
1843  return (v <= probability) ? 1.0 : 0.0;
1844 }
1845 
1846 uint32_t
1848 {
1849  NS_LOG_FUNCTION(this << probability);
1850  return static_cast<uint32_t>(GetValue(probability));
1851 }
1852 
1853 double
1855 {
1856  NS_LOG_FUNCTION(this);
1857  return GetValue(m_probability);
1858 }
1859 
1860 } // namespace ns3
#define min(a, b)
Definition: 80211b.c:41
#define max(a, b)
Definition: 80211b.c:42
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
ns3::BooleanValue attribute value declarations.
The Bernoulli distribution Random Number Generator (RNG).
double GetValue() override
Get the next random value drawn from the distribution.
double m_probability
The probability of success.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
The binomial distribution Random Number Generator (RNG).
double m_probability
The probability of success in each trial.
double GetValue() override
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
uint32_t m_trials
The number of trials.
The Random Number Generator (RNG) that returns a constant.
static TypeId GetTypeId()
Register this type.
double GetValue() override
Get the next random value drawn from the distribution.
ConstantRandomVariable()
Creates a constant RNG with the default constant value.
double GetConstant() const
Get the constant value returned by this RNG stream.
double m_constant
The constant value returned by this RNG stream.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
The Random Number Generator (RNG) that returns a predetermined sequence.
double GetValue() override
Get the next random value drawn from the distribution.
std::size_t m_next
Position of the next value in the array of values.
void SetValueArray(const std::vector< double > &values)
Sets the array of values that holds the predetermined sequence.
static TypeId GetTypeId()
Register this type.
double * m_data
Array of values to return in sequence.
DeterministicRandomVariable()
Creates a deterministic RNG that will have a predetermined sequence of values.
std::size_t m_count
Size of the array of values.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
The Random Number Generator (RNG) that has a specified empirical distribution.
bool SetInterpolate(bool interpolate)
Switch the mode between sampling the CDF and interpolating.
void CDF(double v, double c)
Specifies a point in the empirical distribution.
bool PreSample(double &value)
Do the initial rng draw and check against the extrema.
double DoSampleCDF(double r)
Sample the CDF as a histogram (without interpolation).
double GetValue() override
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
bool m_interpolate
If true GetValue will interpolate, otherwise treat CDF as normal histogram.
bool m_validated
true once the CDF has been validated.
double DoInterpolate(double r)
Linear interpolation between two points on the CDF to estimate the value at r.
virtual double Interpolate()
Returns the next value in the empirical distribution using linear interpolation.
EmpiricalRandomVariable()
Creates an empirical RNG that has a specified, empirical distribution, and configured for interpolati...
void Validate()
Check that the CDF is valid.
std::map< double, double > m_empCdf
The map of CDF points (x, F(x)).
The Erlang distribution Random Number Generator (RNG) that allows stream numbers to be set determinis...
double m_lambda
The lambda value for the Erlang distribution returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
double GetExponentialValue(double mean, double bound)
Returns a random double from an exponential distribution with the specified mean and upper bound.
static TypeId GetTypeId()
Register this type.
uint32_t GetK() const
Returns the k value for the Erlang distribution returned by this RNG stream.
double GetLambda() const
Returns the lambda value for the Erlang distribution returned by this RNG stream.
uint32_t m_k
The k value for the Erlang distribution returned by this RNG stream.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
ErlangRandomVariable()
Creates an Erlang distribution RNG with the default values for k and lambda.
The exponential distribution Random Number Generator (RNG).
ExponentialRandomVariable()
Creates an exponential distribution RNG with the default values for the mean and upper bound.
double GetBound() const
Get the configured upper bound of this RNG.
double m_mean
The mean value of the unbounded exponential distribution.
double GetMean() const
Get the configured mean value of this RNG.
double m_bound
The upper bound on values that can be returned by this RNG stream.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
double GetValue() override
Get the next random value drawn from the distribution.
The gamma distribution Random Number Generator (RNG) that allows stream numbers to be set determinist...
double GetValue() override
Get the next random value drawn from the distribution.
GammaRandomVariable()
Creates a gamma distribution RNG with the default values for alpha and beta.
double m_alpha
The alpha value for the gamma distribution returned by this RNG stream.
double GetNormalValue(double mean, double variance, double bound)
Returns a random double from a normal distribution with the specified mean, variance,...
double m_y
The algorithm produces two values at a time.
double m_v2
The algorithm produces two values at a time.
bool m_nextValid
True if the next normal value is valid.
static TypeId GetTypeId()
Register this type.
double GetAlpha() const
Returns the alpha value for the gamma distribution returned by this RNG stream.
double GetBeta() const
Returns the beta value for the gamma distribution returned by this RNG stream.
double m_beta
The beta value for the gamma distribution returned by this RNG stream.
Hold a signed integer type.
Definition: integer.h:45
The log-normal distribution Random Number Generator (RNG) that allows stream numbers to be set determ...
double GetMu() const
Returns the mu value for the log-normal distribution returned by this RNG stream.
double m_v2
The algorithm produces two values at a time.
double GetSigma() const
Returns the sigma value for the log-normal distribution returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
bool m_nextValid
True if m_normal is valid.
double m_mu
The mu value for the log-normal distribution returned by this RNG stream.
double m_sigma
The sigma value for the log-normal distribution returned by this RNG stream.
LogNormalRandomVariable()
Creates a log-normal distribution RNG with the default values for mu and sigma.
double m_normal
The algorithm produces two values at a time.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
The normal (Gaussian) distribution Random Number Generator (RNG) that allows stream numbers to be set...
double m_y
The algorithm produces two values at a time.
double GetBound() const
Returns the bound on values that can be returned by this RNG stream.
double GetVariance() const
Returns the variance value for the normal distribution returned by this RNG stream.
double m_mean
The mean value for the normal distribution returned by this RNG stream.
static TypeId GetTypeId()
Register this type.
double GetMean() const
Returns the mean value for the normal distribution returned by this RNG stream.
static const double INFINITE_VALUE
Large constant to bound the range.
double m_variance
The variance value for the normal distribution returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
double m_bound
The bound on values that can be returned by this RNG stream.
bool m_nextValid
True if the next value is valid.
NormalRandomVariable()
Creates a normal distribution RNG with the default values for the mean, variance, and bound.
double m_v2
The algorithm produces two values at a time.
A base class which provides memory management and object aggregation.
Definition: object.h:89
The Pareto distribution Random Number Generator (RNG).
double GetShape() const
Returns the shape parameter for the Pareto distribution returned by this RNG stream.
double m_scale
The scale parameter for the Pareto distribution returned by this RNG stream.
ParetoRandomVariable()
Creates a Pareto distribution RNG with the default values for the mean, the shape,...
static TypeId GetTypeId()
Register this type.
double m_shape
The shape parameter for the Pareto distribution returned by this RNG stream.
double GetScale() const
Returns the scale parameter for the Pareto distribution returned by this RNG stream.
double m_bound
The upper bound on values that can be returned by this RNG stream.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
double GetValue() override
Get the next random value drawn from the distribution.
double GetBound() const
Returns the upper bound on values that can be returned by this RNG stream.
The basic uniform Random Number Generator (RNG).
static TypeId GetTypeId()
Register this type.
RngStream * Peek() const
Get the pointer to the underlying RngStream.
bool IsAntithetic() const
Check if antithetic values will be generated.
virtual double GetValue()=0
Get the next random value drawn from the distribution.
~RandomVariableStream() override
Destructor.
bool m_isAntithetic
Indicates if antithetic values should be generated by this RNG stream.
void SetAntithetic(bool isAntithetic)
Specify whether antithetic values should be generated.
int64_t m_stream
The stream number for the RngStream.
RandomVariableStream()
Default constructor.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
RngStream * m_rng
Pointer to the underlying RngStream.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
int64_t GetStream() const
Returns the stream number for the RngStream.
static uint64_t GetNextStreamIndex()
Get the next automatically assigned stream index.
static uint64_t GetRun()
Get the current run number.
static uint32_t GetSeed()
Get the current seed value which will be used by all subsequently instantiated RandomVariableStream o...
Combined Multiple-Recursive Generator MRG32k3a.
Definition: rng-stream.h:50
double RandU01()
Generate the next random number for this stream.
Definition: rng-stream.cc:341
The Random Number Generator (RNG) that returns a pattern of sequential values.
uint32_t m_currentConsecutive
The number of times the current distinct value has been repeated.
double m_min
The first value of the sequence.
Ptr< RandomVariableStream > GetIncrement() const
Get the increment for the sequence.
uint32_t m_consecutive
The number of times each distinct value is repeated.
static TypeId GetTypeId()
Register this type.
double m_current
The current sequence value.
double m_max
Strict upper bound on the sequence.
Ptr< RandomVariableStream > m_increment
Increment between distinct values.
double GetValue() override
Get the next random value drawn from the distribution.
uint32_t GetConsecutive() const
Get the number of times each distinct value of the sequence is repeated before incrementing to the ne...
double GetMax() const
Get the limit of the sequence, which is (at least) one more than the last value of the sequence.
SequentialRandomVariable()
Creates a sequential RNG with the default values for the sequence parameters.
double GetMin() const
Get the first value of the sequence.
bool m_isCurrentSet
Indicates if the current sequence value has been properly initialized.
Hold variables of type string.
Definition: string.h:56
The triangular distribution Random Number Generator (RNG) that allows stream numbers to be set determ...
double GetValue() override
Get the next random value drawn from the distribution.
double GetMean() const
Returns the mean value for the triangular distribution returned by this RNG stream.
static TypeId GetTypeId()
Register this type.
double m_mean
The mean value for the triangular distribution returned by this RNG stream.
double m_max
The upper bound on values that can be returned by this RNG stream.
double GetMax() const
Returns the upper bound on values that can be returned by this RNG stream.
TriangularRandomVariable()
Creates a triangular distribution RNG with the default values for the mean, lower bound,...
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
double m_min
The lower bound on values that can be returned by this RNG stream.
double GetMin() const
Returns the lower bound for the triangular distribution returned by this RNG stream.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
The uniform distribution Random Number Generator (RNG).
UniformRandomVariable()
Creates a uniform distribution RNG with the default range.
uint32_t GetInteger() override
Get the next random value drawn from the distribution.
double GetMax() const
Get the upper bound on values returned by GetValue().
double m_min
The lower bound on values that can be returned by this RNG stream.
double m_max
The upper bound on values that can be returned by this RNG stream.
static TypeId GetTypeId()
Register this type.
double GetValue() override
Get the next random value drawn from the distribution.
double GetMin() const
Get the lower bound on randoms returned by GetValue().
The Weibull distribution Random Number Generator (RNG) which allows stream numbers to be set determin...
double m_shape
The shape parameter for the Weibull distribution returned by this RNG stream.
double m_bound
The upper bound on values that can be returned by this RNG stream.
double m_scale
The scale parameter for the Weibull distribution returned by this RNG stream.
double GetBound() const
Returns the upper bound on values that can be returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
WeibullRandomVariable()
Creates a Weibull distribution RNG with the default values for the scale, shape, and upper bound.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
double GetScale() const
Returns the scale parameter for the Weibull distribution returned by this RNG stream.
double GetShape() const
Returns the shape parameter for the Weibull distribution returned by this RNG stream.
The zeta distribution Random Number Generator (RNG) that allows stream numbers to be set deterministi...
static TypeId GetTypeId()
Register this type.
double m_alpha
The alpha value for the zeta distribution returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
ZetaRandomVariable()
Creates a zeta distribution RNG with the default value for alpha.
double GetAlpha() const
Returns the alpha value for the zeta distribution returned by this RNG stream.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
double m_b
Just for calculus simplifications.
The Zipf distribution Random Number Generator (RNG) that allows stream numbers to be set deterministi...
uint32_t GetN() const
Returns the n value for the Zipf distribution returned by this RNG stream.
static TypeId GetTypeId()
Register this type.
double m_c
The normalization constant.
double GetAlpha() const
Returns the alpha value for the Zipf distribution returned by this RNG stream.
ZipfRandomVariable()
Creates a Zipf distribution RNG with the default values for n and alpha.
double m_alpha
The alpha value for the Zipf distribution returned by this RNG stream.
uint32_t m_n
The n value for the Zipf distribution returned by this RNG stream.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
double GetValue() override
Get the next random value drawn from the distribution.
ns3::DoubleValue attribute value declarations and template implementations.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
ns3::IntegerValue attribute value declarations and template implementations.
Debug message logging.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:46
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
@ normal
Definition: ff-mac-common.h:84
ns3::PointerValue attribute value declarations and template implementations.
ns3::RandomVariableStream declaration, and related classes.
ns3::RngSeedManager declaration.
ns3::RngStream declaration.
ns3::StringValue attribute value declarations.
uint32_t prev