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 */
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
47namespace ns3
48{
49
50NS_LOG_COMPONENT_DEFINE("RandomVariableStream");
51
52NS_OBJECT_ENSURE_REGISTERED(RandomVariableStream);
53
54TypeId
56{
57 static TypeId tid = TypeId("ns3::RandomVariableStream")
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
91void
93{
94 NS_LOG_FUNCTION(this << isAntithetic);
95 m_isAntithetic = isAntithetic;
96}
97
98bool
100{
101 NS_LOG_FUNCTION(this);
102 return m_isAntithetic;
103}
104
105void
107{
108 NS_LOG_FUNCTION(this << stream);
109 // negative values are not legal.
110 NS_ASSERT(stream >= -1);
111 delete m_rng;
112 if (stream == -1)
113 {
114 // The first 2^63 streams are reserved for automatic stream
115 // number assignment.
116 uint64_t nextStream = RngSeedManager::GetNextStreamIndex();
117 NS_ASSERT(nextStream <= ((1ULL) << 63));
119 }
120 else
121 {
122 // The last 2^63 streams are reserved for deterministic stream
123 // number assignment.
124 uint64_t base = ((1ULL) << 63);
125 uint64_t target = base + stream;
127 }
128 m_stream = stream;
129}
130
131int64_t
133{
134 NS_LOG_FUNCTION(this);
135 return m_stream;
136}
137
140{
141 NS_LOG_FUNCTION(this);
142 return m_rng;
143}
144
146
147TypeId
149{
150 static TypeId tid =
151 TypeId("ns3::UniformRandomVariable")
153 .SetGroupName("Core")
154 .AddConstructor<UniformRandomVariable>()
155 .AddAttribute("Min",
156 "The lower bound on the values returned by this RNG stream.",
157 DoubleValue(0),
159 MakeDoubleChecker<double>())
160 .AddAttribute("Max",
161 "The upper bound on the values returned by this RNG stream.",
162 DoubleValue(1.0),
164 MakeDoubleChecker<double>());
165 return tid;
166}
167
169{
170 // m_min and m_max are initialized after constructor by attributes
171 NS_LOG_FUNCTION(this);
172}
173
174double
176{
177 NS_LOG_FUNCTION(this);
178 return m_min;
179}
180
181double
183{
184 NS_LOG_FUNCTION(this);
185 return m_max;
186}
187
188double
190{
191 NS_LOG_FUNCTION(this << min << max);
192 double v = min + Peek()->RandU01() * (max - min);
193 if (IsAntithetic())
194 {
195 v = min + (max - v);
196 }
197 return v;
198}
199
202{
203 NS_LOG_FUNCTION(this << min << max);
204 NS_ASSERT(min <= max);
205 return static_cast<uint32_t>(GetValue((double)(min), (double)(max) + 1.0));
206}
207
208double
210{
211 NS_LOG_FUNCTION(this);
212 return GetValue(m_min, m_max);
213}
214
217{
218 NS_LOG_FUNCTION(this);
219 return (uint32_t)GetValue(m_min, m_max + 1);
220}
221
223
224TypeId
226{
227 static TypeId tid = TypeId("ns3::ConstantRandomVariable")
229 .SetGroupName("Core")
230 .AddConstructor<ConstantRandomVariable>()
231 .AddAttribute("Constant",
232 "The constant value returned by this RNG stream.",
233 DoubleValue(0),
235 MakeDoubleChecker<double>());
236 return tid;
237}
238
240{
241 // m_constant is initialized after constructor by attributes
242 NS_LOG_FUNCTION(this);
243}
244
245double
247{
248 NS_LOG_FUNCTION(this);
249 return m_constant;
250}
251
252double
254{
255 NS_LOG_FUNCTION(this << constant);
256 return constant;
257}
258
261{
262 NS_LOG_FUNCTION(this << constant);
263 return constant;
264}
265
266double
268{
269 NS_LOG_FUNCTION(this);
270 return GetValue(m_constant);
271}
272
275{
276 NS_LOG_FUNCTION(this);
278}
279
281
282TypeId
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
323double
325{
326 NS_LOG_FUNCTION(this);
327 return m_min;
328}
329
330double
332{
333 NS_LOG_FUNCTION(this);
334 return m_max;
335}
336
339{
340 NS_LOG_FUNCTION(this);
341 return m_increment;
342}
343
346{
347 NS_LOG_FUNCTION(this);
348 return m_consecutive;
349}
350
351double
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 minimium value.
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 {
372 }
373 }
374 return r;
375}
376
379{
380 NS_LOG_FUNCTION(this);
381 return (uint32_t)GetValue();
382}
383
385
386TypeId
388{
389 static TypeId tid =
390 TypeId("ns3::ExponentialRandomVariable")
392 .SetGroupName("Core")
393 .AddConstructor<ExponentialRandomVariable>()
394 .AddAttribute("Mean",
395 "The mean of the values returned by this RNG stream.",
396 DoubleValue(1.0),
398 MakeDoubleChecker<double>())
399 .AddAttribute("Bound",
400 "The upper bound on the values returned by this RNG stream.",
401 DoubleValue(0.0),
403 MakeDoubleChecker<double>());
404 return tid;
405}
406
408{
409 // m_mean and m_bound are initialized after constructor by attributes
410 NS_LOG_FUNCTION(this);
411}
412
413double
415{
416 NS_LOG_FUNCTION(this);
417 return m_mean;
418}
419
420double
422{
423 NS_LOG_FUNCTION(this);
424 return m_bound;
425}
426
427double
428ExponentialRandomVariable::GetValue(double mean, double bound)
429{
430 NS_LOG_FUNCTION(this << mean << bound);
431 while (1)
432 {
433 // Get a uniform random variable in [0,1].
434 double v = Peek()->RandU01();
435 if (IsAntithetic())
436 {
437 v = (1 - v);
438 }
439
440 // Calculate the exponential random variable.
441 double r = -mean * std::log(v);
442
443 // Use this value if it's acceptable.
444 if (bound == 0 || r <= bound)
445 {
446 return r;
447 }
448 }
449}
450
453{
454 NS_LOG_FUNCTION(this << mean << bound);
455 return static_cast<uint32_t>(GetValue(mean, bound));
456}
457
458double
460{
461 NS_LOG_FUNCTION(this);
462 return GetValue(m_mean, m_bound);
463}
464
467{
468 NS_LOG_FUNCTION(this);
470}
471
473
474TypeId
476{
477 static TypeId tid =
478 TypeId("ns3::ParetoRandomVariable")
480 .SetGroupName("Core")
481 .AddConstructor<ParetoRandomVariable>()
482 .AddAttribute(
483 "Scale",
484 "The scale parameter for the Pareto distribution returned by this RNG stream.",
485 DoubleValue(1.0),
487 MakeDoubleChecker<double>())
488 .AddAttribute(
489 "Shape",
490 "The shape parameter for the Pareto distribution returned by this RNG stream.",
491 DoubleValue(2.0),
493 MakeDoubleChecker<double>())
494 .AddAttribute(
495 "Bound",
496 "The upper bound on the values returned by this RNG stream (if non-zero).",
497 DoubleValue(0.0),
499 MakeDoubleChecker<double>());
500 return tid;
501}
502
504{
505 // m_shape, m_shape, and m_bound are initialized after constructor
506 // by attributes
507 NS_LOG_FUNCTION(this);
508}
509
510double
512{
513 NS_LOG_FUNCTION(this);
514 return m_scale;
515}
516
517double
519{
520 NS_LOG_FUNCTION(this);
521 return m_shape;
522}
523
524double
526{
527 NS_LOG_FUNCTION(this);
528 return m_bound;
529}
530
531double
532ParetoRandomVariable::GetValue(double scale, double shape, double bound)
533{
534 // Calculate the scale parameter.
535 NS_LOG_FUNCTION(this << scale << shape << bound);
536
537 while (1)
538 {
539 // Get a uniform random variable in [0,1].
540 double v = Peek()->RandU01();
541 if (IsAntithetic())
542 {
543 v = (1 - v);
544 }
545
546 // Calculate the Pareto random variable.
547 double r = (scale * (1.0 / std::pow(v, 1.0 / shape)));
548
549 // Use this value if it's acceptable.
550 if (bound == 0 || r <= bound)
551 {
552 return r;
553 }
554 }
555}
556
559{
560 NS_LOG_FUNCTION(this << scale << shape << bound);
561 return static_cast<uint32_t>(GetValue(scale, shape, bound));
562}
563
564double
566{
567 NS_LOG_FUNCTION(this);
569}
570
573{
574 NS_LOG_FUNCTION(this);
576}
577
579
580TypeId
582{
583 static TypeId tid =
584 TypeId("ns3::WeibullRandomVariable")
586 .SetGroupName("Core")
587 .AddConstructor<WeibullRandomVariable>()
588 .AddAttribute(
589 "Scale",
590 "The scale parameter for the Weibull distribution returned by this RNG stream.",
591 DoubleValue(1.0),
593 MakeDoubleChecker<double>())
594 .AddAttribute(
595 "Shape",
596 "The shape parameter for the Weibull distribution returned by this RNG stream.",
597 DoubleValue(1),
599 MakeDoubleChecker<double>())
600 .AddAttribute("Bound",
601 "The upper bound on the values returned by this RNG stream.",
602 DoubleValue(0.0),
604 MakeDoubleChecker<double>());
605 return tid;
606}
607
609{
610 // m_scale, m_shape, and m_bound are initialized after constructor
611 // by attributes
612 NS_LOG_FUNCTION(this);
613}
614
615double
617{
618 NS_LOG_FUNCTION(this);
619 return m_scale;
620}
621
622double
624{
625 NS_LOG_FUNCTION(this);
626 return m_shape;
627}
628
629double
631{
632 NS_LOG_FUNCTION(this);
633 return m_bound;
634}
635
636double
637WeibullRandomVariable::GetValue(double scale, double shape, double bound)
638{
639 NS_LOG_FUNCTION(this << scale << shape << bound);
640 double exponent = 1.0 / shape;
641 while (1)
642 {
643 // Get a uniform random variable in [0,1].
644 double v = Peek()->RandU01();
645 if (IsAntithetic())
646 {
647 v = (1 - v);
648 }
649
650 // Calculate the Weibull random variable.
651 double r = scale * std::pow(-std::log(v), exponent);
652
653 // Use this value if it's acceptable.
654 if (bound == 0 || r <= bound)
655 {
656 return r;
657 }
658 }
659}
660
663{
664 NS_LOG_FUNCTION(this << scale << shape << bound);
665 return static_cast<uint32_t>(GetValue(scale, shape, bound));
666}
667
668double
670{
671 NS_LOG_FUNCTION(this);
673}
674
677{
678 NS_LOG_FUNCTION(this);
680}
681
683
684const double NormalRandomVariable::INFINITE_VALUE = 1e307;
685
686TypeId
688{
689 static TypeId tid =
690 TypeId("ns3::NormalRandomVariable")
692 .SetGroupName("Core")
693 .AddConstructor<NormalRandomVariable>()
694 .AddAttribute("Mean",
695 "The mean value for the normal distribution returned by this RNG stream.",
696 DoubleValue(0.0),
698 MakeDoubleChecker<double>())
699 .AddAttribute(
700 "Variance",
701 "The variance value for the normal distribution returned by this RNG stream.",
702 DoubleValue(1.0),
704 MakeDoubleChecker<double>())
705 .AddAttribute("Bound",
706 "The bound on the values returned by this RNG stream.",
709 MakeDoubleChecker<double>());
710 return tid;
711}
712
714 : m_nextValid(false)
715{
716 // m_mean, m_variance, and m_bound are initialized after constructor
717 // by attributes
718 NS_LOG_FUNCTION(this);
719}
720
721double
723{
724 NS_LOG_FUNCTION(this);
725 return m_mean;
726}
727
728double
730{
731 NS_LOG_FUNCTION(this);
732 return m_variance;
733}
734
735double
737{
738 NS_LOG_FUNCTION(this);
739 return m_bound;
740}
741
742double
743NormalRandomVariable::GetValue(double mean, double variance, double bound)
744{
745 NS_LOG_FUNCTION(this << mean << variance << bound);
746 if (m_nextValid)
747 { // use previously generated
748 m_nextValid = false;
749 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
750 if (std::fabs(x2 - mean) <= bound)
751 {
752 return x2;
753 }
754 }
755 while (1)
756 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
757 // for algorithm; basically a Box-Muller transform:
758 // http://en.wikipedia.org/wiki/Box-Muller_transform
759 double u1 = Peek()->RandU01();
760 double u2 = Peek()->RandU01();
761 if (IsAntithetic())
762 {
763 u1 = (1 - u1);
764 u2 = (1 - u2);
765 }
766 double v1 = 2 * u1 - 1;
767 double v2 = 2 * u2 - 1;
768 double w = v1 * v1 + v2 * v2;
769 if (w <= 1.0)
770 { // Got good pair
771 double y = std::sqrt((-2 * std::log(w)) / w);
772 double x1 = mean + v1 * y * std::sqrt(variance);
773 // if x1 is in bounds, return it, cache v2 and y
774 if (std::fabs(x1 - mean) <= bound)
775 {
776 m_nextValid = true;
777 m_y = y;
778 m_v2 = v2;
779 return x1;
780 }
781 // otherwise try and return the other if it is valid
782 double x2 = mean + v2 * y * std::sqrt(variance);
783 if (std::fabs(x2 - mean) <= bound)
784 {
785 m_nextValid = false;
786 return x2;
787 }
788 // otherwise, just run this loop again
789 }
790 }
791}
792
795{
796 NS_LOG_FUNCTION(this << mean << variance << bound);
797 return static_cast<uint32_t>(GetValue(mean, variance, bound));
798}
799
800double
802{
803 NS_LOG_FUNCTION(this);
805}
806
809{
810 NS_LOG_FUNCTION(this);
812}
813
815
816TypeId
818{
819 static TypeId tid =
820 TypeId("ns3::LogNormalRandomVariable")
822 .SetGroupName("Core")
823 .AddConstructor<LogNormalRandomVariable>()
824 .AddAttribute(
825 "Mu",
826 "The mu value for the log-normal distribution returned by this RNG stream.",
827 DoubleValue(0.0),
829 MakeDoubleChecker<double>())
830 .AddAttribute(
831 "Sigma",
832 "The sigma value for the log-normal distribution returned by this RNG stream.",
833 DoubleValue(1.0),
835 MakeDoubleChecker<double>());
836 return tid;
837}
838
840{
841 // m_mu and m_sigma are initialized after constructor by
842 // attributes
843 NS_LOG_FUNCTION(this);
844}
845
846double
848{
849 NS_LOG_FUNCTION(this);
850 return m_mu;
851}
852
853double
855{
856 NS_LOG_FUNCTION(this);
857 return m_sigma;
858}
859
860// The code from this function was adapted from the GNU Scientific
861// Library 1.8:
862/* randist/lognormal.c
863 *
864 * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
865 *
866 * This program is free software; you can redistribute it and/or modify
867 * it under the terms of the GNU General Public License as published by
868 * the Free Software Foundation; either version 2 of the License, or (at
869 * your option) any later version.
870 *
871 * This program is distributed in the hope that it will be useful, but
872 * WITHOUT ANY WARRANTY; without even the implied warranty of
873 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
874 * General Public License for more details.
875 *
876 * You should have received a copy of the GNU General Public License
877 * along with this program; if not, write to the Free Software
878 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
879 */
880/* The lognormal distribution has the form
881
882 p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
883
884 for x > 0. Lognormal random numbers are the exponentials of
885 gaussian random numbers */
886double
887LogNormalRandomVariable::GetValue(double mu, double sigma)
888{
889 double v1;
890 double v2;
891 double r2;
892 double normal;
893 double x;
894
895 NS_LOG_FUNCTION(this << mu << sigma);
896
897 do
898 {
899 /* choose x,y in uniform square (-1,-1) to (+1,+1) */
900
901 double u1 = Peek()->RandU01();
902 double u2 = Peek()->RandU01();
903 if (IsAntithetic())
904 {
905 u1 = (1 - u1);
906 u2 = (1 - u2);
907 }
908
909 v1 = -1 + 2 * u1;
910 v2 = -1 + 2 * u2;
911
912 /* see if it is in the unit circle */
913 r2 = v1 * v1 + v2 * v2;
914 } while (r2 > 1.0 || r2 == 0);
915
916 normal = v1 * std::sqrt(-2.0 * std::log(r2) / r2);
917
918 x = std::exp(sigma * normal + mu);
919
920 return x;
921}
922
925{
926 NS_LOG_FUNCTION(this << mu << sigma);
927 return static_cast<uint32_t>(GetValue(mu, sigma));
928}
929
930double
932{
933 NS_LOG_FUNCTION(this);
934 return GetValue(m_mu, m_sigma);
935}
936
939{
940 NS_LOG_FUNCTION(this);
941 return (uint32_t)GetValue(m_mu, m_sigma);
942}
943
945
946TypeId
948{
949 static TypeId tid =
950 TypeId("ns3::GammaRandomVariable")
952 .SetGroupName("Core")
953 .AddConstructor<GammaRandomVariable>()
954 .AddAttribute("Alpha",
955 "The alpha value for the gamma distribution returned by this RNG stream.",
956 DoubleValue(1.0),
958 MakeDoubleChecker<double>())
959 .AddAttribute("Beta",
960 "The beta value for the gamma distribution returned by this RNG stream.",
961 DoubleValue(1.0),
963 MakeDoubleChecker<double>());
964 return tid;
965}
966
968 : m_nextValid(false)
969{
970 // m_alpha and m_beta are initialized after constructor by
971 // attributes
972 NS_LOG_FUNCTION(this);
973}
974
975double
977{
978 NS_LOG_FUNCTION(this);
979 return m_alpha;
980}
981
982double
984{
985 NS_LOG_FUNCTION(this);
986 return m_beta;
987}
988
989/*
990 The code for the following generator functions was adapted from ns-2
991 tools/ranvar.cc
992
993 Originally the algorithm was devised by Marsaglia in 2000:
994 G. Marsaglia, W. W. Tsang: A simple method for generating Gamma variables
995 ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
996
997 The Gamma distribution density function has the form
998
999 x^(alpha-1) * exp(-x/beta)
1000 p(x; alpha, beta) = ----------------------------
1001 beta^alpha * Gamma(alpha)
1002
1003 for x > 0.
1004*/
1005double
1006GammaRandomVariable::GetValue(double alpha, double beta)
1007{
1008 NS_LOG_FUNCTION(this << alpha << beta);
1009 if (alpha < 1)
1010 {
1011 double u = Peek()->RandU01();
1012 if (IsAntithetic())
1013 {
1014 u = (1 - u);
1015 }
1016 return GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
1017 }
1018
1019 double x;
1020 double v;
1021 double u;
1022 double d = alpha - 1.0 / 3.0;
1023 double c = (1.0 / 3.0) / std::sqrt(d);
1024
1025 while (1)
1026 {
1027 do
1028 {
1029 // Get a value from a normal distribution that has mean
1030 // zero, variance 1, and no bound.
1031 double mean = 0.0;
1032 double variance = 1.0;
1034 x = GetNormalValue(mean, variance, bound);
1035
1036 v = 1.0 + c * x;
1037 } while (v <= 0);
1038
1039 v = v * v * v;
1040 u = Peek()->RandU01();
1041 if (IsAntithetic())
1042 {
1043 u = (1 - u);
1044 }
1045 if (u < 1 - 0.0331 * x * x * x * x)
1046 {
1047 break;
1048 }
1049 if (std::log(u) < 0.5 * x * x + d * (1 - v + std::log(v)))
1050 {
1051 break;
1052 }
1053 }
1054
1055 return beta * d * v;
1056}
1057
1060{
1061 NS_LOG_FUNCTION(this << alpha << beta);
1062 return static_cast<uint32_t>(GetValue(alpha, beta));
1063}
1064
1065double
1067{
1068 NS_LOG_FUNCTION(this);
1069 return GetValue(m_alpha, m_beta);
1070}
1071
1074{
1075 NS_LOG_FUNCTION(this);
1076 return (uint32_t)GetValue(m_alpha, m_beta);
1077}
1078
1079double
1080GammaRandomVariable::GetNormalValue(double mean, double variance, double bound)
1081{
1082 NS_LOG_FUNCTION(this << mean << variance << bound);
1083 if (m_nextValid)
1084 { // use previously generated
1085 m_nextValid = false;
1086 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
1087 if (std::fabs(x2 - mean) <= bound)
1088 {
1089 return x2;
1090 }
1091 }
1092 while (1)
1093 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1094 // for algorithm; basically a Box-Muller transform:
1095 // http://en.wikipedia.org/wiki/Box-Muller_transform
1096 double u1 = Peek()->RandU01();
1097 double u2 = Peek()->RandU01();
1098 if (IsAntithetic())
1099 {
1100 u1 = (1 - u1);
1101 u2 = (1 - u2);
1102 }
1103 double v1 = 2 * u1 - 1;
1104 double v2 = 2 * u2 - 1;
1105 double w = v1 * v1 + v2 * v2;
1106 if (w <= 1.0)
1107 { // Got good pair
1108 double y = std::sqrt((-2 * std::log(w)) / w);
1109 double x1 = mean + v1 * y * std::sqrt(variance);
1110 // if x1 is in bounds, return it, cache v2 an y
1111 if (std::fabs(x1 - mean) <= bound)
1112 {
1113 m_nextValid = true;
1114 m_y = y;
1115 m_v2 = v2;
1116 return x1;
1117 }
1118 // otherwise try and return the other if it is valid
1119 double x2 = mean + v2 * y * std::sqrt(variance);
1120 if (std::fabs(x2 - mean) <= bound)
1121 {
1122 m_nextValid = false;
1123 return x2;
1124 }
1125 // otherwise, just run this loop again
1126 }
1127 }
1128}
1129
1131
1132TypeId
1134{
1135 static TypeId tid =
1136 TypeId("ns3::ErlangRandomVariable")
1138 .SetGroupName("Core")
1139 .AddConstructor<ErlangRandomVariable>()
1140 .AddAttribute("K",
1141 "The k value for the Erlang distribution returned by this RNG stream.",
1142 IntegerValue(1),
1144 MakeIntegerChecker<uint32_t>())
1145 .AddAttribute(
1146 "Lambda",
1147 "The lambda value for the Erlang distribution returned by this RNG stream.",
1148 DoubleValue(1.0),
1150 MakeDoubleChecker<double>());
1151 return tid;
1152}
1153
1155{
1156 // m_k and m_lambda are initialized after constructor by attributes
1157 NS_LOG_FUNCTION(this);
1158}
1159
1162{
1163 NS_LOG_FUNCTION(this);
1164 return m_k;
1165}
1166
1167double
1169{
1170 NS_LOG_FUNCTION(this);
1171 return m_lambda;
1172}
1173
1174/*
1175 The code for the following generator functions was adapted from ns-2
1176 tools/ranvar.cc
1177
1178 The Erlang distribution density function has the form
1179
1180 x^(k-1) * exp(-x/lambda)
1181 p(x; k, lambda) = ---------------------------
1182 lambda^k * (k-1)!
1183
1184 for x > 0.
1185*/
1186double
1188{
1189 NS_LOG_FUNCTION(this << k << lambda);
1190 double mean = lambda;
1191 double bound = 0.0;
1192
1193 double result = 0;
1194 for (unsigned int i = 0; i < k; ++i)
1195 {
1196 result += GetExponentialValue(mean, bound);
1197 }
1198
1199 return result;
1200}
1201
1204{
1205 NS_LOG_FUNCTION(this << k << lambda);
1206 return static_cast<uint32_t>(GetValue(k, lambda));
1207}
1208
1209double
1211{
1212 NS_LOG_FUNCTION(this);
1213 return GetValue(m_k, m_lambda);
1214}
1215
1218{
1219 NS_LOG_FUNCTION(this);
1220 return (uint32_t)GetValue(m_k, m_lambda);
1221}
1222
1223double
1225{
1226 NS_LOG_FUNCTION(this << mean << bound);
1227 while (1)
1228 {
1229 // Get a uniform random variable in [0,1].
1230 double v = Peek()->RandU01();
1231 if (IsAntithetic())
1232 {
1233 v = (1 - v);
1234 }
1235
1236 // Calculate the exponential random variable.
1237 double r = -mean * std::log(v);
1238
1239 // Use this value if it's acceptable.
1240 if (bound == 0 || r <= bound)
1241 {
1242 return r;
1243 }
1244 }
1245}
1246
1248
1249TypeId
1251{
1252 static TypeId tid =
1253 TypeId("ns3::TriangularRandomVariable")
1255 .SetGroupName("Core")
1256 .AddConstructor<TriangularRandomVariable>()
1257 .AddAttribute(
1258 "Mean",
1259 "The mean value for the triangular distribution returned by this RNG stream.",
1260 DoubleValue(0.5),
1262 MakeDoubleChecker<double>())
1263 .AddAttribute("Min",
1264 "The lower bound on the values returned by this RNG stream.",
1265 DoubleValue(0.0),
1267 MakeDoubleChecker<double>())
1268 .AddAttribute("Max",
1269 "The upper bound on the values returned by this RNG stream.",
1270 DoubleValue(1.0),
1272 MakeDoubleChecker<double>());
1273 return tid;
1274}
1275
1277{
1278 // m_mean, m_min, and m_max are initialized after constructor by
1279 // attributes
1280 NS_LOG_FUNCTION(this);
1281}
1282
1283double
1285{
1286 NS_LOG_FUNCTION(this);
1287 return m_mean;
1288}
1289
1290double
1292{
1293 NS_LOG_FUNCTION(this);
1294 return m_min;
1295}
1296
1297double
1299{
1300 NS_LOG_FUNCTION(this);
1301 return m_max;
1302}
1303
1304double
1305TriangularRandomVariable::GetValue(double mean, double min, double max)
1306{
1307 // Calculate the mode.
1308 NS_LOG_FUNCTION(this << mean << min << max);
1309 double mode = 3.0 * mean - min - max;
1310
1311 // Get a uniform random variable in [0,1].
1312 double u = Peek()->RandU01();
1313 if (IsAntithetic())
1314 {
1315 u = (1 - u);
1316 }
1317
1318 // Calculate the triangular random variable.
1319 if (u <= (mode - min) / (max - min))
1320 {
1321 return min + std::sqrt(u * (max - min) * (mode - min));
1322 }
1323 else
1324 {
1325 return max - std::sqrt((1 - u) * (max - min) * (max - mode));
1326 }
1327}
1328
1331{
1332 NS_LOG_FUNCTION(this << mean << min << max);
1333 return static_cast<uint32_t>(GetValue(mean, min, max));
1334}
1335
1336double
1338{
1339 NS_LOG_FUNCTION(this);
1340 return GetValue(m_mean, m_min, m_max);
1341}
1342
1345{
1346 NS_LOG_FUNCTION(this);
1347 return (uint32_t)GetValue(m_mean, m_min, m_max);
1348}
1349
1351
1352TypeId
1354{
1355 static TypeId tid =
1356 TypeId("ns3::ZipfRandomVariable")
1358 .SetGroupName("Core")
1359 .AddConstructor<ZipfRandomVariable>()
1360 .AddAttribute("N",
1361 "The n value for the Zipf distribution returned by this RNG stream.",
1362 IntegerValue(1),
1364 MakeIntegerChecker<uint32_t>())
1365 .AddAttribute("Alpha",
1366 "The alpha value for the Zipf distribution returned by this RNG stream.",
1367 DoubleValue(0.0),
1369 MakeDoubleChecker<double>());
1370 return tid;
1371}
1372
1374{
1375 // m_n and m_alpha are initialized after constructor by attributes
1376 NS_LOG_FUNCTION(this);
1377}
1378
1381{
1382 NS_LOG_FUNCTION(this);
1383 return m_n;
1384}
1385
1386double
1388{
1389 NS_LOG_FUNCTION(this);
1390 return m_alpha;
1391}
1392
1393double
1395{
1396 NS_LOG_FUNCTION(this << n << alpha);
1397 // Calculate the normalization constant c.
1398 m_c = 0.0;
1399 for (uint32_t i = 1; i <= n; i++)
1400 {
1401 m_c += (1.0 / std::pow((double)i, alpha));
1402 }
1403 m_c = 1.0 / m_c;
1404
1405 // Get a uniform random variable in [0,1].
1406 double u = Peek()->RandU01();
1407 if (IsAntithetic())
1408 {
1409 u = (1 - u);
1410 }
1411
1412 double sum_prob = 0;
1413 double zipf_value = 0;
1414 for (uint32_t i = 1; i <= m_n; i++)
1415 {
1416 sum_prob += m_c / std::pow((double)i, m_alpha);
1417 if (sum_prob > u)
1418 {
1419 zipf_value = i;
1420 break;
1421 }
1422 }
1423 return zipf_value;
1424}
1425
1428{
1429 NS_LOG_FUNCTION(this << n << alpha);
1430 return static_cast<uint32_t>(GetValue(n, alpha));
1431}
1432
1433double
1435{
1436 NS_LOG_FUNCTION(this);
1437 return GetValue(m_n, m_alpha);
1438}
1439
1442{
1443 NS_LOG_FUNCTION(this);
1444 return (uint32_t)GetValue(m_n, m_alpha);
1445}
1446
1448
1449TypeId
1451{
1452 static TypeId tid =
1453 TypeId("ns3::ZetaRandomVariable")
1455 .SetGroupName("Core")
1456 .AddConstructor<ZetaRandomVariable>()
1457 .AddAttribute("Alpha",
1458 "The alpha value for the zeta distribution returned by this RNG stream.",
1459 DoubleValue(3.14),
1461 MakeDoubleChecker<double>());
1462 return tid;
1463}
1464
1466{
1467 // m_alpha is initialized after constructor by attributes
1468 NS_LOG_FUNCTION(this);
1469}
1470
1471double
1473{
1474 NS_LOG_FUNCTION(this);
1475 return m_alpha;
1476}
1477
1478double
1480{
1481 NS_LOG_FUNCTION(this << alpha);
1482 m_b = std::pow(2.0, alpha - 1.0);
1483
1484 double u;
1485 double v;
1486 double X;
1487 double T;
1488 double test;
1489
1490 do
1491 {
1492 // Get a uniform random variable in [0,1].
1493 u = Peek()->RandU01();
1494 if (IsAntithetic())
1495 {
1496 u = (1 - u);
1497 }
1498
1499 // Get a uniform random variable in [0,1].
1500 v = Peek()->RandU01();
1501 if (IsAntithetic())
1502 {
1503 v = (1 - v);
1504 }
1505
1506 X = std::floor(std::pow(u, -1.0 / (m_alpha - 1.0)));
1507 T = std::pow(1.0 + 1.0 / X, m_alpha - 1.0);
1508 test = v * X * (T - 1.0) / (m_b - 1.0);
1509 } while (test > (T / m_b));
1510
1511 return X;
1512}
1513
1516{
1517 NS_LOG_FUNCTION(this << alpha);
1518 return static_cast<uint32_t>(GetValue(alpha));
1519}
1520
1521double
1523{
1524 NS_LOG_FUNCTION(this);
1525 return GetValue(m_alpha);
1526}
1527
1530{
1531 NS_LOG_FUNCTION(this);
1532 return (uint32_t)GetValue(m_alpha);
1533}
1534
1536
1537TypeId
1539{
1540 static TypeId tid = TypeId("ns3::DeterministicRandomVariable")
1542 .SetGroupName("Core")
1543 .AddConstructor<DeterministicRandomVariable>();
1544 return tid;
1545}
1546
1548 : m_count(0),
1549 m_next(0),
1550 m_data(nullptr)
1551{
1552 NS_LOG_FUNCTION(this);
1553}
1554
1556{
1557 // Delete any values currently set.
1558 NS_LOG_FUNCTION(this);
1559 if (m_data != nullptr)
1560 {
1561 delete[] m_data;
1562 }
1563}
1564
1565void
1566DeterministicRandomVariable::SetValueArray(double* values, std::size_t length)
1567{
1568 NS_LOG_FUNCTION(this << values << length);
1569 // Delete any values currently set.
1570 if (m_data != nullptr)
1571 {
1572 delete[] m_data;
1573 }
1574
1575 // Make room for the values being set.
1576 m_data = new double[length];
1577 m_count = length;
1578 m_next = length;
1579
1580 // Copy the values.
1581 for (std::size_t i = 0; i < m_count; i++)
1582 {
1583 m_data[i] = values[i];
1584 }
1585}
1586
1587double
1589{
1590 NS_LOG_FUNCTION(this);
1591 // Make sure the array has been set.
1592 NS_ASSERT(m_count > 0);
1593
1594 if (m_next == m_count)
1595 {
1596 m_next = 0;
1597 }
1598 return m_data[m_next++];
1599}
1600
1603{
1604 NS_LOG_FUNCTION(this);
1605 return (uint32_t)GetValue();
1606}
1607
1609
1610// ValueCDF methods
1612 : value(0.0),
1613 cdf(0.0)
1614{
1615 NS_LOG_FUNCTION(this);
1616}
1617
1619 : value(v),
1620 cdf(c)
1621{
1622 NS_LOG_FUNCTION(this << v << c);
1623 NS_ASSERT(c >= 0.0 && c <= 1.0);
1624}
1625
1626bool
1628{
1629 return a.cdf < b.cdf;
1630}
1631
1632TypeId
1634{
1635 static TypeId tid =
1636 TypeId("ns3::EmpiricalRandomVariable")
1638 .SetGroupName("Core")
1639 .AddConstructor<EmpiricalRandomVariable>()
1640 .AddAttribute("Interpolate",
1641 "Treat the CDF as a smooth distribution and interpolate, "
1642 "default is to treat the CDF as a histogram and sample.",
1643 BooleanValue(false),
1646 return tid;
1647}
1648
1650 : m_validated(false)
1651{
1652 NS_LOG_FUNCTION(this);
1653}
1654
1655bool
1657{
1658 NS_LOG_FUNCTION(this << interpolate);
1659 bool prev = m_interpolate;
1660 m_interpolate = interpolate;
1661 return prev;
1662}
1663
1666{
1667 NS_LOG_FUNCTION(this);
1668 return static_cast<uint32_t>(GetValue());
1669}
1670
1671bool
1673{
1674 NS_LOG_FUNCTION(this);
1675
1676 if (!m_validated)
1677 {
1678 Validate();
1679 }
1680
1681 // Get a uniform random variable in [0, 1].
1682 double r = Peek()->RandU01();
1683 if (IsAntithetic())
1684 {
1685 r = (1 - r);
1686 }
1687
1688 value = r;
1689 bool valid = false;
1690 // check extrema
1691 if (r <= m_emp.front().cdf)
1692 {
1693 value = m_emp.front().value; // Less than first
1694 valid = true;
1695 }
1696 else if (r >= m_emp.back().cdf)
1697 {
1698 value = m_emp.back().value; // Greater than last
1699 valid = true;
1700 }
1701 return valid;
1702}
1703
1704double
1706{
1707 NS_LOG_FUNCTION(this);
1708
1709 double value;
1710 if (PreSample(value))
1711 {
1712 return value;
1713 }
1714
1715 // value now has the (unused) URNG selector
1716 if (m_interpolate)
1717 {
1719 }
1720 else
1721 {
1723 }
1724 return value;
1725}
1726
1727double
1729{
1730 NS_LOG_FUNCTION(this << r);
1731
1732 ValueCDF selector(0, r);
1733 auto bound = std::upper_bound(m_emp.begin(), m_emp.end(), selector);
1734
1735 return bound->value;
1736}
1737
1738double
1740{
1741 NS_LOG_FUNCTION(this);
1742
1743 double value;
1744 if (PreSample(value))
1745 {
1746 return value;
1747 }
1748
1749 // value now has the (unused) URNG selector
1751 return value;
1752}
1753
1754double
1756{
1757 NS_LOG_FUNCTION(this << r);
1758
1759 // Return a value from the empirical distribution
1760 // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1761
1762 // search
1763 ValueCDF selector(0, r);
1764 auto upper = std::upper_bound(m_emp.begin(), m_emp.end(), selector);
1765 auto lower = std::prev(upper, 1);
1766 if (upper == m_emp.begin())
1767 {
1768 lower = upper;
1769 }
1770
1771 // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1772 double c1 = lower->cdf;
1773 double c2 = upper->cdf;
1774 double v1 = lower->value;
1775 double v2 = upper->value;
1776
1777 double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1778 return value;
1779}
1780
1781void
1783{
1784 // Add a new empirical datapoint to the empirical cdf
1785 // NOTE. These MUST be inserted in non-decreasing order
1786 NS_LOG_FUNCTION(this << v << c);
1787 m_emp.emplace_back(v, c);
1788}
1789
1790void
1792{
1793 NS_LOG_FUNCTION(this);
1794 if (m_emp.empty())
1795 {
1796 NS_FATAL_ERROR("CDF is not initialized");
1797 }
1798 ValueCDF prior = m_emp[0];
1799 for (auto current : m_emp)
1800 {
1801 if (current.value < prior.value || current.cdf < prior.cdf)
1802 { // Error
1803 std::cerr << "Empirical Dist error,"
1804 << " current value " << current.value << " prior value " << prior.value
1805 << " current cdf " << current.cdf << " prior cdf " << prior.cdf << std::endl;
1806 NS_FATAL_ERROR("Empirical Dist error");
1807 }
1808 prior = current;
1809 }
1810 if (prior.cdf != 1.0)
1811 {
1812 NS_FATAL_ERROR("CDF does not cover the whole distribution");
1813 }
1814 m_validated = true;
1815}
1816
1817} // 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 as a double 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.
uint32_t GetInteger() override
Get the next random value as an integer drawn from the distribution.
double m_constant
The constant value returned by this RNG stream.
The Random Number Generator (RNG) that returns a predetermined sequence.
double GetValue() override
Returns the next value in the sequence.
std::size_t m_next
Position of the next value in the array of values.
static TypeId GetTypeId()
Register this type.
double * m_data
Array of values to return in sequence.
uint32_t GetInteger() override
Returns the next value in the sequence.
DeterministicRandomVariable()
Creates a deterministic RNG that will have a predetermined sequence of values.
void SetValueArray(double *values, std::size_t length)
Sets the array of values that holds the predetermined sequence.
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.
uint32_t GetInteger() override
Returns the next value 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
Returns the next value in the empirical 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
Returns a random double from an Erlang distribution with the current k and lambda.
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.
uint32_t GetInteger() override
Returns a random unsigned integer from an Erlang distribution with the current k and lambda.
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.
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.
uint32_t GetInteger() override
Get the next random value as an integer drawn from the distribution.
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.
static TypeId GetTypeId()
Register this type.
double GetValue() override
Get the next random value as a double drawn from the distribution.
The gamma distribution Random Number Generator (RNG) that allows stream numbers to be set determinist...
double GetValue() override
Returns a random double from a gamma distribution with the current alpha and beta.
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.
uint32_t GetInteger() override
Returns a random unsigned integer from a gamma distribution with the current alpha and beta.
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...
uint32_t GetInteger() override
Returns a random unsigned integer from a log-normal distribution with the current mu and sigma.
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
Returns a random double from a log-normal distribution with the current mu and sigma.
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.
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.
uint32_t GetInteger() override
Returns a random unsigned integer from a normal distribution with the current mean,...
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
Returns a random double from a normal distribution with the current mean, variance,...
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.
uint32_t GetInteger() override
Returns a random unsigned integer from a Pareto distribution with the current mean,...
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.
double GetValue() override
Returns a random double from a Pareto distribution with the current mean, shape, and upper bound.
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 as a double 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.
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.
uint32_t GetInteger() override
Get the next random value as an integer drawn from the distribution.
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 as a double 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:42
The triangular distribution Random Number Generator (RNG) that allows stream numbers to be set determ...
double GetValue() override
Returns a random double from a triangular distribution with the current mean, min,...
uint32_t GetInteger() override
Returns a random unsigned integer from a triangular distribution with the current mean,...
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,...
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 as an integer 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 as a double drawn from the distribution.
double GetMin() const
Get the lower bound on randoms returned by GetValue().
The Weibull distribution Random Number Generator (RNG) that allows stream numbers to be set determini...
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
Returns a random double from a Weibull distribution with the current scale, shape,...
WeibullRandomVariable()
Creates a Weibull distribution RNG with the default values for the scale, shape, and upper bound.
static TypeId GetTypeId()
Register this type.
uint32_t GetInteger() override
Returns a random unsigned integer from a Weibull distribution with the current scale,...
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
Returns a random double from a zeta distribution with the current alpha.
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.
uint32_t GetInteger() override
Returns a random unsigned integer from a zeta distribution with the current alpha.
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.
uint32_t GetInteger() override
Returns a random unsigned integer from a Zipf distribution with the current n and alpha.
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.
double GetValue() override
Returns a random double from a Zipf distribution with the current n and alpha.
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)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:46
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:230
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#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:45
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