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
44
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
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),
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
354 m_current += m_increment->GetValue();
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
690void
692{
693 m_variance = stdDev * stdDev;
694}
695
696double
698{
699 return m_mean;
700}
701
702double
704{
705 return m_variance;
706}
707
708double
710{
711 return sqrt(m_variance);
712}
713
714double
716{
717 return m_bound;
718}
719
720double
721NormalRandomVariable::GetValue(double mean, double variance, double bound)
722{
723 if (m_nextValid)
724 { // use previously generated
725 m_nextValid = false;
726 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
727 if (std::fabs(x2 - mean) <= bound)
728 {
729 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
730 << " variance: " << variance << " bound: " << bound);
731 return x2;
732 }
733 }
734 while (true)
735 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
736 // for algorithm; basically a Box-Muller transform:
737 // http://en.wikipedia.org/wiki/Box-Muller_transform
738 double u1 = Peek()->RandU01();
739 double u2 = Peek()->RandU01();
740 if (IsAntithetic())
741 {
742 u1 = (1 - u1);
743 u2 = (1 - u2);
744 }
745 double v1 = 2 * u1 - 1;
746 double v2 = 2 * u2 - 1;
747 double w = v1 * v1 + v2 * v2;
748 if (w <= 1.0)
749 { // Got good pair
750 double y = std::sqrt((-2 * std::log(w)) / w);
751 double x1 = mean + v1 * y * std::sqrt(variance);
752 // if x1 is in bounds, return it, cache v2 and y
753 if (std::fabs(x1 - mean) <= bound)
754 {
755 m_nextValid = true;
756 m_y = y;
757 m_v2 = v2;
758 NS_LOG_DEBUG("value: " << x1 << " stream: " << GetStream() << " mean: " << mean
759 << " variance: " << variance << " bound: " << bound);
760 return x1;
761 }
762 // otherwise try and return the other if it is valid
763 double x2 = mean + v2 * y * std::sqrt(variance);
764 if (std::fabs(x2 - mean) <= bound)
765 {
766 m_nextValid = false;
767 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
768 << " variance: " << variance << " bound: " << bound);
769 return x2;
770 }
771 // otherwise, just run this loop again
772 }
773 }
774}
775
778{
779 auto v = static_cast<uint32_t>(GetValue(mean, variance, bound));
780 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
781 << " variance: " << variance << " bound: " << bound);
782 return v;
783}
784
785double
790
792
793TypeId
795{
796 static TypeId tid =
797 TypeId("ns3::LogNormalRandomVariable")
799 .SetGroupName("Core")
800 .AddConstructor<LogNormalRandomVariable>()
801 .AddAttribute(
802 "Mu",
803 "The mu value for the log-normal distribution returned by this RNG stream.",
804 DoubleValue(0.0),
807 .AddAttribute(
808 "Sigma",
809 "The sigma value for the log-normal distribution returned by this RNG stream.",
810 DoubleValue(1.0),
813 return tid;
814}
815
817 : m_nextValid(false)
818{
819 // m_mu and m_sigma are initialized after constructor by
820 // attributes
821 NS_LOG_FUNCTION(this);
822}
823
824double
826{
827 return m_mu;
828}
829
830double
832{
833 return m_sigma;
834}
835
836// The code from this function was adapted from the GNU Scientific
837// Library 1.8:
838/* randist/lognormal.c
839 *
840 * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
841 *
842 * SPDX-License-Identifier: GPL-2.0-or-later
843 */
844/* The lognormal distribution has the form
845
846 p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
847
848 for x > 0. Lognormal random numbers are the exponentials of
849 gaussian random numbers */
850double
851LogNormalRandomVariable::GetValue(double mu, double sigma)
852{
853 if (m_nextValid)
854 { // use previously generated
855 m_nextValid = false;
856 double v = std::exp(sigma * m_v2 * m_normal + mu);
857 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mu: " << mu
858 << " sigma: " << sigma);
859 return v;
860 }
861
862 double v1;
863 double v2;
864 double r2;
865 double normal;
866 double x;
867
868 do
869 {
870 /* choose x,y in uniform square (-1,-1) to (+1,+1) */
871
872 double u1 = Peek()->RandU01();
873 double u2 = Peek()->RandU01();
874 if (IsAntithetic())
875 {
876 u1 = (1 - u1);
877 u2 = (1 - u2);
878 }
879
880 v1 = -1 + 2 * u1;
881 v2 = -1 + 2 * u2;
882
883 /* see if it is in the unit circle */
884 r2 = v1 * v1 + v2 * v2;
885 } while (r2 > 1.0 || r2 == 0);
886
887 m_normal = std::sqrt(-2.0 * std::log(r2) / r2);
888 normal = v1 * m_normal;
889 m_nextValid = true;
890 m_v2 = v2;
891
892 x = std::exp(sigma * normal + mu);
893 NS_LOG_DEBUG("value: " << x << " stream: " << GetStream() << " mu: " << mu
894 << " sigma: " << sigma);
895
896 return x;
897}
898
901{
902 auto v = static_cast<uint32_t>(GetValue(mu, sigma));
903 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mu: " << mu
904 << " sigma: " << sigma);
905 return v;
906}
907
908double
913
915
916TypeId
918{
919 static TypeId tid =
920 TypeId("ns3::GammaRandomVariable")
922 .SetGroupName("Core")
923 .AddConstructor<GammaRandomVariable>()
924 .AddAttribute("Alpha",
925 "The alpha value for the gamma distribution returned by this RNG stream.",
926 DoubleValue(1.0),
929 .AddAttribute("Beta",
930 "The beta value for the gamma distribution returned by this RNG stream.",
931 DoubleValue(1.0),
934 return tid;
935}
936
938 : m_nextValid(false)
939{
940 // m_alpha and m_beta are initialized after constructor by
941 // attributes
942 NS_LOG_FUNCTION(this);
943}
944
945double
947{
948 return m_alpha;
949}
950
951double
953{
954 return m_beta;
955}
956
957/*
958 The code for the following generator functions was adapted from ns-2
959 tools/ranvar.cc
960
961 Originally the algorithm was devised by Marsaglia in 2000:
962 G. Marsaglia, W. W. Tsang: A simple method for generating Gamma variables
963 ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
964
965 The Gamma distribution density function has the form
966
967 x^(alpha-1) * exp(-x/beta)
968 p(x; alpha, beta) = ----------------------------
969 beta^alpha * Gamma(alpha)
970
971 for x > 0.
972*/
973double
974GammaRandomVariable::GetValue(double alpha, double beta)
975{
976 if (alpha < 1)
977 {
978 double u = Peek()->RandU01();
979 if (IsAntithetic())
980 {
981 u = (1 - u);
982 }
983 double v = GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
984 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " alpha: " << alpha
985 << " beta: " << beta);
986 return GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
987 }
988
989 double x;
990 double v;
991 double u;
992 double d = alpha - 1.0 / 3.0;
993 double c = (1.0 / 3.0) / std::sqrt(d);
994
995 while (true)
996 {
997 do
998 {
999 // Get a value from a normal distribution that has mean
1000 // zero, variance 1, and no bound.
1001 double mean = 0.0;
1002 double variance = 1.0;
1004 x = GetNormalValue(mean, variance, bound);
1005
1006 v = 1.0 + c * x;
1007 } while (v <= 0);
1008
1009 v = v * v * v;
1010 u = Peek()->RandU01();
1011 if (IsAntithetic())
1012 {
1013 u = (1 - u);
1014 }
1015 if (u < 1 - 0.0331 * x * x * x * x)
1016 {
1017 break;
1018 }
1019 if (std::log(u) < 0.5 * x * x + d * (1 - v + std::log(v)))
1020 {
1021 break;
1022 }
1023 }
1024
1025 double value = beta * d * v;
1026 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream() << " alpha: " << alpha
1027 << " beta: " << beta);
1028 return value;
1029}
1030
1031double
1036
1037double
1038GammaRandomVariable::GetNormalValue(double mean, double variance, double bound)
1039{
1040 if (m_nextValid)
1041 { // use previously generated
1042 m_nextValid = false;
1043 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
1044 if (std::fabs(x2 - mean) <= bound)
1045 {
1046 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
1047 << " variance: " << variance << " bound: " << bound);
1048 return x2;
1049 }
1050 }
1051 while (true)
1052 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1053 // for algorithm; basically a Box-Muller transform:
1054 // http://en.wikipedia.org/wiki/Box-Muller_transform
1055 double u1 = Peek()->RandU01();
1056 double u2 = Peek()->RandU01();
1057 if (IsAntithetic())
1058 {
1059 u1 = (1 - u1);
1060 u2 = (1 - u2);
1061 }
1062 double v1 = 2 * u1 - 1;
1063 double v2 = 2 * u2 - 1;
1064 double w = v1 * v1 + v2 * v2;
1065 if (w <= 1.0)
1066 { // Got good pair
1067 double y = std::sqrt((-2 * std::log(w)) / w);
1068 double x1 = mean + v1 * y * std::sqrt(variance);
1069 // if x1 is in bounds, return it, cache v2 an y
1070 if (std::fabs(x1 - mean) <= bound)
1071 {
1072 m_nextValid = true;
1073 m_y = y;
1074 m_v2 = v2;
1075 NS_LOG_DEBUG("value: " << x1 << " stream: " << GetStream() << " mean: " << mean
1076 << " variance: " << variance << " bound: " << bound);
1077 return x1;
1078 }
1079 // otherwise try and return the other if it is valid
1080 double x2 = mean + v2 * y * std::sqrt(variance);
1081 if (std::fabs(x2 - mean) <= bound)
1082 {
1083 m_nextValid = false;
1084 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
1085 << " variance: " << variance << " bound: " << bound);
1086 return x2;
1087 }
1088 // otherwise, just run this loop again
1089 }
1090 }
1091}
1092
1094
1095TypeId
1097{
1098 static TypeId tid =
1099 TypeId("ns3::ErlangRandomVariable")
1101 .SetGroupName("Core")
1102 .AddConstructor<ErlangRandomVariable>()
1103 .AddAttribute("K",
1104 "The k value for the Erlang distribution returned by this RNG stream.",
1105 IntegerValue(1),
1108 .AddAttribute(
1109 "Lambda",
1110 "The lambda value for the Erlang distribution returned by this RNG stream.",
1111 DoubleValue(1.0),
1114 return tid;
1115}
1116
1118{
1119 // m_k and m_lambda are initialized after constructor by attributes
1120 NS_LOG_FUNCTION(this);
1121}
1122
1125{
1126 return m_k;
1127}
1128
1129double
1131{
1132 return m_lambda;
1133}
1134
1135/*
1136 The code for the following generator functions was adapted from ns-2
1137 tools/ranvar.cc
1138
1139 The Erlang distribution density function has the form
1140
1141 x^(k-1) * exp(-x/lambda)
1142 p(x; k, lambda) = ---------------------------
1143 lambda^k * (k-1)!
1144
1145 for x > 0.
1146*/
1147double
1149{
1150 double mean = lambda;
1151 double bound = 0.0;
1152
1153 double result = 0;
1154 for (unsigned int i = 0; i < k; ++i)
1155 {
1156 result += GetExponentialValue(mean, bound);
1157 }
1158 NS_LOG_DEBUG("value: " << result << " stream: " << GetStream() << " k: " << k
1159 << " lambda: " << lambda);
1160 return result;
1161}
1162
1165{
1166 auto v = static_cast<uint32_t>(GetValue(k, lambda));
1167 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " k: " << k
1168 << " lambda: " << lambda);
1169 return v;
1170}
1171
1172double
1177
1178double
1180{
1181 while (true)
1182 {
1183 // Get a uniform random variable in [0,1].
1184 double v = Peek()->RandU01();
1185 if (IsAntithetic())
1186 {
1187 v = (1 - v);
1188 }
1189
1190 // Calculate the exponential random variable.
1191 double r = -mean * std::log(v);
1192
1193 // Use this value if it's acceptable.
1194 if (bound == 0 || r <= bound)
1195 {
1196 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " mean:: " << mean
1197 << " bound: " << bound);
1198 return r;
1199 }
1200 }
1201}
1202
1204
1205TypeId
1207{
1208 static TypeId tid =
1209 TypeId("ns3::TriangularRandomVariable")
1211 .SetGroupName("Core")
1212 .AddConstructor<TriangularRandomVariable>()
1213 .AddAttribute(
1214 "Mean",
1215 "The mean value for the triangular distribution returned by this RNG stream.",
1216 DoubleValue(0.5),
1219 .AddAttribute("Min",
1220 "The lower bound on the values returned by this RNG stream.",
1221 DoubleValue(0.0),
1224 .AddAttribute("Max",
1225 "The upper bound on the values returned by this RNG stream.",
1226 DoubleValue(1.0),
1229 return tid;
1230}
1231
1233{
1234 // m_mean, m_min, and m_max are initialized after constructor by
1235 // attributes
1236 NS_LOG_FUNCTION(this);
1237}
1238
1239double
1241{
1242 return m_mean;
1243}
1244
1245double
1247{
1248 return m_min;
1249}
1250
1251double
1253{
1254 return m_max;
1255}
1256
1257double
1258TriangularRandomVariable::GetValue(double mean, double min, double max)
1259{
1260 // Calculate the mode.
1261 double mode = 3.0 * mean - min - max;
1262
1263 // Get a uniform random variable in [0,1].
1264 double u = Peek()->RandU01();
1265 if (IsAntithetic())
1266 {
1267 u = (1 - u);
1268 }
1269
1270 // Calculate the triangular random variable.
1271 if (u <= (mode - min) / (max - min))
1272 {
1273 double v = min + std::sqrt(u * (max - min) * (mode - min));
1274 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mean: " << mean
1275 << " min: " << min << " max: " << max);
1276 return v;
1277 }
1278 else
1279 {
1280 double v = max - std::sqrt((1 - u) * (max - min) * (max - mode));
1281 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mean: " << mean
1282 << " min: " << min << " max: " << max);
1283 return v;
1284 }
1285}
1286
1289{
1290 auto v = static_cast<uint32_t>(GetValue(mean, min, max));
1291 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
1292 << " min: " << min << " max: " << max);
1293 return v;
1294}
1295
1296double
1301
1303
1304TypeId
1306{
1307 static TypeId tid =
1308 TypeId("ns3::ZipfRandomVariable")
1310 .SetGroupName("Core")
1311 .AddConstructor<ZipfRandomVariable>()
1312 .AddAttribute("N",
1313 "The n value for the Zipf distribution returned by this RNG stream.",
1314 IntegerValue(1),
1317 .AddAttribute("Alpha",
1318 "The alpha value for the Zipf distribution returned by this RNG stream.",
1319 DoubleValue(0.0),
1322 return tid;
1323}
1324
1326{
1327 // m_n and m_alpha are initialized after constructor by attributes
1328 NS_LOG_FUNCTION(this);
1329}
1330
1333{
1334 return m_n;
1335}
1336
1337double
1339{
1340 return m_alpha;
1341}
1342
1343double
1345{
1346 // Calculate the normalization constant c.
1347 m_c = 0.0;
1348 for (uint32_t i = 1; i <= n; i++)
1349 {
1350 m_c += (1.0 / std::pow((double)i, alpha));
1351 }
1352 m_c = 1.0 / m_c;
1353
1354 // Get a uniform random variable in [0,1].
1355 double u = Peek()->RandU01();
1356 if (IsAntithetic())
1357 {
1358 u = (1 - u);
1359 }
1360
1361 double sum_prob = 0;
1362 double zipf_value = 0;
1363 for (uint32_t i = 1; i <= n; i++)
1364 {
1365 sum_prob += m_c / std::pow((double)i, alpha);
1366 if (sum_prob > u)
1367 {
1368 zipf_value = i;
1369 break;
1370 }
1371 }
1372 NS_LOG_DEBUG("value: " << zipf_value << " stream: " << GetStream() << " n: " << n
1373 << " alpha: " << alpha);
1374 return zipf_value;
1375}
1376
1379{
1380 NS_LOG_FUNCTION(this << n << alpha);
1381 auto v = static_cast<uint32_t>(GetValue(n, alpha));
1382 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " n: " << n
1383 << " alpha: " << alpha);
1384 return v;
1385}
1386
1387double
1392
1394
1395TypeId
1397{
1398 static TypeId tid =
1399 TypeId("ns3::ZetaRandomVariable")
1401 .SetGroupName("Core")
1402 .AddConstructor<ZetaRandomVariable>()
1403 .AddAttribute("Alpha",
1404 "The alpha value for the zeta distribution returned by this RNG stream.",
1405 DoubleValue(3.14),
1408 return tid;
1409}
1410
1412{
1413 // m_alpha is initialized after constructor by attributes
1414 NS_LOG_FUNCTION(this);
1415}
1416
1417double
1419{
1420 return m_alpha;
1421}
1422
1423double
1425{
1426 m_b = std::pow(2.0, alpha - 1.0);
1427
1428 double u;
1429 double v;
1430 double X;
1431 double T;
1432 double test;
1433
1434 do
1435 {
1436 // Get a uniform random variable in [0,1].
1437 u = Peek()->RandU01();
1438 if (IsAntithetic())
1439 {
1440 u = (1 - u);
1441 }
1442
1443 // Get a uniform random variable in [0,1].
1444 v = Peek()->RandU01();
1445 if (IsAntithetic())
1446 {
1447 v = (1 - v);
1448 }
1449
1450 X = std::floor(std::pow(u, -1.0 / (alpha - 1.0)));
1451 T = std::pow(1.0 + 1.0 / X, alpha - 1.0);
1452 test = v * X * (T - 1.0) / (m_b - 1.0);
1453 } while (test > (T / m_b));
1454 NS_LOG_DEBUG("value: " << X << " stream: " << GetStream() << " alpha: " << alpha);
1455 return X;
1456}
1457
1460{
1461 auto v = static_cast<uint32_t>(GetValue(alpha));
1462 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " alpha: " << alpha);
1463 return v;
1464}
1465
1466double
1471
1473
1474TypeId
1476{
1477 static TypeId tid = TypeId("ns3::DeterministicRandomVariable")
1479 .SetGroupName("Core")
1480 .AddConstructor<DeterministicRandomVariable>();
1481 return tid;
1482}
1483
1485 : m_count(0),
1486 m_next(0),
1487 m_data(nullptr)
1488{
1489 NS_LOG_FUNCTION(this);
1490}
1491
1493{
1494 // Delete any values currently set.
1495 NS_LOG_FUNCTION(this);
1496 if (m_data != nullptr)
1497 {
1498 delete[] m_data;
1499 }
1500}
1501
1502void
1503DeterministicRandomVariable::SetValueArray(const std::vector<double>& values)
1504{
1505 SetValueArray(values.data(), values.size());
1506}
1507
1508void
1509DeterministicRandomVariable::SetValueArray(const double* values, std::size_t length)
1510{
1511 NS_LOG_FUNCTION(this << values << length);
1512 // Delete any values currently set.
1513 if (m_data != nullptr)
1514 {
1515 delete[] m_data;
1516 }
1517
1518 // Make room for the values being set.
1519 m_data = new double[length];
1520 m_count = length;
1521 m_next = length;
1522
1523 // Copy the values.
1524 for (std::size_t i = 0; i < m_count; i++)
1525 {
1526 m_data[i] = values[i];
1527 }
1528}
1529
1530double
1532{
1533 // Make sure the array has been set.
1534 NS_ASSERT(m_count > 0);
1535
1536 if (m_next == m_count)
1537 {
1538 m_next = 0;
1539 }
1540 double v = m_data[m_next++];
1541 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream());
1542 return v;
1543}
1544
1546
1547TypeId
1549{
1550 static TypeId tid =
1551 TypeId("ns3::EmpiricalRandomVariable")
1553 .SetGroupName("Core")
1554 .AddConstructor<EmpiricalRandomVariable>()
1555 .AddAttribute("Interpolate",
1556 "Treat the CDF as a smooth distribution and interpolate, "
1557 "default is to treat the CDF as a histogram and sample.",
1558 BooleanValue(false),
1561 return tid;
1562}
1563
1569
1570bool
1572{
1573 NS_LOG_FUNCTION(this << interpolate);
1574 bool prev = m_interpolate;
1575 m_interpolate = interpolate;
1576 return prev;
1577}
1578
1579bool
1581{
1582 NS_LOG_FUNCTION(this << value);
1583 if (!m_validated)
1584 {
1585 Validate();
1586 }
1587
1588 // Get a uniform random variable in [0, 1].
1589 double r = Peek()->RandU01();
1590 if (IsAntithetic())
1591 {
1592 r = (1 - r);
1593 }
1594
1595 value = r;
1596 bool valid = false;
1597 // check extrema
1598 if (r <= m_empCdf.begin()->first)
1599 {
1600 value = m_empCdf.begin()->second; // Less than first
1601 valid = true;
1602 }
1603 else if (r >= m_empCdf.rbegin()->first)
1604 {
1605 value = m_empCdf.rbegin()->second; // Greater than last
1606 valid = true;
1607 }
1608 return valid;
1609}
1610
1611double
1613{
1614 double value;
1615 if (PreSample(value))
1616 {
1617 return value;
1618 }
1619
1620 // value now has the (unused) URNG selector
1621 if (m_interpolate)
1622 {
1623 value = DoInterpolate(value);
1624 }
1625 else
1626 {
1627 value = DoSampleCDF(value);
1628 }
1629 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream());
1630 return value;
1631}
1632
1633double
1635{
1636 NS_LOG_FUNCTION(this << r);
1637
1638 // Find first CDF that is greater than r
1639 auto bound = m_empCdf.upper_bound(r);
1640
1641 return bound->second;
1642}
1643
1644double
1646{
1647 NS_LOG_FUNCTION(this);
1648
1649 double value;
1650 if (PreSample(value))
1651 {
1652 return value;
1653 }
1654
1655 // value now has the (unused) URNG selector
1656 value = DoInterpolate(value);
1657 return value;
1658}
1659
1660double
1662{
1663 NS_LOG_FUNCTION(this << r);
1664
1665 // Return a value from the empirical distribution
1666 // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1667
1668 // search
1669 auto upper = m_empCdf.upper_bound(r);
1670 auto lower = std::prev(upper, 1);
1671
1672 if (upper == m_empCdf.begin())
1673 {
1674 lower = upper;
1675 }
1676
1677 // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1678 double c1 = lower->first;
1679 double c2 = upper->first;
1680 double v1 = lower->second;
1681 double v2 = upper->second;
1682
1683 double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1684 return value;
1685}
1686
1687void
1689{
1690 NS_LOG_FUNCTION(this << v << c);
1691
1692 auto vPrevious = m_empCdf.find(c);
1693
1694 if (vPrevious != m_empCdf.end())
1695 {
1696 NS_LOG_WARN("Empirical CDF already has a value " << vPrevious->second << " for CDF " << c
1697 << ". Overwriting it with value " << v
1698 << ".");
1699 }
1700
1701 m_empCdf[c] = v;
1702}
1703
1704void
1706{
1707 NS_LOG_FUNCTION(this);
1708
1709 if (m_empCdf.empty())
1710 {
1711 NS_FATAL_ERROR("CDF is not initialized");
1712 }
1713
1714 double vPrev = m_empCdf.begin()->second;
1715
1716 // Check if values are non-decreasing
1717 for (const auto& cdfPair : m_empCdf)
1718 {
1719 const auto& vCurr = cdfPair.second;
1720
1721 if (vCurr < vPrev)
1722 {
1723 NS_FATAL_ERROR("Empirical distribution has decreasing CDF values. Current CDF: "
1724 << vCurr << ", prior CDF: " << vPrev);
1725 }
1726
1727 vPrev = vCurr;
1728 }
1729
1730 // Bounds check on CDF endpoints
1731 auto firstCdfPair = m_empCdf.begin();
1732 auto lastCdfPair = m_empCdf.rbegin();
1733
1734 if (firstCdfPair->first < 0.0)
1735 {
1736 NS_FATAL_ERROR("Empirical distribution has invalid first CDF value. CDF: "
1737 << firstCdfPair->first << ", Value: " << firstCdfPair->second);
1738 }
1739
1740 if (lastCdfPair->first > 1.0)
1741 {
1742 NS_FATAL_ERROR("Empirical distribution has invalid last CDF value. CDF: "
1743 << lastCdfPair->first << ", Value: " << lastCdfPair->second);
1744 }
1745
1746 m_validated = true;
1747}
1748
1750
1751TypeId
1753{
1754 static TypeId tid =
1755 TypeId("ns3::BinomialRandomVariable")
1757 .SetGroupName("Core")
1758 .AddConstructor<BinomialRandomVariable>()
1759 .AddAttribute("Trials",
1760 "The number of trials.",
1761 IntegerValue(10),
1764 .AddAttribute("Probability",
1765 "The probability of success in each trial.",
1766 DoubleValue(0.5),
1769 return tid;
1770}
1771
1773{
1774 // m_trials and m_probability are initialized after constructor by attributes
1775 NS_LOG_FUNCTION(this);
1776}
1777
1778double
1780{
1781 double successes = 0;
1782
1783 for (uint32_t i = 0; i < trials; ++i)
1784 {
1785 double v = Peek()->RandU01();
1786 if (IsAntithetic())
1787 {
1788 v = (1 - v);
1789 }
1790
1791 if (v <= probability)
1792 {
1793 successes += 1;
1794 }
1795 }
1796 NS_LOG_DEBUG("value: " << successes << " stream: " << GetStream() << " trials: " << trials
1797 << " probability: " << probability);
1798 return successes;
1799}
1800
1803{
1804 auto v = static_cast<uint32_t>(GetValue(trials, probability));
1805 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " trials: " << trials
1806 << " probability: " << probability);
1807 return v;
1808}
1809
1810double
1815
1817
1818TypeId
1820{
1821 static TypeId tid =
1822 TypeId("ns3::BernoulliRandomVariable")
1824 .SetGroupName("Core")
1825 .AddConstructor<BernoulliRandomVariable>()
1826 .AddAttribute("Probability",
1827 "The probability of the random variable returning a value of 1.",
1828 DoubleValue(0.5),
1831 return tid;
1832}
1833
1835{
1836 // m_probability is initialized after constructor by attributes
1837 NS_LOG_FUNCTION(this);
1838}
1839
1840double
1842{
1843 double v = Peek()->RandU01();
1844 if (IsAntithetic())
1845 {
1846 v = (1 - v);
1847 }
1848
1849 double value = (v <= probability) ? 1.0 : 0.0;
1850 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream()
1851 << " probability: " << probability);
1852 return value;
1853}
1854
1857{
1858 auto v = static_cast<uint32_t>(GetValue(probability));
1859 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream()
1860 << " probability: " << probability);
1861 return v;
1862}
1863
1864double
1869
1871
1872TypeId
1874{
1875 static TypeId tid =
1876 TypeId("ns3::LaplacianRandomVariable")
1878 .SetGroupName("Core")
1879 .AddConstructor<LaplacianRandomVariable>()
1880 .AddAttribute("Location",
1881 "The location parameter for the Laplacian distribution returned by this "
1882 "RNG stream.",
1883 DoubleValue(0.0),
1886 .AddAttribute(
1887 "Scale",
1888 "The scale parameter for the Laplacian distribution returned by this RNG stream.",
1889 DoubleValue(1.0),
1892 .AddAttribute("Bound",
1893 "The bound on the values returned by this RNG stream.",
1894 DoubleValue(0.0),
1897 return tid;
1898}
1899
1904
1905double
1907{
1908 return m_location;
1909}
1910
1911double
1913{
1914 return m_scale;
1915}
1916
1917double
1919{
1920 return m_bound;
1921}
1922
1923double
1924LaplacianRandomVariable::GetValue(double location, double scale, double bound)
1925{
1926 NS_LOG_FUNCTION(this << location << scale << bound);
1927 NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
1928
1929 while (true)
1930 {
1931 // Get a uniform random variable in [-0.5,0.5].
1932 auto v = (Peek()->RandU01() - 0.5);
1933 if (IsAntithetic())
1934 {
1935 v = (1 - v);
1936 }
1937
1938 // Calculate the laplacian random variable.
1939 const auto sgn = (v > 0) ? 1 : ((v < 0) ? -1 : 0);
1940 const auto r = location - (scale * sgn * std::log(1.0 - (2.0 * std::abs(v))));
1941
1942 // Use this value if it's acceptable.
1943 if (bound == 0.0 || std::fabs(r - location) <= bound)
1944 {
1945 return r;
1946 }
1947 }
1948}
1949
1952{
1953 NS_LOG_FUNCTION(this << location << scale << bound);
1954 return static_cast<uint32_t>(GetValue(location, scale, bound));
1955}
1956
1957double
1963
1964double
1966{
1967 NS_LOG_FUNCTION(scale);
1968 return 2.0 * std::pow(scale, 2.0);
1969}
1970
1971double
1976
1978
1979TypeId
1981{
1982 static TypeId tid =
1983 TypeId("ns3::LargestExtremeValueRandomVariable")
1985 .SetGroupName("Core")
1986 .AddConstructor<LargestExtremeValueRandomVariable>()
1987 .AddAttribute("Location",
1988 "The location parameter for the Largest Extreme Value distribution "
1989 "returned by this RNG stream.",
1990 DoubleValue(0.0),
1993 .AddAttribute("Scale",
1994 "The scale parameter for the Largest Extreme Value distribution "
1995 "returned by this RNG stream.",
1996 DoubleValue(1.0),
1999 return tid;
2000}
2001
2006
2007double
2012
2013double
2018
2019double
2021{
2022 NS_LOG_FUNCTION(this << location << scale);
2023 NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
2024
2025 // Get a uniform random variable in [0,1].
2026 auto v = Peek()->RandU01();
2027 if (IsAntithetic())
2028 {
2029 v = (1 - v);
2030 }
2031
2032 // Calculate the largest extreme value random variable.
2033 const auto t = std::log(v) * (-1.0);
2034 const auto r = location - (scale * std::log(t));
2035
2036 return r;
2037}
2038
2041{
2042 NS_LOG_FUNCTION(this << location << scale);
2043 return static_cast<uint32_t>(GetValue(location, scale));
2044}
2045
2046double
2052
2053double
2055{
2056 NS_LOG_FUNCTION(location << scale);
2057 return (location + (scale * std::numbers::egamma));
2058}
2059
2060double
2065
2066double
2068{
2069 NS_LOG_FUNCTION(scale);
2070 return std::pow((scale * std::numbers::pi), 2) / 6.0;
2071}
2072
2073double
2078
2079} // 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:83
Object()
Constructor.
Definition object.cc:96
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:67
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:114
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:249
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:270
#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.