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
145TypeId
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
655const double NormalRandomVariable::INFINITE_VALUE = 1e307;
656
657TypeId
659{
660 static TypeId tid =
661 TypeId("ns3::NormalRandomVariable")
663 .SetGroupName("Core")
664 .AddConstructor<NormalRandomVariable>()
665 .AddAttribute("Mean",
666 "The mean value for the normal distribution returned by this RNG stream.",
667 DoubleValue(0.0),
670 .AddAttribute(
671 "Variance",
672 "The variance value for the normal distribution returned by this RNG stream.",
673 DoubleValue(1.0),
676 .AddAttribute("Bound",
677 "The bound on the values returned by this RNG stream.",
681 return tid;
682}
683
685 : m_nextValid(false)
686{
687 // m_mean, m_variance, and m_bound are initialized after constructor
688 // by attributes
689 NS_LOG_FUNCTION(this);
690}
691
692double
694{
695 return m_mean;
696}
697
698double
700{
701 return m_variance;
702}
703
704double
706{
707 return m_bound;
708}
709
710double
711NormalRandomVariable::GetValue(double mean, double variance, double bound)
712{
713 if (m_nextValid)
714 { // use previously generated
715 m_nextValid = false;
716 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
717 if (std::fabs(x2 - mean) <= bound)
718 {
719 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
720 << " variance: " << variance << " bound: " << bound);
721 return x2;
722 }
723 }
724 while (true)
725 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
726 // for algorithm; basically a Box-Muller transform:
727 // http://en.wikipedia.org/wiki/Box-Muller_transform
728 double u1 = Peek()->RandU01();
729 double u2 = Peek()->RandU01();
730 if (IsAntithetic())
731 {
732 u1 = (1 - u1);
733 u2 = (1 - u2);
734 }
735 double v1 = 2 * u1 - 1;
736 double v2 = 2 * u2 - 1;
737 double w = v1 * v1 + v2 * v2;
738 if (w <= 1.0)
739 { // Got good pair
740 double y = std::sqrt((-2 * std::log(w)) / w);
741 double x1 = mean + v1 * y * std::sqrt(variance);
742 // if x1 is in bounds, return it, cache v2 and y
743 if (std::fabs(x1 - mean) <= bound)
744 {
745 m_nextValid = true;
746 m_y = y;
747 m_v2 = v2;
748 NS_LOG_DEBUG("value: " << x1 << " stream: " << GetStream() << " mean: " << mean
749 << " variance: " << variance << " bound: " << bound);
750 return x1;
751 }
752 // otherwise try and return the other if it is valid
753 double x2 = mean + v2 * y * std::sqrt(variance);
754 if (std::fabs(x2 - mean) <= bound)
755 {
756 m_nextValid = false;
757 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
758 << " variance: " << variance << " bound: " << bound);
759 return x2;
760 }
761 // otherwise, just run this loop again
762 }
763 }
764}
765
768{
769 auto v = static_cast<uint32_t>(GetValue(mean, variance, bound));
770 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
771 << " variance: " << variance << " bound: " << bound);
772 return v;
773}
774
775double
780
782
783TypeId
785{
786 static TypeId tid =
787 TypeId("ns3::LogNormalRandomVariable")
789 .SetGroupName("Core")
790 .AddConstructor<LogNormalRandomVariable>()
791 .AddAttribute(
792 "Mu",
793 "The mu value for the log-normal distribution returned by this RNG stream.",
794 DoubleValue(0.0),
797 .AddAttribute(
798 "Sigma",
799 "The sigma value for the log-normal distribution returned by this RNG stream.",
800 DoubleValue(1.0),
803 return tid;
804}
805
807 : m_nextValid(false)
808{
809 // m_mu and m_sigma are initialized after constructor by
810 // attributes
811 NS_LOG_FUNCTION(this);
812}
813
814double
816{
817 return m_mu;
818}
819
820double
822{
823 return m_sigma;
824}
825
826// The code from this function was adapted from the GNU Scientific
827// Library 1.8:
828/* randist/lognormal.c
829 *
830 * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
831 *
832 * SPDX-License-Identifier: GPL-2.0-or-later
833 */
834/* The lognormal distribution has the form
835
836 p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
837
838 for x > 0. Lognormal random numbers are the exponentials of
839 gaussian random numbers */
840double
841LogNormalRandomVariable::GetValue(double mu, double sigma)
842{
843 if (m_nextValid)
844 { // use previously generated
845 m_nextValid = false;
846 double v = std::exp(sigma * m_v2 * m_normal + mu);
847 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mu: " << mu
848 << " sigma: " << sigma);
849 return v;
850 }
851
852 double v1;
853 double v2;
854 double r2;
855 double normal;
856 double x;
857
858 do
859 {
860 /* choose x,y in uniform square (-1,-1) to (+1,+1) */
861
862 double u1 = Peek()->RandU01();
863 double u2 = Peek()->RandU01();
864 if (IsAntithetic())
865 {
866 u1 = (1 - u1);
867 u2 = (1 - u2);
868 }
869
870 v1 = -1 + 2 * u1;
871 v2 = -1 + 2 * u2;
872
873 /* see if it is in the unit circle */
874 r2 = v1 * v1 + v2 * v2;
875 } while (r2 > 1.0 || r2 == 0);
876
877 m_normal = std::sqrt(-2.0 * std::log(r2) / r2);
878 normal = v1 * m_normal;
879 m_nextValid = true;
880 m_v2 = v2;
881
882 x = std::exp(sigma * normal + mu);
883 NS_LOG_DEBUG("value: " << x << " stream: " << GetStream() << " mu: " << mu
884 << " sigma: " << sigma);
885
886 return x;
887}
888
891{
892 auto v = static_cast<uint32_t>(GetValue(mu, sigma));
893 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mu: " << mu
894 << " sigma: " << sigma);
895 return v;
896}
897
898double
903
905
906TypeId
908{
909 static TypeId tid =
910 TypeId("ns3::GammaRandomVariable")
912 .SetGroupName("Core")
913 .AddConstructor<GammaRandomVariable>()
914 .AddAttribute("Alpha",
915 "The alpha value for the gamma distribution returned by this RNG stream.",
916 DoubleValue(1.0),
919 .AddAttribute("Beta",
920 "The beta value for the gamma distribution returned by this RNG stream.",
921 DoubleValue(1.0),
924 return tid;
925}
926
928 : m_nextValid(false)
929{
930 // m_alpha and m_beta are initialized after constructor by
931 // attributes
932 NS_LOG_FUNCTION(this);
933}
934
935double
937{
938 return m_alpha;
939}
940
941double
943{
944 return m_beta;
945}
946
947/*
948 The code for the following generator functions was adapted from ns-2
949 tools/ranvar.cc
950
951 Originally the algorithm was devised by Marsaglia in 2000:
952 G. Marsaglia, W. W. Tsang: A simple method for generating Gamma variables
953 ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
954
955 The Gamma distribution density function has the form
956
957 x^(alpha-1) * exp(-x/beta)
958 p(x; alpha, beta) = ----------------------------
959 beta^alpha * Gamma(alpha)
960
961 for x > 0.
962*/
963double
964GammaRandomVariable::GetValue(double alpha, double beta)
965{
966 if (alpha < 1)
967 {
968 double u = Peek()->RandU01();
969 if (IsAntithetic())
970 {
971 u = (1 - u);
972 }
973 double v = GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
974 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " alpha: " << alpha
975 << " beta: " << beta);
976 return GetValue(1.0 + alpha, beta) * std::pow(u, 1.0 / alpha);
977 }
978
979 double x;
980 double v;
981 double u;
982 double d = alpha - 1.0 / 3.0;
983 double c = (1.0 / 3.0) / std::sqrt(d);
984
985 while (true)
986 {
987 do
988 {
989 // Get a value from a normal distribution that has mean
990 // zero, variance 1, and no bound.
991 double mean = 0.0;
992 double variance = 1.0;
994 x = GetNormalValue(mean, variance, bound);
995
996 v = 1.0 + c * x;
997 } while (v <= 0);
998
999 v = v * v * v;
1000 u = Peek()->RandU01();
1001 if (IsAntithetic())
1002 {
1003 u = (1 - u);
1004 }
1005 if (u < 1 - 0.0331 * x * x * x * x)
1006 {
1007 break;
1008 }
1009 if (std::log(u) < 0.5 * x * x + d * (1 - v + std::log(v)))
1010 {
1011 break;
1012 }
1013 }
1014
1015 double value = beta * d * v;
1016 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream() << " alpha: " << alpha
1017 << " beta: " << beta);
1018 return value;
1019}
1020
1021double
1026
1027double
1028GammaRandomVariable::GetNormalValue(double mean, double variance, double bound)
1029{
1030 if (m_nextValid)
1031 { // use previously generated
1032 m_nextValid = false;
1033 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
1034 if (std::fabs(x2 - mean) <= bound)
1035 {
1036 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
1037 << " variance: " << variance << " bound: " << bound);
1038 return x2;
1039 }
1040 }
1041 while (true)
1042 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1043 // for algorithm; basically a Box-Muller transform:
1044 // http://en.wikipedia.org/wiki/Box-Muller_transform
1045 double u1 = Peek()->RandU01();
1046 double u2 = Peek()->RandU01();
1047 if (IsAntithetic())
1048 {
1049 u1 = (1 - u1);
1050 u2 = (1 - u2);
1051 }
1052 double v1 = 2 * u1 - 1;
1053 double v2 = 2 * u2 - 1;
1054 double w = v1 * v1 + v2 * v2;
1055 if (w <= 1.0)
1056 { // Got good pair
1057 double y = std::sqrt((-2 * std::log(w)) / w);
1058 double x1 = mean + v1 * y * std::sqrt(variance);
1059 // if x1 is in bounds, return it, cache v2 an y
1060 if (std::fabs(x1 - mean) <= bound)
1061 {
1062 m_nextValid = true;
1063 m_y = y;
1064 m_v2 = v2;
1065 NS_LOG_DEBUG("value: " << x1 << " stream: " << GetStream() << " mean: " << mean
1066 << " variance: " << variance << " bound: " << bound);
1067 return x1;
1068 }
1069 // otherwise try and return the other if it is valid
1070 double x2 = mean + v2 * y * std::sqrt(variance);
1071 if (std::fabs(x2 - mean) <= bound)
1072 {
1073 m_nextValid = false;
1074 NS_LOG_DEBUG("value: " << x2 << " stream: " << GetStream() << " mean: " << mean
1075 << " variance: " << variance << " bound: " << bound);
1076 return x2;
1077 }
1078 // otherwise, just run this loop again
1079 }
1080 }
1081}
1082
1084
1085TypeId
1087{
1088 static TypeId tid =
1089 TypeId("ns3::ErlangRandomVariable")
1091 .SetGroupName("Core")
1092 .AddConstructor<ErlangRandomVariable>()
1093 .AddAttribute("K",
1094 "The k value for the Erlang distribution returned by this RNG stream.",
1095 IntegerValue(1),
1098 .AddAttribute(
1099 "Lambda",
1100 "The lambda value for the Erlang distribution returned by this RNG stream.",
1101 DoubleValue(1.0),
1104 return tid;
1105}
1106
1108{
1109 // m_k and m_lambda are initialized after constructor by attributes
1110 NS_LOG_FUNCTION(this);
1111}
1112
1115{
1116 return m_k;
1117}
1118
1119double
1121{
1122 return m_lambda;
1123}
1124
1125/*
1126 The code for the following generator functions was adapted from ns-2
1127 tools/ranvar.cc
1128
1129 The Erlang distribution density function has the form
1130
1131 x^(k-1) * exp(-x/lambda)
1132 p(x; k, lambda) = ---------------------------
1133 lambda^k * (k-1)!
1134
1135 for x > 0.
1136*/
1137double
1139{
1140 double mean = lambda;
1141 double bound = 0.0;
1142
1143 double result = 0;
1144 for (unsigned int i = 0; i < k; ++i)
1145 {
1146 result += GetExponentialValue(mean, bound);
1147 }
1148 NS_LOG_DEBUG("value: " << result << " stream: " << GetStream() << " k: " << k
1149 << " lambda: " << lambda);
1150 return result;
1151}
1152
1155{
1156 auto v = static_cast<uint32_t>(GetValue(k, lambda));
1157 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " k: " << k
1158 << " lambda: " << lambda);
1159 return v;
1160}
1161
1162double
1167
1168double
1170{
1171 while (true)
1172 {
1173 // Get a uniform random variable in [0,1].
1174 double v = Peek()->RandU01();
1175 if (IsAntithetic())
1176 {
1177 v = (1 - v);
1178 }
1179
1180 // Calculate the exponential random variable.
1181 double r = -mean * std::log(v);
1182
1183 // Use this value if it's acceptable.
1184 if (bound == 0 || r <= bound)
1185 {
1186 NS_LOG_DEBUG("value: " << r << " stream: " << GetStream() << " mean:: " << mean
1187 << " bound: " << bound);
1188 return r;
1189 }
1190 }
1191}
1192
1194
1195TypeId
1197{
1198 static TypeId tid =
1199 TypeId("ns3::TriangularRandomVariable")
1201 .SetGroupName("Core")
1202 .AddConstructor<TriangularRandomVariable>()
1203 .AddAttribute(
1204 "Mean",
1205 "The mean value for the triangular distribution returned by this RNG stream.",
1206 DoubleValue(0.5),
1209 .AddAttribute("Min",
1210 "The lower bound on the values returned by this RNG stream.",
1211 DoubleValue(0.0),
1214 .AddAttribute("Max",
1215 "The upper bound on the values returned by this RNG stream.",
1216 DoubleValue(1.0),
1219 return tid;
1220}
1221
1223{
1224 // m_mean, m_min, and m_max are initialized after constructor by
1225 // attributes
1226 NS_LOG_FUNCTION(this);
1227}
1228
1229double
1231{
1232 return m_mean;
1233}
1234
1235double
1237{
1238 return m_min;
1239}
1240
1241double
1243{
1244 return m_max;
1245}
1246
1247double
1248TriangularRandomVariable::GetValue(double mean, double min, double max)
1249{
1250 // Calculate the mode.
1251 double mode = 3.0 * mean - min - max;
1252
1253 // Get a uniform random variable in [0,1].
1254 double u = Peek()->RandU01();
1255 if (IsAntithetic())
1256 {
1257 u = (1 - u);
1258 }
1259
1260 // Calculate the triangular random variable.
1261 if (u <= (mode - min) / (max - min))
1262 {
1263 double v = min + std::sqrt(u * (max - min) * (mode - min));
1264 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mean: " << mean
1265 << " min: " << min << " max: " << max);
1266 return v;
1267 }
1268 else
1269 {
1270 double v = max - std::sqrt((1 - u) * (max - min) * (max - mode));
1271 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream() << " mean: " << mean
1272 << " min: " << min << " max: " << max);
1273 return v;
1274 }
1275}
1276
1279{
1280 auto v = static_cast<uint32_t>(GetValue(mean, min, max));
1281 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " mean: " << mean
1282 << " min: " << min << " max: " << max);
1283 return v;
1284}
1285
1286double
1291
1293
1294TypeId
1296{
1297 static TypeId tid =
1298 TypeId("ns3::ZipfRandomVariable")
1300 .SetGroupName("Core")
1301 .AddConstructor<ZipfRandomVariable>()
1302 .AddAttribute("N",
1303 "The n value for the Zipf distribution returned by this RNG stream.",
1304 IntegerValue(1),
1307 .AddAttribute("Alpha",
1308 "The alpha value for the Zipf distribution returned by this RNG stream.",
1309 DoubleValue(0.0),
1312 return tid;
1313}
1314
1316{
1317 // m_n and m_alpha are initialized after constructor by attributes
1318 NS_LOG_FUNCTION(this);
1319}
1320
1323{
1324 return m_n;
1325}
1326
1327double
1329{
1330 return m_alpha;
1331}
1332
1333double
1335{
1336 // Calculate the normalization constant c.
1337 m_c = 0.0;
1338 for (uint32_t i = 1; i <= n; i++)
1339 {
1340 m_c += (1.0 / std::pow((double)i, alpha));
1341 }
1342 m_c = 1.0 / m_c;
1343
1344 // Get a uniform random variable in [0,1].
1345 double u = Peek()->RandU01();
1346 if (IsAntithetic())
1347 {
1348 u = (1 - u);
1349 }
1350
1351 double sum_prob = 0;
1352 double zipf_value = 0;
1353 for (uint32_t i = 1; i <= n; i++)
1354 {
1355 sum_prob += m_c / std::pow((double)i, alpha);
1356 if (sum_prob > u)
1357 {
1358 zipf_value = i;
1359 break;
1360 }
1361 }
1362 NS_LOG_DEBUG("value: " << zipf_value << " stream: " << GetStream() << " n: " << n
1363 << " alpha: " << alpha);
1364 return zipf_value;
1365}
1366
1369{
1370 NS_LOG_FUNCTION(this << n << alpha);
1371 auto v = static_cast<uint32_t>(GetValue(n, alpha));
1372 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " n: " << n
1373 << " alpha: " << alpha);
1374 return v;
1375}
1376
1377double
1382
1384
1385TypeId
1387{
1388 static TypeId tid =
1389 TypeId("ns3::ZetaRandomVariable")
1391 .SetGroupName("Core")
1392 .AddConstructor<ZetaRandomVariable>()
1393 .AddAttribute("Alpha",
1394 "The alpha value for the zeta distribution returned by this RNG stream.",
1395 DoubleValue(3.14),
1398 return tid;
1399}
1400
1402{
1403 // m_alpha is initialized after constructor by attributes
1404 NS_LOG_FUNCTION(this);
1405}
1406
1407double
1409{
1410 return m_alpha;
1411}
1412
1413double
1415{
1416 m_b = std::pow(2.0, alpha - 1.0);
1417
1418 double u;
1419 double v;
1420 double X;
1421 double T;
1422 double test;
1423
1424 do
1425 {
1426 // Get a uniform random variable in [0,1].
1427 u = Peek()->RandU01();
1428 if (IsAntithetic())
1429 {
1430 u = (1 - u);
1431 }
1432
1433 // Get a uniform random variable in [0,1].
1434 v = Peek()->RandU01();
1435 if (IsAntithetic())
1436 {
1437 v = (1 - v);
1438 }
1439
1440 X = std::floor(std::pow(u, -1.0 / (alpha - 1.0)));
1441 T = std::pow(1.0 + 1.0 / X, alpha - 1.0);
1442 test = v * X * (T - 1.0) / (m_b - 1.0);
1443 } while (test > (T / m_b));
1444 NS_LOG_DEBUG("value: " << X << " stream: " << GetStream() << " alpha: " << alpha);
1445 return X;
1446}
1447
1450{
1451 auto v = static_cast<uint32_t>(GetValue(alpha));
1452 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " alpha: " << alpha);
1453 return v;
1454}
1455
1456double
1461
1463
1464TypeId
1466{
1467 static TypeId tid = TypeId("ns3::DeterministicRandomVariable")
1469 .SetGroupName("Core")
1470 .AddConstructor<DeterministicRandomVariable>();
1471 return tid;
1472}
1473
1475 : m_count(0),
1476 m_next(0),
1477 m_data(nullptr)
1478{
1479 NS_LOG_FUNCTION(this);
1480}
1481
1483{
1484 // Delete any values currently set.
1485 NS_LOG_FUNCTION(this);
1486 if (m_data != nullptr)
1487 {
1488 delete[] m_data;
1489 }
1490}
1491
1492void
1493DeterministicRandomVariable::SetValueArray(const std::vector<double>& values)
1494{
1495 SetValueArray(values.data(), values.size());
1496}
1497
1498void
1499DeterministicRandomVariable::SetValueArray(const double* values, std::size_t length)
1500{
1501 NS_LOG_FUNCTION(this << values << length);
1502 // Delete any values currently set.
1503 if (m_data != nullptr)
1504 {
1505 delete[] m_data;
1506 }
1507
1508 // Make room for the values being set.
1509 m_data = new double[length];
1510 m_count = length;
1511 m_next = length;
1512
1513 // Copy the values.
1514 for (std::size_t i = 0; i < m_count; i++)
1515 {
1516 m_data[i] = values[i];
1517 }
1518}
1519
1520double
1522{
1523 // Make sure the array has been set.
1524 NS_ASSERT(m_count > 0);
1525
1526 if (m_next == m_count)
1527 {
1528 m_next = 0;
1529 }
1530 double v = m_data[m_next++];
1531 NS_LOG_DEBUG("value: " << v << " stream: " << GetStream());
1532 return v;
1533}
1534
1536
1537TypeId
1539{
1540 static TypeId tid =
1541 TypeId("ns3::EmpiricalRandomVariable")
1543 .SetGroupName("Core")
1544 .AddConstructor<EmpiricalRandomVariable>()
1545 .AddAttribute("Interpolate",
1546 "Treat the CDF as a smooth distribution and interpolate, "
1547 "default is to treat the CDF as a histogram and sample.",
1548 BooleanValue(false),
1551 return tid;
1552}
1553
1555 : m_validated(false)
1556{
1557 NS_LOG_FUNCTION(this);
1558}
1559
1560bool
1562{
1563 NS_LOG_FUNCTION(this << interpolate);
1564 bool prev = m_interpolate;
1565 m_interpolate = interpolate;
1566 return prev;
1567}
1568
1569bool
1571{
1572 NS_LOG_FUNCTION(this << value);
1573 if (!m_validated)
1574 {
1575 Validate();
1576 }
1577
1578 // Get a uniform random variable in [0, 1].
1579 double r = Peek()->RandU01();
1580 if (IsAntithetic())
1581 {
1582 r = (1 - r);
1583 }
1584
1585 value = r;
1586 bool valid = false;
1587 // check extrema
1588 if (r <= m_empCdf.begin()->first)
1589 {
1590 value = m_empCdf.begin()->second; // Less than first
1591 valid = true;
1592 }
1593 else if (r >= m_empCdf.rbegin()->first)
1594 {
1595 value = m_empCdf.rbegin()->second; // Greater than last
1596 valid = true;
1597 }
1598 return valid;
1599}
1600
1601double
1603{
1604 double value;
1605 if (PreSample(value))
1606 {
1607 return value;
1608 }
1609
1610 // value now has the (unused) URNG selector
1611 if (m_interpolate)
1612 {
1613 value = DoInterpolate(value);
1614 }
1615 else
1616 {
1617 value = DoSampleCDF(value);
1618 }
1619 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream());
1620 return value;
1621}
1622
1623double
1625{
1626 NS_LOG_FUNCTION(this << r);
1627
1628 // Find first CDF that is greater than r
1629 auto bound = m_empCdf.upper_bound(r);
1630
1631 return bound->second;
1632}
1633
1634double
1636{
1637 NS_LOG_FUNCTION(this);
1638
1639 double value;
1640 if (PreSample(value))
1641 {
1642 return value;
1643 }
1644
1645 // value now has the (unused) URNG selector
1646 value = DoInterpolate(value);
1647 return value;
1648}
1649
1650double
1652{
1653 NS_LOG_FUNCTION(this << r);
1654
1655 // Return a value from the empirical distribution
1656 // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1657
1658 // search
1659 auto upper = m_empCdf.upper_bound(r);
1660 auto lower = std::prev(upper, 1);
1661
1662 if (upper == m_empCdf.begin())
1663 {
1664 lower = upper;
1665 }
1666
1667 // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1668 double c1 = lower->first;
1669 double c2 = upper->first;
1670 double v1 = lower->second;
1671 double v2 = upper->second;
1672
1673 double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1674 return value;
1675}
1676
1677void
1679{
1680 NS_LOG_FUNCTION(this << v << c);
1681
1682 auto vPrevious = m_empCdf.find(c);
1683
1684 if (vPrevious != m_empCdf.end())
1685 {
1686 NS_LOG_WARN("Empirical CDF already has a value " << vPrevious->second << " for CDF " << c
1687 << ". Overwriting it with value " << v
1688 << ".");
1689 }
1690
1691 m_empCdf[c] = v;
1692}
1693
1694void
1696{
1697 NS_LOG_FUNCTION(this);
1698
1699 if (m_empCdf.empty())
1700 {
1701 NS_FATAL_ERROR("CDF is not initialized");
1702 }
1703
1704 double vPrev = m_empCdf.begin()->second;
1705
1706 // Check if values are non-decreasing
1707 for (const auto& cdfPair : m_empCdf)
1708 {
1709 const auto& vCurr = cdfPair.second;
1710
1711 if (vCurr < vPrev)
1712 {
1713 NS_FATAL_ERROR("Empirical distribution has decreasing CDF values. Current CDF: "
1714 << vCurr << ", prior CDF: " << vPrev);
1715 }
1716
1717 vPrev = vCurr;
1718 }
1719
1720 // Bounds check on CDF endpoints
1721 auto firstCdfPair = m_empCdf.begin();
1722 auto lastCdfPair = m_empCdf.rbegin();
1723
1724 if (firstCdfPair->first < 0.0)
1725 {
1726 NS_FATAL_ERROR("Empirical distribution has invalid first CDF value. CDF: "
1727 << firstCdfPair->first << ", Value: " << firstCdfPair->second);
1728 }
1729
1730 if (lastCdfPair->first > 1.0)
1731 {
1732 NS_FATAL_ERROR("Empirical distribution has invalid last CDF value. CDF: "
1733 << lastCdfPair->first << ", Value: " << lastCdfPair->second);
1734 }
1735
1736 m_validated = true;
1737}
1738
1740
1741TypeId
1743{
1744 static TypeId tid =
1745 TypeId("ns3::BinomialRandomVariable")
1747 .SetGroupName("Core")
1748 .AddConstructor<BinomialRandomVariable>()
1749 .AddAttribute("Trials",
1750 "The number of trials.",
1751 IntegerValue(10),
1754 .AddAttribute("Probability",
1755 "The probability of success in each trial.",
1756 DoubleValue(0.5),
1759 return tid;
1760}
1761
1763{
1764 // m_trials and m_probability are initialized after constructor by attributes
1765 NS_LOG_FUNCTION(this);
1766}
1767
1768double
1770{
1771 double successes = 0;
1772
1773 for (uint32_t i = 0; i < trials; ++i)
1774 {
1775 double v = Peek()->RandU01();
1776 if (IsAntithetic())
1777 {
1778 v = (1 - v);
1779 }
1780
1781 if (v <= probability)
1782 {
1783 successes += 1;
1784 }
1785 }
1786 NS_LOG_DEBUG("value: " << successes << " stream: " << GetStream() << " trials: " << trials
1787 << " probability: " << probability);
1788 return successes;
1789}
1790
1793{
1794 auto v = static_cast<uint32_t>(GetValue(trials, probability));
1795 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream() << " trials: " << trials
1796 << " probability: " << probability);
1797 return v;
1798}
1799
1800double
1805
1807
1808TypeId
1810{
1811 static TypeId tid =
1812 TypeId("ns3::BernoulliRandomVariable")
1814 .SetGroupName("Core")
1815 .AddConstructor<BernoulliRandomVariable>()
1816 .AddAttribute("Probability",
1817 "The probability of the random variable returning a value of 1.",
1818 DoubleValue(0.5),
1821 return tid;
1822}
1823
1825{
1826 // m_probability is initialized after constructor by attributes
1827 NS_LOG_FUNCTION(this);
1828}
1829
1830double
1832{
1833 double v = Peek()->RandU01();
1834 if (IsAntithetic())
1835 {
1836 v = (1 - v);
1837 }
1838
1839 double value = (v <= probability) ? 1.0 : 0.0;
1840 NS_LOG_DEBUG("value: " << value << " stream: " << GetStream()
1841 << " probability: " << probability);
1842 return value;
1843}
1844
1847{
1848 auto v = static_cast<uint32_t>(GetValue(probability));
1849 NS_LOG_DEBUG("integer value: " << v << " stream: " << GetStream()
1850 << " probability: " << probability);
1851 return v;
1852}
1853
1854double
1859
1861
1862TypeId
1864{
1865 static TypeId tid =
1866 TypeId("ns3::LaplacianRandomVariable")
1868 .SetGroupName("Core")
1869 .AddConstructor<LaplacianRandomVariable>()
1870 .AddAttribute("Location",
1871 "The location parameter for the Laplacian distribution returned by this "
1872 "RNG stream.",
1873 DoubleValue(0.0),
1876 .AddAttribute(
1877 "Scale",
1878 "The scale parameter for the Laplacian distribution returned by this RNG stream.",
1879 DoubleValue(1.0),
1882 .AddAttribute("Bound",
1883 "The bound on the values returned by this RNG stream.",
1884 DoubleValue(0.0),
1887 return tid;
1888}
1889
1894
1895double
1897{
1898 return m_location;
1899}
1900
1901double
1903{
1904 return m_scale;
1905}
1906
1907double
1909{
1910 return m_bound;
1911}
1912
1913double
1914LaplacianRandomVariable::GetValue(double location, double scale, double bound)
1915{
1916 NS_LOG_FUNCTION(this << location << scale << bound);
1917 NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
1918
1919 while (true)
1920 {
1921 // Get a uniform random variable in [-0.5,0.5].
1922 auto v = (Peek()->RandU01() - 0.5);
1923 if (IsAntithetic())
1924 {
1925 v = (1 - v);
1926 }
1927
1928 // Calculate the laplacian random variable.
1929 const auto sgn = (v > 0) ? 1 : ((v < 0) ? -1 : 0);
1930 const auto r = location - (scale * sgn * std::log(1.0 - (2.0 * std::abs(v))));
1931
1932 // Use this value if it's acceptable.
1933 if (bound == 0.0 || std::fabs(r - location) <= bound)
1934 {
1935 return r;
1936 }
1937 }
1938}
1939
1942{
1943 NS_LOG_FUNCTION(this << location << scale << bound);
1944 return static_cast<uint32_t>(GetValue(location, scale, bound));
1945}
1946
1947double
1953
1954double
1956{
1957 NS_LOG_FUNCTION(scale);
1958 return 2.0 * std::pow(scale, 2.0);
1959}
1960
1961double
1966
1968
1969TypeId
1971{
1972 static TypeId tid =
1973 TypeId("ns3::LargestExtremeValueRandomVariable")
1975 .SetGroupName("Core")
1976 .AddConstructor<LargestExtremeValueRandomVariable>()
1977 .AddAttribute("Location",
1978 "The location parameter for the Largest Extreme Value distribution "
1979 "returned by this RNG stream.",
1980 DoubleValue(0.0),
1983 .AddAttribute("Scale",
1984 "The scale parameter for the Largest Extreme Value distribution "
1985 "returned by this RNG stream.",
1986 DoubleValue(1.0),
1989 return tid;
1990}
1991
1996
1997double
2002
2003double
2008
2009double
2011{
2012 NS_LOG_FUNCTION(this << location << scale);
2013 NS_ABORT_MSG_IF(scale <= 0, "Scale parameter should be larger than 0");
2014
2015 // Get a uniform random variable in [0,1].
2016 auto v = Peek()->RandU01();
2017 if (IsAntithetic())
2018 {
2019 v = (1 - v);
2020 }
2021
2022 // Calculate the largest extreme value random variable.
2023 const auto t = std::log(v) * (-1.0);
2024 const auto r = location - (scale * std::log(t));
2025
2026 return r;
2027}
2028
2031{
2032 NS_LOG_FUNCTION(this << location << scale);
2033 return static_cast<uint32_t>(GetValue(location, scale));
2034}
2035
2036double
2042
2043double
2045{
2046 NS_LOG_FUNCTION(location << scale);
2047 return (location + (scale * std::numbers::egamma));
2048}
2049
2050double
2055
2056double
2058{
2059 NS_LOG_FUNCTION(scale);
2060 return std::pow((scale * std::numbers::pi), 2) / 6.0;
2061}
2062
2063double
2068
2069} // 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 const double INFINITE_VALUE
Large constant to bound the range.
double m_variance
The variance value for the normal distribution returned by this RNG stream.
double GetValue() override
Get the next random value drawn from the distribution.
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
double m_bound
The bound on values that can be returned by this RNG stream.
bool m_nextValid
True if the next value is valid.
NormalRandomVariable()
Creates a normal distribution RNG with the default values for the mean, variance, and bound.
double m_v2
The algorithm produces two values at a time.
A base class which provides memory management and object aggregation.
Definition object.h:78
TypeId GetInstanceTypeId() const override
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:48
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.