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#include "uinteger.h"
26
27#include <algorithm> // upper_bound
28#include <cmath>
29#include <iostream>
30#include <numbers>
31
32/**
33 * @file
34 * @ingroup randomvariable
35 * ns3::RandomVariableStream and related implementations
36 */
37
38namespace ns3
39{
40
41NS_LOG_COMPONENT_DEFINE("RandomVariableStream");
42
43NS_OBJECT_ENSURE_REGISTERED(RandomVariableStream);
44
45TypeId
47{
48 static TypeId tid = TypeId("ns3::RandomVariableStream")
50 .SetGroupName("Core")
51 .AddAttribute("Stream",
52 "The stream number for this RNG stream. -1 means "
53 "\"allocate a stream automatically\". "
54 "Note that if -1 is set, Get will return -1 so that it "
55 "is not possible to know which "
56 "value was automatically allocated.",
57 IntegerValue(-1),
61 .AddAttribute("Antithetic",
62 "Set this RNG stream to generate antithetic values",
63 BooleanValue(false),
67 return tid;
68}
69
71 : m_rng(nullptr)
72{
73 NS_LOG_FUNCTION(this);
74}
75
80
81void
83{
84 NS_LOG_FUNCTION(this << isAntithetic);
85 m_isAntithetic = isAntithetic;
86}
87
88bool
93
96{
97 auto value = static_cast<uint32_t>(GetValue());
99 << " integer value: " << value << " stream: " << GetStream());
100 return value;
101}
102
103void
105{
106 NS_LOG_FUNCTION(this << stream);
107 // negative values are not legal.
108 NS_ASSERT(stream >= -1);
109 delete m_rng;
110 if (stream == -1)
111 {
112 // The first 2^63 streams are reserved for automatic stream
113 // number assignment.
114 uint64_t nextStream = RngSeedManager::GetNextStreamIndex();
115 NS_ASSERT(nextStream <= ((1ULL) << 63));
116 NS_LOG_INFO(GetInstanceTypeId().GetName() << " automatic stream: " << nextStream);
118 }
119 else
120 {
121 // The last 2^63 streams are reserved for deterministic stream
122 // number assignment.
123 uint64_t base = ((1ULL) << 63);
124 uint64_t target = base + stream;
125 NS_LOG_INFO(GetInstanceTypeId().GetName() << " configured stream: " << stream);
127 }
128 m_stream = stream;
129}
130
131int64_t
133{
134 return m_stream;
135}
136
139{
140 return m_rng;
141}
142
144
147{
148 static TypeId tid =
149 TypeId("ns3::UniformRandomVariable")
151 .SetGroupName("Core")
152 .AddConstructor<UniformRandomVariable>()
153 .AddAttribute("Min",
154 "The lower bound on the values returned by this RNG stream.",
155 DoubleValue(0),
158 .AddAttribute("Max",
159 "The upper bound on the values returned by this RNG stream.",
160 DoubleValue(1.0),
163 return tid;
164}
165
167{
168 // m_min and m_max are initialized after constructor by attributes
169 NS_LOG_FUNCTION(this);
170}
171
172double
174{
175 return m_min;
176}
177
178double
180{
181 return m_max;
182}
183
184double
185UniformRandomVariable::GetValue(double min, double max)
186{
187 double v = min + Peek()->RandU01() * (max - min);
188 if (IsAntithetic())
189 {
190 v = min + (max - v);
191 }
192 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " min: " << min
193 << " max: " << max);
194 return v;
195}
196
199{
200 NS_ASSERT(min <= max);
201 auto v = static_cast<uint32_t>(GetValue((double)(min), (double)(max) + 1.0));
202 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " min: " << min << " max "
203 << max);
204 return v;
205}
206
207double
212
215{
216 auto v = static_cast<uint32_t>(GetValue(m_min, m_max + 1));
217 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream());
218 return v;
219}
220
222
223TypeId
225{
226 static TypeId tid = TypeId("ns3::ConstantRandomVariable")
228 .SetGroupName("Core")
229 .AddConstructor<ConstantRandomVariable>()
230 .AddAttribute("Constant",
231 "The constant value returned by this RNG stream.",
232 DoubleValue(0),
235 return tid;
236}
237
239{
240 // m_constant is initialized after constructor by attributes
241 NS_LOG_FUNCTION(this);
242}
243
244double
246{
247 NS_LOG_FUNCTION(this);
248 return m_constant;
249}
250
251double
253{
254 NS_LOG_DEBUG("value: " << constant << " stream: " << GetStream());
255 return constant;
256}
257
260{
261 NS_LOG_DEBUG("integer value: " << constant << " stream: " << GetStream());
262 return constant;
263}
264
265double
270
272
273TypeId
275{
276 static TypeId tid =
277 TypeId("ns3::SequentialRandomVariable")
279 .SetGroupName("Core")
280 .AddConstructor<SequentialRandomVariable>()
281 .AddAttribute("Min",
282 "The first value of the sequence.",
283 DoubleValue(0),
286 .AddAttribute("Max",
287 "One more than the last value of the sequence.",
288 DoubleValue(0),
291 .AddAttribute("Increment",
292 "The sequence random variable increment.",
293 StringValue("ns3::ConstantRandomVariable[Constant=1]"),
296 .AddAttribute("Consecutive",
297 "The number of times each member of the sequence is repeated.",
298 IntegerValue(1),
301 return tid;
302}
303
305 : m_current(0),
306 m_currentConsecutive(0),
307 m_isCurrentSet(false)
308{
309 // m_min, m_max, m_increment, and m_consecutive are initialized
310 // after constructor by attributes.
311 NS_LOG_FUNCTION(this);
312}
313
314double
316{
317 return m_min;
318}
319
320double
322{
323 return m_max;
324}
325
331
337
338double
340{
341 // Set the current sequence value if it hasn't been set.
342 if (!m_isCurrentSet)
343 {
344 // Start the sequence at its minimum value.
346 m_isCurrentSet = true;
347 }
348
349 // Return a sequential series of values
350 double r = m_current;
352 { // Time to advance to next
355 if (m_current >= m_max)
356 {
358 }
359 }
360 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream());
361 return r;
362}
363
365
366TypeId
368{
369 static TypeId tid =
370 TypeId("ns3::ExponentialRandomVariable")
372 .SetGroupName("Core")
373 .AddConstructor<ExponentialRandomVariable>()
374 .AddAttribute("Mean",
375 "The mean of the values returned by this RNG stream.",
376 DoubleValue(1.0),
379 .AddAttribute("Bound",
380 "The upper bound on the values returned by this RNG stream.",
381 DoubleValue(0.0),
384 return tid;
385}
386
388{
389 // m_mean and m_bound are initialized after constructor by attributes
390 NS_LOG_FUNCTION(this);
391}
392
393double
395{
396 return m_mean;
397}
398
399double
401{
402 return m_bound;
403}
404
405double
406ExponentialRandomVariable::GetValue(double mean, double bound)
407{
408 while (true)
409 {
410 // Get a uniform random variable in [0,1].
411 double v = Peek()->RandU01();
412 if (IsAntithetic())
413 {
414 v = (1 - v);
415 }
416
417 // Calculate the exponential random variable.
418 double r = -mean * std::log(v);
419
420 // Use this value if it's acceptable.
421 if (bound == 0 || r <= bound)
422 {
423 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " mean: " << mean
424 << " bound: " << bound);
425 return r;
426 }
427 }
428}
429
432{
433 NS_LOG_FUNCTION(this << mean << bound);
434 auto v = static_cast<uint32_t>(GetValue(mean, bound));
435 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
436 << " bound: " << bound);
437 return v;
438}
439
440double
445
447
448TypeId
450{
451 static TypeId tid =
452 TypeId("ns3::ParetoRandomVariable")
454 .SetGroupName("Core")
455 .AddConstructor<ParetoRandomVariable>()
456 .AddAttribute(
457 "Scale",
458 "The scale parameter for the Pareto distribution returned by this RNG stream.",
459 DoubleValue(1.0),
462 .AddAttribute(
463 "Shape",
464 "The shape parameter for the Pareto distribution returned by this RNG stream.",
465 DoubleValue(2.0),
468 .AddAttribute(
469 "Bound",
470 "The upper bound on the values returned by this RNG stream (if non-zero).",
471 DoubleValue(0.0),
474 return tid;
475}
476
478{
479 // m_shape, m_shape, and m_bound are initialized after constructor
480 // by attributes
481 NS_LOG_FUNCTION(this);
482}
483
484double
486{
487 return m_scale;
488}
489
490double
492{
493 return m_shape;
494}
495
496double
498{
499 return m_bound;
500}
501
502double
503ParetoRandomVariable::GetValue(double scale, double shape, double bound)
504{
505 while (true)
506 {
507 // Get a uniform random variable in [0,1].
508 double v = Peek()->RandU01();
509 if (IsAntithetic())
510 {
511 v = (1 - v);
512 }
513
514 // Calculate the Pareto random variable.
515 double r = (scale * (1.0 / std::pow(v, 1.0 / shape)));
516
517 // Use this value if it's acceptable.
518 if (bound == 0 || r <= bound)
519 {
520 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " scale: " << scale
521 << " shape: " << shape << " bound: " << bound);
522 return r;
523 }
524 }
525}
526
529{
530 auto v = static_cast<uint32_t>(GetValue(scale, shape, bound));
531 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " scale: " << scale
532 << " shape: " << shape << " bound: " << bound);
533 return v;
534}
535
536double
541
543
544TypeId
546{
547 static TypeId tid =
548 TypeId("ns3::WeibullRandomVariable")
550 .SetGroupName("Core")
551 .AddConstructor<WeibullRandomVariable>()
552 .AddAttribute(
553 "Scale",
554 "The scale parameter for the Weibull distribution returned by this RNG stream.",
555 DoubleValue(1.0),
558 .AddAttribute(
559 "Shape",
560 "The shape parameter for the Weibull distribution returned by this RNG stream.",
561 DoubleValue(1),
564 .AddAttribute("Bound",
565 "The upper bound on the values returned by this RNG stream.",
566 DoubleValue(0.0),
569 return tid;
570}
571
573{
574 // m_scale, m_shape, and m_bound are initialized after constructor
575 // by attributes
576 NS_LOG_FUNCTION(this);
577}
578
579double
581{
582 return m_scale;
583}
584
585double
587{
588 return m_shape;
589}
590
591double
593{
594 return m_bound;
595}
596
597double
598WeibullRandomVariable::GetMean(double scale, double shape)
599{
600 NS_LOG_FUNCTION(scale << shape);
601 return scale * std::tgamma(1 + (1 / shape));
602}
603
604double
606{
607 NS_LOG_FUNCTION(this);
608 return GetMean(m_scale, m_shape);
609}
610
611double
612WeibullRandomVariable::GetValue(double scale, double shape, double bound)
613{
614 double exponent = 1.0 / shape;
615 while (true)
616 {
617 // Get a uniform random variable in [0,1].
618 double v = Peek()->RandU01();
619 if (IsAntithetic())
620 {
621 v = (1 - v);
622 }
623
624 // Calculate the Weibull random variable.
625 double r = scale * std::pow(-std::log(v), exponent);
626
627 // Use this value if it's acceptable.
628 if (bound == 0 || r <= bound)
629 {
630 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " scale: " << scale
631 << " shape: " << shape << " bound: " << bound);
632 return r;
633 }
634 }
635}
636
639{
640 auto v = static_cast<uint32_t>(GetValue(scale, shape, bound));
641 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " scale: " << scale
642 << " shape: " << shape << " bound: " << bound);
643 return v;
644}
645
646double
652
654
655TypeId
657{
658 static TypeId tid =
659 TypeId("ns3::NormalRandomVariable")
661 .SetGroupName("Core")
662 .AddConstructor<NormalRandomVariable>()
663 .AddAttribute("Mean",
664 "The mean value for the normal distribution returned by this RNG stream.",
665 DoubleValue(0.0),
668 .AddAttribute(
669 "Variance",
670 "The variance value for the normal distribution returned by this RNG stream.",
671 DoubleValue(1.0),
674 .AddAttribute("Bound",
675 "The bound on the values returned by this RNG stream.",
679 return tid;
680}
681
683 : m_nextValid(false)
684{
685 // m_mean, m_variance, and m_bound are initialized after constructor
686 // by attributes
687 NS_LOG_FUNCTION(this);
688}
689
690double
692{
693 return m_mean;
694}
695
696double
698{
699 return m_variance;
700}
701
702double
704{
705 return m_bound;
706}
707
708double
709NormalRandomVariable::GetValue(double mean, double variance, double bound)
710{
711 if (m_nextValid)
712 { // use previously generated
713 m_nextValid = false;
714 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
715 if (std::fabs(x2 - mean) <= bound)
716 {
717 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
718 << " variance: " << variance << " bound: " << bound);
719 return x2;
720 }
721 }
722 while (true)
723 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
724 // for algorithm; basically a Box-Muller transform:
725 // http://en.wikipedia.org/wiki/Box-Muller_transform
726 double u1 = Peek()->RandU01();
727 double u2 = Peek()->RandU01();
728 if (IsAntithetic())
729 {
730 u1 = (1 - u1);
731 u2 = (1 - u2);
732 }
733 double v1 = 2 * u1 - 1;
734 double v2 = 2 * u2 - 1;
735 double w = v1 * v1 + v2 * v2;
736 if (w <= 1.0)
737 { // Got good pair
738 double y = std::sqrt((-2 * std::log(w)) / w);
739 double x1 = mean + v1 * y * std::sqrt(variance);
740 // if x1 is in bounds, return it, cache v2 and y
741 if (std::fabs(x1 - mean) <= bound)
742 {
743 m_nextValid = true;
744 m_y = y;
745 m_v2 = v2;
746 NS_LOG_DEBUG("value: " << x1 << " stream: " << GetStream() << " mean: " << mean
747 << " variance: " << variance << " bound: " << bound);
748 return x1;
749 }
750 // otherwise try and return the other if it is valid
751 double x2 = mean + v2 * y * std::sqrt(variance);
752 if (std::fabs(x2 - mean) <= bound)
753 {
754 m_nextValid = false;
755 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
756 << " variance: " << variance << " bound: " << bound);
757 return x2;
758 }
759 // otherwise, just run this loop again
760 }
761 }
762}
763
766{
767 auto v = static_cast<uint32_t>(GetValue(mean, variance, bound));
768 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
769 << " variance: " << variance << " bound: " << bound);
770 return v;
771}
772
773double
778
780
781TypeId
783{
784 static TypeId tid =
785 TypeId("ns3::LogNormalRandomVariable")
787 .SetGroupName("Core")
788 .AddConstructor<LogNormalRandomVariable>()
789 .AddAttribute(
790 "Mu",
791 "The mu value for the log-normal distribution returned by this RNG stream.",
792 DoubleValue(0.0),
795 .AddAttribute(
796 "Sigma",
797 "The sigma value for the log-normal distribution returned by this RNG stream.",
798 DoubleValue(1.0),
801 return tid;
802}
803
805 : m_nextValid(false)
806{
807 // m_mu and m_sigma are initialized after constructor by
808 // attributes
809 NS_LOG_FUNCTION(this);
810}
811
812double
814{
815 return m_mu;
816}
817
818double
820{
821 return m_sigma;
822}
823
824// The code from this function was adapted from the GNU Scientific
825// Library 1.8:
826/* randist/lognormal.c
827 *
828 * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
829 *
830 * SPDX-License-Identifier: GPL-2.0-or-later
831 */
832/* The lognormal distribution has the form
833
834 p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
835
836 for x > 0. Lognormal random numbers are the exponentials of
837 gaussian random numbers */
838double
839LogNormalRandomVariable::GetValue(double mu, double sigma)
840{
841 if (m_nextValid)
842 { // use previously generated
843 m_nextValid = false;
844 double v = std::exp(sigma * m_v2 * m_normal + mu);
845 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mu: " << mu
846 << " sigma: " << sigma);
847 return v;
848 }
849
850 double v1;
851 double v2;
852 double r2;
853 double normal;
854 double x;
855
856 do
857 {
858 /* choose x,y in uniform square (-1,-1) to (+1,+1) */
859
860 double u1 = Peek()->RandU01();
861 double u2 = Peek()->RandU01();
862 if (IsAntithetic())
863 {
864 u1 = (1 - u1);
865 u2 = (1 - u2);
866 }
867
868 v1 = -1 + 2 * u1;
869 v2 = -1 + 2 * u2;
870
871 /* see if it is in the unit circle */
872 r2 = v1 * v1 + v2 * v2;
873 } while (r2 > 1.0 || r2 == 0);
874
875 m_normal = std::sqrt(-2.0 * std::log(r2) / r2);
876 normal = v1 * m_normal;
877 m_nextValid = true;
878 m_v2 = v2;
879
880 x = std::exp(sigma * normal + mu);
881 NS_LOG_DEBUG("value: " << x << " stream: " << GetStream() << " mu: " << mu
882 << " sigma: " << sigma);
883
884 return x;
885}
886
889{
890 auto v = static_cast<uint32_t>(GetValue(mu, sigma));
891 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mu: " << mu
892 << " sigma: " << sigma);
893 return v;
894}
895
896double
901
903
904TypeId
906{
907 static TypeId tid =
908 TypeId("ns3::GammaRandomVariable")
910 .SetGroupName("Core")
911 .AddConstructor<GammaRandomVariable>()
912 .AddAttribute("Alpha",
913 "The alpha value for the gamma distribution returned by this RNG stream.",
914 DoubleValue(1.0),
917 .AddAttribute("Beta",
918 "The beta value for the gamma distribution returned by this RNG stream.",
919 DoubleValue(1.0),
922 return tid;
923}
924
926 : m_nextValid(false)
927{
928 // m_alpha and m_beta are initialized after constructor by
929 // attributes
930 NS_LOG_FUNCTION(this);
931}
932
933double
935{
936 return m_alpha;
937}
938
939double
941{
942 return m_beta;
943}
944
945/*
946 The code for the following generator functions was adapted from ns-2
947 tools/ranvar.cc
948
949 Originally the algorithm was devised by Marsaglia in 2000:
950 G. Marsaglia, W. W. Tsang: A simple method for generating Gamma variables
951 ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
952
953 The Gamma distribution density function has the form
954
955 x^(alpha-1) * exp(-x/beta)
956 p(x; alpha, beta) = ----------------------------
957 beta^alpha * Gamma(alpha)
958
959 for x > 0.
960*/
961double
962GammaRandomVariable::GetValue(double alpha, double beta)
963{
964 if (alpha < 1)
965 {
966 double u = Peek()->RandU01();
967 if (IsAntithetic())
968 {
969 u = (1 - u);
970 }
971 double v = GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
972 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " alpha: " << alpha
973 << " beta: " << beta);
974 return GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
975 }
976
977 double x;
978 double v;
979 double u;
980 double d = alpha - 1.0 / 3.0;
981 double c = (1.0 / 3.0) / std::sqrt(d);
982
983 while (true)
984 {
985 do
986 {
987 // Get a value from a normal distribution that has mean
988 // zero, variance 1, and no bound.
989 double mean = 0.0;
990 double variance = 1.0;
992 x = GetNormalValue(mean, variance, bound);
993
994 v = 1.0 + c * x;
995 } while (v <= 0);
996
997 v = v * v * v;
998 u = Peek()->RandU01();
999 if (IsAntithetic())
1000 {
1001 u = (1 - u);
1002 }
1003 if (u < 1 - 0.0331 * x * x * x * x)
1004 {
1005 break;
1006 }
1007 if (std::log(u) < 0.5 * x * x + d * (1 - v + std::log(v)))
1008 {
1009 break;
1010 }
1011 }
1012
1013 double value = beta * d * v;
1014 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream() << " alpha: " << alpha
1015 << " beta: " << beta);
1016 return value;
1017}
1018
1019double
1024
1025double
1026GammaRandomVariable::GetNormalValue(double mean, double variance, double bound)
1027{
1028 if (m_nextValid)
1029 { // use previously generated
1030 m_nextValid = false;
1031 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
1032 if (std::fabs(x2 - mean) <= bound)
1033 {
1034 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
1035 << " variance: " << variance << " bound: " << bound);
1036 return x2;
1037 }
1038 }
1039 while (true)
1040 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1041 // for algorithm; basically a Box-Muller transform:
1042 // http://en.wikipedia.org/wiki/Box-Muller_transform
1043 double u1 = Peek()->RandU01();
1044 double u2 = Peek()->RandU01();
1045 if (IsAntithetic())
1046 {
1047 u1 = (1 - u1);
1048 u2 = (1 - u2);
1049 }
1050 double v1 = 2 * u1 - 1;
1051 double v2 = 2 * u2 - 1;
1052 double w = v1 * v1 + v2 * v2;
1053 if (w <= 1.0)
1054 { // Got good pair
1055 double y = std::sqrt((-2 * std::log(w)) / w);
1056 double x1 = mean + v1 * y * std::sqrt(variance);
1057 // if x1 is in bounds, return it, cache v2 an y
1058 if (std::fabs(x1 - mean) <= bound)
1059 {
1060 m_nextValid = true;
1061 m_y = y;
1062 m_v2 = v2;
1063 NS_LOG_DEBUG("value: " << x1 << " stream: " << GetStream() << " mean: " << mean
1064 << " variance: " << variance << " bound: " << bound);
1065 return x1;
1066 }
1067 // otherwise try and return the other if it is valid
1068 double x2 = mean + v2 * y * std::sqrt(variance);
1069 if (std::fabs(x2 - mean) <= bound)
1070 {
1071 m_nextValid = false;
1072 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
1073 << " variance: " << variance << " bound: " << bound);
1074 return x2;
1075 }
1076 // otherwise, just run this loop again
1077 }
1078 }
1079}
1080
1082
1083TypeId
1085{
1086 static TypeId tid =
1087 TypeId("ns3::ErlangRandomVariable")
1089 .SetGroupName("Core")
1090 .AddConstructor<ErlangRandomVariable>()
1091 .AddAttribute("K",
1092 "The k value for the Erlang distribution returned by this RNG stream.",
1093 IntegerValue(1),
1096 .AddAttribute(
1097 "Lambda",
1098 "The lambda value for the Erlang distribution returned by this RNG stream.",
1099 DoubleValue(1.0),
1102 return tid;
1103}
1104
1106{
1107 // m_k and m_lambda are initialized after constructor by attributes
1108 NS_LOG_FUNCTION(this);
1109}
1110
1113{
1114 return m_k;
1115}
1116
1117double
1119{
1120 return m_lambda;
1121}
1122
1123/*
1124 The code for the following generator functions was adapted from ns-2
1125 tools/ranvar.cc
1126
1127 The Erlang distribution density function has the form
1128
1129 x^(k-1) * exp(-x/lambda)
1130 p(x; k, lambda) = ---------------------------
1131 lambda^k * (k-1)!
1132
1133 for x > 0.
1134*/
1135double
1137{
1138 double mean = lambda;
1139 double bound = 0.0;
1140
1141 double result = 0;
1142 for (unsigned int i = 0; i < k; ++i)
1143 {
1144 result += GetExponentialValue(mean, bound);
1145 }
1146 NS_LOG_DEBUG("value: " << result << " stream: " << GetStream() << " k: " << k
1147 << " lambda: " << lambda);
1148 return result;
1149}
1150
1153{
1154 auto v = static_cast<uint32_t>(GetValue(k, lambda));
1155 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " k: " << k
1156 << " lambda: " << lambda);
1157 return v;
1158}
1159
1160double
1165
1166double
1168{
1169 while (true)
1170 {
1171 // Get a uniform random variable in [0,1].
1172 double v = Peek()->RandU01();
1173 if (IsAntithetic())
1174 {
1175 v = (1 - v);
1176 }
1177
1178 // Calculate the exponential random variable.
1179 double r = -mean * std::log(v);
1180
1181 // Use this value if it's acceptable.
1182 if (bound == 0 || r <= bound)
1183 {
1184 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " mean:: " << mean
1185 << " bound: " << bound);
1186 return r;
1187 }
1188 }
1189}
1190
1192
1193TypeId
1195{
1196 static TypeId tid =
1197 TypeId("ns3::TriangularRandomVariable")
1199 .SetGroupName("Core")
1200 .AddConstructor<TriangularRandomVariable>()
1201 .AddAttribute(
1202 "Mean",
1203 "The mean value for the triangular distribution returned by this RNG stream.",
1204 DoubleValue(0.5),
1207 .AddAttribute("Min",
1208 "The lower bound on the values returned by this RNG stream.",
1209 DoubleValue(0.0),
1212 .AddAttribute("Max",
1213 "The upper bound on the values returned by this RNG stream.",
1214 DoubleValue(1.0),
1217 return tid;
1218}
1219
1221{
1222 // m_mean, m_min, and m_max are initialized after constructor by
1223 // attributes
1224 NS_LOG_FUNCTION(this);
1225}
1226
1227double
1229{
1230 return m_mean;
1231}
1232
1233double
1235{
1236 return m_min;
1237}
1238
1239double
1241{
1242 return m_max;
1243}
1244
1245double
1246TriangularRandomVariable::GetValue(double mean, double min, double max)
1247{
1248 // Calculate the mode.
1249 double mode = 3.0 * mean - min - max;
1250
1251 // Get a uniform random variable in [0,1].
1252 double u = Peek()->RandU01();
1253 if (IsAntithetic())
1254 {
1255 u = (1 - u);
1256 }
1257
1258 // Calculate the triangular random variable.
1259 if (u <= (mode - min) / (max - min))
1260 {
1261 double v = min + std::sqrt(u * (max - min) * (mode - min));
1262 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mean: " << mean
1263 << " min: " << min << " max: " << max);
1264 return v;
1265 }
1266 else
1267 {
1268 double v = max - std::sqrt((1 - u) * (max - min) * (max - mode));
1269 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mean: " << mean
1270 << " min: " << min << " max: " << max);
1271 return v;
1272 }
1273}
1274
1277{
1278 auto v = static_cast<uint32_t>(GetValue(mean, min, max));
1279 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
1280 << " min: " << min << " max: " << max);
1281 return v;
1282}
1283
1284double
1289
1291
1292TypeId
1294{
1295 static TypeId tid =
1296 TypeId("ns3::ZipfRandomVariable")
1298 .SetGroupName("Core")
1299 .AddConstructor<ZipfRandomVariable>()
1300 .AddAttribute("N",
1301 "The n value for the Zipf distribution returned by this RNG stream.",
1302 IntegerValue(1),
1305 .AddAttribute("Alpha",
1306 "The alpha value for the Zipf distribution returned by this RNG stream.",
1307 DoubleValue(0.0),
1310 return tid;
1311}
1312
1314{
1315 // m_n and m_alpha are initialized after constructor by attributes
1316 NS_LOG_FUNCTION(this);
1317}
1318
1321{
1322 return m_n;
1323}
1324
1325double
1327{
1328 return m_alpha;
1329}
1330
1331double
1333{
1334 // Calculate the normalization constant c.
1335 m_c = 0.0;
1336 for (uint32_t i = 1; i <= n; i++)
1337 {
1338 m_c += (1.0 / std::pow((double)i, alpha));
1339 }
1340 m_c = 1.0 / m_c;
1341
1342 // Get a uniform random variable in [0,1].
1343 double u = Peek()->RandU01();
1344 if (IsAntithetic())
1345 {
1346 u = (1 - u);
1347 }
1348
1349 double sum_prob = 0;
1350 double zipf_value = 0;
1351 for (uint32_t i = 1; i <= n; i++)
1352 {
1353 sum_prob += m_c / std::pow((double)i, alpha);
1354 if (sum_prob > u)
1355 {
1356 zipf_value = i;
1357 break;
1358 }
1359 }
1360 NS_LOG_DEBUG("value: " << zipf_value << " stream: " << GetStream() << " n: " << n
1361 << " alpha: " << alpha);
1362 return zipf_value;
1363}
1364
1367{
1368 NS_LOG_FUNCTION(this << n << alpha);
1369 auto v = static_cast<uint32_t>(GetValue(n, alpha));
1370 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " n: " << n
1371 << " alpha: " << alpha);
1372 return v;
1373}
1374
1375double
1380
1382
1383TypeId
1385{
1386 static TypeId tid =
1387 TypeId("ns3::ZetaRandomVariable")
1389 .SetGroupName("Core")
1390 .AddConstructor<ZetaRandomVariable>()
1391 .AddAttribute("Alpha",
1392 "The alpha value for the zeta distribution returned by this RNG stream.",
1393 DoubleValue(3.14),
1396 return tid;
1397}
1398
1400{
1401 // m_alpha is initialized after constructor by attributes
1402 NS_LOG_FUNCTION(this);
1403}
1404
1405double
1407{
1408 return m_alpha;
1409}
1410
1411double
1413{
1414 m_b = std::pow(2.0, alpha - 1.0);
1415
1416 double u;
1417 double v;
1418 double X;
1419 double T;
1420 double test;
1421
1422 do
1423 {
1424 // Get a uniform random variable in [0,1].
1425 u = Peek()->RandU01();
1426 if (IsAntithetic())
1427 {
1428 u = (1 - u);
1429 }
1430
1431 // Get a uniform random variable in [0,1].
1432 v = Peek()->RandU01();
1433 if (IsAntithetic())
1434 {
1435 v = (1 - v);
1436 }
1437
1438 X = std::floor(std::pow(u, -1.0 / (alpha - 1.0)));
1439 T = std::pow(1.0 + 1.0 / X, alpha - 1.0);
1440 test = v * X * (T - 1.0) / (m_b - 1.0);
1441 } while (test > (T / m_b));
1442 NS_LOG_DEBUG("value: " << X << " stream: " << GetStream() << " alpha: " << alpha);
1443 return X;
1444}
1445
1448{
1449 auto v = static_cast<uint32_t>(GetValue(alpha));
1450 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " alpha: " << alpha);
1451 return v;
1452}
1453
1454double
1459
1461
1462TypeId
1464{
1465 static TypeId tid = TypeId("ns3::DeterministicRandomVariable")
1467 .SetGroupName("Core")
1468 .AddConstructor<DeterministicRandomVariable>();
1469 return tid;
1470}
1471
1473 : m_count(0),
1474 m_next(0),
1475 m_data(nullptr)
1476{
1477 NS_LOG_FUNCTION(this);
1478}
1479
1481{
1482 // Delete any values currently set.
1483 NS_LOG_FUNCTION(this);
1484 if (m_data != nullptr)
1485 {
1486 delete[] m_data;
1487 }
1488}
1489
1490void
1491DeterministicRandomVariable::SetValueArray(const std::vector<double>& values)
1492{
1493 SetValueArray(values.data(), values.size());
1494}
1495
1496void
1497DeterministicRandomVariable::SetValueArray(const double* values, std::size_t length)
1498{
1499 NS_LOG_FUNCTION(this << values << length);
1500 // Delete any values currently set.
1501 if (m_data != nullptr)
1502 {
1503 delete[] m_data;
1504 }
1505
1506 // Make room for the values being set.
1507 m_data = new double[length];
1508 m_count = length;
1509 m_next = length;
1510
1511 // Copy the values.
1512 for (std::size_t i = 0; i < m_count; i++)
1513 {
1514 m_data[i] = values[i];
1515 }
1516}
1517
1518double
1520{
1521 // Make sure the array has been set.
1522 NS_ASSERT(m_count > 0);
1523
1524 if (m_next == m_count)
1525 {
1526 m_next = 0;
1527 }
1528 double v = m_data[m_next++];
1529 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream());
1530 return v;
1531}
1532
1534
1535TypeId
1537{
1538 static TypeId tid =
1539 TypeId("ns3::EmpiricalRandomVariable")
1541 .SetGroupName("Core")
1542 .AddConstructor<EmpiricalRandomVariable>()
1543 .AddAttribute("Interpolate",
1544 "Treat the CDF as a smooth distribution and interpolate, "
1545 "default is to treat the CDF as a histogram and sample.",
1546 BooleanValue(false),
1549 return tid;
1550}
1551
1553 : m_validated(false)
1554{
1555 NS_LOG_FUNCTION(this);
1556}
1557
1558bool
1560{
1561 NS_LOG_FUNCTION(this << interpolate);
1562 bool prev = m_interpolate;
1563 m_interpolate = interpolate;
1564 return prev;
1565}
1566
1567bool
1569{
1570 NS_LOG_FUNCTION(this << value);
1571 if (!m_validated)
1572 {
1573 Validate();
1574 }
1575
1576 // Get a uniform random variable in [0, 1].
1577 double r = Peek()->RandU01();
1578 if (IsAntithetic())
1579 {
1580 r = (1 - r);
1581 }
1582
1583 value = r;
1584 bool valid = false;
1585 // check extrema
1586 if (r <= m_empCdf.begin()->first)
1587 {
1588 value = m_empCdf.begin()->second; // Less than first
1589 valid = true;
1590 }
1591 else if (r >= m_empCdf.rbegin()->first)
1592 {
1593 value = m_empCdf.rbegin()->second; // Greater than last
1594 valid = true;
1595 }
1596 return valid;
1597}
1598
1599double
1601{
1602 double value;
1603 if (PreSample(value))
1604 {
1605 return value;
1606 }
1607
1608 // value now has the (unused) URNG selector
1609 if (m_interpolate)
1610 {
1611 value = DoInterpolate(value);
1612 }
1613 else
1614 {
1615 value = DoSampleCDF(value);
1616 }
1617 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream());
1618 return value;
1619}
1620
1621double
1623{
1624 NS_LOG_FUNCTION(this << r);
1625
1626 // Find first CDF that is greater than r
1627 auto bound = m_empCdf.upper_bound(r);
1628
1629 return bound->second;
1630}
1631
1632double
1634{
1635 NS_LOG_FUNCTION(this);
1636
1637 double value;
1638 if (PreSample(value))
1639 {
1640 return value;
1641 }
1642
1643 // value now has the (unused) URNG selector
1644 value = DoInterpolate(value);
1645 return value;
1646}
1647
1648double
1650{
1651 NS_LOG_FUNCTION(this << r);
1652
1653 // Return a value from the empirical distribution
1654 // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1655
1656 // search
1657 auto upper = m_empCdf.upper_bound(r);
1658 auto lower = std::prev(upper, 1);
1659
1660 if (upper == m_empCdf.begin())
1661 {
1662 lower = upper;
1663 }
1664
1665 // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1666 double c1 = lower->first;
1667 double c2 = upper->first;
1668 double v1 = lower->second;
1669 double v2 = upper->second;
1670
1671 double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1672 return value;
1673}
1674
1675void
1677{
1678 NS_LOG_FUNCTION(this << v << c);
1679
1680 auto vPrevious = m_empCdf.find(c);
1681
1682 if (vPrevious != m_empCdf.end())
1683 {
1684 NS_LOG_WARN("Empirical CDF already has a value " << vPrevious->second << " for CDF " << c
1685 << ". Overwriting it with value " << v
1686 << ".");
1687 }
1688
1689 m_empCdf[c] = v;
1690}
1691
1692void
1694{
1695 NS_LOG_FUNCTION(this);
1696
1697 if (m_empCdf.empty())
1698 {
1699 NS_FATAL_ERROR("CDF is not initialized");
1700 }
1701
1702 double vPrev = m_empCdf.begin()->second;
1703
1704 // Check if values are non-decreasing
1705 for (const auto& cdfPair : m_empCdf)
1706 {
1707 const auto& vCurr = cdfPair.second;
1708
1709 if (vCurr < vPrev)
1710 {
1711 NS_FATAL_ERROR("Empirical distribution has decreasing CDF values. Current CDF: "
1712 << vCurr << ", prior CDF: " << vPrev);
1713 }
1714
1715 vPrev = vCurr;
1716 }
1717
1718 // Bounds check on CDF endpoints
1719 auto firstCdfPair = m_empCdf.begin();
1720 auto lastCdfPair = m_empCdf.rbegin();
1721
1722 if (firstCdfPair->first < 0.0)
1723 {
1724 NS_FATAL_ERROR("Empirical distribution has invalid first CDF value. CDF: "
1725 << firstCdfPair->first << ", Value: " << firstCdfPair->second);
1726 }
1727
1728 if (lastCdfPair->first > 1.0)
1729 {
1730 NS_FATAL_ERROR("Empirical distribution has invalid last CDF value. CDF: "
1731 << lastCdfPair->first << ", Value: " << lastCdfPair->second);
1732 }
1733
1734 m_validated = true;
1735}
1736
1738
1739TypeId
1741{
1742 static TypeId tid =
1743 TypeId("ns3::BinomialRandomVariable")
1745 .SetGroupName("Core")
1746 .AddConstructor<BinomialRandomVariable>()
1747 .AddAttribute("Trials",
1748 "The number of trials.",
1749 IntegerValue(10),
1752 .AddAttribute("Probability",
1753 "The probability of success in each trial.",
1754 DoubleValue(0.5),
1757 return tid;
1758}
1759
1761{
1762 // m_trials and m_probability are initialized after constructor by attributes
1763 NS_LOG_FUNCTION(this);
1764}
1765
1766double
1768{
1769 double successes = 0;
1770
1771 for (uint32_t i = 0; i < trials; ++i)
1772 {
1773 double v = Peek()->RandU01();
1774 if (IsAntithetic())
1775 {
1776 v = (1 - v);
1777 }
1778
1779 if (v <= probability)
1780 {
1781 successes += 1;
1782 }
1783 }
1784 NS_LOG_DEBUG("value: " << successes << " stream: " << GetStream() << " trials: " << trials
1785 << " probability: " << probability);
1786 return successes;
1787}
1788
1791{
1792 auto v = static_cast<uint32_t>(GetValue(trials, probability));
1793 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " trials: " << trials
1794 << " probability: " << probability);
1795 return v;
1796}
1797
1798double
1803
1805
1806TypeId
1808{
1809 static TypeId tid =
1810 TypeId("ns3::BernoulliRandomVariable")
1812 .SetGroupName("Core")
1813 .AddConstructor<BernoulliRandomVariable>()
1814 .AddAttribute("Probability",
1815 "The probability of the random variable returning a value of 1.",
1816 DoubleValue(0.5),
1819 return tid;
1820}
1821
1823{
1824 // m_probability is initialized after constructor by attributes
1825 NS_LOG_FUNCTION(this);
1826}
1827
1828double
1830{
1831 double v = Peek()->RandU01();
1832 if (IsAntithetic())
1833 {
1834 v = (1 - v);
1835 }
1836
1837 double value = (v <= probability) ? 1.0 : 0.0;
1838 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream()
1839 << " probability: " << probability);
1840 return value;
1841}
1842
1845{
1846 auto v = static_cast<uint32_t>(GetValue(probability));
1847 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream()
1848 << " probability: " << probability);
1849 return v;
1850}
1851
1852double
1857
1859
1860TypeId
1862{
1863 static TypeId tid =
1864 TypeId("ns3::LaplacianRandomVariable")
1866 .SetGroupName("Core")
1867 .AddConstructor<LaplacianRandomVariable>()
1868 .AddAttribute("Location",
1869 "The location parameter for the Laplacian distribution returned by this "
1870 "RNG stream.",
1871 DoubleValue(0.0),
1874 .AddAttribute(
1875 "Scale",
1876 "The scale parameter for the Laplacian distribution returned by this RNG stream.",
1877 DoubleValue(1.0),
1880 .AddAttribute("Bound",
1881 "The bound on the values returned by this RNG stream.",
1882 DoubleValue(0.0),
1885 return tid;
1886}
1887
1892
1893double
1895{
1896 return m_location;
1897}
1898
1899double
1901{
1902 return m_scale;
1903}
1904
1905double
1907{
1908 return m_bound;
1909}
1910
1911double
1912LaplacianRandomVariable::GetValue(double location, double scale, double bound)
1913{
1914 NS_LOG_FUNCTION(this << location << scale << bound);
1915 NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
1916
1917 while (true)
1918 {
1919 // Get a uniform random variable in [-0.5,0.5].
1920 auto v = (Peek()->RandU01() - 0.5);
1921 if (IsAntithetic())
1922 {
1923 v = (1 - v);
1924 }
1925
1926 // Calculate the laplacian random variable.
1927 const auto sgn = (v > 0) ? 1 : ((v < 0) ? -1 : 0);
1928 const auto r = location - (scale * sgn * std::log(1.0 - (2.0 * std::abs(v))));
1929
1930 // Use this value if it's acceptable.
1931 if (bound == 0.0 || std::fabs(r - location) <= bound)
1932 {
1933 return r;
1934 }
1935 }
1936}
1937
1940{
1941 NS_LOG_FUNCTION(this << location << scale << bound);
1942 return static_cast<uint32_t>(GetValue(location, scale, bound));
1943}
1944
1945double
1951
1952double
1954{
1955 NS_LOG_FUNCTION(scale);
1956 return 2.0 * std::pow(scale, 2.0);
1957}
1958
1959double
1964
1966
1967TypeId
1969{
1970 static TypeId tid =
1971 TypeId("ns3::LargestExtremeValueRandomVariable")
1973 .SetGroupName("Core")
1974 .AddConstructor<LargestExtremeValueRandomVariable>()
1975 .AddAttribute("Location",
1976 "The location parameter for the Largest Extreme Value distribution "
1977 "returned by this RNG stream.",
1978 DoubleValue(0.0),
1981 .AddAttribute("Scale",
1982 "The scale parameter for the Largest Extreme Value distribution "
1983 "returned by this RNG stream.",
1984 DoubleValue(1.0),
1987 return tid;
1988}
1989
1994
1995double
2000
2001double
2006
2007double
2009{
2010 NS_LOG_FUNCTION(this << location << scale);
2011 NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
2012
2013 // Get a uniform random variable in [0,1].
2014 auto v = Peek()->RandU01();
2015 if (IsAntithetic())
2016 {
2017 v = (1 - v);
2018 }
2019
2020 // Calculate the largest extreme value random variable.
2021 const auto t = std::log(v) * (-1.0);
2022 const auto r = location - (scale * std::log(t));
2023
2024 return r;
2025}
2026
2029{
2030 NS_LOG_FUNCTION(this << location << scale);
2031 return static_cast<uint32_t>(GetValue(location, scale));
2032}
2033
2034double
2040
2041double
2043{
2044 NS_LOG_FUNCTION(location << scale);
2045 return (location + (scale * std::numbers::egamma));
2046}
2047
2048double
2053
2054double
2056{
2057 NS_LOG_FUNCTION(scale);
2058 return std::pow((scale * std::numbers::pi), 2) / 6.0;
2059}
2060
2061double
2066
2067} // namespace ns3
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
ns3::BooleanValue attribute value declarations.
The Bernoulli distribution Random Number Generator (RNG).
double GetValue() override
Get the next random value drawn from the distribution.
double m_probability
The probability of success.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
The binomial distribution Random Number Generator (RNG).
double m_probability
The probability of success in each trial.
double GetValue() override
Get the next random value drawn from the distribution.
static TypeId GetTypeId()
Register this type.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
uint32_t m_trials
The number of trials.
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 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 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.
A base class which provides memory management and object aggregation.
Definition object.h:78
TypeId GetInstanceTypeId() const final
Get the most derived TypeId for this Object.
Definition object.cc:83
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.
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:1001
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:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#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:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#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
ns3::UintegerValue attribute value declarations and template implementations.