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 (1)
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 (1)
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 (1)
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 (1)
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 {
806  // m_mu and m_sigma are initialized after constructor by
807  // attributes
808  NS_LOG_FUNCTION(this);
809 }
810 
811 double
813 {
814  NS_LOG_FUNCTION(this);
815  return m_mu;
816 }
817 
818 double
820 {
821  NS_LOG_FUNCTION(this);
822  return m_sigma;
823 }
824 
825 // The code from this function was adapted from the GNU Scientific
826 // Library 1.8:
827 /* randist/lognormal.c
828  *
829  * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
830  *
831  * This program is free software; you can redistribute it and/or modify
832  * it under the terms of the GNU General Public License as published by
833  * the Free Software Foundation; either version 2 of the License, or (at
834  * your option) any later version.
835  *
836  * This program is distributed in the hope that it will be useful, but
837  * WITHOUT ANY WARRANTY; without even the implied warranty of
838  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
839  * General Public License for more details.
840  *
841  * You should have received a copy of the GNU General Public License
842  * along with this program; if not, write to the Free Software
843  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
844  */
845 /* The lognormal distribution has the form
846 
847  p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
848 
849  for x > 0. Lognormal random numbers are the exponentials of
850  gaussian random numbers */
851 double
853 {
854  double v1;
855  double v2;
856  double r2;
857  double normal;
858  double x;
859 
860  NS_LOG_FUNCTION(this << mu << sigma);
861 
862  do
863  {
864  /* choose x,y in uniform square (-1,-1) to (+1,+1) */
865 
866  double u1 = Peek()->RandU01();
867  double u2 = Peek()->RandU01();
868  if (IsAntithetic())
869  {
870  u1 = (1 - u1);
871  u2 = (1 - u2);
872  }
873 
874  v1 = -1 + 2 * u1;
875  v2 = -1 + 2 * u2;
876 
877  /* see if it is in the unit circle */
878  r2 = v1 * v1 + v2 * v2;
879  } while (r2 > 1.0 || r2 == 0);
880 
881  normal = v1 * std::sqrt(-2.0 * std::log(r2) / r2);
882 
883  x = std::exp(sigma * normal + mu);
884 
885  return x;
886 }
887 
888 uint32_t
890 {
891  NS_LOG_FUNCTION(this << mu << sigma);
892  return static_cast<uint32_t>(GetValue(mu, sigma));
893 }
894 
895 double
897 {
898  NS_LOG_FUNCTION(this);
899  return GetValue(m_mu, m_sigma);
900 }
901 
903 
904 TypeId
906 {
907  static TypeId tid =
908  TypeId("ns3::GammaRandomVariable")
910  .SetGroupName("Core")
911  .AddConstructor<GammaRandomVariable>()
912  .AddAttribute("Alpha",
913  "The alpha value for the gamma distribution returned by this RNG stream.",
914  DoubleValue(1.0),
916  MakeDoubleChecker<double>())
917  .AddAttribute("Beta",
918  "The beta value for the gamma distribution returned by this RNG stream.",
919  DoubleValue(1.0),
921  MakeDoubleChecker<double>());
922  return tid;
923 }
924 
926  : m_nextValid(false)
927 {
928  // m_alpha and m_beta are initialized after constructor by
929  // attributes
930  NS_LOG_FUNCTION(this);
931 }
932 
933 double
935 {
936  NS_LOG_FUNCTION(this);
937  return m_alpha;
938 }
939 
940 double
942 {
943  NS_LOG_FUNCTION(this);
944  return m_beta;
945 }
946 
947 /*
948  The code for the following generator functions was adapted from ns-2
949  tools/ranvar.cc
950 
951  Originally the algorithm was devised by Marsaglia in 2000:
952  G. Marsaglia, W. W. Tsang: A simple method for generating Gamma variables
953  ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
954 
955  The Gamma distribution density function has the form
956 
957  x^(alpha-1) * exp(-x/beta)
958  p(x; alpha, beta) = ----------------------------
959  beta^alpha * Gamma(alpha)
960 
961  for x > 0.
962 */
963 double
964 GammaRandomVariable::GetValue(double alpha, double beta)
965 {
966  NS_LOG_FUNCTION(this << alpha << beta);
967  if (alpha < 1)
968  {
969  double u = Peek()->RandU01();
970  if (IsAntithetic())
971  {
972  u = (1 - u);
973  }
974  return GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
975  }
976 
977  double x;
978  double v;
979  double u;
980  double d = alpha - 1.0 / 3.0;
981  double c = (1.0 / 3.0) / std::sqrt(d);
982 
983  while (1)
984  {
985  do
986  {
987  // Get a value from a normal distribution that has mean
988  // zero, variance 1, and no bound.
989  double mean = 0.0;
990  double variance = 1.0;
992  x = GetNormalValue(mean, variance, bound);
993 
994  v = 1.0 + c * x;
995  } while (v <= 0);
996 
997  v = v * v * v;
998  u = Peek()->RandU01();
999  if (IsAntithetic())
1000  {
1001  u = (1 - u);
1002  }
1003  if (u < 1 - 0.0331 * x * x * x * x)
1004  {
1005  break;
1006  }
1007  if (std::log(u) < 0.5 * x * x + d * (1 - v + std::log(v)))
1008  {
1009  break;
1010  }
1011  }
1012 
1013  return beta * d * v;
1014 }
1015 
1016 double
1018 {
1019  NS_LOG_FUNCTION(this);
1020  return GetValue(m_alpha, m_beta);
1021 }
1022 
1023 double
1024 GammaRandomVariable::GetNormalValue(double mean, double variance, double bound)
1025 {
1026  NS_LOG_FUNCTION(this << mean << variance << bound);
1027  if (m_nextValid)
1028  { // use previously generated
1029  m_nextValid = false;
1030  double x2 = mean + m_v2 * m_y * std::sqrt(variance);
1031  if (std::fabs(x2 - mean) <= bound)
1032  {
1033  return x2;
1034  }
1035  }
1036  while (1)
1037  { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1038  // for algorithm; basically a Box-Muller transform:
1039  // http://en.wikipedia.org/wiki/Box-Muller_transform
1040  double u1 = Peek()->RandU01();
1041  double u2 = Peek()->RandU01();
1042  if (IsAntithetic())
1043  {
1044  u1 = (1 - u1);
1045  u2 = (1 - u2);
1046  }
1047  double v1 = 2 * u1 - 1;
1048  double v2 = 2 * u2 - 1;
1049  double w = v1 * v1 + v2 * v2;
1050  if (w <= 1.0)
1051  { // Got good pair
1052  double y = std::sqrt((-2 * std::log(w)) / w);
1053  double x1 = mean + v1 * y * std::sqrt(variance);
1054  // if x1 is in bounds, return it, cache v2 an y
1055  if (std::fabs(x1 - mean) <= bound)
1056  {
1057  m_nextValid = true;
1058  m_y = y;
1059  m_v2 = v2;
1060  return x1;
1061  }
1062  // otherwise try and return the other if it is valid
1063  double x2 = mean + v2 * y * std::sqrt(variance);
1064  if (std::fabs(x2 - mean) <= bound)
1065  {
1066  m_nextValid = false;
1067  return x2;
1068  }
1069  // otherwise, just run this loop again
1070  }
1071  }
1072 }
1073 
1075 
1076 TypeId
1078 {
1079  static TypeId tid =
1080  TypeId("ns3::ErlangRandomVariable")
1082  .SetGroupName("Core")
1083  .AddConstructor<ErlangRandomVariable>()
1084  .AddAttribute("K",
1085  "The k value for the Erlang distribution returned by this RNG stream.",
1086  IntegerValue(1),
1088  MakeIntegerChecker<uint32_t>())
1089  .AddAttribute(
1090  "Lambda",
1091  "The lambda value for the Erlang distribution returned by this RNG stream.",
1092  DoubleValue(1.0),
1094  MakeDoubleChecker<double>());
1095  return tid;
1096 }
1097 
1099 {
1100  // m_k and m_lambda are initialized after constructor by attributes
1101  NS_LOG_FUNCTION(this);
1102 }
1103 
1104 uint32_t
1106 {
1107  NS_LOG_FUNCTION(this);
1108  return m_k;
1109 }
1110 
1111 double
1113 {
1114  NS_LOG_FUNCTION(this);
1115  return m_lambda;
1116 }
1117 
1118 /*
1119  The code for the following generator functions was adapted from ns-2
1120  tools/ranvar.cc
1121 
1122  The Erlang distribution density function has the form
1123 
1124  x^(k-1) * exp(-x/lambda)
1125  p(x; k, lambda) = ---------------------------
1126  lambda^k * (k-1)!
1127 
1128  for x > 0.
1129 */
1130 double
1131 ErlangRandomVariable::GetValue(uint32_t k, double lambda)
1132 {
1133  NS_LOG_FUNCTION(this << k << lambda);
1134  double mean = lambda;
1135  double bound = 0.0;
1136 
1137  double result = 0;
1138  for (unsigned int i = 0; i < k; ++i)
1139  {
1140  result += GetExponentialValue(mean, bound);
1141  }
1142 
1143  return result;
1144 }
1145 
1146 uint32_t
1147 ErlangRandomVariable::GetInteger(uint32_t k, uint32_t lambda)
1148 {
1149  NS_LOG_FUNCTION(this << k << lambda);
1150  return static_cast<uint32_t>(GetValue(k, lambda));
1151 }
1152 
1153 double
1155 {
1156  NS_LOG_FUNCTION(this);
1157  return GetValue(m_k, m_lambda);
1158 }
1159 
1160 double
1162 {
1163  NS_LOG_FUNCTION(this << mean << bound);
1164  while (1)
1165  {
1166  // Get a uniform random variable in [0,1].
1167  double v = Peek()->RandU01();
1168  if (IsAntithetic())
1169  {
1170  v = (1 - v);
1171  }
1172 
1173  // Calculate the exponential random variable.
1174  double r = -mean * std::log(v);
1175 
1176  // Use this value if it's acceptable.
1177  if (bound == 0 || r <= bound)
1178  {
1179  return r;
1180  }
1181  }
1182 }
1183 
1185 
1186 TypeId
1188 {
1189  static TypeId tid =
1190  TypeId("ns3::TriangularRandomVariable")
1192  .SetGroupName("Core")
1193  .AddConstructor<TriangularRandomVariable>()
1194  .AddAttribute(
1195  "Mean",
1196  "The mean value for the triangular distribution returned by this RNG stream.",
1197  DoubleValue(0.5),
1199  MakeDoubleChecker<double>())
1200  .AddAttribute("Min",
1201  "The lower bound on the values returned by this RNG stream.",
1202  DoubleValue(0.0),
1204  MakeDoubleChecker<double>())
1205  .AddAttribute("Max",
1206  "The upper bound on the values returned by this RNG stream.",
1207  DoubleValue(1.0),
1209  MakeDoubleChecker<double>());
1210  return tid;
1211 }
1212 
1214 {
1215  // m_mean, m_min, and m_max are initialized after constructor by
1216  // attributes
1217  NS_LOG_FUNCTION(this);
1218 }
1219 
1220 double
1222 {
1223  NS_LOG_FUNCTION(this);
1224  return m_mean;
1225 }
1226 
1227 double
1229 {
1230  NS_LOG_FUNCTION(this);
1231  return m_min;
1232 }
1233 
1234 double
1236 {
1237  NS_LOG_FUNCTION(this);
1238  return m_max;
1239 }
1240 
1241 double
1242 TriangularRandomVariable::GetValue(double mean, double min, double max)
1243 {
1244  // Calculate the mode.
1245  NS_LOG_FUNCTION(this << mean << min << max);
1246  double mode = 3.0 * mean - min - max;
1247 
1248  // Get a uniform random variable in [0,1].
1249  double u = Peek()->RandU01();
1250  if (IsAntithetic())
1251  {
1252  u = (1 - u);
1253  }
1254 
1255  // Calculate the triangular random variable.
1256  if (u <= (mode - min) / (max - min))
1257  {
1258  return min + std::sqrt(u * (max - min) * (mode - min));
1259  }
1260  else
1261  {
1262  return max - std::sqrt((1 - u) * (max - min) * (max - mode));
1263  }
1264 }
1265 
1266 uint32_t
1267 TriangularRandomVariable::GetInteger(uint32_t mean, uint32_t min, uint32_t max)
1268 {
1269  NS_LOG_FUNCTION(this << mean << min << max);
1270  return static_cast<uint32_t>(GetValue(mean, min, max));
1271 }
1272 
1273 double
1275 {
1276  NS_LOG_FUNCTION(this);
1277  return GetValue(m_mean, m_min, m_max);
1278 }
1279 
1281 
1282 TypeId
1284 {
1285  static TypeId tid =
1286  TypeId("ns3::ZipfRandomVariable")
1288  .SetGroupName("Core")
1289  .AddConstructor<ZipfRandomVariable>()
1290  .AddAttribute("N",
1291  "The n value for the Zipf distribution returned by this RNG stream.",
1292  IntegerValue(1),
1294  MakeIntegerChecker<uint32_t>())
1295  .AddAttribute("Alpha",
1296  "The alpha value for the Zipf distribution returned by this RNG stream.",
1297  DoubleValue(0.0),
1299  MakeDoubleChecker<double>());
1300  return tid;
1301 }
1302 
1304 {
1305  // m_n and m_alpha are initialized after constructor by attributes
1306  NS_LOG_FUNCTION(this);
1307 }
1308 
1309 uint32_t
1311 {
1312  NS_LOG_FUNCTION(this);
1313  return m_n;
1314 }
1315 
1316 double
1318 {
1319  NS_LOG_FUNCTION(this);
1320  return m_alpha;
1321 }
1322 
1323 double
1324 ZipfRandomVariable::GetValue(uint32_t n, double alpha)
1325 {
1326  NS_LOG_FUNCTION(this << n << alpha);
1327  // Calculate the normalization constant c.
1328  m_c = 0.0;
1329  for (uint32_t i = 1; i <= n; i++)
1330  {
1331  m_c += (1.0 / std::pow((double)i, alpha));
1332  }
1333  m_c = 1.0 / m_c;
1334 
1335  // Get a uniform random variable in [0,1].
1336  double u = Peek()->RandU01();
1337  if (IsAntithetic())
1338  {
1339  u = (1 - u);
1340  }
1341 
1342  double sum_prob = 0;
1343  double zipf_value = 0;
1344  for (uint32_t i = 1; i <= m_n; i++)
1345  {
1346  sum_prob += m_c / std::pow((double)i, m_alpha);
1347  if (sum_prob > u)
1348  {
1349  zipf_value = i;
1350  break;
1351  }
1352  }
1353  return zipf_value;
1354 }
1355 
1356 uint32_t
1357 ZipfRandomVariable::GetInteger(uint32_t n, uint32_t alpha)
1358 {
1359  NS_LOG_FUNCTION(this << n << alpha);
1360  return static_cast<uint32_t>(GetValue(n, alpha));
1361 }
1362 
1363 double
1365 {
1366  NS_LOG_FUNCTION(this);
1367  return GetValue(m_n, m_alpha);
1368 }
1369 
1371 
1372 TypeId
1374 {
1375  static TypeId tid =
1376  TypeId("ns3::ZetaRandomVariable")
1378  .SetGroupName("Core")
1379  .AddConstructor<ZetaRandomVariable>()
1380  .AddAttribute("Alpha",
1381  "The alpha value for the zeta distribution returned by this RNG stream.",
1382  DoubleValue(3.14),
1384  MakeDoubleChecker<double>());
1385  return tid;
1386 }
1387 
1389 {
1390  // m_alpha is initialized after constructor by attributes
1391  NS_LOG_FUNCTION(this);
1392 }
1393 
1394 double
1396 {
1397  NS_LOG_FUNCTION(this);
1398  return m_alpha;
1399 }
1400 
1401 double
1403 {
1404  NS_LOG_FUNCTION(this << alpha);
1405  m_b = std::pow(2.0, alpha - 1.0);
1406 
1407  double u;
1408  double v;
1409  double X;
1410  double T;
1411  double test;
1412 
1413  do
1414  {
1415  // Get a uniform random variable in [0,1].
1416  u = Peek()->RandU01();
1417  if (IsAntithetic())
1418  {
1419  u = (1 - u);
1420  }
1421 
1422  // Get a uniform random variable in [0,1].
1423  v = Peek()->RandU01();
1424  if (IsAntithetic())
1425  {
1426  v = (1 - v);
1427  }
1428 
1429  X = std::floor(std::pow(u, -1.0 / (m_alpha - 1.0)));
1430  T = std::pow(1.0 + 1.0 / X, m_alpha - 1.0);
1431  test = v * X * (T - 1.0) / (m_b - 1.0);
1432  } while (test > (T / m_b));
1433 
1434  return X;
1435 }
1436 
1437 uint32_t
1439 {
1440  NS_LOG_FUNCTION(this << alpha);
1441  return static_cast<uint32_t>(GetValue(alpha));
1442 }
1443 
1444 double
1446 {
1447  NS_LOG_FUNCTION(this);
1448  return GetValue(m_alpha);
1449 }
1450 
1452 
1453 TypeId
1455 {
1456  static TypeId tid = TypeId("ns3::DeterministicRandomVariable")
1458  .SetGroupName("Core")
1459  .AddConstructor<DeterministicRandomVariable>();
1460  return tid;
1461 }
1462 
1464  : m_count(0),
1465  m_next(0),
1466  m_data(nullptr)
1467 {
1468  NS_LOG_FUNCTION(this);
1469 }
1470 
1472 {
1473  // Delete any values currently set.
1474  NS_LOG_FUNCTION(this);
1475  if (m_data != nullptr)
1476  {
1477  delete[] m_data;
1478  }
1479 }
1480 
1481 void
1482 DeterministicRandomVariable::SetValueArray(const std::vector<double>& values)
1483 {
1484  SetValueArray(values.data(), values.size());
1485 }
1486 
1487 void
1488 DeterministicRandomVariable::SetValueArray(const double* values, std::size_t length)
1489 {
1490  NS_LOG_FUNCTION(this << values << length);
1491  // Delete any values currently set.
1492  if (m_data != nullptr)
1493  {
1494  delete[] m_data;
1495  }
1496 
1497  // Make room for the values being set.
1498  m_data = new double[length];
1499  m_count = length;
1500  m_next = length;
1501 
1502  // Copy the values.
1503  for (std::size_t i = 0; i < m_count; i++)
1504  {
1505  m_data[i] = values[i];
1506  }
1507 }
1508 
1509 double
1511 {
1512  NS_LOG_FUNCTION(this);
1513  // Make sure the array has been set.
1514  NS_ASSERT(m_count > 0);
1515 
1516  if (m_next == m_count)
1517  {
1518  m_next = 0;
1519  }
1520  return m_data[m_next++];
1521 }
1522 
1524 
1525 // ValueCDF methods
1527  : value(0.0),
1528  cdf(0.0)
1529 {
1530  NS_LOG_FUNCTION(this);
1531 }
1532 
1534  : value(v),
1535  cdf(c)
1536 {
1537  NS_LOG_FUNCTION(this << v << c);
1538  NS_ASSERT(c >= 0.0 && c <= 1.0);
1539 }
1540 
1541 bool
1543 {
1544  return a.cdf < b.cdf;
1545 }
1546 
1547 TypeId
1549 {
1550  static TypeId tid =
1551  TypeId("ns3::EmpiricalRandomVariable")
1553  .SetGroupName("Core")
1554  .AddConstructor<EmpiricalRandomVariable>()
1555  .AddAttribute("Interpolate",
1556  "Treat the CDF as a smooth distribution and interpolate, "
1557  "default is to treat the CDF as a histogram and sample.",
1558  BooleanValue(false),
1560  MakeBooleanChecker());
1561  return tid;
1562 }
1563 
1565  : m_validated(false)
1566 {
1567  NS_LOG_FUNCTION(this);
1568 }
1569 
1570 bool
1572 {
1573  NS_LOG_FUNCTION(this << interpolate);
1574  bool prev = m_interpolate;
1575  m_interpolate = interpolate;
1576  return prev;
1577 }
1578 
1579 bool
1581 {
1582  NS_LOG_FUNCTION(this);
1583 
1584  if (!m_validated)
1585  {
1586  Validate();
1587  }
1588 
1589  // Get a uniform random variable in [0, 1].
1590  double r = Peek()->RandU01();
1591  if (IsAntithetic())
1592  {
1593  r = (1 - r);
1594  }
1595 
1596  value = r;
1597  bool valid = false;
1598  // check extrema
1599  if (r <= m_emp.front().cdf)
1600  {
1601  value = m_emp.front().value; // Less than first
1602  valid = true;
1603  }
1604  else if (r >= m_emp.back().cdf)
1605  {
1606  value = m_emp.back().value; // Greater than last
1607  valid = true;
1608  }
1609  return valid;
1610 }
1611 
1612 double
1614 {
1615  NS_LOG_FUNCTION(this);
1616 
1617  double value;
1618  if (PreSample(value))
1619  {
1620  return value;
1621  }
1622 
1623  // value now has the (unused) URNG selector
1624  if (m_interpolate)
1625  {
1627  }
1628  else
1629  {
1630  value = DoSampleCDF(value);
1631  }
1632  return value;
1633 }
1634 
1635 double
1637 {
1638  NS_LOG_FUNCTION(this << r);
1639 
1640  ValueCDF selector(0, r);
1641  auto bound = std::upper_bound(m_emp.begin(), m_emp.end(), selector);
1642 
1643  return bound->value;
1644 }
1645 
1646 double
1648 {
1649  NS_LOG_FUNCTION(this);
1650 
1651  double value;
1652  if (PreSample(value))
1653  {
1654  return value;
1655  }
1656 
1657  // value now has the (unused) URNG selector
1659  return value;
1660 }
1661 
1662 double
1664 {
1665  NS_LOG_FUNCTION(this << r);
1666 
1667  // Return a value from the empirical distribution
1668  // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1669 
1670  // search
1671  ValueCDF selector(0, r);
1672  auto upper = std::upper_bound(m_emp.begin(), m_emp.end(), selector);
1673  auto lower = std::prev(upper, 1);
1674  if (upper == m_emp.begin())
1675  {
1676  lower = upper;
1677  }
1678 
1679  // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1680  double c1 = lower->cdf;
1681  double c2 = upper->cdf;
1682  double v1 = lower->value;
1683  double v2 = upper->value;
1684 
1685  double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1686  return value;
1687 }
1688 
1689 void
1690 EmpiricalRandomVariable::CDF(double v, double c)
1691 {
1692  // Add a new empirical datapoint to the empirical cdf
1693  // NOTE. These MUST be inserted in non-decreasing order
1694  NS_LOG_FUNCTION(this << v << c);
1695  m_emp.emplace_back(v, c);
1696 }
1697 
1698 void
1700 {
1701  NS_LOG_FUNCTION(this);
1702  if (m_emp.empty())
1703  {
1704  NS_FATAL_ERROR("CDF is not initialized");
1705  }
1706  ValueCDF prior = m_emp[0];
1707  for (auto current : m_emp)
1708  {
1709  if (current.value < prior.value || current.cdf < prior.cdf)
1710  { // Error
1711  std::cerr << "Empirical Dist error,"
1712  << " current value " << current.value << " prior value " << prior.value
1713  << " current cdf " << current.cdf << " prior cdf " << prior.cdf << std::endl;
1714  NS_FATAL_ERROR("Empirical Dist error");
1715  }
1716  prior = current;
1717  }
1718  if (prior.cdf != 1.0)
1719  {
1720  NS_FATAL_ERROR("CDF does not cover the whole distribution");
1721  }
1722  m_validated = true;
1723 }
1724 
1725 } // namespace ns3
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
ns3::BooleanValue attribute value declarations.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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
Helper to hold one point of the CDF.
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...
std::vector< ValueCDF > m_emp
The vector of CDF points.
void Validate()
Check that the CDF is valid.
friend bool operator<(ValueCDF a, ValueCDF b)
Comparison operator, for use by std::upper_bound.
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 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.
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.
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:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: double.h:43
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: integer.h:46
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: pointer.h:231
#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_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.
@ normal
Definition: ff-mac-common.h:84
value
Definition: second.py:41
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