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 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Rajib Bhattacharjea<raj.b@gatech.edu>
19 * Hadi Arbabi<marbabi@cs.odu.edu>
20 * Mathieu Lacage <mathieu.lacage@gmail.com>
21 *
22 * Modified by Mitch Watrous <watrous@u.washington.edu>
23 *
24 */
26
27#include "assert.h"
28#include "boolean.h"
29#include "double.h"
30#include "integer.h"
31#include "log.h"
32#include "pointer.h"
33#include "rng-seed-manager.h"
34#include "rng-stream.h"
35#include "string.h"
36
37#include <algorithm> // upper_bound
38#include <cmath>
39#include <iostream>
40
41/**
42 * \file
43 * \ingroup randomvariable
44 * ns3::RandomVariableStream and related implementations
45 */
46
47namespace ns3
48{
49
50NS_LOG_COMPONENT_DEFINE("RandomVariableStream");
51
52NS_OBJECT_ENSURE_REGISTERED(RandomVariableStream);
53
54TypeId
56{
57 static TypeId tid = TypeId("ns3::RandomVariableStream")
59 .SetGroupName("Core")
60 .AddAttribute("Stream",
61 "The stream number for this RNG stream. -1 means "
62 "\"allocate a stream automatically\". "
63 "Note that if -1 is set, Get will return -1 so that it "
64 "is not possible to know which "
65 "value was automatically allocated.",
66 IntegerValue(-1),
69 MakeIntegerChecker<int64_t>())
70 .AddAttribute("Antithetic",
71 "Set this RNG stream to generate antithetic values",
72 BooleanValue(false),
76 return tid;
77}
78
80 : m_rng(nullptr)
81{
82 NS_LOG_FUNCTION(this);
83}
84
86{
87 NS_LOG_FUNCTION(this);
88 delete m_rng;
89}
90
91void
93{
94 NS_LOG_FUNCTION(this << isAntithetic);
95 m_isAntithetic = isAntithetic;
96}
97
98bool
100{
101 NS_LOG_FUNCTION(this);
102 return m_isAntithetic;
103}
104
107{
108 NS_LOG_FUNCTION(this);
109 return static_cast<uint32_t>(GetValue());
110}
111
112void
114{
115 NS_LOG_FUNCTION(this << stream);
116 // negative values are not legal.
117 NS_ASSERT(stream >= -1);
118 delete m_rng;
119 if (stream == -1)
120 {
121 // The first 2^63 streams are reserved for automatic stream
122 // number assignment.
123 uint64_t nextStream = RngSeedManager::GetNextStreamIndex();
124 NS_ASSERT(nextStream <= ((1ULL) << 63));
126 }
127 else
128 {
129 // The last 2^63 streams are reserved for deterministic stream
130 // number assignment.
131 uint64_t base = ((1ULL) << 63);
132 uint64_t target = base + stream;
134 }
135 m_stream = stream;
136}
137
138int64_t
140{
141 NS_LOG_FUNCTION(this);
142 return m_stream;
143}
144
147{
148 NS_LOG_FUNCTION(this);
149 return m_rng;
150}
151
153
154TypeId
156{
157 static TypeId tid =
158 TypeId("ns3::UniformRandomVariable")
160 .SetGroupName("Core")
161 .AddConstructor<UniformRandomVariable>()
162 .AddAttribute("Min",
163 "The lower bound on the values returned by this RNG stream.",
164 DoubleValue(0),
166 MakeDoubleChecker<double>())
167 .AddAttribute("Max",
168 "The upper bound on the values returned by this RNG stream.",
169 DoubleValue(1.0),
171 MakeDoubleChecker<double>());
172 return tid;
173}
174
176{
177 // m_min and m_max are initialized after constructor by attributes
178 NS_LOG_FUNCTION(this);
179}
180
181double
183{
184 NS_LOG_FUNCTION(this);
185 return m_min;
186}
187
188double
190{
191 NS_LOG_FUNCTION(this);
192 return m_max;
193}
194
195double
196UniformRandomVariable::GetValue(double min, double max)
197{
198 NS_LOG_FUNCTION(this << min << max);
199 double v = min + Peek()->RandU01() * (max - min);
200 if (IsAntithetic())
201 {
202 v = min + (max - v);
203 }
204 return v;
205}
206
209{
210 NS_LOG_FUNCTION(this << min << max);
211 NS_ASSERT(min <= max);
212 return static_cast<uint32_t>(GetValue((double)(min), (double)(max) + 1.0));
213}
214
215double
217{
218 NS_LOG_FUNCTION(this);
219 return GetValue(m_min, m_max);
220}
221
224{
225 NS_LOG_FUNCTION(this);
226 return static_cast<uint32_t>(GetValue(m_min, m_max + 1));
227}
228
230
231TypeId
233{
234 static TypeId tid = TypeId("ns3::ConstantRandomVariable")
236 .SetGroupName("Core")
237 .AddConstructor<ConstantRandomVariable>()
238 .AddAttribute("Constant",
239 "The constant value returned by this RNG stream.",
240 DoubleValue(0),
242 MakeDoubleChecker<double>());
243 return tid;
244}
245
247{
248 // m_constant is initialized after constructor by attributes
249 NS_LOG_FUNCTION(this);
250}
251
252double
254{
255 NS_LOG_FUNCTION(this);
256 return m_constant;
257}
258
259double
261{
262 NS_LOG_FUNCTION(this << constant);
263 return constant;
264}
265
268{
269 NS_LOG_FUNCTION(this << constant);
270 return constant;
271}
272
273double
275{
276 NS_LOG_FUNCTION(this);
277 return GetValue(m_constant);
278}
279
281
282TypeId
284{
285 static TypeId tid =
286 TypeId("ns3::SequentialRandomVariable")
288 .SetGroupName("Core")
289 .AddConstructor<SequentialRandomVariable>()
290 .AddAttribute("Min",
291 "The first value of the sequence.",
292 DoubleValue(0),
294 MakeDoubleChecker<double>())
295 .AddAttribute("Max",
296 "One more than the last value of the sequence.",
297 DoubleValue(0),
299 MakeDoubleChecker<double>())
300 .AddAttribute("Increment",
301 "The sequence random variable increment.",
302 StringValue("ns3::ConstantRandomVariable[Constant=1]"),
304 MakePointerChecker<RandomVariableStream>())
305 .AddAttribute("Consecutive",
306 "The number of times each member of the sequence is repeated.",
307 IntegerValue(1),
309 MakeIntegerChecker<uint32_t>());
310 return tid;
311}
312
314 : m_current(0),
315 m_currentConsecutive(0),
316 m_isCurrentSet(false)
317{
318 // m_min, m_max, m_increment, and m_consecutive are initialized
319 // after constructor by attributes.
320 NS_LOG_FUNCTION(this);
321}
322
323double
325{
326 NS_LOG_FUNCTION(this);
327 return m_min;
328}
329
330double
332{
333 NS_LOG_FUNCTION(this);
334 return m_max;
335}
336
339{
340 NS_LOG_FUNCTION(this);
341 return m_increment;
342}
343
346{
347 NS_LOG_FUNCTION(this);
348 return m_consecutive;
349}
350
351double
353{
354 // Set the current sequence value if it hasn't been set.
355 NS_LOG_FUNCTION(this);
356 if (!m_isCurrentSet)
357 {
358 // Start the sequence at its minimum value.
360 m_isCurrentSet = true;
361 }
362
363 // Return a sequential series of values
364 double r = m_current;
366 { // Time to advance to next
369 if (m_current >= m_max)
370 {
372 }
373 }
374 return r;
375}
376
378
379TypeId
381{
382 static TypeId tid =
383 TypeId("ns3::ExponentialRandomVariable")
385 .SetGroupName("Core")
386 .AddConstructor<ExponentialRandomVariable>()
387 .AddAttribute("Mean",
388 "The mean of the values returned by this RNG stream.",
389 DoubleValue(1.0),
391 MakeDoubleChecker<double>())
392 .AddAttribute("Bound",
393 "The upper bound on the values returned by this RNG stream.",
394 DoubleValue(0.0),
396 MakeDoubleChecker<double>());
397 return tid;
398}
399
401{
402 // m_mean and m_bound are initialized after constructor by attributes
403 NS_LOG_FUNCTION(this);
404}
405
406double
408{
409 NS_LOG_FUNCTION(this);
410 return m_mean;
411}
412
413double
415{
416 NS_LOG_FUNCTION(this);
417 return m_bound;
418}
419
420double
421ExponentialRandomVariable::GetValue(double mean, double bound)
422{
423 NS_LOG_FUNCTION(this << mean << bound);
424 while (true)
425 {
426 // Get a uniform random variable in [0,1].
427 double v = Peek()->RandU01();
428 if (IsAntithetic())
429 {
430 v = (1 - v);
431 }
432
433 // Calculate the exponential random variable.
434 double r = -mean * std::log(v);
435
436 // Use this value if it's acceptable.
437 if (bound == 0 || r <= bound)
438 {
439 return r;
440 }
441 }
442}
443
446{
447 NS_LOG_FUNCTION(this << mean << bound);
448 return static_cast<uint32_t>(GetValue(mean, bound));
449}
450
451double
453{
454 NS_LOG_FUNCTION(this);
455 return GetValue(m_mean, m_bound);
456}
457
459
460TypeId
462{
463 static TypeId tid =
464 TypeId("ns3::ParetoRandomVariable")
466 .SetGroupName("Core")
467 .AddConstructor<ParetoRandomVariable>()
468 .AddAttribute(
469 "Scale",
470 "The scale parameter for the Pareto distribution returned by this RNG stream.",
471 DoubleValue(1.0),
473 MakeDoubleChecker<double>())
474 .AddAttribute(
475 "Shape",
476 "The shape parameter for the Pareto distribution returned by this RNG stream.",
477 DoubleValue(2.0),
479 MakeDoubleChecker<double>())
480 .AddAttribute(
481 "Bound",
482 "The upper bound on the values returned by this RNG stream (if non-zero).",
483 DoubleValue(0.0),
485 MakeDoubleChecker<double>());
486 return tid;
487}
488
490{
491 // m_shape, m_shape, and m_bound are initialized after constructor
492 // by attributes
493 NS_LOG_FUNCTION(this);
494}
495
496double
498{
499 NS_LOG_FUNCTION(this);
500 return m_scale;
501}
502
503double
505{
506 NS_LOG_FUNCTION(this);
507 return m_shape;
508}
509
510double
512{
513 NS_LOG_FUNCTION(this);
514 return m_bound;
515}
516
517double
518ParetoRandomVariable::GetValue(double scale, double shape, double bound)
519{
520 // Calculate the scale parameter.
521 NS_LOG_FUNCTION(this << scale << shape << bound);
522
523 while (true)
524 {
525 // Get a uniform random variable in [0,1].
526 double v = Peek()->RandU01();
527 if (IsAntithetic())
528 {
529 v = (1 - v);
530 }
531
532 // Calculate the Pareto random variable.
533 double r = (scale * (1.0 / std::pow(v, 1.0 / shape)));
534
535 // Use this value if it's acceptable.
536 if (bound == 0 || r <= bound)
537 {
538 return r;
539 }
540 }
541}
542
545{
546 NS_LOG_FUNCTION(this << scale << shape << bound);
547 return static_cast<uint32_t>(GetValue(scale, shape, bound));
548}
549
550double
552{
553 NS_LOG_FUNCTION(this);
555}
556
558
559TypeId
561{
562 static TypeId tid =
563 TypeId("ns3::WeibullRandomVariable")
565 .SetGroupName("Core")
566 .AddConstructor<WeibullRandomVariable>()
567 .AddAttribute(
568 "Scale",
569 "The scale parameter for the Weibull distribution returned by this RNG stream.",
570 DoubleValue(1.0),
572 MakeDoubleChecker<double>())
573 .AddAttribute(
574 "Shape",
575 "The shape parameter for the Weibull distribution returned by this RNG stream.",
576 DoubleValue(1),
578 MakeDoubleChecker<double>())
579 .AddAttribute("Bound",
580 "The upper bound on the values returned by this RNG stream.",
581 DoubleValue(0.0),
583 MakeDoubleChecker<double>());
584 return tid;
585}
586
588{
589 // m_scale, m_shape, and m_bound are initialized after constructor
590 // by attributes
591 NS_LOG_FUNCTION(this);
592}
593
594double
596{
597 NS_LOG_FUNCTION(this);
598 return m_scale;
599}
600
601double
603{
604 NS_LOG_FUNCTION(this);
605 return m_shape;
606}
607
608double
610{
611 NS_LOG_FUNCTION(this);
612 return m_bound;
613}
614
615double
616WeibullRandomVariable::GetValue(double scale, double shape, double bound)
617{
618 NS_LOG_FUNCTION(this << scale << shape << bound);
619 double exponent = 1.0 / shape;
620 while (true)
621 {
622 // Get a uniform random variable in [0,1].
623 double v = Peek()->RandU01();
624 if (IsAntithetic())
625 {
626 v = (1 - v);
627 }
628
629 // Calculate the Weibull random variable.
630 double r = scale * std::pow(-std::log(v), exponent);
631
632 // Use this value if it's acceptable.
633 if (bound == 0 || r <= bound)
634 {
635 return r;
636 }
637 }
638}
639
642{
643 NS_LOG_FUNCTION(this << scale << shape << bound);
644 return static_cast<uint32_t>(GetValue(scale, shape, bound));
645}
646
647double
649{
650 NS_LOG_FUNCTION(this);
652}
653
655
656const double NormalRandomVariable::INFINITE_VALUE = 1e307;
657
658TypeId
660{
661 static TypeId tid =
662 TypeId("ns3::NormalRandomVariable")
664 .SetGroupName("Core")
665 .AddConstructor<NormalRandomVariable>()
666 .AddAttribute("Mean",
667 "The mean value for the normal distribution returned by this RNG stream.",
668 DoubleValue(0.0),
670 MakeDoubleChecker<double>())
671 .AddAttribute(
672 "Variance",
673 "The variance value for the normal distribution returned by this RNG stream.",
674 DoubleValue(1.0),
676 MakeDoubleChecker<double>())
677 .AddAttribute("Bound",
678 "The bound on the values returned by this RNG stream.",
681 MakeDoubleChecker<double>());
682 return tid;
683}
684
686 : m_nextValid(false)
687{
688 // m_mean, m_variance, and m_bound are initialized after constructor
689 // by attributes
690 NS_LOG_FUNCTION(this);
691}
692
693double
695{
696 NS_LOG_FUNCTION(this);
697 return m_mean;
698}
699
700double
702{
703 NS_LOG_FUNCTION(this);
704 return m_variance;
705}
706
707double
709{
710 NS_LOG_FUNCTION(this);
711 return m_bound;
712}
713
714double
715NormalRandomVariable::GetValue(double mean, double variance, double bound)
716{
717 NS_LOG_FUNCTION(this << mean << variance << bound);
718 if (m_nextValid)
719 { // use previously generated
720 m_nextValid = false;
721 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
722 if (std::fabs(x2 - mean) <= bound)
723 {
724 return x2;
725 }
726 }
727 while (true)
728 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
729 // for algorithm; basically a Box-Muller transform:
730 // http://en.wikipedia.org/wiki/Box-Muller_transform
731 double u1 = Peek()->RandU01();
732 double u2 = Peek()->RandU01();
733 if (IsAntithetic())
734 {
735 u1 = (1 - u1);
736 u2 = (1 - u2);
737 }
738 double v1 = 2 * u1 - 1;
739 double v2 = 2 * u2 - 1;
740 double w = v1 * v1 + v2 * v2;
741 if (w <= 1.0)
742 { // Got good pair
743 double y = std::sqrt((-2 * std::log(w)) / w);
744 double x1 = mean + v1 * y * std::sqrt(variance);
745 // if x1 is in bounds, return it, cache v2 and y
746 if (std::fabs(x1 - mean) <= bound)
747 {
748 m_nextValid = true;
749 m_y = y;
750 m_v2 = v2;
751 return x1;
752 }
753 // otherwise try and return the other if it is valid
754 double x2 = mean + v2 * y * std::sqrt(variance);
755 if (std::fabs(x2 - mean) <= bound)
756 {
757 m_nextValid = false;
758 return x2;
759 }
760 // otherwise, just run this loop again
761 }
762 }
763}
764
767{
768 NS_LOG_FUNCTION(this << mean << variance << bound);
769 return static_cast<uint32_t>(GetValue(mean, variance, bound));
770}
771
772double
774{
775 NS_LOG_FUNCTION(this);
777}
778
780
781TypeId
783{
784 static TypeId tid =
785 TypeId("ns3::LogNormalRandomVariable")
787 .SetGroupName("Core")
788 .AddConstructor<LogNormalRandomVariable>()
789 .AddAttribute(
790 "Mu",
791 "The mu value for the log-normal distribution returned by this RNG stream.",
792 DoubleValue(0.0),
794 MakeDoubleChecker<double>())
795 .AddAttribute(
796 "Sigma",
797 "The sigma value for the log-normal distribution returned by this RNG stream.",
798 DoubleValue(1.0),
800 MakeDoubleChecker<double>());
801 return tid;
802}
803
805 : m_nextValid(false)
806{
807 // m_mu and m_sigma are initialized after constructor by
808 // attributes
809 NS_LOG_FUNCTION(this);
810}
811
812double
814{
815 NS_LOG_FUNCTION(this);
816 return m_mu;
817}
818
819double
821{
822 NS_LOG_FUNCTION(this);
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 * This program is free software; you can redistribute it and/or modify
833 * it under the terms of the GNU General Public License as published by
834 * the Free Software Foundation; either version 2 of the License, or (at
835 * your option) any later version.
836 *
837 * This program is distributed in the hope that it will be useful, but
838 * WITHOUT ANY WARRANTY; without even the implied warranty of
839 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
840 * General Public License for more details.
841 *
842 * You should have received a copy of the GNU General Public License
843 * along with this program; if not, write to the Free Software
844 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
845 */
846/* The lognormal distribution has the form
847
848 p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
849
850 for x > 0. Lognormal random numbers are the exponentials of
851 gaussian random numbers */
852double
853LogNormalRandomVariable::GetValue(double mu, double sigma)
854{
855 if (m_nextValid)
856 { // use previously generated
857 m_nextValid = false;
858 double normal = m_v2 * m_normal;
859
860 return std::exp(sigma * normal + mu);
861 }
862
863 double v1;
864 double v2;
865 double r2;
866 double normal;
867 double x;
868
869 NS_LOG_FUNCTION(this << mu << sigma);
870
871 do
872 {
873 /* choose x,y in uniform square (-1,-1) to (+1,+1) */
874
875 double u1 = Peek()->RandU01();
876 double u2 = Peek()->RandU01();
877 if (IsAntithetic())
878 {
879 u1 = (1 - u1);
880 u2 = (1 - u2);
881 }
882
883 v1 = -1 + 2 * u1;
884 v2 = -1 + 2 * u2;
885
886 /* see if it is in the unit circle */
887 r2 = v1 * v1 + v2 * v2;
888 } while (r2 > 1.0 || r2 == 0);
889
890 m_normal = std::sqrt(-2.0 * std::log(r2) / r2);
891 normal = v1 * m_normal;
892 m_nextValid = true;
893 m_v2 = v2;
894
895 x = std::exp(sigma * normal + mu);
896
897 return x;
898}
899
902{
903 NS_LOG_FUNCTION(this << mu << sigma);
904 return static_cast<uint32_t>(GetValue(mu, sigma));
905}
906
907double
909{
910 NS_LOG_FUNCTION(this);
911 return GetValue(m_mu, m_sigma);
912}
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),
928 MakeDoubleChecker<double>())
929 .AddAttribute("Beta",
930 "The beta value for the gamma distribution returned by this RNG stream.",
931 DoubleValue(1.0),
933 MakeDoubleChecker<double>());
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 NS_LOG_FUNCTION(this);
949 return m_alpha;
950}
951
952double
954{
955 NS_LOG_FUNCTION(this);
956 return m_beta;
957}
958
959/*
960 The code for the following generator functions was adapted from ns-2
961 tools/ranvar.cc
962
963 Originally the algorithm was devised by Marsaglia in 2000:
964 G. Marsaglia, W. W. Tsang: A simple method for generating Gamma variables
965 ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
966
967 The Gamma distribution density function has the form
968
969 x^(alpha-1) * exp(-x/beta)
970 p(x; alpha, beta) = ----------------------------
971 beta^alpha * Gamma(alpha)
972
973 for x > 0.
974*/
975double
976GammaRandomVariable::GetValue(double alpha, double beta)
977{
978 NS_LOG_FUNCTION(this << alpha << beta);
979 if (alpha < 1)
980 {
981 double u = Peek()->RandU01();
982 if (IsAntithetic())
983 {
984 u = (1 - u);
985 }
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 return beta * d * v;
1026}
1027
1028double
1030{
1031 NS_LOG_FUNCTION(this);
1032 return GetValue(m_alpha, m_beta);
1033}
1034
1035double
1036GammaRandomVariable::GetNormalValue(double mean, double variance, double bound)
1037{
1038 NS_LOG_FUNCTION(this << mean << variance << bound);
1039 if (m_nextValid)
1040 { // use previously generated
1041 m_nextValid = false;
1042 double x2 = mean + m_v2 * m_y * std::sqrt(variance);
1043 if (std::fabs(x2 - mean) <= bound)
1044 {
1045 return x2;
1046 }
1047 }
1048 while (true)
1049 { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1050 // for algorithm; basically a Box-Muller transform:
1051 // http://en.wikipedia.org/wiki/Box-Muller_transform
1052 double u1 = Peek()->RandU01();
1053 double u2 = Peek()->RandU01();
1054 if (IsAntithetic())
1055 {
1056 u1 = (1 - u1);
1057 u2 = (1 - u2);
1058 }
1059 double v1 = 2 * u1 - 1;
1060 double v2 = 2 * u2 - 1;
1061 double w = v1 * v1 + v2 * v2;
1062 if (w <= 1.0)
1063 { // Got good pair
1064 double y = std::sqrt((-2 * std::log(w)) / w);
1065 double x1 = mean + v1 * y * std::sqrt(variance);
1066 // if x1 is in bounds, return it, cache v2 an y
1067 if (std::fabs(x1 - mean) <= bound)
1068 {
1069 m_nextValid = true;
1070 m_y = y;
1071 m_v2 = v2;
1072 return x1;
1073 }
1074 // otherwise try and return the other if it is valid
1075 double x2 = mean + v2 * y * std::sqrt(variance);
1076 if (std::fabs(x2 - mean) <= bound)
1077 {
1078 m_nextValid = false;
1079 return x2;
1080 }
1081 // otherwise, just run this loop again
1082 }
1083 }
1084}
1085
1087
1088TypeId
1090{
1091 static TypeId tid =
1092 TypeId("ns3::ErlangRandomVariable")
1094 .SetGroupName("Core")
1095 .AddConstructor<ErlangRandomVariable>()
1096 .AddAttribute("K",
1097 "The k value for the Erlang distribution returned by this RNG stream.",
1098 IntegerValue(1),
1100 MakeIntegerChecker<uint32_t>())
1101 .AddAttribute(
1102 "Lambda",
1103 "The lambda value for the Erlang distribution returned by this RNG stream.",
1104 DoubleValue(1.0),
1106 MakeDoubleChecker<double>());
1107 return tid;
1108}
1109
1111{
1112 // m_k and m_lambda are initialized after constructor by attributes
1113 NS_LOG_FUNCTION(this);
1114}
1115
1118{
1119 NS_LOG_FUNCTION(this);
1120 return m_k;
1121}
1122
1123double
1125{
1126 NS_LOG_FUNCTION(this);
1127 return m_lambda;
1128}
1129
1130/*
1131 The code for the following generator functions was adapted from ns-2
1132 tools/ranvar.cc
1133
1134 The Erlang distribution density function has the form
1135
1136 x^(k-1) * exp(-x/lambda)
1137 p(x; k, lambda) = ---------------------------
1138 lambda^k * (k-1)!
1139
1140 for x > 0.
1141*/
1142double
1144{
1145 NS_LOG_FUNCTION(this << k << lambda);
1146 double mean = lambda;
1147 double bound = 0.0;
1148
1149 double result = 0;
1150 for (unsigned int i = 0; i < k; ++i)
1151 {
1152 result += GetExponentialValue(mean, bound);
1153 }
1154
1155 return result;
1156}
1157
1160{
1161 NS_LOG_FUNCTION(this << k << lambda);
1162 return static_cast<uint32_t>(GetValue(k, lambda));
1163}
1164
1165double
1167{
1168 NS_LOG_FUNCTION(this);
1169 return GetValue(m_k, m_lambda);
1170}
1171
1172double
1174{
1175 NS_LOG_FUNCTION(this << mean << bound);
1176 while (true)
1177 {
1178 // Get a uniform random variable in [0,1].
1179 double v = Peek()->RandU01();
1180 if (IsAntithetic())
1181 {
1182 v = (1 - v);
1183 }
1184
1185 // Calculate the exponential random variable.
1186 double r = -mean * std::log(v);
1187
1188 // Use this value if it's acceptable.
1189 if (bound == 0 || r <= bound)
1190 {
1191 return r;
1192 }
1193 }
1194}
1195
1197
1198TypeId
1200{
1201 static TypeId tid =
1202 TypeId("ns3::TriangularRandomVariable")
1204 .SetGroupName("Core")
1205 .AddConstructor<TriangularRandomVariable>()
1206 .AddAttribute(
1207 "Mean",
1208 "The mean value for the triangular distribution returned by this RNG stream.",
1209 DoubleValue(0.5),
1211 MakeDoubleChecker<double>())
1212 .AddAttribute("Min",
1213 "The lower bound on the values returned by this RNG stream.",
1214 DoubleValue(0.0),
1216 MakeDoubleChecker<double>())
1217 .AddAttribute("Max",
1218 "The upper bound on the values returned by this RNG stream.",
1219 DoubleValue(1.0),
1221 MakeDoubleChecker<double>());
1222 return tid;
1223}
1224
1226{
1227 // m_mean, m_min, and m_max are initialized after constructor by
1228 // attributes
1229 NS_LOG_FUNCTION(this);
1230}
1231
1232double
1234{
1235 NS_LOG_FUNCTION(this);
1236 return m_mean;
1237}
1238
1239double
1241{
1242 NS_LOG_FUNCTION(this);
1243 return m_min;
1244}
1245
1246double
1248{
1249 NS_LOG_FUNCTION(this);
1250 return m_max;
1251}
1252
1253double
1254TriangularRandomVariable::GetValue(double mean, double min, double max)
1255{
1256 // Calculate the mode.
1257 NS_LOG_FUNCTION(this << mean << min << max);
1258 double mode = 3.0 * mean - min - max;
1259
1260 // Get a uniform random variable in [0,1].
1261 double u = Peek()->RandU01();
1262 if (IsAntithetic())
1263 {
1264 u = (1 - u);
1265 }
1266
1267 // Calculate the triangular random variable.
1268 if (u <= (mode - min) / (max - min))
1269 {
1270 return min + std::sqrt(u * (max - min) * (mode - min));
1271 }
1272 else
1273 {
1274 return max - std::sqrt((1 - u) * (max - min) * (max - mode));
1275 }
1276}
1277
1280{
1281 NS_LOG_FUNCTION(this << mean << min << max);
1282 return static_cast<uint32_t>(GetValue(mean, min, max));
1283}
1284
1285double
1287{
1288 NS_LOG_FUNCTION(this);
1289 return GetValue(m_mean, m_min, m_max);
1290}
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),
1306 MakeIntegerChecker<uint32_t>())
1307 .AddAttribute("Alpha",
1308 "The alpha value for the Zipf distribution returned by this RNG stream.",
1309 DoubleValue(0.0),
1311 MakeDoubleChecker<double>());
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 NS_LOG_FUNCTION(this);
1325 return m_n;
1326}
1327
1328double
1330{
1331 NS_LOG_FUNCTION(this);
1332 return m_alpha;
1333}
1334
1335double
1337{
1338 NS_LOG_FUNCTION(this << n << alpha);
1339 // Calculate the normalization constant c.
1340 m_c = 0.0;
1341 for (uint32_t i = 1; i <= n; i++)
1342 {
1343 m_c += (1.0 / std::pow((double)i, alpha));
1344 }
1345 m_c = 1.0 / m_c;
1346
1347 // Get a uniform random variable in [0,1].
1348 double u = Peek()->RandU01();
1349 if (IsAntithetic())
1350 {
1351 u = (1 - u);
1352 }
1353
1354 double sum_prob = 0;
1355 double zipf_value = 0;
1356 for (uint32_t i = 1; i <= m_n; i++)
1357 {
1358 sum_prob += m_c / std::pow((double)i, m_alpha);
1359 if (sum_prob > u)
1360 {
1361 zipf_value = i;
1362 break;
1363 }
1364 }
1365 return zipf_value;
1366}
1367
1370{
1371 NS_LOG_FUNCTION(this << n << alpha);
1372 return static_cast<uint32_t>(GetValue(n, alpha));
1373}
1374
1375double
1377{
1378 NS_LOG_FUNCTION(this);
1379 return GetValue(m_n, m_alpha);
1380}
1381
1383
1384TypeId
1386{
1387 static TypeId tid =
1388 TypeId("ns3::ZetaRandomVariable")
1390 .SetGroupName("Core")
1391 .AddConstructor<ZetaRandomVariable>()
1392 .AddAttribute("Alpha",
1393 "The alpha value for the zeta distribution returned by this RNG stream.",
1394 DoubleValue(3.14),
1396 MakeDoubleChecker<double>());
1397 return tid;
1398}
1399
1401{
1402 // m_alpha is initialized after constructor by attributes
1403 NS_LOG_FUNCTION(this);
1404}
1405
1406double
1408{
1409 NS_LOG_FUNCTION(this);
1410 return m_alpha;
1411}
1412
1413double
1415{
1416 NS_LOG_FUNCTION(this << alpha);
1417 m_b = std::pow(2.0, alpha - 1.0);
1418
1419 double u;
1420 double v;
1421 double X;
1422 double T;
1423 double test;
1424
1425 do
1426 {
1427 // Get a uniform random variable in [0,1].
1428 u = Peek()->RandU01();
1429 if (IsAntithetic())
1430 {
1431 u = (1 - u);
1432 }
1433
1434 // Get a uniform random variable in [0,1].
1435 v = Peek()->RandU01();
1436 if (IsAntithetic())
1437 {
1438 v = (1 - v);
1439 }
1440
1441 X = std::floor(std::pow(u, -1.0 / (m_alpha - 1.0)));
1442 T = std::pow(1.0 + 1.0 / X, m_alpha - 1.0);
1443 test = v * X * (T - 1.0) / (m_b - 1.0);
1444 } while (test > (T / m_b));
1445
1446 return X;
1447}
1448
1451{
1452 NS_LOG_FUNCTION(this << alpha);
1453 return static_cast<uint32_t>(GetValue(alpha));
1454}
1455
1456double
1458{
1459 NS_LOG_FUNCTION(this);
1460 return GetValue(m_alpha);
1461}
1462
1464
1465TypeId
1467{
1468 static TypeId tid = TypeId("ns3::DeterministicRandomVariable")
1470 .SetGroupName("Core")
1471 .AddConstructor<DeterministicRandomVariable>();
1472 return tid;
1473}
1474
1476 : m_count(0),
1477 m_next(0),
1478 m_data(nullptr)
1479{
1480 NS_LOG_FUNCTION(this);
1481}
1482
1484{
1485 // Delete any values currently set.
1486 NS_LOG_FUNCTION(this);
1487 if (m_data != nullptr)
1488 {
1489 delete[] m_data;
1490 }
1491}
1492
1493void
1494DeterministicRandomVariable::SetValueArray(const std::vector<double>& values)
1495{
1496 SetValueArray(values.data(), values.size());
1497}
1498
1499void
1500DeterministicRandomVariable::SetValueArray(const double* values, std::size_t length)
1501{
1502 NS_LOG_FUNCTION(this << values << length);
1503 // Delete any values currently set.
1504 if (m_data != nullptr)
1505 {
1506 delete[] m_data;
1507 }
1508
1509 // Make room for the values being set.
1510 m_data = new double[length];
1511 m_count = length;
1512 m_next = length;
1513
1514 // Copy the values.
1515 for (std::size_t i = 0; i < m_count; i++)
1516 {
1517 m_data[i] = values[i];
1518 }
1519}
1520
1521double
1523{
1524 NS_LOG_FUNCTION(this);
1525 // Make sure the array has been set.
1526 NS_ASSERT(m_count > 0);
1527
1528 if (m_next == m_count)
1529 {
1530 m_next = 0;
1531 }
1532 return m_data[m_next++];
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);
1573
1574 if (!m_validated)
1575 {
1576 Validate();
1577 }
1578
1579 // Get a uniform random variable in [0, 1].
1580 double r = Peek()->RandU01();
1581 if (IsAntithetic())
1582 {
1583 r = (1 - r);
1584 }
1585
1586 value = r;
1587 bool valid = false;
1588 // check extrema
1589 if (r <= m_empCdf.begin()->first)
1590 {
1591 value = m_empCdf.begin()->second; // Less than first
1592 valid = true;
1593 }
1594 else if (r >= m_empCdf.rbegin()->first)
1595 {
1596 value = m_empCdf.rbegin()->second; // Greater than last
1597 valid = true;
1598 }
1599 return valid;
1600}
1601
1602double
1604{
1605 NS_LOG_FUNCTION(this);
1606
1607 double value;
1608 if (PreSample(value))
1609 {
1610 return value;
1611 }
1612
1613 // value now has the (unused) URNG selector
1614 if (m_interpolate)
1615 {
1616 value = DoInterpolate(value);
1617 }
1618 else
1619 {
1620 value = DoSampleCDF(value);
1621 }
1622 return value;
1623}
1624
1625double
1627{
1628 NS_LOG_FUNCTION(this << r);
1629
1630 // Find first CDF that is greater than r
1631 auto bound = m_empCdf.upper_bound(r);
1632
1633 return bound->second;
1634}
1635
1636double
1638{
1639 NS_LOG_FUNCTION(this);
1640
1641 double value;
1642 if (PreSample(value))
1643 {
1644 return value;
1645 }
1646
1647 // value now has the (unused) URNG selector
1648 value = DoInterpolate(value);
1649 return value;
1650}
1651
1652double
1654{
1655 NS_LOG_FUNCTION(this << r);
1656
1657 // Return a value from the empirical distribution
1658 // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1659
1660 // search
1661 auto upper = m_empCdf.upper_bound(r);
1662 auto lower = std::prev(upper, 1);
1663
1664 if (upper == m_empCdf.begin())
1665 {
1666 lower = upper;
1667 }
1668
1669 // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1670 double c1 = lower->first;
1671 double c2 = upper->first;
1672 double v1 = lower->second;
1673 double v2 = upper->second;
1674
1675 double value = (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1676 return value;
1677}
1678
1679void
1681{
1682 NS_LOG_FUNCTION(this << v << c);
1683
1684 auto vPrevious = m_empCdf.find(c);
1685
1686 if (vPrevious != m_empCdf.end())
1687 {
1688 NS_LOG_WARN("Empirical CDF already has a value " << vPrevious->second << " for CDF " << c
1689 << ". Overwriting it with value " << v
1690 << ".");
1691 }
1692
1693 m_empCdf[c] = v;
1694}
1695
1696void
1698{
1699 NS_LOG_FUNCTION(this);
1700
1701 if (m_empCdf.empty())
1702 {
1703 NS_FATAL_ERROR("CDF is not initialized");
1704 }
1705
1706 double vPrev = m_empCdf.begin()->second;
1707
1708 // Check if values are non-decreasing
1709 for (const auto& cdfPair : m_empCdf)
1710 {
1711 const auto& vCurr = cdfPair.second;
1712
1713 if (vCurr < vPrev)
1714 {
1715 NS_FATAL_ERROR("Empirical distribution has decreasing CDF values. Current CDF: "
1716 << vCurr << ", prior CDF: " << vPrev);
1717 }
1718
1719 vPrev = vCurr;
1720 }
1721
1722 // Bounds check on CDF endpoints
1723 auto firstCdfPair = m_empCdf.begin();
1724 auto lastCdfPair = m_empCdf.rbegin();
1725
1726 if (firstCdfPair->first < 0.0)
1727 {
1728 NS_FATAL_ERROR("Empirical distribution has invalid first CDF value. CDF: "
1729 << firstCdfPair->first << ", Value: " << firstCdfPair->second);
1730 }
1731
1732 if (lastCdfPair->first > 1.0)
1733 {
1734 NS_FATAL_ERROR("Empirical distribution has invalid last CDF value. CDF: "
1735 << lastCdfPair->first << ", Value: " << lastCdfPair->second);
1736 }
1737
1738 m_validated = true;
1739}
1740
1742
1743TypeId
1745{
1746 static TypeId tid =
1747 TypeId("ns3::BinomialRandomVariable")
1749 .SetGroupName("Core")
1750 .AddConstructor<BinomialRandomVariable>()
1751 .AddAttribute("Trials",
1752 "The number of trials.",
1753 IntegerValue(10),
1755 MakeIntegerChecker<uint32_t>(0))
1756 .AddAttribute("Probability",
1757 "The probability of success in each trial.",
1758 DoubleValue(0.5),
1760 MakeDoubleChecker<double>(0));
1761 return tid;
1762}
1763
1765{
1766 // m_trials and m_probability are initialized after constructor by attributes
1767 NS_LOG_FUNCTION(this);
1768}
1769
1770double
1772{
1773 NS_LOG_FUNCTION(this << trials << probability);
1774
1775 double successes = 0;
1776
1777 for (uint32_t i = 0; i < trials; ++i)
1778 {
1779 double v = Peek()->RandU01();
1780 if (IsAntithetic())
1781 {
1782 v = (1 - v);
1783 }
1784
1785 if (v <= probability)
1786 {
1787 successes += 1;
1788 }
1789 }
1790
1791 return successes;
1792}
1793
1796{
1797 NS_LOG_FUNCTION(this << trials << probability);
1798 return static_cast<uint32_t>(GetValue(trials, probability));
1799}
1800
1801double
1803{
1804 NS_LOG_FUNCTION(this);
1806}
1807
1809
1810TypeId
1812{
1813 static TypeId tid =
1814 TypeId("ns3::BernoulliRandomVariable")
1816 .SetGroupName("Core")
1817 .AddConstructor<BernoulliRandomVariable>()
1818 .AddAttribute("Probability",
1819 "The probability of the random variable returning a value of 1.",
1820 DoubleValue(0.5),
1822 MakeDoubleChecker<double>(0));
1823 return tid;
1824}
1825
1827{
1828 // m_probability is initialized after constructor by attributes
1829 NS_LOG_FUNCTION(this);
1830}
1831
1832double
1834{
1835 NS_LOG_FUNCTION(this << probability);
1836
1837 double v = Peek()->RandU01();
1838 if (IsAntithetic())
1839 {
1840 v = (1 - v);
1841 }
1842
1843 return (v <= probability) ? 1.0 : 0.0;
1844}
1845
1848{
1849 NS_LOG_FUNCTION(this << probability);
1850 return static_cast<uint32_t>(GetValue(probability));
1851}
1852
1853double
1855{
1856 NS_LOG_FUNCTION(this);
1857 return GetValue(m_probability);
1858}
1859
1860} // 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:37
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:42
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:45
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:89
The Pareto distribution Random Number Generator (RNG).
double GetShape() const
Returns the shape parameter for the Pareto distribution returned by this RNG stream.
double m_scale
The scale parameter for the Pareto distribution returned by this RNG stream.
ParetoRandomVariable()
Creates a Pareto distribution RNG with the default values for the mean, the shape,...
static TypeId GetTypeId()
Register this type.
double m_shape
The shape parameter for the Pareto distribution returned by this RNG stream.
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:77
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:50
double RandU01()
Generate the next random number for this stream.
Definition: rng-stream.cc:341
The Random Number Generator (RNG) that returns a pattern of sequential values.
uint32_t m_currentConsecutive
The number of times the current distinct value has been repeated.
double m_min
The first value of the sequence.
Ptr< RandomVariableStream > GetIncrement() const
Get the increment for the sequence.
uint32_t m_consecutive
The number of times each distinct value is repeated.
static TypeId GetTypeId()
Register this type.
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:56
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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 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:66
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:46
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
ns3::IntegerValue attribute value declarations and template implementations.
Debug message logging.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ normal
Definition: ff-mac-common.h:84
-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