A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
random-variable-stream.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006 Georgia Tech Research Corporation
4  * Copyright (c) 2011 Mathieu Lacage
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Rajib Bhattacharjea<raj.b@gatech.edu>
20  * Hadi Arbabi<marbabi@cs.odu.edu>
21  * Mathieu Lacage <mathieu.lacage@gmail.com>
22  *
23  * Modified by Mitch Watrous <watrous@u.washington.edu>
24  *
25  */
26 #include "random-variable-stream.h"
27 #include "assert.h"
28 #include "boolean.h"
29 #include "double.h"
30 #include "integer.h"
31 #include "string.h"
32 #include "pointer.h"
33 #include "log.h"
34 #include "rng-stream.h"
35 #include "rng-seed-manager.h"
36 #include <cmath>
37 #include <iostream>
38 
39 NS_LOG_COMPONENT_DEFINE ("RandomVariableStream");
40 
41 namespace ns3 {
42 
43 NS_OBJECT_ENSURE_REGISTERED (RandomVariableStream);
44 
45 TypeId
47 {
48  static TypeId tid = TypeId ("ns3::RandomVariableStream")
49  .SetParent<Object> ()
50  .AddAttribute("Stream",
51  "The stream number for this RNG stream. -1 means \"allocate a stream automatically\". "
52  "Note that if -1 is set, Get will return -1 so that it is not possible to know which "
53  "value was automatically allocated.",
54  IntegerValue(-1),
55  MakeIntegerAccessor(&RandomVariableStream::SetStream,
57  MakeIntegerChecker<int64_t>())
58  .AddAttribute("Antithetic", "Set this RNG stream to generate antithetic values",
59  BooleanValue (false),
60  MakeBooleanAccessor(&RandomVariableStream::SetAntithetic,
62  MakeBooleanChecker())
63  ;
64  return tid;
65 }
66 
68  : m_rng (0)
69 {
70  NS_LOG_FUNCTION (this);
71 }
73 {
74  NS_LOG_FUNCTION (this);
75  delete m_rng;
76 }
77 
78 void
80 {
81  NS_LOG_FUNCTION (this << isAntithetic);
82  m_isAntithetic = isAntithetic;
83 }
84 bool
86 {
87  NS_LOG_FUNCTION (this);
88  return m_isAntithetic;
89 }
90 void
92 {
93  NS_LOG_FUNCTION (this << stream);
94  // negative values are not legal.
95  NS_ASSERT (stream >= -1);
96  delete m_rng;
97  if (stream == -1)
98  {
99  // The first 2^63 streams are reserved for automatic stream
100  // number assignment.
101  uint64_t nextStream = RngSeedManager::GetNextStreamIndex ();
102  NS_ASSERT(nextStream <= ((1ULL)<<63));
104  nextStream,
106  }
107  else
108  {
109  // The last 2^63 streams are reserved for deterministic stream
110  // number assignment.
111  uint64_t base = ((1ULL)<<63);
112  uint64_t target = base + stream;
114  target,
116  }
117  m_stream = stream;
118 }
119 int64_t
121 {
122  NS_LOG_FUNCTION (this);
123  return m_stream;
124 }
125 
126 RngStream *
128 {
129  NS_LOG_FUNCTION (this);
130  return m_rng;
131 }
132 
134 
135 TypeId
137 {
138  static TypeId tid = TypeId ("ns3::UniformRandomVariable")
140  .AddConstructor<UniformRandomVariable> ()
141  .AddAttribute("Min", "The lower bound on the values returned by this RNG stream.",
142  DoubleValue(0),
143  MakeDoubleAccessor(&UniformRandomVariable::m_min),
144  MakeDoubleChecker<double>())
145  .AddAttribute("Max", "The upper bound on the values returned by this RNG stream.",
146  DoubleValue(1.0),
147  MakeDoubleAccessor(&UniformRandomVariable::m_max),
148  MakeDoubleChecker<double>())
149  ;
150  return tid;
151 }
153 {
154  // m_min and m_max are initialized after constructor by attributes
155  NS_LOG_FUNCTION (this);
156 }
157 
158 double
160 {
161  NS_LOG_FUNCTION (this);
162  return m_min;
163 }
164 double
166 {
167  NS_LOG_FUNCTION (this);
168  return m_max;
169 }
170 
171 double
172 UniformRandomVariable::GetValue (double min, double max)
173 {
174  NS_LOG_FUNCTION (this << min << max);
175  double v = min + Peek ()->RandU01 () * (max - min);
176  if (IsAntithetic ())
177  {
178  v = min + (max - v);
179  }
180  return v;
181 }
182 uint32_t
183 UniformRandomVariable::GetInteger (uint32_t min, uint32_t max)
184 {
185  NS_LOG_FUNCTION (this << min << max);
186  NS_ASSERT (min <= max);
187  return static_cast<uint32_t> ( GetValue (min, max + 1) );
188 }
189 
190 double
192 {
193  NS_LOG_FUNCTION (this);
194  return GetValue (m_min, m_max);
195 }
196 uint32_t
198 {
199  NS_LOG_FUNCTION (this);
200  return (uint32_t)GetValue (m_min, m_max + 1);
201 }
202 
204 
205 TypeId
207 {
208  static TypeId tid = TypeId ("ns3::ConstantRandomVariable")
210  .AddConstructor<ConstantRandomVariable> ()
211  .AddAttribute("Constant", "The constant value returned by this RNG stream.",
212  DoubleValue(0),
213  MakeDoubleAccessor(&ConstantRandomVariable::m_constant),
214  MakeDoubleChecker<double>())
215  ;
216  return tid;
217 }
219 {
220  // m_constant is initialized after constructor by attributes
221  NS_LOG_FUNCTION (this);
222 }
223 
224 double
226 {
227  NS_LOG_FUNCTION (this);
228  return m_constant;
229 }
230 
231 double
233 {
234  NS_LOG_FUNCTION (this << constant);
235  return constant;
236 }
237 uint32_t
239 {
240  NS_LOG_FUNCTION (this << constant);
241  return constant;
242 }
243 
244 double
246 {
247  NS_LOG_FUNCTION (this);
248  return GetValue (m_constant);
249 }
250 uint32_t
252 {
253  NS_LOG_FUNCTION (this);
254  return (uint32_t)GetValue (m_constant);
255 }
256 
258 
259 TypeId
261 {
262  static TypeId tid = TypeId ("ns3::SequentialRandomVariable")
264  .AddConstructor<SequentialRandomVariable> ()
265  .AddAttribute("Min", "The first value of the sequence.",
266  DoubleValue(0),
267  MakeDoubleAccessor(&SequentialRandomVariable::m_min),
268  MakeDoubleChecker<double>())
269  .AddAttribute("Max", "One more than the last value of the sequence.",
270  DoubleValue(0),
271  MakeDoubleAccessor(&SequentialRandomVariable::m_max),
272  MakeDoubleChecker<double>())
273  .AddAttribute("Increment", "The sequence random variable increment.",
274  StringValue("ns3::ConstantRandomVariable[Constant=1]"),
275  MakePointerAccessor (&SequentialRandomVariable::m_increment),
276  MakePointerChecker<RandomVariableStream> ())
277  .AddAttribute("Consecutive", "The number of times each member of the sequence is repeated.",
278  IntegerValue(1),
279  MakeIntegerAccessor(&SequentialRandomVariable::m_consecutive),
280  MakeIntegerChecker<uint32_t>());
281  ;
282  return tid;
283 }
285  :
286  m_current (0),
287  m_currentConsecutive (0),
288  m_isCurrentSet (false)
289 {
290  // m_min, m_max, m_increment, and m_consecutive are initialized
291  // after constructor by attributes.
292  NS_LOG_FUNCTION (this);
293 }
294 
295 double
297 {
298  NS_LOG_FUNCTION (this);
299  return m_min;
300 }
301 
302 double
304 {
305  NS_LOG_FUNCTION (this);
306  return m_max;
307 }
308 
311 {
312  NS_LOG_FUNCTION (this);
313  return m_increment;
314 }
315 
316 uint32_t
318 {
319  NS_LOG_FUNCTION (this);
320  return m_consecutive;
321 }
322 
323 double
325 {
326  // Set the current sequence value if it hasn't been set.
327  NS_LOG_FUNCTION (this);
328  if (!m_isCurrentSet)
329  {
330  // Start the sequence at its minimium value.
331  m_current = m_min;
332  m_isCurrentSet = true;
333  }
334 
335  // Return a sequential series of values
336  double r = m_current;
338  { // Time to advance to next
341  if (m_current >= m_max)
342  {
343  m_current = m_min + (m_current - m_max);
344  }
345  }
346  return r;
347 }
348 
349 uint32_t
351 {
352  NS_LOG_FUNCTION (this);
353  return (uint32_t)GetValue ();
354 }
355 
357 
358 TypeId
360 {
361  static TypeId tid = TypeId ("ns3::ExponentialRandomVariable")
363  .AddConstructor<ExponentialRandomVariable> ()
364  .AddAttribute("Mean", "The mean of the values returned by this RNG stream.",
365  DoubleValue(1.0),
366  MakeDoubleAccessor(&ExponentialRandomVariable::m_mean),
367  MakeDoubleChecker<double>())
368  .AddAttribute("Bound", "The upper bound on the values returned by this RNG stream.",
369  DoubleValue(0.0),
370  MakeDoubleAccessor(&ExponentialRandomVariable::m_bound),
371  MakeDoubleChecker<double>())
372  ;
373  return tid;
374 }
376 {
377  // m_mean and m_bound are initialized after constructor by attributes
378  NS_LOG_FUNCTION (this);
379 }
380 
381 double
383 {
384  NS_LOG_FUNCTION (this);
385  return m_mean;
386 }
387 double
389 {
390  NS_LOG_FUNCTION (this);
391  return m_bound;
392 }
393 
394 double
395 ExponentialRandomVariable::GetValue (double mean, double bound)
396 {
397  NS_LOG_FUNCTION (this << mean << bound);
398  while (1)
399  {
400  // Get a uniform random variable in [0,1].
401  double v = Peek ()->RandU01 ();
402  if (IsAntithetic ())
403  {
404  v = (1 - v);
405  }
406 
407  // Calculate the exponential random variable.
408  double r = -mean*std::log (v);
409 
410  // Use this value if it's acceptable.
411  if (bound == 0 || r <= bound)
412  {
413  return r;
414  }
415  }
416 }
417 uint32_t
418 ExponentialRandomVariable::GetInteger (uint32_t mean, uint32_t bound)
419 {
420  NS_LOG_FUNCTION (this << mean << bound);
421  return static_cast<uint32_t> ( GetValue (mean, bound) );
422 }
423 
424 double
426 {
427  NS_LOG_FUNCTION (this);
428  return GetValue (m_mean, m_bound);
429 }
430 uint32_t
432 {
433  NS_LOG_FUNCTION (this);
434  return (uint32_t)GetValue (m_mean, m_bound);
435 }
436 
438 
439 TypeId
441 {
442  static TypeId tid = TypeId ("ns3::ParetoRandomVariable")
444  .AddConstructor<ParetoRandomVariable> ()
445  .AddAttribute("Mean", "The mean parameter for the Pareto distribution returned by this RNG stream.",
446  DoubleValue(1.0),
447  MakeDoubleAccessor(&ParetoRandomVariable::m_mean),
448  MakeDoubleChecker<double>())
449  .AddAttribute("Shape", "The shape parameter for the Pareto distribution returned by this RNG stream.",
450  DoubleValue(2.0),
451  MakeDoubleAccessor(&ParetoRandomVariable::m_shape),
452  MakeDoubleChecker<double>())
453  .AddAttribute("Bound", "The upper bound on the values returned by this RNG stream.",
454  DoubleValue(0.0),
455  MakeDoubleAccessor(&ParetoRandomVariable::m_bound),
456  MakeDoubleChecker<double>())
457  ;
458  return tid;
459 }
461 {
462  // m_mean, m_shape, and m_bound are initialized after constructor
463  // by attributes
464  NS_LOG_FUNCTION (this);
465 }
466 
467 double
469 {
470  NS_LOG_FUNCTION (this);
471  return m_mean;
472 }
473 double
475 {
476  NS_LOG_FUNCTION (this);
477  return m_shape;
478 }
479 double
481 {
482  NS_LOG_FUNCTION (this);
483  return m_bound;
484 }
485 
486 double
487 ParetoRandomVariable::GetValue (double mean, double shape, double bound)
488 {
489  // Calculate the scale parameter.
490  NS_LOG_FUNCTION (this << mean << shape << bound);
491  double scale = mean * (shape - 1.0) / shape;
492 
493  while (1)
494  {
495  // Get a uniform random variable in [0,1].
496  double v = Peek ()->RandU01 ();
497  if (IsAntithetic ())
498  {
499  v = (1 - v);
500  }
501 
502  // Calculate the Pareto random variable.
503  double r = (scale * ( 1.0 / std::pow (v, 1.0 / shape)));
504 
505  // Use this value if it's acceptable.
506  if (bound == 0 || r <= bound)
507  {
508  return r;
509  }
510  }
511 }
512 uint32_t
513 ParetoRandomVariable::GetInteger (uint32_t mean, uint32_t shape, uint32_t bound)
514 {
515  NS_LOG_FUNCTION (this << mean << shape << bound);
516  return static_cast<uint32_t> ( GetValue (mean, shape, bound) );
517 }
518 
519 double
521 {
522  NS_LOG_FUNCTION (this);
523  return GetValue (m_mean, m_shape, m_bound);
524 }
525 uint32_t
527 {
528  NS_LOG_FUNCTION (this);
529  return (uint32_t)GetValue (m_mean, m_shape, m_bound);
530 }
531 
533 
534 TypeId
536 {
537  static TypeId tid = TypeId ("ns3::WeibullRandomVariable")
539  .AddConstructor<WeibullRandomVariable> ()
540  .AddAttribute("Scale", "The scale parameter for the Weibull distribution returned by this RNG stream.",
541  DoubleValue(1.0),
542  MakeDoubleAccessor(&WeibullRandomVariable::m_scale),
543  MakeDoubleChecker<double>())
544  .AddAttribute("Shape", "The shape parameter for the Weibull distribution returned by this RNG stream.",
545  DoubleValue(1),
546  MakeDoubleAccessor(&WeibullRandomVariable::m_shape),
547  MakeDoubleChecker<double>())
548  .AddAttribute("Bound", "The upper bound on the values returned by this RNG stream.",
549  DoubleValue(0.0),
550  MakeDoubleAccessor(&WeibullRandomVariable::m_bound),
551  MakeDoubleChecker<double>())
552  ;
553  return tid;
554 }
556 {
557  // m_scale, m_shape, and m_bound are initialized after constructor
558  // by attributes
559  NS_LOG_FUNCTION (this);
560 }
561 
562 double
564 {
565  NS_LOG_FUNCTION (this);
566  return m_scale;
567 }
568 double
570 {
571  NS_LOG_FUNCTION (this);
572  return m_shape;
573 }
574 double
576 {
577  NS_LOG_FUNCTION (this);
578  return m_bound;
579 }
580 
581 double
582 WeibullRandomVariable::GetValue (double scale, double shape, double bound)
583 {
584  NS_LOG_FUNCTION (this << scale << shape << bound);
585  double exponent = 1.0 / shape;
586  while (1)
587  {
588  // Get a uniform random variable in [0,1].
589  double v = Peek ()->RandU01 ();
590  if (IsAntithetic ())
591  {
592  v = (1 - v);
593  }
594 
595  // Calculate the Weibull random variable.
596  double r = scale * std::pow ( -std::log (v), exponent);
597 
598  // Use this value if it's acceptable.
599  if (bound == 0 || r <= bound)
600  {
601  return r;
602  }
603  }
604 }
605 uint32_t
606 WeibullRandomVariable::GetInteger (uint32_t scale, uint32_t shape, uint32_t bound)
607 {
608  NS_LOG_FUNCTION (this << scale << shape << bound);
609  return static_cast<uint32_t> ( GetValue (scale, shape, bound) );
610 }
611 
612 double
614 {
615  NS_LOG_FUNCTION (this);
616  return GetValue (m_scale, m_shape, m_bound);
617 }
618 uint32_t
620 {
621  NS_LOG_FUNCTION (this);
622  return (uint32_t)GetValue (m_scale, m_shape, m_bound);
623 }
624 
626 
627 const double NormalRandomVariable::INFINITE_VALUE = 1e307;
628 
629 TypeId
631 {
632  static TypeId tid = TypeId ("ns3::NormalRandomVariable")
634  .AddConstructor<NormalRandomVariable> ()
635  .AddAttribute("Mean", "The mean value for the normal distribution returned by this RNG stream.",
636  DoubleValue(0.0),
637  MakeDoubleAccessor(&NormalRandomVariable::m_mean),
638  MakeDoubleChecker<double>())
639  .AddAttribute("Variance", "The variance value for the normal distribution returned by this RNG stream.",
640  DoubleValue(1.0),
641  MakeDoubleAccessor(&NormalRandomVariable::m_variance),
642  MakeDoubleChecker<double>())
643  .AddAttribute("Bound", "The bound on the values returned by this RNG stream.",
645  MakeDoubleAccessor(&NormalRandomVariable::m_bound),
646  MakeDoubleChecker<double>())
647  ;
648  return tid;
649 }
651  :
652  m_nextValid (false)
653 {
654  // m_mean, m_variance, and m_bound are initialized after constructor
655  // by attributes
656  NS_LOG_FUNCTION (this);
657 }
658 
659 double
661 {
662  NS_LOG_FUNCTION (this);
663  return m_mean;
664 }
665 double
667 {
668  NS_LOG_FUNCTION (this);
669  return m_variance;
670 }
671 double
673 {
674  NS_LOG_FUNCTION (this);
675  return m_bound;
676 }
677 
678 double
679 NormalRandomVariable::GetValue (double mean, double variance, double bound)
680 {
681  NS_LOG_FUNCTION (this << mean << variance << bound);
682  if (m_nextValid)
683  { // use previously generated
684  m_nextValid = false;
685  return m_next;
686  }
687  while (1)
688  { // See Simulation Modeling and Analysis p. 466 (Averill Law)
689  // for algorithm; basically a Box-Muller transform:
690  // http://en.wikipedia.org/wiki/Box-Muller_transform
691  double u1 = Peek ()->RandU01 ();
692  double u2 = Peek ()->RandU01 ();
693  if (IsAntithetic ())
694  {
695  u1 = (1 - u1);
696  u2 = (1 - u2);
697  }
698  double v1 = 2 * u1 - 1;
699  double v2 = 2 * u2 - 1;
700  double w = v1 * v1 + v2 * v2;
701  if (w <= 1.0)
702  { // Got good pair
703  double y = std::sqrt ((-2 * std::log (w)) / w);
704  m_next = mean + v2 * y * std::sqrt (variance);
705  // if next is in bounds, it is valid
706  m_nextValid = std::fabs (m_next - mean) <= bound;
707  double x1 = mean + v1 * y * std::sqrt (variance);
708  // if x1 is in bounds, return it
709  if (std::fabs (x1 - mean) <= bound)
710  {
711  return x1;
712  }
713  // otherwise try and return m_next if it is valid
714  else if (m_nextValid)
715  {
716  m_nextValid = false;
717  return m_next;
718  }
719  // otherwise, just run this loop again
720  }
721  }
722 }
723 
724 uint32_t
725 NormalRandomVariable::GetInteger (uint32_t mean, uint32_t variance, uint32_t bound)
726 {
727  NS_LOG_FUNCTION (this << mean << variance << bound);
728  return static_cast<uint32_t> ( GetValue (mean, variance, bound) );
729 }
730 
731 double
733 {
734  NS_LOG_FUNCTION (this);
735  return GetValue (m_mean, m_variance, m_bound);
736 }
737 uint32_t
739 {
740  NS_LOG_FUNCTION (this);
741  return (uint32_t)GetValue (m_mean, m_variance, m_bound);
742 }
743 
745 
746 TypeId
748 {
749  static TypeId tid = TypeId ("ns3::LogNormalRandomVariable")
751  .AddConstructor<LogNormalRandomVariable> ()
752  .AddAttribute("Mu", "The mu value for the log-normal distribution returned by this RNG stream.",
753  DoubleValue(0.0),
754  MakeDoubleAccessor(&LogNormalRandomVariable::m_mu),
755  MakeDoubleChecker<double>())
756  .AddAttribute("Sigma", "The sigma value for the log-normal distribution returned by this RNG stream.",
757  DoubleValue(1.0),
758  MakeDoubleAccessor(&LogNormalRandomVariable::m_sigma),
759  MakeDoubleChecker<double>())
760  ;
761  return tid;
762 }
764 {
765  // m_mu and m_sigma are initialized after constructor by
766  // attributes
767  NS_LOG_FUNCTION (this);
768 }
769 
770 double
772 {
773  NS_LOG_FUNCTION (this);
774  return m_mu;
775 }
776 double
778 {
779  NS_LOG_FUNCTION (this);
780  return m_sigma;
781 }
782 
783 // The code from this function was adapted from the GNU Scientific
784 // Library 1.8:
785 /* randist/lognormal.c
786  *
787  * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
788  *
789  * This program is free software; you can redistribute it and/or modify
790  * it under the terms of the GNU General Public License as published by
791  * the Free Software Foundation; either version 2 of the License, or (at
792  * your option) any later version.
793  *
794  * This program is distributed in the hope that it will be useful, but
795  * WITHOUT ANY WARRANTY; without even the implied warranty of
796  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
797  * General Public License for more details.
798  *
799  * You should have received a copy of the GNU General Public License
800  * along with this program; if not, write to the Free Software
801  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
802  */
803 /* The lognormal distribution has the form
804 
805  p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
806 
807  for x > 0. Lognormal random numbers are the exponentials of
808  gaussian random numbers */
809 double
810 LogNormalRandomVariable::GetValue (double mu, double sigma)
811 {
812  double v1, v2, r2, normal, x;
813 
814  NS_LOG_FUNCTION (this << mu << sigma);
815 
816  do
817  {
818  /* choose x,y in uniform square (-1,-1) to (+1,+1) */
819 
820  double u1 = Peek ()->RandU01 ();
821  double u2 = Peek ()->RandU01 ();
822  if (IsAntithetic ())
823  {
824  u1 = (1 - u1);
825  u2 = (1 - u2);
826  }
827 
828  v1 = -1 + 2 * u1;
829  v2 = -1 + 2 * u2;
830 
831  /* see if it is in the unit circle */
832  r2 = v1 * v1 + v2 * v2;
833  }
834  while (r2 > 1.0 || r2 == 0);
835 
836  normal = v1 * std::sqrt (-2.0 * std::log (r2) / r2);
837 
838  x = std::exp (sigma * normal + mu);
839 
840  return x;
841 }
842 
843 uint32_t
844 LogNormalRandomVariable::GetInteger (uint32_t mu, uint32_t sigma)
845 {
846  NS_LOG_FUNCTION (this << mu << sigma);
847  return static_cast<uint32_t> ( GetValue (mu, sigma));
848 }
849 
850 double
852 {
853  NS_LOG_FUNCTION (this);
854  return GetValue (m_mu, m_sigma);
855 }
856 uint32_t
858 {
859  NS_LOG_FUNCTION (this);
860  return (uint32_t)GetValue (m_mu, m_sigma);
861 }
862 
864 
865 TypeId
867 {
868  static TypeId tid = TypeId ("ns3::GammaRandomVariable")
870  .AddConstructor<GammaRandomVariable> ()
871  .AddAttribute("Alpha", "The alpha value for the gamma distribution returned by this RNG stream.",
872  DoubleValue(1.0),
873  MakeDoubleAccessor(&GammaRandomVariable::m_alpha),
874  MakeDoubleChecker<double>())
875  .AddAttribute("Beta", "The beta value for the gamma distribution returned by this RNG stream.",
876  DoubleValue(1.0),
877  MakeDoubleAccessor(&GammaRandomVariable::m_beta),
878  MakeDoubleChecker<double>())
879  ;
880  return tid;
881 }
883  :
884  m_nextValid (false)
885 {
886  // m_alpha and m_beta are initialized after constructor by
887  // attributes
888  NS_LOG_FUNCTION (this);
889 }
890 
891 double
893 {
894  NS_LOG_FUNCTION (this);
895  return m_alpha;
896 }
897 double
899 {
900  NS_LOG_FUNCTION (this);
901  return m_beta;
902 }
903 
904 /*
905  The code for the following generator functions was adapted from ns-2
906  tools/ranvar.cc
907 
908  Originally the algorithm was devised by Marsaglia in 2000:
909  G. Marsaglia, W. W. Tsang: A simple method for gereating Gamma variables
910  ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
911 
912  The Gamma distribution density function has the form
913 
914  x^(alpha-1) * exp(-x/beta)
915  p(x; alpha, beta) = ----------------------------
916  beta^alpha * Gamma(alpha)
917 
918  for x > 0.
919 */
920 double
921 GammaRandomVariable::GetValue (double alpha, double beta)
922 {
923  NS_LOG_FUNCTION (this << alpha << beta);
924  if (alpha < 1)
925  {
926  double u = Peek ()->RandU01 ();
927  if (IsAntithetic ())
928  {
929  u = (1 - u);
930  }
931  return GetValue (1.0 + alpha, beta) * std::pow (u, 1.0 / alpha);
932  }
933 
934  double x, v, u;
935  double d = alpha - 1.0 / 3.0;
936  double c = (1.0 / 3.0) / std::sqrt (d);
937 
938  while (1)
939  {
940  do
941  {
942  // Get a value from a normal distribution that has mean
943  // zero, variance 1, and no bound.
944  double mean = 0.0;
945  double variance = 1.0;
947  x = GetNormalValue (mean, variance, bound);
948 
949  v = 1.0 + c * x;
950  }
951  while (v <= 0);
952 
953  v = v * v * v;
954  u = Peek ()->RandU01 ();
955  if (IsAntithetic ())
956  {
957  u = (1 - u);
958  }
959  if (u < 1 - 0.0331 * x * x * x * x)
960  {
961  break;
962  }
963  if (std::log (u) < 0.5 * x * x + d * (1 - v + std::log (v)))
964  {
965  break;
966  }
967  }
968 
969  return beta * d * v;
970 }
971 
972 uint32_t
973 GammaRandomVariable::GetInteger (uint32_t alpha, uint32_t beta)
974 {
975  NS_LOG_FUNCTION (this << alpha << beta);
976  return static_cast<uint32_t> ( GetValue (alpha, beta));
977 }
978 
979 double
981 {
982  NS_LOG_FUNCTION (this);
983  return GetValue (m_alpha, m_beta);
984 }
985 uint32_t
987 {
988  NS_LOG_FUNCTION (this);
989  return (uint32_t)GetValue (m_alpha, m_beta);
990 }
991 
992 double
993 GammaRandomVariable::GetNormalValue (double mean, double variance, double bound)
994 {
995  NS_LOG_FUNCTION (this << mean << variance << bound);
996  if (m_nextValid)
997  { // use previously generated
998  m_nextValid = false;
999  return m_next;
1000  }
1001  while (1)
1002  { // See Simulation Modeling and Analysis p. 466 (Averill Law)
1003  // for algorithm; basically a Box-Muller transform:
1004  // http://en.wikipedia.org/wiki/Box-Muller_transform
1005  double u1 = Peek ()->RandU01 ();
1006  double u2 = Peek ()->RandU01 ();
1007  if (IsAntithetic ())
1008  {
1009  u1 = (1 - u1);
1010  u2 = (1 - u2);
1011  }
1012  double v1 = 2 * u1 - 1;
1013  double v2 = 2 * u2 - 1;
1014  double w = v1 * v1 + v2 * v2;
1015  if (w <= 1.0)
1016  { // Got good pair
1017  double y = std::sqrt ((-2 * std::log (w)) / w);
1018  m_next = mean + v2 * y * std::sqrt (variance);
1019  // if next is in bounds, it is valid
1020  m_nextValid = std::fabs (m_next - mean) <= bound;
1021  double x1 = mean + v1 * y * std::sqrt (variance);
1022  // if x1 is in bounds, return it
1023  if (std::fabs (x1 - mean) <= bound)
1024  {
1025  return x1;
1026  }
1027  // otherwise try and return m_next if it is valid
1028  else if (m_nextValid)
1029  {
1030  m_nextValid = false;
1031  return m_next;
1032  }
1033  // otherwise, just run this loop again
1034  }
1035  }
1036 }
1037 
1039 
1040 TypeId
1042 {
1043  static TypeId tid = TypeId ("ns3::ErlangRandomVariable")
1045  .AddConstructor<ErlangRandomVariable> ()
1046  .AddAttribute("K", "The k value for the Erlang distribution returned by this RNG stream.",
1047  IntegerValue(1),
1048  MakeIntegerAccessor(&ErlangRandomVariable::m_k),
1049  MakeIntegerChecker<uint32_t>())
1050  .AddAttribute("Lambda", "The lambda value for the Erlang distribution returned by this RNG stream.",
1051  DoubleValue(1.0),
1052  MakeDoubleAccessor(&ErlangRandomVariable::m_lambda),
1053  MakeDoubleChecker<double>())
1054  ;
1055  return tid;
1056 }
1058 {
1059  // m_k and m_lambda are initialized after constructor by attributes
1060  NS_LOG_FUNCTION (this);
1061 }
1062 
1063 uint32_t
1065 {
1066  NS_LOG_FUNCTION (this);
1067  return m_k;
1068 }
1069 double
1071 {
1072  NS_LOG_FUNCTION (this);
1073  return m_lambda;
1074 }
1075 
1076 /*
1077  The code for the following generator functions was adapted from ns-2
1078  tools/ranvar.cc
1079 
1080  The Erlang distribution density function has the form
1081 
1082  x^(k-1) * exp(-x/lambda)
1083  p(x; k, lambda) = ---------------------------
1084  lambda^k * (k-1)!
1085 
1086  for x > 0.
1087 */
1088 double
1089 ErlangRandomVariable::GetValue (uint32_t k, double lambda)
1090 {
1091  NS_LOG_FUNCTION (this << k << lambda);
1092  double mean = lambda;
1093  double bound = 0.0;
1094 
1095  double result = 0;
1096  for (unsigned int i = 0; i < k; ++i)
1097  {
1098  result += GetExponentialValue (mean, bound);
1099 
1100  }
1101 
1102  return result;
1103 }
1104 
1105 uint32_t
1106 ErlangRandomVariable::GetInteger (uint32_t k, uint32_t lambda)
1107 {
1108  NS_LOG_FUNCTION (this << k << lambda);
1109  return static_cast<uint32_t> ( GetValue (k, lambda));
1110 }
1111 
1112 double
1114 {
1115  NS_LOG_FUNCTION (this);
1116  return GetValue (m_k, m_lambda);
1117 }
1118 uint32_t
1120 {
1121  NS_LOG_FUNCTION (this);
1122  return (uint32_t)GetValue (m_k, m_lambda);
1123 }
1124 
1125 double
1127 {
1128  NS_LOG_FUNCTION (this << mean << bound);
1129  while (1)
1130  {
1131  // Get a uniform random variable in [0,1].
1132  double v = Peek ()->RandU01 ();
1133  if (IsAntithetic ())
1134  {
1135  v = (1 - v);
1136  }
1137 
1138  // Calculate the exponential random variable.
1139  double r = -mean*std::log (v);
1140 
1141  // Use this value if it's acceptable.
1142  if (bound == 0 || r <= bound)
1143  {
1144  return r;
1145  }
1146  }
1147 }
1148 
1150 
1151 TypeId
1153 {
1154  static TypeId tid = TypeId ("ns3::TriangularRandomVariable")
1156  .AddConstructor<TriangularRandomVariable> ()
1157  .AddAttribute("Mean", "The mean value for the triangular distribution returned by this RNG stream.",
1158  DoubleValue(0.5),
1159  MakeDoubleAccessor(&TriangularRandomVariable::m_mean),
1160  MakeDoubleChecker<double>())
1161  .AddAttribute("Min", "The lower bound on the values returned by this RNG stream.",
1162  DoubleValue(0.0),
1163  MakeDoubleAccessor(&TriangularRandomVariable::m_min),
1164  MakeDoubleChecker<double>())
1165  .AddAttribute("Max", "The upper bound on the values returned by this RNG stream.",
1166  DoubleValue(1.0),
1167  MakeDoubleAccessor(&TriangularRandomVariable::m_max),
1168  MakeDoubleChecker<double>())
1169  ;
1170  return tid;
1171 }
1173  :
1174  m_mode (0.5)
1175 {
1176  // m_mean, m_min, and m_max are initialized after constructor by
1177  // attributes
1178  NS_LOG_FUNCTION (this);
1179 }
1180 
1181 double
1183 {
1184  NS_LOG_FUNCTION (this);
1185  return m_mean;
1186 }
1187 double
1189 {
1190  NS_LOG_FUNCTION (this);
1191  return m_min;
1192 }
1193 double
1195 {
1196  NS_LOG_FUNCTION (this);
1197  return m_max;
1198 }
1199 
1200 double
1201 TriangularRandomVariable::GetValue (double mean, double min, double max)
1202 {
1203  // Calculate the mode.
1204  NS_LOG_FUNCTION (this << mean << min << max);
1205  double mode = 3.0 * mean - min - max;
1206 
1207  // Get a uniform random variable in [0,1].
1208  double u = Peek ()->RandU01 ();
1209  if (IsAntithetic ())
1210  {
1211  u = (1 - u);
1212  }
1213 
1214  // Calculate the triangular random variable.
1215  if (u <= (mode - min) / (max - min) )
1216  {
1217  return min + std::sqrt (u * (max - min) * (mode - min) );
1218  }
1219  else
1220  {
1221  return max - std::sqrt ( (1 - u) * (max - min) * (max - mode) );
1222  }
1223 }
1224 
1225 uint32_t
1226 TriangularRandomVariable::GetInteger (uint32_t mean, uint32_t min, uint32_t max)
1227 {
1228  NS_LOG_FUNCTION (this << mean << min << max);
1229  return static_cast<uint32_t> ( GetValue (mean, min, max) );
1230 }
1231 
1232 double
1234 {
1235  NS_LOG_FUNCTION (this);
1236  return GetValue (m_mean, m_min, m_max);
1237 }
1238 uint32_t
1240 {
1241  NS_LOG_FUNCTION (this);
1242  return (uint32_t)GetValue (m_mean, m_min, m_max);
1243 }
1244 
1246 
1247 TypeId
1249 {
1250  static TypeId tid = TypeId ("ns3::ZipfRandomVariable")
1252  .AddConstructor<ZipfRandomVariable> ()
1253  .AddAttribute("N", "The n value for the Zipf distribution returned by this RNG stream.",
1254  IntegerValue(1),
1255  MakeIntegerAccessor(&ZipfRandomVariable::m_n),
1256  MakeIntegerChecker<uint32_t>())
1257  .AddAttribute("Alpha", "The alpha value for the Zipf distribution returned by this RNG stream.",
1258  DoubleValue(0.0),
1259  MakeDoubleAccessor(&ZipfRandomVariable::m_alpha),
1260  MakeDoubleChecker<double>())
1261  ;
1262  return tid;
1263 }
1265 {
1266  // m_n and m_alpha are initialized after constructor by attributes
1267  NS_LOG_FUNCTION (this);
1268 }
1269 
1270 uint32_t
1272 {
1273  NS_LOG_FUNCTION (this);
1274  return m_n;
1275 }
1276 double
1278 {
1279  NS_LOG_FUNCTION (this);
1280  return m_alpha;
1281 }
1282 
1283 double
1284 ZipfRandomVariable::GetValue (uint32_t n, double alpha)
1285 {
1286  NS_LOG_FUNCTION (this << n << alpha);
1287  // Calculate the normalization constant c.
1288  m_c = 0.0;
1289  for (uint32_t i = 1; i <= n; i++)
1290  {
1291  m_c += (1.0 / std::pow ((double)i,alpha));
1292  }
1293  m_c = 1.0 / m_c;
1294 
1295  // Get a uniform random variable in [0,1].
1296  double u = Peek ()->RandU01 ();
1297  if (IsAntithetic ())
1298  {
1299  u = (1 - u);
1300  }
1301 
1302  double sum_prob = 0,zipf_value = 0;
1303  for (uint32_t i = 1; i <= m_n; i++)
1304  {
1305  sum_prob += m_c / std::pow ((double)i,m_alpha);
1306  if (sum_prob > u)
1307  {
1308  zipf_value = i;
1309  break;
1310  }
1311  }
1312  return zipf_value;
1313 }
1314 
1315 uint32_t
1316 ZipfRandomVariable::GetInteger (uint32_t n, uint32_t alpha)
1317 {
1318  NS_LOG_FUNCTION (this << n << alpha);
1319  return static_cast<uint32_t> ( GetValue (n, alpha));
1320 }
1321 
1322 double
1324 {
1325  NS_LOG_FUNCTION (this);
1326  return GetValue (m_n, m_alpha);
1327 }
1328 uint32_t
1330 {
1331  NS_LOG_FUNCTION (this);
1332  return (uint32_t)GetValue (m_n, m_alpha);
1333 }
1334 
1336 
1337 TypeId
1339 {
1340  static TypeId tid = TypeId ("ns3::ZetaRandomVariable")
1342  .AddConstructor<ZetaRandomVariable> ()
1343  .AddAttribute("Alpha", "The alpha value for the zeta distribution returned by this RNG stream.",
1344  DoubleValue(3.14),
1345  MakeDoubleAccessor(&ZetaRandomVariable::m_alpha),
1346  MakeDoubleChecker<double>())
1347  ;
1348  return tid;
1349 }
1351 {
1352  // m_alpha is initialized after constructor by attributes
1353  NS_LOG_FUNCTION (this);
1354 }
1355 
1356 double
1358 {
1359  NS_LOG_FUNCTION (this);
1360  return m_alpha;
1361 }
1362 
1363 double
1365 {
1366  NS_LOG_FUNCTION (this << alpha);
1367  m_b = std::pow (2.0, alpha - 1.0);
1368 
1369  double u, v;
1370  double X, T;
1371  double test;
1372 
1373  do
1374  {
1375  // Get a uniform random variable in [0,1].
1376  u = Peek ()->RandU01 ();
1377  if (IsAntithetic ())
1378  {
1379  u = (1 - u);
1380  }
1381 
1382  // Get a uniform random variable in [0,1].
1383  v = Peek ()->RandU01 ();
1384  if (IsAntithetic ())
1385  {
1386  v = (1 - v);
1387  }
1388 
1389  X = std::floor (std::pow (u, -1.0 / (m_alpha - 1.0)));
1390  T = std::pow (1.0 + 1.0 / X, m_alpha - 1.0);
1391  test = v * X * (T - 1.0) / (m_b - 1.0);
1392  }
1393  while ( test > (T / m_b) );
1394 
1395  return X;
1396 }
1397 
1398 uint32_t
1400 {
1401  NS_LOG_FUNCTION (this << alpha);
1402  return static_cast<uint32_t> ( GetValue (alpha));
1403 }
1404 
1405 double
1407 {
1408  NS_LOG_FUNCTION (this);
1409  return GetValue (m_alpha);
1410 }
1411 uint32_t
1413 {
1414  NS_LOG_FUNCTION (this);
1415  return (uint32_t)GetValue (m_alpha);
1416 }
1417 
1419 
1420 TypeId
1422 {
1423  static TypeId tid = TypeId ("ns3::DeterministicRandomVariable")
1425  .AddConstructor<DeterministicRandomVariable> ()
1426  ;
1427  return tid;
1428 }
1430  :
1431  m_count (0),
1432  m_next (0),
1433  m_data (0)
1434 {
1435  NS_LOG_FUNCTION (this);
1436 }
1438 {
1439  // Delete any values currently set.
1440  NS_LOG_FUNCTION (this);
1441  if (m_data != 0)
1442  {
1443  delete[] m_data;
1444  }
1445 }
1446 
1447 void
1448 DeterministicRandomVariable::SetValueArray (double* values, uint64_t length)
1449 {
1450  NS_LOG_FUNCTION (this << values << length);
1451  // Delete any values currently set.
1452  if (m_data != 0)
1453  {
1454  delete[] m_data;
1455  }
1456 
1457  // Make room for the values being set.
1458  m_data = new double[length];
1459  m_count = length;
1460  m_next = length;
1461 
1462  // Copy the values.
1463  for (uint64_t i = 0; i < m_count; i++)
1464  {
1465  m_data[i] = values[i];
1466  }
1467 }
1468 
1469 double
1471 {
1472  NS_LOG_FUNCTION (this);
1473  // Make sure the array has been set.
1474  NS_ASSERT (m_count > 0);
1475 
1476  if (m_next == m_count)
1477  {
1478  m_next = 0;
1479  }
1480  return m_data[m_next++];
1481 }
1482 
1483 uint32_t
1485 {
1486  NS_LOG_FUNCTION (this);
1487  return (uint32_t)GetValue ();
1488 }
1489 
1491 
1492 // ValueCDF methods
1494  : value (0.0),
1495  cdf (0.0)
1496 {
1497  NS_LOG_FUNCTION (this);
1498 }
1500  : value (v),
1501  cdf (c)
1502 {
1503  NS_LOG_FUNCTION (this << v << c);
1504 }
1506  : value (c.value),
1507  cdf (c.cdf)
1508 {
1509  NS_LOG_FUNCTION (this << &c);
1510 }
1511 
1512 TypeId
1514 {
1515  static TypeId tid = TypeId ("ns3::EmpiricalRandomVariable")
1517  .AddConstructor<EmpiricalRandomVariable> ()
1518  ;
1519  return tid;
1520 }
1522  :
1523  validated (false)
1524 {
1525  NS_LOG_FUNCTION (this);
1526 }
1527 
1528 double
1530 {
1531  NS_LOG_FUNCTION (this);
1532  // Return a value from the empirical distribution
1533  // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1534  if (emp.size () == 0)
1535  {
1536  return 0.0; // HuH? No empirical data
1537  }
1538  if (!validated)
1539  {
1540  Validate (); // Insure in non-decreasing
1541  }
1542 
1543  // Get a uniform random variable in [0,1].
1544  double r = Peek ()->RandU01 ();
1545  if (IsAntithetic ())
1546  {
1547  r = (1 - r);
1548  }
1549 
1550  if (r <= emp.front ().cdf)
1551  {
1552  return emp.front ().value; // Less than first
1553  }
1554  if (r >= emp.back ().cdf)
1555  {
1556  return emp.back ().value; // Greater than last
1557  }
1558  // Binary search
1559  std::vector<ValueCDF>::size_type bottom = 0;
1560  std::vector<ValueCDF>::size_type top = emp.size () - 1;
1561  while (1)
1562  {
1563  std::vector<ValueCDF>::size_type c = (top + bottom) / 2;
1564  if (r >= emp[c].cdf && r < emp[c + 1].cdf)
1565  { // Found it
1566  return Interpolate (emp[c].cdf, emp[c + 1].cdf,
1567  emp[c].value, emp[c + 1].value,
1568  r);
1569  }
1570  // Not here, adjust bounds
1571  if (r < emp[c].cdf)
1572  {
1573  top = c - 1;
1574  }
1575  else
1576  {
1577  bottom = c + 1;
1578  }
1579  }
1580 }
1581 
1582 uint32_t
1584 {
1585  NS_LOG_FUNCTION (this);
1586  return (uint32_t)GetValue ();
1587 }
1588 
1589 void EmpiricalRandomVariable::CDF (double v, double c)
1590 { // Add a new empirical datapoint to the empirical cdf
1591  // NOTE. These MUST be inserted in non-decreasing order
1592  NS_LOG_FUNCTION (this << v << c);
1593  emp.push_back (ValueCDF (v, c));
1594 }
1595 
1597 {
1598  NS_LOG_FUNCTION (this);
1599  ValueCDF prior;
1600  for (std::vector<ValueCDF>::size_type i = 0; i < emp.size (); ++i)
1601  {
1602  ValueCDF& current = emp[i];
1603  if (current.value < prior.value || current.cdf < prior.cdf)
1604  { // Error
1605  std::cerr << "Empirical Dist error,"
1606  << " current value " << current.value
1607  << " prior value " << prior.value
1608  << " current cdf " << current.cdf
1609  << " prior cdf " << prior.cdf << std::endl;
1610  NS_FATAL_ERROR ("Empirical Dist error");
1611  }
1612  prior = current;
1613  }
1614  validated = true;
1615 }
1616 
1617 double EmpiricalRandomVariable::Interpolate (double c1, double c2,
1618  double v1, double v2, double r)
1619 { // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1620  NS_LOG_FUNCTION (this << c1 << c2 << v1 << v2 << r);
1621  return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1622 }
1623 
1624 } // namespace ns3