A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Authors: Rajib Bhattacharjea<raj.b@gatech.edu>
8 * Hadi Arbabi<marbabi@cs.odu.edu>
9 * Mathieu Lacage <mathieu.lacage@gmail.com>
10 *
11 * Modified by Mitch Watrous <watrous@u.washington.edu>
12 *
13 */
15
16#include "assert.h"
17#include "boolean.h"
18#include "double.h"
19#include "integer.h"
20#include "log.h"
21#include "pointer.h"
22#include "rng-seed-manager.h"
23#include "rng-stream.h"
24#include "string.h"
25
26#include <cmath>
27#include <iostream>
28#include <numbers>
29
30/**
31 * @file
32 * @ingroup randomvariable
33 * ns3::RandomVariableStream and related implementations
34 */
35
36namespace ns3
37{
38
39NS_LOG_COMPONENT_DEFINE("RandomVariableStream");
40
42
45{
46 static TypeId tid = TypeId("ns3::RandomVariableStream")
48 .SetGroupName("Core")
49 .AddAttribute("Stream",
50 "The stream number for this RNG stream. -1 means "
51 "\"allocate a stream automatically\". "
52 "Note that if -1 is set, Get will return -1 so that it "
53 "is not possible to know which "
54 "value was automatically allocated.",
55 IntegerValue(-1),
59 .AddAttribute("Antithetic",
60 "Set this RNG stream to generate antithetic values",
61 BooleanValue(false),
65 return tid;
66}
67
73
78
79void
81{
82 NS_LOG_FUNCTION(this << isAntithetic);
83 m_isAntithetic = isAntithetic;
84}
85
86bool
91
94{
95 auto value = static_cast<uint32_t>(GetValue());
97 << " integer value: " << value << " stream: " << GetStream());
98 return value;
99}
100
101void
103{
104 NS_LOG_FUNCTION(this << stream);
105 // negative values are not legal.
106 NS_ASSERT(stream >= -1);
107 delete m_rng;
108 if (stream == -1)
109 {
110 // The first 2^63 streams are reserved for automatic stream
111 // number assignment.
112 uint64_t nextStream = RngSeedManager::GetNextStreamIndex();
113 NS_ASSERT(nextStream <= ((1ULL) << 63));
114 NS_LOG_INFO(GetInstanceTypeId().GetName() << " automatic stream: " << nextStream);
116 }
117 else
118 {
119 // The last 2^63 streams are reserved for deterministic stream
120 // number assignment.
121 uint64_t base = ((1ULL) << 63);
122 uint64_t target = base + stream;
123 NS_LOG_INFO(GetInstanceTypeId().GetName() << " configured stream: " << stream);
125 }
126 m_stream = stream;
127}
128
129int64_t
131{
132 return m_stream;
133}
134
137{
138 return m_rng;
139}
140
142
143TypeId
146 static TypeId tid =
147 TypeId("ns3::UniformRandomVariable")
149 .SetGroupName("Core")
150 .AddConstructor<UniformRandomVariable>()
151 .AddAttribute("Min",
152 "The lower bound on the values returned by this RNG stream.",
153 DoubleValue(0),
156 .AddAttribute("Max",
157 "The upper bound on the values returned by this RNG stream.",
158 DoubleValue(1.0),
161 return tid;
162}
163
165{
166 // m_min and m_max are initialized after constructor by attributes
167 NS_LOG_FUNCTION(this);
168}
169
170double
172{
173 return m_min;
174}
175
176double
178{
179 return m_max;
180}
181
182double
183UniformRandomVariable::GetValue(double min, double max)
184{
185 double v = min + Peek()->RandU01() * (max - min);
186 if (IsAntithetic())
187 {
188 v = min + (max - v);
189 }
190 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " min: " << min
191 << " max: " << max);
192 return v;
193}
194
197{
198 NS_ASSERT(min <= max);
199 auto v = static_cast<uint32_t>(GetValue((double)(min), (double)(max) + 1.0));
200 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " min: " << min << " max "
201 << max);
202 return v;
203}
204
205double
210
213{
214 auto v = static_cast<uint32_t>(GetValue(m_min, m_max + 1));
215 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream());
216 return v;
217}
218
220
221TypeId
223{
224 static TypeId tid = TypeId("ns3::ConstantRandomVariable")
226 .SetGroupName("Core")
227 .AddConstructor<ConstantRandomVariable>()
228 .AddAttribute("Constant",
229 "The constant value returned by this RNG stream.",
230 DoubleValue(0),
233 return tid;
234}
235
237{
238 // m_constant is initialized after constructor by attributes
239 NS_LOG_FUNCTION(this);
240}
241
242double
244{
245 NS_LOG_FUNCTION(this);
246 return m_constant;
247}
248
249double
251{
252 NS_LOG_DEBUG("value: " << constant << " stream: " << GetStream());
253 return constant;
254}
255
258{
259 NS_LOG_DEBUG("integer value: " << constant << " stream: " << GetStream());
260 return constant;
261}
262
263double
268
270
271TypeId
273{
274 static TypeId tid =
275 TypeId("ns3::SequentialRandomVariable")
277 .SetGroupName("Core")
278 .AddConstructor<SequentialRandomVariable>()
279 .AddAttribute("Min",
280 "The first value of the sequence.",
281 DoubleValue(0),
284 .AddAttribute("Max",
285 "One more than the last value of the sequence.",
286 DoubleValue(0),
289 .AddAttribute("Increment",
290 "The sequence random variable increment.",
291 StringValue("ns3::ConstantRandomVariable[Constant=1]"),
294 .AddAttribute("Consecutive",
295 "The number of times each member of the sequence is repeated.",
296 IntegerValue(1),
299 return tid;
300}
301
303 : m_current(0),
305 m_isCurrentSet(false)
306{
307 // m_min, m_max, m_increment, and m_consecutive are initialized
308 // after constructor by attributes.
309 NS_LOG_FUNCTION(this);
310}
311
312double
314{
315 return m_min;
316}
317
318double
320{
321 return m_max;
322}
323
329
335
336double
338{
339 // Set the current sequence value if it hasn't been set.
340 if (!m_isCurrentSet)
341 {
342 // Start the sequence at its minimum value.
344 m_isCurrentSet = true;
345 }
346
347 // Return a sequential series of values
348 double r = m_current;
350 { // Time to advance to next
352 m_current += m_increment->GetValue();
353 if (m_current >= m_max)
354 {
356 }
357 }
358 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream());
359 return r;
360}
361
363
364TypeId
366{
367 static TypeId tid =
368 TypeId("ns3::ExponentialRandomVariable")
370 .SetGroupName("Core")
371 .AddConstructor<ExponentialRandomVariable>()
372 .AddAttribute("Mean",
373 "The mean of the values returned by this RNG stream.",
374 DoubleValue(1.0),
377 .AddAttribute("Bound",
378 "The upper bound on the values returned by this RNG stream.",
379 DoubleValue(0.0),
382 return tid;
383}
384
386{
387 // m_mean and m_bound are initialized after constructor by attributes
388 NS_LOG_FUNCTION(this);
389}
390
391double
393{
394 return m_mean;
395}
396
397double
399{
400 return m_bound;
401}
402
403double
404ExponentialRandomVariable::GetValue(double mean, double bound)
405{
406 while (true)
407 {
408 // Get a uniform random variable in [0,1].
409 double v = Peek()->RandU01();
410 if (IsAntithetic())
411 {
412 v = (1 - v);
413 }
414
415 // Calculate the exponential random variable.
416 double r = -mean * std::log(v);
417
418 // Use this value if it's acceptable.
419 if (bound == 0 || r <= bound)
420 {
421 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " mean: " << mean
422 << " bound: " << bound);
423 return r;
424 }
425 }
426}
427
430{
431 NS_LOG_FUNCTION(this << mean << bound);
432 auto v = static_cast<uint32_t>(GetValue(mean, bound));
433 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
434 << " bound: " << bound);
435 return v;
436}
437
438double
443
445
446TypeId
448{
449 static TypeId tid =
450 TypeId("ns3::ParetoRandomVariable")
452 .SetGroupName("Core")
453 .AddConstructor<ParetoRandomVariable>()
454 .AddAttribute(
455 "Scale",
456 "The scale parameter for the Pareto distribution returned by this RNG stream.",
457 DoubleValue(1.0),
460 .AddAttribute(
461 "Shape",
462 "The shape parameter for the Pareto distribution returned by this RNG stream.",
463 DoubleValue(2.0),
466 .AddAttribute(
467 "Bound",
468 "The upper bound on the values returned by this RNG stream (if non-zero).",
469 DoubleValue(0.0),
472 return tid;
473}
474
476{
477 // m_shape, m_shape, and m_bound are initialized after constructor
478 // by attributes
479 NS_LOG_FUNCTION(this);
480}
481
482double
484{
485 return m_scale;
486}
487
488double
490{
491 return m_shape;
492}
493
494double
496{
497 return m_bound;
498}
499
500double
501ParetoRandomVariable::GetValue(double scale, double shape, double bound)
502{
503 while (true)
504 {
505 // Get a uniform random variable in [0,1].
506 double v = Peek()->RandU01();
507 if (IsAntithetic())
508 {
509 v = (1 - v);
510 }
511
512 // Calculate the Pareto random variable.
513 double r = (scale * (1.0 / std::pow(v, 1.0 / shape)));
514
515 // Use this value if it's acceptable.
516 if (bound == 0 || r <= bound)
517 {
518 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " scale: " << scale
519 << " shape: " << shape << " bound: " << bound);
520 return r;
521 }
522 }
523}
524
527{
528 auto v = static_cast<uint32_t>(GetValue(scale, shape, bound));
529 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " scale: " << scale
530 << " shape: " << shape << " bound: " << bound);
531 return v;
532}
533
534double
539
541
542TypeId
544{
545 static TypeId tid =
546 TypeId("ns3::WeibullRandomVariable")
548 .SetGroupName("Core")
549 .AddConstructor<WeibullRandomVariable>()
550 .AddAttribute(
551 "Scale",
552 "The scale parameter for the Weibull distribution returned by this RNG stream.",
553 DoubleValue(1.0),
556 .AddAttribute(
557 "Shape",
558 "The shape parameter for the Weibull distribution returned by this RNG stream.",
559 DoubleValue(1),
562 .AddAttribute("Bound",
563 "The upper bound on the values returned by this RNG stream.",
564 DoubleValue(0.0),
567 return tid;
568}
569
571{
572 // m_scale, m_shape, and m_bound are initialized after constructor
573 // by attributes
574 NS_LOG_FUNCTION(this);
575}
576
577double
579{
580 return m_scale;
581}
582
583double
585{
586 return m_shape;
587}
588
589double
591{
592 return m_bound;
593}
594
595double
596WeibullRandomVariable::GetMean(double scale, double shape)
597{
598 NS_LOG_FUNCTION(scale << shape);
599 return scale * std::tgamma(1 + (1 / shape));
600}
601
602double
604{
605 NS_LOG_FUNCTION(this);
606 return GetMean(m_scale, m_shape);
607}
608
609double
610WeibullRandomVariable::GetValue(double scale, double shape, double bound)
611{
612 double exponent = 1.0 / shape;
613 while (true)
614 {
615 // Get a uniform random variable in [0,1].
616 double v = Peek()->RandU01();
617 if (IsAntithetic())
618 {
619 v = (1 - v);
620 }
621
622 // Calculate the Weibull random variable.
623 double r = scale * std::pow(-std::log(v), exponent);
624
625 // Use this value if it's acceptable.
626 if (bound == 0 || r <= bound)
627 {
628 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " scale: " << scale
629 << " shape: " << shape << " bound: " << bound);
630 return r;
631 }
632 }
633}
634
637{
638 auto v = static_cast<uint32_t>(GetValue(scale, shape, bound));
639 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " scale: " << scale
640 << " shape: " << shape << " bound: " << bound);
641 return v;
642}
643
644double
650
652
653TypeId
655{
656 static TypeId tid =
657 TypeId("ns3::NormalRandomVariable")
659 .SetGroupName("Core")
660 .AddConstructor<NormalRandomVariable>()
661 .AddAttribute("Mean",
662 "The mean value for the normal distribution returned by this RNG stream.",
663 DoubleValue(0.0),
666 .AddAttribute(
667 "Variance",
668 "The variance value for the normal distribution returned by this RNG stream.",
669 DoubleValue(1.0),
672 .AddAttribute("Bound",
673 "The bound on the values returned by this RNG stream.",
677 return tid;
678}
679
681 : m_nextValid(false)
682{
683 // m_mean, m_variance, and m_bound are initialized after constructor
684 // by attributes
685 NS_LOG_FUNCTION(this);
686}
687
688void
690{
691 m_variance = stdDev * stdDev;
692}
693
694double
696{
697 return m_mean;
698}
699
700double
702{
703 return m_variance;
704}
705
706double
708{
709 return sqrt(m_variance);
710}
711
712double
714{
715 return m_bound;
716}
717
718double
719NormalRandomVariable::GetValue(double mean, double variance, double bound)
720{
721 if (m_nextValid)
722 { // use previously generated
723 m_nextValid = false;
724 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
725 if (std::fabs(x2 - mean) <= bound)
726 {
727 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
728 << " variance: " << variance << " bound: " << bound);
729 return x2;
730 }
731 }
732 while (true)
733 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
734 // for algorithm; basically a Box-Muller transform:
735 // http://en.wikipedia.org/wiki/Box-Muller_transform
736 double u1 = Peek()->RandU01();
737 double u2 = Peek()->RandU01();
738 if (IsAntithetic())
739 {
740 u1 = (1 - u1);
741 u2 = (1 - u2);
742 }
743 double v1 = 2 * u1 - 1;
744 double v2 = 2 * u2 - 1;
745 double w = v1 * v1 + v2 * v2;
746 if (w <= 1.0)
747 { // Got good pair
748 double y = std::sqrt((-2 * std::log(w)) / w);
749 double x1 = mean + v1 * y * std::sqrt(variance);
750 // if x1 is in bounds, return it, cache v2 and y
751 if (std::fabs(x1 - mean) <= bound)
752 {
753 m_nextValid = true;
754 m_y = y;
755 m_v2 = v2;
756 NS_LOG_DEBUG("value: " << x1 << " stream: " << GetStream() << " mean: " << mean
757 << " variance: " << variance << " bound: " << bound);
758 return x1;
759 }
760 // otherwise try and return the other if it is valid
761 double x2 = mean + v2 * y * std::sqrt(variance);
762 if (std::fabs(x2 - mean) <= bound)
763 {
764 m_nextValid = false;
765 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
766 << " variance: " << variance << " bound: " << bound);
767 return x2;
768 }
769 // otherwise, just run this loop again
770 }
771 }
772}
773
776{
777 auto v = static_cast<uint32_t>(GetValue(mean, variance, bound));
778 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
779 << " variance: " << variance << " bound: " << bound);
780 return v;
781}
782
783double
788
790
791TypeId
793{
794 static TypeId tid =
795 TypeId("ns3::LogNormalRandomVariable")
797 .SetGroupName("Core")
798 .AddConstructor<LogNormalRandomVariable>()
799 .AddAttribute(
800 "Mu",
801 "The mu value for the log-normal distribution returned by this RNG stream.",
802 DoubleValue(0.0),
805 .AddAttribute(
806 "Sigma",
807 "The sigma value for the log-normal distribution returned by this RNG stream.",
808 DoubleValue(1.0),
811 return tid;
812}
813
815 : m_nextValid(false)
816{
817 // m_mu and m_sigma are initialized after constructor by
818 // attributes
819 NS_LOG_FUNCTION(this);
820}
821
822double
824{
825 return m_mu;
826}
827
828double
830{
831 return m_sigma;
832}
833
834// The code from this function was adapted from the GNU Scientific
835// Library 1.8:
836/* randist/lognormal.c
837 *
838 * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
839 *
840 * SPDX-License-Identifier: GPL-2.0-or-later
841 */
842/* The lognormal distribution has the form
843
844 p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
845
846 for x > 0. Lognormal random numbers are the exponentials of
847 gaussian random numbers */
848double
849LogNormalRandomVariable::GetValue(double mu, double sigma)
850{
851 if (m_nextValid)
852 { // use previously generated
853 m_nextValid = false;
854 double v = std::exp(sigma * m_v2 * m_normal + mu);
855 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mu: " << mu
856 << " sigma: " << sigma);
857 return v;
858 }
859
860 double v1;
861 double v2;
862 double r2;
863 double normal;
864 double x;
865
866 do
867 {
868 /* choose x,y in uniform square (-1,-1) to (+1,+1) */
869
870 double u1 = Peek()->RandU01();
871 double u2 = Peek()->RandU01();
872 if (IsAntithetic())
873 {
874 u1 = (1 - u1);
875 u2 = (1 - u2);
876 }
877
878 v1 = -1 + 2 * u1;
879 v2 = -1 + 2 * u2;
880
881 /* see if it is in the unit circle */
882 r2 = v1 * v1 + v2 * v2;
883 } while (r2 > 1.0 || r2 == 0);
884
885 m_normal = std::sqrt(-2.0 * std::log(r2) / r2);
886 normal = v1 * m_normal;
887 m_nextValid = true;
888 m_v2 = v2;
889
890 x = std::exp(sigma * normal + mu);
891 NS_LOG_DEBUG("value: " << x << " stream: " << GetStream() << " mu: " << mu
892 << " sigma: " << sigma);
893
894 return x;
895}
896
899{
900 auto v = static_cast<uint32_t>(GetValue(mu, sigma));
901 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mu: " << mu
902 << " sigma: " << sigma);
903 return v;
904}
905
906double
911
913
914TypeId
916{
917 static TypeId tid =
918 TypeId("ns3::GammaRandomVariable")
920 .SetGroupName("Core")
921 .AddConstructor<GammaRandomVariable>()
922 .AddAttribute("Alpha",
923 "The alpha value for the gamma distribution returned by this RNG stream.",
924 DoubleValue(1.0),
927 .AddAttribute("Beta",
928 "The beta value for the gamma distribution returned by this RNG stream.",
929 DoubleValue(1.0),
932 return tid;
933}
934
936 : m_nextValid(false)
937{
938 // m_alpha and m_beta are initialized after constructor by
939 // attributes
940 NS_LOG_FUNCTION(this);
941}
942
943double
945{
946 return m_alpha;
947}
948
949double
951{
952 return m_beta;
953}
954
955/*
956 The code for the following generator functions was adapted from ns-2
957 tools/ranvar.cc
958
959 Originally the algorithm was devised by Marsaglia in 2000:
960 G. Marsaglia, W. W. Tsang: A simple method for generating Gamma variables
961 ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
962
963 The Gamma distribution density function has the form
964
965 x^(alpha-1) * exp(-x/beta)
966 p(x; alpha, beta) = ----------------------------
967 beta^alpha * Gamma(alpha)
968
969 for x > 0.
970*/
971double
972GammaRandomVariable::GetValue(double alpha, double beta)
973{
974 if (alpha < 1)
975 {
976 double u = Peek()->RandU01();
977 if (IsAntithetic())
978 {
979 u = (1 - u);
980 }
981 double v = GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
982 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " alpha: " << alpha
983 << " beta: " << beta);
984 return GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
985 }
986
987 double x;
988 double v;
989 double u;
990 double d = alpha - 1.0 / 3.0;
991 double c = (1.0 / 3.0) / std::sqrt(d);
992
993 while (true)
994 {
995 do
996 {
997 // Get a value from a normal distribution that has mean
998 // zero, variance 1, and no bound.
999 double mean = 0.0;
1000 double variance = 1.0;
1002 x = GetNormalValue(mean, variance, bound);
1003
1004 v = 1.0 + c * x;
1005 } while (v <= 0);
1006
1007 v = v * v * v;
1008 u = Peek()->RandU01();
1009 if (IsAntithetic())
1010 {
1011 u = (1 - u);
1012 }
1013 if (u < 1 - 0.0331 * x * x * x * x)
1014 {
1015 break;
1016 }
1017 if (std::log(u) < 0.5 * x * x + d * (1 - v + std::log(v)))
1018 {
1019 break;
1020 }
1021 }
1022
1023 double value = beta * d * v;
1024 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream() << " alpha: " << alpha
1025 << " beta: " << beta);
1026 return value;
1027}
1028
1029double
1034
1035double
1036GammaRandomVariable::GetNormalValue(double mean, double variance, double bound)
1037{
1038 if (m_nextValid)
1039 { // use previously generated
1040 m_nextValid = false;
1041 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
1042 if (std::fabs(x2 - mean) <= bound)
1043 {
1044 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
1045 << " variance: " << variance << " bound: " << bound);
1046 return x2;
1047 }
1048 }
1049 while (true)
1050 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1051 // for algorithm; basically a Box-Muller transform:
1052 // http://en.wikipedia.org/wiki/Box-Muller_transform
1053 double u1 = Peek()->RandU01();
1054 double u2 = Peek()->RandU01();
1055 if (IsAntithetic())
1056 {
1057 u1 = (1 - u1);
1058 u2 = (1 - u2);
1059 }
1060 double v1 = 2 * u1 - 1;
1061 double v2 = 2 * u2 - 1;
1062 double w = v1 * v1 + v2 * v2;
1063 if (w <= 1.0)
1064 { // Got good pair
1065 double y = std::sqrt((-2 * std::log(w)) / w);
1066 double x1 = mean + v1 * y * std::sqrt(variance);
1067 // if x1 is in bounds, return it, cache v2 an y
1068 if (std::fabs(x1 - mean) <= bound)
1069 {
1070 m_nextValid = true;
1071 m_y = y;
1072 m_v2 = v2;
1073 NS_LOG_DEBUG("value: " << x1 << " stream: " << GetStream() << " mean: " << mean
1074 << " variance: " << variance << " bound: " << bound);
1075 return x1;
1076 }
1077 // otherwise try and return the other if it is valid
1078 double x2 = mean + v2 * y * std::sqrt(variance);
1079 if (std::fabs(x2 - mean) <= bound)
1080 {
1081 m_nextValid = false;
1082 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
1083 << " variance: " << variance << " bound: " << bound);
1084 return x2;
1085 }
1086 // otherwise, just run this loop again
1087 }
1088 }
1089}
1090
1092
1093TypeId
1095{
1096 static TypeId tid =
1097 TypeId("ns3::ErlangRandomVariable")
1099 .SetGroupName("Core")
1100 .AddConstructor<ErlangRandomVariable>()
1101 .AddAttribute("K",
1102 "The k value for the Erlang distribution returned by this RNG stream.",
1103 IntegerValue(1),
1106 .AddAttribute(
1107 "Lambda",
1108 "The lambda value for the Erlang distribution returned by this RNG stream.",
1109 DoubleValue(1.0),
1112 return tid;
1113}
1114
1116{
1117 // m_k and m_lambda are initialized after constructor by attributes
1118 NS_LOG_FUNCTION(this);
1119}
1120
1123{
1124 return m_k;
1125}
1126
1127double
1129{
1130 return m_lambda;
1131}
1132
1133/*
1134 The code for the following generator functions was adapted from ns-2
1135 tools/ranvar.cc
1136
1137 The Erlang distribution density function has the form
1138
1139 x^(k-1) * exp(-x/lambda)
1140 p(x; k, lambda) = ---------------------------
1141 lambda^k * (k-1)!
1142
1143 for x > 0.
1144*/
1145double
1147{
1148 double mean = lambda;
1149 double bound = 0.0;
1150
1151 double result = 0;
1152 for (unsigned int i = 0; i < k; ++i)
1153 {
1154 result += GetExponentialValue(mean, bound);
1155 }
1156 NS_LOG_DEBUG("value: " << result << " stream: " << GetStream() << " k: " << k
1157 << " lambda: " << lambda);
1158 return result;
1159}
1160
1163{
1164 auto v = static_cast<uint32_t>(GetValue(k, lambda));
1165 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " k: " << k
1166 << " lambda: " << lambda);
1167 return v;
1168}
1169
1170double
1175
1176double
1178{
1179 while (true)
1180 {
1181 // Get a uniform random variable in [0,1].
1182 double v = Peek()->RandU01();
1183 if (IsAntithetic())
1184 {
1185 v = (1 - v);
1186 }
1187
1188 // Calculate the exponential random variable.
1189 double r = -mean * std::log(v);
1190
1191 // Use this value if it's acceptable.
1192 if (bound == 0 || r <= bound)
1193 {
1194 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " mean:: " << mean
1195 << " bound: " << bound);
1196 return r;
1197 }
1198 }
1199}
1200
1202
1203TypeId
1205{
1206 static TypeId tid =
1207 TypeId("ns3::TriangularRandomVariable")
1209 .SetGroupName("Core")
1210 .AddConstructor<TriangularRandomVariable>()
1211 .AddAttribute(
1212 "Mean",
1213 "The mean value for the triangular distribution returned by this RNG stream.",
1214 DoubleValue(0.5),
1217 .AddAttribute("Min",
1218 "The lower bound on the values returned by this RNG stream.",
1219 DoubleValue(0.0),
1222 .AddAttribute("Max",
1223 "The upper bound on the values returned by this RNG stream.",
1224 DoubleValue(1.0),
1227 return tid;
1228}
1229
1231{
1232 // m_mean, m_min, and m_max are initialized after constructor by
1233 // attributes
1234 NS_LOG_FUNCTION(this);
1235}
1236
1237double
1239{
1240 return m_mean;
1241}
1242
1243double
1245{
1246 return m_min;
1247}
1248
1249double
1251{
1252 return m_max;
1253}
1254
1255double
1256TriangularRandomVariable::GetValue(double mean, double min, double max)
1257{
1258 // Calculate the mode.
1259 double mode = 3.0 * mean - min - max;
1260
1261 // Get a uniform random variable in [0,1].
1262 double u = Peek()->RandU01();
1263 if (IsAntithetic())
1264 {
1265 u = (1 - u);
1266 }
1267
1268 // Calculate the triangular random variable.
1269 if (u <= (mode - min) / (max - min))
1270 {
1271 double v = min + std::sqrt(u * (max - min) * (mode - min));
1272 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mean: " << mean
1273 << " min: " << min << " max: " << max);
1274 return v;
1275 }
1276 else
1277 {
1278 double v = max - std::sqrt((1 - u) * (max - min) * (max - mode));
1279 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mean: " << mean
1280 << " min: " << min << " max: " << max);
1281 return v;
1282 }
1283}
1284
1287{
1288 auto v = static_cast<uint32_t>(GetValue(mean, min, max));
1289 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
1290 << " min: " << min << " max: " << max);
1291 return v;
1292}
1293
1294double
1299
1301
1302TypeId
1304{
1305 static TypeId tid =
1306 TypeId("ns3::ZipfRandomVariable")
1308 .SetGroupName("Core")
1309 .AddConstructor<ZipfRandomVariable>()
1310 .AddAttribute("N",
1311 "The n value for the Zipf distribution returned by this RNG stream.",
1312 IntegerValue(1),
1315 .AddAttribute("Alpha",
1316 "The alpha value for the Zipf distribution returned by this RNG stream.",
1317 DoubleValue(0.0),
1320 return tid;
1321}
1322
1324{
1325 // m_n and m_alpha are initialized after constructor by attributes
1326 NS_LOG_FUNCTION(this);
1327}
1328
1331{
1332 return m_n;
1333}
1334
1335double
1337{
1338 return m_alpha;
1339}
1340
1341double
1343{
1344 // Calculate the normalization constant c.
1345 m_c = 0.0;
1346 for (uint32_t i = 1; i <= n; i++)
1347 {
1348 m_c += (1.0 / std::pow((double)i, alpha));
1349 }
1350 m_c = 1.0 / m_c;
1351
1352 // Get a uniform random variable in [0,1].
1353 double u = Peek()->RandU01();
1354 if (IsAntithetic())
1355 {
1356 u = (1 - u);
1357 }
1358
1359 double sum_prob = 0;
1360 double zipf_value = 0;
1361 for (uint32_t i = 1; i <= n; i++)
1362 {
1363 sum_prob += m_c / std::pow((double)i, alpha);
1364 if (sum_prob > u)
1365 {
1366 zipf_value = i;
1367 break;
1368 }
1369 }
1370 NS_LOG_DEBUG("value: " << zipf_value << " stream: " << GetStream() << " n: " << n
1371 << " alpha: " << alpha);
1372 return zipf_value;
1373}
1374
1377{
1378 NS_LOG_FUNCTION(this << n << alpha);
1379 auto v = static_cast<uint32_t>(GetValue(n, alpha));
1380 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " n: " << n
1381 << " alpha: " << alpha);
1382 return v;
1383}
1384
1385double
1390
1392
1393TypeId
1395{
1396 static TypeId tid =
1397 TypeId("ns3::ZetaRandomVariable")
1399 .SetGroupName("Core")
1400 .AddConstructor<ZetaRandomVariable>()
1401 .AddAttribute("Alpha",
1402 "The alpha value for the zeta distribution returned by this RNG stream.",
1403 DoubleValue(3.14),
1406 return tid;
1407}
1408
1410{
1411 // m_alpha is initialized after constructor by attributes
1412 NS_LOG_FUNCTION(this);
1413}
1414
1415double
1417{
1418 return m_alpha;
1419}
1420
1421double
1423{
1424 m_b = std::pow(2.0, alpha - 1.0);
1425
1426 double u;
1427 double v;
1428 double X;
1429 double T;
1430 double test;
1431
1432 do
1433 {
1434 // Get a uniform random variable in [0,1].
1435 u = Peek()->RandU01();
1436 if (IsAntithetic())
1437 {
1438 u = (1 - u);
1439 }
1440
1441 // Get a uniform random variable in [0,1].
1442 v = Peek()->RandU01();
1443 if (IsAntithetic())
1444 {
1445 v = (1 - v);
1446 }
1447
1448 X = std::floor(std::pow(u, -1.0 / (alpha - 1.0)));
1449 T = std::pow(1.0 + 1.0 / X, alpha - 1.0);
1450 test = v * X * (T - 1.0) / (m_b - 1.0);
1451 } while (test > (T / m_b));
1452 NS_LOG_DEBUG("value: " << X << " stream: " << GetStream() << " alpha: " << alpha);
1453 return X;
1454}
1455
1458{
1459 auto v = static_cast<uint32_t>(GetValue(alpha));
1460 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " alpha: " << alpha);
1461 return v;
1462}
1463
1464double
1469
1471
1472TypeId
1474{
1475 static TypeId tid = TypeId("ns3::DeterministicRandomVariable")
1477 .SetGroupName("Core")
1478 .AddConstructor<DeterministicRandomVariable>();
1479 return tid;
1480}
1481
1483 : m_count(0),
1484 m_next(0),
1485 m_data(nullptr)
1486{
1487 NS_LOG_FUNCTION(this);
1488}
1489
1491{
1492 // Delete any values currently set.
1493 NS_LOG_FUNCTION(this);
1494 if (m_data != nullptr)
1495 {
1496 delete[] m_data;
1497 }
1498}
1499
1500void
1501DeterministicRandomVariable::SetValueArray(const std::vector<double>& values)
1502{
1503 SetValueArray(values.data(), values.size());
1504}
1505
1506void
1507DeterministicRandomVariable::SetValueArray(const double* values, std::size_t length)
1508{
1509 NS_LOG_FUNCTION(this << values << length);
1510 // Delete any values currently set.
1511 if (m_data != nullptr)
1512 {
1513 delete[] m_data;
1514 }
1515
1516 // Make room for the values being set.
1517 m_data = new double[length];
1518 m_count = length;
1519 m_next = length;
1520
1521 // Copy the values.
1522 for (std::size_t i = 0; i < m_count; i++)
1523 {
1524 m_data[i] = values[i];
1525 }
1526}
1527
1528double
1530{
1531 // Make sure the array has been set.
1532 NS_ASSERT(m_count > 0);
1533
1534 if (m_next == m_count)
1535 {
1536 m_next = 0;
1537 }
1538 double v = m_data[m_next++];
1539 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream());
1540 return v;
1541}
1542
1544
1545TypeId
1547{
1548 static TypeId tid =
1549 TypeId("ns3::EmpiricalRandomVariable")
1551 .SetGroupName("Core")
1552 .AddConstructor<EmpiricalRandomVariable>()
1553 .AddAttribute("Interpolate",
1554 "Treat the CDF as a smooth distribution and interpolate, "
1555 "default is to treat the CDF as a histogram and sample.",
1556 BooleanValue(false),
1559 return tid;
1560}
1561
1567
1568bool
1570{
1571 NS_LOG_FUNCTION(this << interpolate);
1572 bool prev = m_interpolate;
1573 m_interpolate = interpolate;
1574 return prev;
1575}
1576
1577bool
1579{
1580 NS_LOG_FUNCTION(this << value);
1581 if (!m_validated)
1582 {
1583 Validate();
1584 }
1585
1586 // Get a uniform random variable in [0, 1].
1587 double r = Peek()->RandU01();
1588 if (IsAntithetic())
1589 {
1590 r = (1 - r);
1591 }
1592
1593 value = r;
1594 bool valid = false;
1595 // check extrema
1596 if (r <= m_empCdf.begin()->first)
1597 {
1598 value = m_empCdf.begin()->second; // Less than first
1599 valid = true;
1600 }
1601 else if (r >= m_empCdf.rbegin()->first)
1602 {
1603 value = m_empCdf.rbegin()->second; // Greater than last
1604 valid = true;
1605 }
1606 return valid;
1607}
1608
1609double
1611{
1612 double value;
1613 if (PreSample(value))
1614 {
1615 return value;
1616 }
1617
1618 // value now has the (unused) URNG selector
1619 if (m_interpolate)
1620 {
1621 value = DoInterpolate(value);
1622 }
1623 else
1624 {
1625 value = DoSampleCDF(value);
1626 }
1627 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream());
1628 return value;
1629}
1630
1631double
1633{
1634 NS_LOG_FUNCTION(this << r);
1635
1636 // Find first CDF that is greater than r
1637 auto bound = m_empCdf.upper_bound(r);
1638
1639 return bound->second;
1640}
1641
1642double
1644{
1645 NS_LOG_FUNCTION(this);
1646
1647 double value;
1648 if (PreSample(value))
1649 {
1650 return value;
1651 }
1652
1653 // value now has the (unused) URNG selector
1654 value = DoInterpolate(value);
1655 return value;
1656}
1657
1658double
1660{
1661 NS_LOG_FUNCTION(this << r);
1662
1663 // Return a value from the empirical distribution
1664 // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1665
1666 // search
1667 auto upper = m_empCdf.upper_bound(r);
1668 auto lower = std::prev(upper, 1);
1669
1670 if (upper == m_empCdf.begin())
1671 {
1672 lower = upper;
1673 }
1674
1675 // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1676 double c1 = lower->first;
1677 double c2 = upper->first;
1678 double v1 = lower->second;
1679 double v2 = upper->second;
1680
1681 double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1682 return value;
1683}
1684
1685void
1687{
1688 NS_LOG_FUNCTION(this << v << c);
1689
1690 auto vPrevious = m_empCdf.find(c);
1691
1692 if (vPrevious != m_empCdf.end())
1693 {
1694 NS_LOG_WARN("Empirical CDF already has a value " << vPrevious->second << " for CDF " << c
1695 << ". Overwriting it with value " << v
1696 << ".");
1697 }
1698
1699 m_empCdf[c] = v;
1700}
1701
1702void
1704{
1705 NS_LOG_FUNCTION(this);
1706
1707 if (m_empCdf.empty())
1708 {
1709 NS_FATAL_ERROR("CDF is not initialized");
1710 }
1711
1712 double vPrev = m_empCdf.begin()->second;
1713
1714 // Check if values are non-decreasing
1715 for (const auto& cdfPair : m_empCdf)
1716 {
1717 const auto& vCurr = cdfPair.second;
1718
1719 if (vCurr < vPrev)
1720 {
1721 NS_FATAL_ERROR("Empirical distribution has decreasing CDF values. Current CDF: "
1722 << vCurr << ", prior CDF: " << vPrev);
1723 }
1724
1725 vPrev = vCurr;
1726 }
1727
1728 // Bounds check on CDF endpoints
1729 auto firstCdfPair = m_empCdf.begin();
1730 auto lastCdfPair = m_empCdf.rbegin();
1731
1732 if (firstCdfPair->first < 0.0)
1733 {
1734 NS_FATAL_ERROR("Empirical distribution has invalid first CDF value. CDF: "
1735 << firstCdfPair->first << ", Value: " << firstCdfPair->second);
1736 }
1737
1738 if (lastCdfPair->first > 1.0)
1739 {
1740 NS_FATAL_ERROR("Empirical distribution has invalid last CDF value. CDF: "
1741 << lastCdfPair->first << ", Value: " << lastCdfPair->second);
1742 }
1743
1744 m_validated = true;
1745}
1746
1748
1749TypeId
1751{
1752 static TypeId tid =
1753 TypeId("ns3::BinomialRandomVariable")
1755 .SetGroupName("Core")
1756 .AddConstructor<BinomialRandomVariable>()
1757 .AddAttribute("Trials",
1758 "The number of trials.",
1759 IntegerValue(10),
1762 .AddAttribute("Probability",
1763 "The probability of success in each trial.",
1764 DoubleValue(0.5),
1767 return tid;
1768}
1769
1771{
1772 // m_trials and m_probability are initialized after constructor by attributes
1773 NS_LOG_FUNCTION(this);
1774}
1775
1776double
1778{
1779 double successes = 0;
1780
1781 for (uint32_t i = 0; i < trials; ++i)
1782 {
1783 double v = Peek()->RandU01();
1784 if (IsAntithetic())
1785 {
1786 v = (1 - v);
1787 }
1788
1789 if (v <= probability)
1790 {
1791 successes += 1;
1792 }
1793 }
1794 NS_LOG_DEBUG("value: " << successes << " stream: " << GetStream() << " trials: " << trials
1795 << " probability: " << probability);
1796 return successes;
1797}
1798
1801{
1802 auto v = static_cast<uint32_t>(GetValue(trials, probability));
1803 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " trials: " << trials
1804 << " probability: " << probability);
1805 return v;
1806}
1807
1808double
1813
1815
1816TypeId
1818{
1819 static TypeId tid =
1820 TypeId("ns3::BernoulliRandomVariable")
1822 .SetGroupName("Core")
1823 .AddConstructor<BernoulliRandomVariable>()
1824 .AddAttribute("Probability",
1825 "The probability of the random variable returning a value of 1.",
1826 DoubleValue(0.5),
1829 return tid;
1830}
1831
1833{
1834 // m_probability is initialized after constructor by attributes
1835 NS_LOG_FUNCTION(this);
1836}
1837
1838double
1840{
1841 double v = Peek()->RandU01();
1842 if (IsAntithetic())
1843 {
1844 v = (1 - v);
1845 }
1846
1847 double value = (v <= probability) ? 1.0 : 0.0;
1848 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream()
1849 << " probability: " << probability);
1850 return value;
1851}
1852
1855{
1856 auto v = static_cast<uint32_t>(GetValue(probability));
1857 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream()
1858 << " probability: " << probability);
1859 return v;
1860}
1861
1862double
1867
1869
1870TypeId
1872{
1873 static TypeId tid =
1874 TypeId("ns3::LaplacianRandomVariable")
1876 .SetGroupName("Core")
1877 .AddConstructor<LaplacianRandomVariable>()
1878 .AddAttribute("Location",
1879 "The location parameter for the Laplacian distribution returned by this "
1880 "RNG stream.",
1881 DoubleValue(0.0),
1884 .AddAttribute(
1885 "Scale",
1886 "The scale parameter for the Laplacian distribution returned by this RNG stream.",
1887 DoubleValue(1.0),
1890 .AddAttribute("Bound",
1891 "The bound on the values returned by this RNG stream.",
1892 DoubleValue(0.0),
1895 return tid;
1896}
1897
1902
1903double
1905{
1906 return m_location;
1907}
1908
1909double
1911{
1912 return m_scale;
1913}
1914
1915double
1917{
1918 return m_bound;
1919}
1920
1921double
1922LaplacianRandomVariable::GetValue(double location, double scale, double bound)
1923{
1924 NS_LOG_FUNCTION(this << location << scale << bound);
1925 NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
1926
1927 while (true)
1928 {
1929 // Get a uniform random variable in [-0.5,0.5].
1930 auto v = (Peek()->RandU01() - 0.5);
1931 if (IsAntithetic())
1932 {
1933 v = (1 - v);
1934 }
1935
1936 // Calculate the laplacian random variable.
1937 const auto sgn = (v > 0) ? 1 : ((v < 0) ? -1 : 0);
1938 const auto r = location - (scale * sgn * std::log(1.0 - (2.0 * std::abs(v))));
1939
1940 // Use this value if it's acceptable.
1941 if (bound == 0.0 || std::fabs(r - location) <= bound)
1942 {
1943 return r;
1944 }
1945 }
1946}
1947
1950{
1951 NS_LOG_FUNCTION(this << location << scale << bound);
1952 return static_cast<uint32_t>(GetValue(location, scale, bound));
1953}
1954
1955double
1961
1962double
1964{
1965 NS_LOG_FUNCTION(scale);
1966 return 2.0 * std::pow(scale, 2.0);
1967}
1968
1969double
1974
1976
1977TypeId
1979{
1980 static TypeId tid =
1981 TypeId("ns3::LargestExtremeValueRandomVariable")
1983 .SetGroupName("Core")
1984 .AddConstructor<LargestExtremeValueRandomVariable>()
1985 .AddAttribute("Location",
1986 "The location parameter for the Largest Extreme Value distribution "
1987 "returned by this RNG stream.",
1988 DoubleValue(0.0),
1991 .AddAttribute("Scale",
1992 "The scale parameter for the Largest Extreme Value distribution "
1993 "returned by this RNG stream.",
1994 DoubleValue(1.0),
1997 return tid;
1998}
1999
2004
2005double
2010
2011double
2016
2017double
2019{
2020 NS_LOG_FUNCTION(this << location << scale);
2021 NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
2022
2023 // Get a uniform random variable in [0,1].
2024 auto v = Peek()->RandU01();
2025 if (IsAntithetic())
2026 {
2027 v = (1 - v);
2028 }
2029
2030 // Calculate the largest extreme value random variable.
2031 const auto t = std::log(v) * (-1.0);
2032 const auto r = location - (scale * std::log(t));
2033
2034 return r;
2035}
2036
2039{
2040 NS_LOG_FUNCTION(this << location << scale);
2041 return static_cast<uint32_t>(GetValue(location, scale));
2042}
2043
2044double
2050
2051double
2053{
2054 NS_LOG_FUNCTION(location << scale);
2055 return (location + (scale * std::numbers::egamma));
2056}
2057
2058double
2063
2064double
2066{
2067 NS_LOG_FUNCTION(scale);
2068 return std::pow((scale * std::numbers::pi), 2) / 6.0;
2069}
2070
2071double
2076
2077} // namespace ns3
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
ns3::BooleanValue attribute value declarations.
cairo_uint64_t x
_cairo_uint_96by64_32x64_divrem:
uint32_t r
uint32_t v
uint32_t u
return result
The Bernoulli distribution Random Number Generator (RNG).
double GetValue() override
Get the next random value drawn from the distribution.
double m_probability
The probability of success.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
The binomial distribution Random Number Generator (RNG).
double m_probability
The probability of success in each trial.
double GetValue() override
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
uint32_t m_trials
The number of trials.
AttributeValue implementation for Boolean.
Definition boolean.h:26
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:31
The Random Number Generator (RNG) that has a specified empirical distribution.
bool SetInterpolate(bool interpolate)
Switch the mode between sampling the CDF and interpolating.
void CDF(double v, double c)
Specifies a point in the empirical distribution.
bool PreSample(double &value)
Do the initial rng draw and check against the extrema.
double DoSampleCDF(double r)
Sample the CDF as a histogram (without interpolation).
double GetValue() override
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
bool m_interpolate
If true GetValue will interpolate, otherwise treat CDF as normal histogram.
bool m_validated
true once the CDF has been validated.
double DoInterpolate(double r)
Linear interpolation between two points on the CDF to estimate the value at r.
virtual double Interpolate()
Returns the next value in the empirical distribution using linear interpolation.
EmpiricalRandomVariable()
Creates an empirical RNG that has a specified, empirical distribution, and configured for interpolati...
void Validate()
Check that the CDF is valid.
std::map< double, double > m_empCdf
The map of CDF points (x, F(x)).
The Erlang distribution Random Number Generator (RNG) that allows stream numbers to be set determinis...
double m_lambda
The lambda value for the Erlang distribution returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
double GetExponentialValue(double mean, double bound)
Returns a random double from an exponential distribution with the specified mean and upper bound.
static TypeId GetTypeId()
Register this type.
uint32_t GetK() const
Returns the k value for the Erlang distribution returned by this RNG stream.
double GetLambda() const
Returns the lambda value for the Erlang distribution returned by this RNG stream.
uint32_t m_k
The k value for the Erlang distribution returned by this RNG stream.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
ErlangRandomVariable()
Creates an Erlang distribution RNG with the default values for k and lambda.
The exponential distribution Random Number Generator (RNG).
ExponentialRandomVariable()
Creates an exponential distribution RNG with the default values for the mean and upper bound.
double GetBound() const
Get the configured upper bound of this RNG.
double m_mean
The mean value of the unbounded exponential distribution.
double GetMean() const
Get the configured mean value of this RNG.
double m_bound
The upper bound on values that can be returned by this RNG stream.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
double GetValue() override
Get the next random value drawn from the distribution.
The gamma distribution Random Number Generator (RNG) that allows stream numbers to be set determinist...
double GetValue() override
Get the next random value drawn from the distribution.
GammaRandomVariable()
Creates a gamma distribution RNG with the default values for alpha and beta.
double m_alpha
The alpha value for the gamma distribution returned by this RNG stream.
double GetNormalValue(double mean, double variance, double bound)
Returns a random double from a normal distribution with the specified mean, variance,...
double m_y
The algorithm produces two values at a time.
double m_v2
The algorithm produces two values at a time.
bool m_nextValid
True if the next normal value is valid.
static TypeId GetTypeId()
Register this type.
double GetAlpha() const
Returns the alpha value for the gamma distribution returned by this RNG stream.
double GetBeta() const
Returns the beta value for the gamma distribution returned by this RNG stream.
double m_beta
The beta value for the gamma distribution returned by this RNG stream.
Hold a signed integer type.
Definition integer.h:34
The laplacian distribution Random Number Generator (RNG).
double m_location
The location value of the laplacian distribution.
double GetValue() override
Get the next random value drawn from the distribution.
double GetBound() const
Get the configured bound of this RNG.
static TypeId GetTypeId()
Register this type.
double m_bound
The bound on values that can be returned by this RNG stream.
LaplacianRandomVariable()
Creates an unbounded laplacian distribution RNG with the default values for the location and the scal...
double GetLocation() const
Get the configured location value of this RNG.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
double m_scale
The scale value of the laplacian distribution.
double GetScale() const
Get the configured scale value of this RNG.
double GetVariance() const
Returns the variance value for the laplacian distribution returned by this RNG stream.
The Largest Extreme Value distribution Random Number Generator (RNG).
double m_scale
The scale value of the Largest Extreme Value distribution.
double GetMean() const
Returns the mean value for the Largest Extreme Value distribution returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
LargestExtremeValueRandomVariable()
Creates a Largest Extreme Value distribution RNG with the default values for the location and the sca...
double GetVariance() const
Returns the variance value for the Largest Extreme Value distribution returned by this RNG stream.
double GetScale() const
Get the configured scale value of this RNG.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
double GetLocation() const
Get the configured location value of this RNG.
double m_location
The location value of the Largest Extreme Value distribution.
The log-normal distribution Random Number Generator (RNG) that allows stream numbers to be set determ...
double GetMu() const
Returns the mu value for the log-normal distribution returned by this RNG stream.
double m_v2
The algorithm produces two values at a time.
double GetSigma() const
Returns the sigma value for the log-normal distribution returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
bool m_nextValid
True if m_normal is valid.
double m_mu
The mu value for the log-normal distribution returned by this RNG stream.
double m_sigma
The sigma value for the log-normal distribution returned by this RNG stream.
LogNormalRandomVariable()
Creates a log-normal distribution RNG with the default values for mu and sigma.
double m_normal
The algorithm produces two values at a time.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
The normal (Gaussian) distribution Random Number Generator (RNG) that allows stream numbers to be set...
double m_y
The algorithm produces two values at a time.
double GetBound() const
Returns the bound on values that can be returned by this RNG stream.
double GetStdDev() const
Returns the standard deviation value for the normal distribution returned by this RNG stream.
double GetVariance() const
Returns the variance value for the normal distribution returned by this RNG stream.
void SetStdDev(double stdDev)
Set standard deviation of this normal distribution 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 constexpr 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.
TypeId GetInstanceTypeId() const final
Get the most derived TypeId for this Object.
Definition object.cc:80
Object()
Caller graph was not generated because of its size.
Definition object.cc:93
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
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:39
double RandU01()
Generate the next random number for this stream.
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:45
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:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
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 GetMean() const
Returns the mean value 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:55
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
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:70
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
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:32
Ptr< const AttributeChecker > MakeIntegerChecker()
Definition integer.h:99
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:35
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:250
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:273
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:253
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:267
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
ns3::IntegerValue attribute value declarations and template implementations.
Debug message logging.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
-ns3 Test suite for the ns3 wrapper script
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