A Discrete-Event Network Simulator
API
random-variable-stream-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009-12 University of Washington
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  * This file is based on rng-test-suite.cc.
19  *
20  * Modified by Mitch Watrous <watrous@u.washington.edu>
21  *
22  */
23 
24 
25 #include <gsl/gsl_cdf.h>
26 #include <gsl/gsl_histogram.h>
27 #include <gsl/gsl_sf_zeta.h>
28 #include <ctime>
29 #include <fstream>
30 #include <cmath>
31 
32 #include "ns3/boolean.h"
33 #include "ns3/double.h"
34 #include "ns3/string.h"
35 #include "ns3/integer.h"
36 #include "ns3/test.h"
37 #include "ns3/log.h"
38 #include "ns3/rng-seed-manager.h"
39 #include "ns3/random-variable-stream.h"
40 
41 using namespace ns3;
42 
43 NS_LOG_COMPONENT_DEFINE ("RandomVariableStreamGenerators");
44 
45 namespace ns3 {
46 
47 namespace test {
48 
49 namespace RandomVariable {
50 
61 class TestCaseBase : public TestCase
62 {
63 public:
65  static const uint32_t N_BINS {50};
67  static const uint32_t N_MEASUREMENTS {1000000};
69  static const uint32_t N_RUNS {5};
70 
75  TestCaseBase (std::string name)
76  : TestCase (name)
77  {}
78 
90  std::vector<double>
91  UniformHistogramBins (gsl_histogram *h, double start, double end,
92  bool underflow = true, bool overflow = true) const
93  {
94  NS_LOG_FUNCTION (this << h << start << end);
95  std::size_t nBins = gsl_histogram_bins (h);
96  double increment = (end - start) / (nBins - 1.);
97  double d = start;
98 
99  std::vector<double> range (nBins + 1);
100 
101  for (auto & r : range)
102  {
103  r = d;
104  d += increment;
105  }
106  if (underflow)
107  {
108  range[0] = -std::numeric_limits<double>::max ();
109  }
110  if (overflow)
111  {
112  range[nBins] = std::numeric_limits<double>::max ();
113  }
114 
115  gsl_histogram_set_ranges (h, range.data (), nBins + 1);
116  return range;
117  }
118 
124  double
126  {
127  NS_LOG_FUNCTION (this << rng);
128  double sum = 0.0;
129  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
130  {
131  double value = rng->GetValue ();
132  sum += value;
133  }
134  double valueMean = sum / N_MEASUREMENTS;
135  return valueMean;
136  }
137 
140  {
141  public:
146  virtual Ptr<RandomVariableStream> Create (void) const = 0;
147  };
148 
154  template <typename RNG>
156  {
157  public:
162  RngGenerator (bool anti = false)
163  : m_anti (anti)
164  {}
165 
166  // Inherited
168  Create (void) const
169  {
170  auto rng = CreateObject<RNG> ();
171  rng->SetAttribute ("Antithetic", BooleanValue (m_anti));
172  return rng;
173  }
174 
175  private:
177  bool m_anti;
178  };
179 
195  double
196  ChiSquared (gsl_histogram * h,
197  const std::vector<double> & expected,
199  {
200  NS_LOG_FUNCTION (this << h << expected.size () << rng);
201  NS_ASSERT_MSG (gsl_histogram_bins (h) == expected.size (),
202  "Histogram and expected vector have different sizes.");
203 
204  // Sample the rng into the histogram
205  for (std::size_t i = 0; i < N_MEASUREMENTS; ++i)
206  {
207  double value = rng->GetValue ();
208  gsl_histogram_increment (h, value);
209  }
210 
211  // Compute the chi square value
212  double chiSquared = 0;
213  std::size_t nBins = gsl_histogram_bins (h);
214  for (std::size_t i = 0; i < nBins; ++i)
215  {
216  double hbin = gsl_histogram_get (h, i);
217  double tmp = hbin - expected[i];
218  tmp *= tmp;
219  tmp /= expected[i];
220  chiSquared += tmp;
221  }
222 
223  return chiSquared;
224  }
225 
256  virtual double
258  {
259  return 0;
260  }
261 
270  double
272  std::size_t nRuns) const
273  {
274  NS_LOG_FUNCTION (this << generator << nRuns);
275 
276  double sum = 0.;
277  for (std::size_t i = 0; i < nRuns; ++i)
278  {
279  auto rng = generator->Create ();
280  double result = ChiSquaredTest (rng);
281  sum += result;
282  }
283  sum /= (double)nRuns;
284  return sum;
285  }
286 
317  void
319  {
320  if (m_seedSet == false)
321  {
322  uint32_t seed;
323  if (RngSeedManager::GetRun () == 0)
324  {
325  seed = static_cast<uint32_t> (time (0));
326  m_seedSet = true;
327  NS_LOG_DEBUG ("Special run number value of zero; seeding with time of day: " << seed);
328 
329  }
330  else
331  {
332  seed = RngSeedManager::GetSeed ();
333  m_seedSet = true;
334  NS_LOG_DEBUG ("Using the values seed: " <<
335  seed << " and run: " << RngSeedManager::GetRun ());
336  }
337  SeedManager::SetSeed (seed);
338  }
339  }
340 
341 private:
343  bool m_seedSet = false;
344 
345 }; // class TestCaseBase
346 
347 
353 {
354 public:
355 
356  // Constructor
357  UniformTestCase ();
358 
359  // Inherited
361 
362 private:
363  // Inherited
364  virtual void DoRun (void);
365 };
366 
368  : TestCaseBase ("Uniform Random Variable Stream Generator")
369 {}
370 
371 double
373 {
374  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
375 
376  // Note that this assumes that the range for u is [0,1], which is
377  // the default range for this distribution.
378  gsl_histogram_set_ranges_uniform (h, 0., 1.);
379 
380  std::vector<double> expected (N_BINS, ((double)N_MEASUREMENTS / (double)N_BINS));
381 
382  double chiSquared = ChiSquared (h, expected, rng);
383  gsl_histogram_free (h);
384  return chiSquared;
385 }
386 
387 void
389 {
390  NS_LOG_FUNCTION (this);
391  SetTestSuiteSeed ();
392 
393  double confidence = 0.99;
394  double maxStatistic = gsl_cdf_chisq_Pinv (confidence, (N_BINS - 1));
395  NS_LOG_DEBUG ("Chi square required at " << confidence << " confidence for " << N_BINS << " bins is " << maxStatistic);
396 
397  double result = maxStatistic;
398  // If chi-squared test fails, re-try it up to N_RUNS times
399  for (uint32_t i = 0; i < N_RUNS; ++i)
400  {
401  Ptr<UniformRandomVariable> rng = CreateObject<UniformRandomVariable> ();
403  NS_LOG_DEBUG ("Chi square result is " << result);
404  if (result < maxStatistic)
405  {
406  break;
407  }
408  }
409 
410  NS_TEST_ASSERT_MSG_LT (result, maxStatistic, "Chi-squared statistic out of range");
411 
412  double min = 0.0;
413  double max = 10.0;
414  double value;
415 
416  // Create the RNG with the specified range.
417  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
418 
419  x->SetAttribute ("Min", DoubleValue (min));
420  x->SetAttribute ("Max", DoubleValue (max));
421 
422  // Test that values are always within the range:
423  //
424  // [min, max)
425  //
426  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
427  {
428  value = x->GetValue ();
429  NS_TEST_ASSERT_MSG_EQ ((value >= min), true, "Value less than minimum.");
430  NS_TEST_ASSERT_MSG_LT (value, max, "Value greater than or equal to maximum.");
431  }
432 
433  // Boundary checking on GetInteger; should be [min,max]; from bug 1964
434  static const uint32_t UNIFORM_INTEGER_MIN {0};
435  static const uint32_t UNIFORM_INTEGER_MAX {4294967295U};
436  // [0,0] should return 0
437  uint32_t intValue;
438  intValue = x->GetInteger (UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MIN);
439  NS_TEST_ASSERT_MSG_EQ (intValue, UNIFORM_INTEGER_MIN, "Uniform RV GetInteger boundary testing");
440  // [UNIFORM_INTEGER_MAX, UNIFORM_INTEGER_MAX] should return UNIFORM_INTEGER_MAX
441  intValue = x->GetInteger (UNIFORM_INTEGER_MAX, UNIFORM_INTEGER_MAX);
442  NS_TEST_ASSERT_MSG_EQ (intValue, UNIFORM_INTEGER_MAX, "Uniform RV GetInteger boundary testing");
443  // [0,1] should return mix of 0 or 1
444  intValue = 0;
445  for (int i = 0; i < 20; i++)
446  {
447  intValue += x->GetInteger (UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MIN + 1);
448  }
449  NS_TEST_ASSERT_MSG_GT (intValue, 0, "Uniform RV GetInteger boundary testing");
450  NS_TEST_ASSERT_MSG_LT (intValue, 20, "Uniform RV GetInteger boundary testing");
451  // [MAX-1,MAX] should return mix of MAX-1 or MAX
452  uint32_t count = 0;
453  for (int i = 0; i < 20; i++)
454  {
455  intValue = x->GetInteger (UNIFORM_INTEGER_MAX - 1, UNIFORM_INTEGER_MAX);
456  if (intValue == UNIFORM_INTEGER_MAX)
457  {
458  count++;
459  }
460  }
461  NS_TEST_ASSERT_MSG_GT (count, 0, "Uniform RV GetInteger boundary testing");
462  NS_TEST_ASSERT_MSG_LT (count, 20, "Uniform RV GetInteger boundary testing");
463  // multiple [0,UNIFORM_INTEGER_MAX] should return non-zero
464  intValue = x->GetInteger (UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MAX);
465  uint32_t intValue2 = x->GetInteger (UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MAX);
466  NS_TEST_ASSERT_MSG_GT (intValue + intValue2, 0, "Uniform RV GetInteger boundary testing");
467 
468 }
469 
475 {
476 public:
477 
478  // Constructor
480 
481  // Inherited
483 
484 private:
485  // Inherited
486  virtual void DoRun (void);
487 };
488 
490  : TestCaseBase ("Antithetic Uniform Random Variable Stream Generator")
491 {}
492 
493 double
495 {
496  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
497 
498  // Note that this assumes that the range for u is [0,1], which is
499  // the default range for this distribution.
500  gsl_histogram_set_ranges_uniform (h, 0., 1.);
501 
502  std::vector<double> expected (N_BINS, ((double)N_MEASUREMENTS / (double)N_BINS));
503 
504  double chiSquared = ChiSquared (h, expected, rng);
505  gsl_histogram_free (h);
506  return chiSquared;
507 }
508 
509 void
511 {
512  NS_LOG_FUNCTION (this);
513  SetTestSuiteSeed ();
514 
515  auto generator = RngGenerator<UniformRandomVariable> (true);
516  double sum = ChiSquaredsAverage (&generator, N_RUNS);
517  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
518  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
519 
520  double min = 0.0;
521  double max = 10.0;
522  double value;
523 
524  // Create the RNG with the specified range.
525  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
526 
527  // Make this generate antithetic values.
528  x->SetAttribute ("Antithetic", BooleanValue (true));
529 
530  x->SetAttribute ("Min", DoubleValue (min));
531  x->SetAttribute ("Max", DoubleValue (max));
532 
533  // Test that values are always within the range:
534  //
535  // [min, max)
536  //
537  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
538  {
539  value = x->GetValue ();
540  NS_TEST_ASSERT_MSG_EQ ((value >= min), true, "Value less than minimum.");
541  NS_TEST_ASSERT_MSG_LT (value, max, "Value greater than or equal to maximum.");
542  }
543 
544 
545 }
551 {
552 public:
553  // Constructor
554  ConstantTestCase ();
555 
556 private:
557  // Inherited
558  virtual void DoRun (void);
559 
561  static constexpr double TOLERANCE {1e-8};
562 };
563 
565  : TestCaseBase ("Constant Random Variable Stream Generator")
566 {}
567 
568 void
570 {
571  NS_LOG_FUNCTION (this);
572  SetTestSuiteSeed ();
573 
574  Ptr<ConstantRandomVariable> c = CreateObject<ConstantRandomVariable> ();
575 
576  double constant;
577 
578  // Test that the constant value can be changed using its attribute.
579  constant = 10.0;
580  c->SetAttribute ("Constant", DoubleValue (constant));
581  NS_TEST_ASSERT_MSG_EQ_TOL (c->GetValue (), constant, TOLERANCE, "Constant value changed");
582  c->SetAttribute ("Constant", DoubleValue (20.0));
583  NS_TEST_ASSERT_MSG_NE (c->GetValue (), constant, "Constant value not changed");
584 
585  // Test that the constant value does not change.
586  constant = c->GetValue ();
587  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
588  {
589  NS_TEST_ASSERT_MSG_EQ_TOL (c->GetValue (), constant, TOLERANCE, "Constant value changed in loop");
590  }
591 }
592 
598 {
599 public:
600  // Constructor
602 
603 private:
604  // Inherited
605  virtual void DoRun (void);
606 
608  static constexpr double TOLERANCE {1e-8};
609 };
610 
612  : TestCaseBase ("Sequential Random Variable Stream Generator")
613 {}
614 
615 void
617 {
618  NS_LOG_FUNCTION (this);
619  SetTestSuiteSeed ();
620 
621  Ptr<SequentialRandomVariable> s = CreateObject<SequentialRandomVariable> ();
622 
623  // The following four attributes should give the sequence
624  //
625  // 4, 4, 7, 7, 10, 10
626  //
627  s->SetAttribute ("Min", DoubleValue (4));
628  s->SetAttribute ("Max", DoubleValue (11));
629  s->SetAttribute ("Increment", StringValue ("ns3::UniformRandomVariable[Min=3.0|Max=3.0]"));
630  s->SetAttribute ("Consecutive", IntegerValue (2));
631 
632  double value;
633 
634  // Test that the sequencet is correct.
635  value = s->GetValue ();
636  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence value 1 wrong.");
637  value = s->GetValue ();
638  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence value 2 wrong.");
639  value = s->GetValue ();
640  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence value 3 wrong.");
641  value = s->GetValue ();
642  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence value 4 wrong.");
643  value = s->GetValue ();
644  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence value 5 wrong.");
645  value = s->GetValue ();
646  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence value 6 wrong.");
647 
648 }
649 
655 {
656 public:
657  // Constructor
658  NormalTestCase ();
659 
660  // Inherited
662 
663 private:
664  // Inherited
665  virtual void DoRun (void);
666 
668  static constexpr double TOLERANCE {5};
669 };
670 
672  : TestCaseBase ("Normal Random Variable Stream Generator")
673 {}
674 
675 double
677 {
678  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
679  auto range = UniformHistogramBins (h, -4., 4.);
680 
681  std::vector<double> expected (N_BINS);
682 
683  // Note that this assumes that n has mean equal to zero and standard
684  // deviation equal to one, which are their default values for this
685  // distribution.
686  double sigma = 1.;
687 
688  for (std::size_t i = 0; i < N_BINS; ++i)
689  {
690  expected[i] = gsl_cdf_gaussian_P (range[i + 1], sigma) - gsl_cdf_gaussian_P (range[i], sigma);
691  expected[i] *= N_MEASUREMENTS;
692  }
693 
694  double chiSquared = ChiSquared (h, expected, rng);
695  gsl_histogram_free (h);
696  return chiSquared;
697 }
698 
699 void
701 {
702  NS_LOG_FUNCTION (this);
703  SetTestSuiteSeed ();
704 
705  auto generator = RngGenerator<NormalRandomVariable> ();
706  auto rng = generator.Create ();
707 
708  double sum = ChiSquaredsAverage (&generator, N_RUNS);
709  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
710  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
711 
712  double mean = 5.0;
713  double variance = 2.0;
714 
715  // Create the RNG with the specified range.
716  Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> ();
717  x->SetAttribute ("Mean", DoubleValue (mean));
718  x->SetAttribute ("Variance", DoubleValue (variance));
719 
720  // Calculate the mean of these values.
721  double valueMean = Average (x);
722 
723  // The expected value for the mean of the values returned by a
724  // normally distributed random variable is equal to mean.
725  double expectedMean = mean;
726  double expectedRms = mean / std::sqrt (variance * N_MEASUREMENTS);
727 
728  // Test that values have approximately the right mean value.
729  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedRms * TOLERANCE, "Wrong mean value.");
730 }
731 
737 {
738 public:
739  // Constructor
741 
742  // Inherited
744 
745 private:
746  // Inherited
747  virtual void DoRun (void);
748 
750  static constexpr double TOLERANCE {5};
751 };
752 
754  : TestCaseBase ("Antithetic Normal Random Variable Stream Generator")
755 {}
756 
757 double
759 {
760  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
761  auto range = UniformHistogramBins (h, -4, 4);
762 
763  std::vector<double> expected (N_BINS);
764 
765  // Note that this assumes that n has mean equal to zero and standard
766  // deviation equal to one, which are their default values for this
767  // distribution.
768  double sigma = 1.;
769 
770  for (std::size_t i = 0; i < N_BINS; ++i)
771  {
772  expected[i] = gsl_cdf_gaussian_P (range[i + 1], sigma) - gsl_cdf_gaussian_P (range[i], sigma);
773  expected[i] *= N_MEASUREMENTS;
774  }
775 
776  double chiSquared = ChiSquared (h, expected, rng);
777 
778  gsl_histogram_free (h);
779  return chiSquared;
780 }
781 
782 void
784 {
785  NS_LOG_FUNCTION (this);
786  SetTestSuiteSeed ();
787 
788  auto generator = RngGenerator<NormalRandomVariable> (true);
789  double sum = ChiSquaredsAverage (&generator, N_RUNS);
790  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
791  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
792 
793  double mean = 5.0;
794  double variance = 2.0;
795 
796  // Create the RNG with the specified range.
797  Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> ();
798  x->SetAttribute ("Mean", DoubleValue (mean));
799  x->SetAttribute ("Variance", DoubleValue (variance));
800 
801  // Make this generate antithetic values.
802  x->SetAttribute ("Antithetic", BooleanValue (true));
803 
804  // Calculate the mean of these values.
805  double valueMean = Average (x);
806 
807  // The expected value for the mean of the values returned by a
808  // normally distributed random variable is equal to mean.
809  double expectedMean = mean;
810  double expectedRms = mean / std::sqrt (variance * N_MEASUREMENTS);
811 
812  // Test that values have approximately the right mean value.
813  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedRms * TOLERANCE, "Wrong mean value.");
814 }
815 
821 {
822 public:
823  // Constructor
825 
826  // Inherited
828 
829 private:
830  // Inherited
831  virtual void DoRun (void);
832 
834  static constexpr double TOLERANCE {5};
835 };
836 
838  : TestCaseBase ("Exponential Random Variable Stream Generator")
839 {}
840 
841 double
843 {
844  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
845  auto range = UniformHistogramBins (h, 0, 10, false);
846 
847  std::vector<double> expected (N_BINS);
848 
849  // Note that this assumes that e has mean equal to one, which is the
850  // default value for this distribution.
851  double mu = 1.;
852 
853  for (std::size_t i = 0; i < N_BINS; ++i)
854  {
855  expected[i] = gsl_cdf_exponential_P (range[i + 1], mu) - gsl_cdf_exponential_P (range[i], mu);
856  expected[i] *= N_MEASUREMENTS;
857  }
858 
859  double chiSquared = ChiSquared (h, expected, rng);
860 
861  gsl_histogram_free (h);
862  return chiSquared;
863 }
864 
865 void
867 {
868  NS_LOG_FUNCTION (this);
869  SetTestSuiteSeed ();
870 
871  auto generator = RngGenerator<ExponentialRandomVariable> ();
872  double sum = ChiSquaredsAverage (&generator, N_RUNS);
873  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
874  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
875 
876  double mean = 3.14;
877  double bound = 0.0;
878 
879  // Create the RNG with the specified range.
880  Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> ();
881  x->SetAttribute ("Mean", DoubleValue (mean));
882  x->SetAttribute ("Bound", DoubleValue (bound));
883 
884  // Calculate the mean of these values.
885  double valueMean = Average (x);
886  double expectedMean = mean;
887  double expectedRms = std::sqrt (mean / N_MEASUREMENTS);
888 
889  // Test that values have approximately the right mean value.
890  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedRms * TOLERANCE, "Wrong mean value.");
891 }
892 
898 {
899 public:
900  // Constructor
902 
903  // Inherited
905 
906 private:
907  // Inherited
908  virtual void DoRun (void);
909 
911  static constexpr double TOLERANCE {5};
912 };
913 
915  : TestCaseBase ("Antithetic Exponential Random Variable Stream Generator")
916 {}
917 
918 double
920 {
921  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
922  auto range = UniformHistogramBins (h, 0, 10, false);
923 
924  std::vector<double> expected (N_BINS);
925 
926  // Note that this assumes that e has mean equal to one, which is the
927  // default value for this distribution.
928  double mu = 1.;
929 
930  for (std::size_t i = 0; i < N_BINS; ++i)
931  {
932  expected[i] = gsl_cdf_exponential_P (range[i + 1], mu) - gsl_cdf_exponential_P (range[i], mu);
933  expected[i] *= N_MEASUREMENTS;
934  }
935 
936  double chiSquared = ChiSquared (h, expected, rng);
937 
938  gsl_histogram_free (h);
939  return chiSquared;
940 }
941 
942 void
944 {
945  NS_LOG_FUNCTION (this);
946  SetTestSuiteSeed ();
947 
948  auto generator = RngGenerator<ExponentialRandomVariable> (true);
949  double sum = ChiSquaredsAverage (&generator, N_RUNS);
950  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
951  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
952 
953  double mean = 3.14;
954  double bound = 0.0;
955 
956  // Create the RNG with the specified range.
957  Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> ();
958  x->SetAttribute ("Mean", DoubleValue (mean));
959  x->SetAttribute ("Bound", DoubleValue (bound));
960 
961  // Make this generate antithetic values.
962  x->SetAttribute ("Antithetic", BooleanValue (true));
963 
964  // Calculate the mean of these values.
965  double valueMean = Average (x);
966  double expectedMean = mean;
967  double expectedRms = std::sqrt (mean / N_MEASUREMENTS);
968 
969  // Test that values have approximately the right mean value.
970  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedRms * TOLERANCE, "Wrong mean value.");
971 }
972 
978 {
979 public:
980  // Constructor
981  ParetoTestCase ();
982 
983  // Inherited
985 
986 private:
987  // Inherited
988  virtual void DoRun (void);
989 
994  static constexpr double TOLERANCE {1e-2};
995 };
996 
998  : TestCaseBase ("Pareto Random Variable Stream Generator")
999 {}
1000 
1001 double
1003 {
1004  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1005  auto range = UniformHistogramBins (h, 1, 10, false);
1006 
1007  std::vector<double> expected (N_BINS);
1008 
1009  double shape = 2.0;
1010  double scale = 1.0;
1011 
1012  for (std::size_t i = 0; i < N_BINS; ++i)
1013  {
1014  expected[i] = gsl_cdf_pareto_P (range[i + 1], shape, scale) - gsl_cdf_pareto_P (range[i], shape, scale);
1015  expected[i] *= N_MEASUREMENTS;
1016  }
1017 
1018  double chiSquared = ChiSquared (h, expected, rng);
1019 
1020  gsl_histogram_free (h);
1021  return chiSquared;
1022 }
1023 
1024 void
1026 {
1027  NS_LOG_FUNCTION (this);
1028  SetTestSuiteSeed ();
1029 
1030  auto generator = RngGenerator<ParetoRandomVariable> ();
1031  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1032  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1033  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1034 
1035  double shape = 2.0;
1036  double scale = 1.0;
1037 
1038  // Create the RNG with the specified range.
1039  Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
1040  x->SetAttribute ("Shape", DoubleValue (shape));
1041  x->SetAttribute ("Scale", DoubleValue (scale));
1042 
1043  // Calculate the mean of these values.
1044  double valueMean = Average (x);
1045 
1046  // The expected value for the mean is given by
1047  //
1048  // shape * scale
1049  // E[value] = --------------- ,
1050  // shape - 1
1051  //
1052  // where
1053  //
1054  // scale = mean * (shape - 1.0) / shape .
1055  double expectedMean = (shape * scale) / (shape - 1.0);
1056 
1057  // Test that values have approximately the right mean value.
1058  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1059 }
1060 
1066 {
1067 public:
1068  // Constructor
1070 
1071  // Inherited
1073 
1074 private:
1075  // Inherited
1076  virtual void DoRun (void);
1077 
1082  static constexpr double TOLERANCE {1e-2};
1083 };
1084 
1086  : TestCaseBase ("Antithetic Pareto Random Variable Stream Generator")
1087 {}
1088 
1089 double
1091 {
1092  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1093  auto range = UniformHistogramBins (h, 1, 10, false);
1094 
1095  std::vector<double> expected (N_BINS);
1096 
1097  double shape = 2.0;
1098  double scale = 1.0;
1099 
1100  for (std::size_t i = 0; i < N_BINS; ++i)
1101  {
1102  expected[i] = gsl_cdf_pareto_P (range[i + 1], shape, scale) - gsl_cdf_pareto_P (range[i], shape, scale);
1103  expected[i] *= N_MEASUREMENTS;
1104  }
1105 
1106  double chiSquared = ChiSquared (h, expected, rng);
1107 
1108  gsl_histogram_free (h);
1109  return chiSquared;
1110 }
1111 
1112 void
1114 {
1115  NS_LOG_FUNCTION (this);
1116  SetTestSuiteSeed ();
1117 
1118  auto generator = RngGenerator<ParetoRandomVariable> (true);
1119  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1120  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1121  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1122 
1123  double shape = 2.0;
1124  double scale = 1.0;
1125 
1126  // Create the RNG with the specified range.
1127  Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
1128  x->SetAttribute ("Shape", DoubleValue (shape));
1129  x->SetAttribute ("Scale", DoubleValue (scale));
1130 
1131  // Make this generate antithetic values.
1132  x->SetAttribute ("Antithetic", BooleanValue (true));
1133 
1134  // Calculate the mean of these values.
1135  double valueMean = Average (x);
1136 
1137  // The expected value for the mean is given by
1138  //
1139  // shape * scale
1140  // E[value] = --------------- ,
1141  // shape - 1
1142  //
1143  // where
1144  //
1145  // scale = mean * (shape - 1.0) / shape .
1146  //
1147  double expectedMean = (shape * scale) / (shape - 1.0);
1148 
1149  // Test that values have approximately the right mean value.
1150  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1151 }
1152 
1158 {
1159 public:
1160  // Constructor
1161  WeibullTestCase ();
1162 
1163  // Inherited
1165 
1166 private:
1167  // Inherited
1168  virtual void DoRun (void);
1169 
1174  static constexpr double TOLERANCE {1e-2};
1175 };
1176 
1178  : TestCaseBase ("Weibull Random Variable Stream Generator")
1179 {}
1180 
1181 double
1183 {
1184  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1185  auto range = UniformHistogramBins (h, 1, 10, false);
1186 
1187  std::vector<double> expected (N_BINS);
1188 
1189  // Note that this assumes that p has shape equal to one and scale
1190  // equal to one, which are their default values for this
1191  // distribution.
1192  double a = 1.0;
1193  double b = 1.0;
1194 
1195  for (std::size_t i = 0; i < N_BINS; ++i)
1196  {
1197  expected[i] = gsl_cdf_weibull_P (range[i + 1], a, b) - gsl_cdf_weibull_P (range[i], a, b);
1198  expected[i] *= N_MEASUREMENTS;
1199  NS_LOG_INFO ("weibull: " << expected[i]);
1200  }
1201 
1202  double chiSquared = ChiSquared (h, expected, rng);
1203 
1204  gsl_histogram_free (h);
1205  return chiSquared;
1206 }
1207 
1208 void
1210 {
1211  NS_LOG_FUNCTION (this);
1212  SetTestSuiteSeed ();
1213 
1214  auto generator = RngGenerator<WeibullRandomVariable> ();
1215  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1216  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1217  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1218 
1219  double scale = 5.0;
1220  double shape = 1.0;
1221 
1222  // Create the RNG with the specified range.
1223  Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> ();
1224  x->SetAttribute ("Scale", DoubleValue (scale));
1225  x->SetAttribute ("Shape", DoubleValue (shape));
1226 
1227  // Calculate the mean of these values.
1228  double valueMean = Average (x);
1229 
1230  // The expected value for the mean of the values returned by a
1231  // Weibull distributed random variable is
1232  //
1233  // E[value] = scale * Gamma(1 + 1 / shape) ,
1234  //
1235  // where Gamma() is the Gamma function. Note that
1236  //
1237  // Gamma(n) = (n - 1)!
1238  //
1239  // if n is a positive integer.
1240  //
1241  // For this test,
1242  //
1243  // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1244  // = Gamma(2)
1245  // = (2 - 1)!
1246  // = 1
1247  //
1248  // which means
1249  //
1250  // E[value] = scale .
1251  //
1252  double expectedMean = scale;
1253 
1254  // Test that values have approximately the right mean value.
1255  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1256 }
1257 
1263 {
1264 public:
1265  // Constructor
1267 
1268  // Inherited
1270 
1271 private:
1272  // Inherited
1273  virtual void DoRun (void);
1274 
1279  static constexpr double TOLERANCE {1e-2};
1280 };
1281 
1283  : TestCaseBase ("Antithetic Weibull Random Variable Stream Generator")
1284 {}
1285 
1286 double
1288 {
1289  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1290  auto range = UniformHistogramBins (h, 1, 10, false);
1291 
1292  std::vector<double> expected (N_BINS);
1293 
1294  // Note that this assumes that p has shape equal to one and scale
1295  // equal to one, which are their default values for this
1296  // distribution.
1297  double a = 1.0;
1298  double b = 1.0;
1299 
1300  for (std::size_t i = 0; i < N_BINS; ++i)
1301  {
1302  expected[i] = gsl_cdf_weibull_P (range[i + 1], a, b) - gsl_cdf_weibull_P (range[i], a, b);
1303  expected[i] *= N_MEASUREMENTS;
1304  }
1305 
1306  double chiSquared = ChiSquared (h, expected, rng);
1307 
1308  gsl_histogram_free (h);
1309  return chiSquared;
1310 }
1311 
1312 void
1314 {
1315  NS_LOG_FUNCTION (this);
1316  SetTestSuiteSeed ();
1317 
1318  auto generator = RngGenerator<WeibullRandomVariable> (true);
1319  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1320  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1321  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1322 
1323  double scale = 5.0;
1324  double shape = 1.0;
1325 
1326  // Create the RNG with the specified range.
1327  Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> ();
1328  x->SetAttribute ("Scale", DoubleValue (scale));
1329  x->SetAttribute ("Shape", DoubleValue (shape));
1330 
1331  // Make this generate antithetic values.
1332  x->SetAttribute ("Antithetic", BooleanValue (true));
1333 
1334  // Calculate the mean of these values.
1335  double valueMean = Average (x);
1336 
1337  // The expected value for the mean of the values returned by a
1338  // Weibull distributed random variable is
1339  //
1340  // E[value] = scale * Gamma(1 + 1 / shape) ,
1341  //
1342  // where Gamma() is the Gamma function. Note that
1343  //
1344  // Gamma(n) = (n - 1)!
1345  //
1346  // if n is a positive integer.
1347  //
1348  // For this test,
1349  //
1350  // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1351  // = Gamma(2)
1352  // = (2 - 1)!
1353  // = 1
1354  //
1355  // which means
1356  //
1357  // E[value] = scale .
1358  //
1359  double expectedMean = scale;
1360 
1361  // Test that values have approximately the right mean value.
1362  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1363 }
1364 
1370 {
1371 public:
1372  // Constructor
1373  LogNormalTestCase ();
1374 
1375  // Inherited
1377 
1378 private:
1379  // Inherited
1380  virtual void DoRun (void);
1381 
1386  static constexpr double TOLERANCE {3e-2};
1387 };
1388 
1390  : TestCaseBase ("Log-Normal Random Variable Stream Generator")
1391 {}
1392 
1393 double
1395 {
1396  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1397  auto range = UniformHistogramBins (h, 0, 10, false);
1398 
1399  std::vector<double> expected (N_BINS);
1400 
1401  // Note that this assumes that n has mu equal to zero and sigma
1402  // equal to one, which are their default values for this
1403  // distribution.
1404  double mu = 0.0;
1405  double sigma = 1.0;
1406 
1407  for (std::size_t i = 0; i < N_BINS; ++i)
1408  {
1409  expected[i] = gsl_cdf_lognormal_P (range[i + 1], mu, sigma) - gsl_cdf_lognormal_P (range[i], mu, sigma);
1410  expected[i] *= N_MEASUREMENTS;
1411  }
1412 
1413  double chiSquared = ChiSquared (h, expected, rng);
1414 
1415  gsl_histogram_free (h);
1416  return chiSquared;
1417 }
1418 
1419 void
1421 {
1422  NS_LOG_FUNCTION (this);
1423  SetTestSuiteSeed ();
1424 
1425  auto generator = RngGenerator<LogNormalRandomVariable> ();
1426  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1427  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1428 
1429  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1430 
1431  double mu = 5.0;
1432  double sigma = 2.0;
1433 
1434  // Create the RNG with the specified range.
1435  Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> ();
1436  x->SetAttribute ("Mu", DoubleValue (mu));
1437  x->SetAttribute ("Sigma", DoubleValue (sigma));
1438 
1439  // Calculate the mean of these values.
1440  double valueMean = Average (x);
1441 
1442  // The expected value for the mean of the values returned by a
1443  // log-normally distributed random variable is equal to
1444  //
1445  // 2
1446  // mu + sigma / 2
1447  // E[value] = e .
1448  //
1449  double expectedMean = std::exp (mu + sigma * sigma / 2.0);
1450 
1451  // Test that values have approximately the right mean value.
1452  //
1459  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1460 }
1461 
1467 {
1468 public:
1469  // Constructor
1471 
1472  // Inherited
1474 
1475 private:
1476  // Inherited
1477  virtual void DoRun (void);
1478 
1483  static constexpr double TOLERANCE {3e-2};
1484 };
1485 
1487  : TestCaseBase ("Antithetic Log-Normal Random Variable Stream Generator")
1488 {}
1489 
1490 double
1492 {
1493  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1494  auto range = UniformHistogramBins (h, 0, 10, false);
1495 
1496  std::vector<double> expected (N_BINS);
1497 
1498  // Note that this assumes that n has mu equal to zero and sigma
1499  // equal to one, which are their default values for this
1500  // distribution.
1501  double mu = 0.0;
1502  double sigma = 1.0;
1503 
1504  for (std::size_t i = 0; i < N_BINS; ++i)
1505  {
1506  expected[i] = gsl_cdf_lognormal_P (range[i + 1], mu, sigma) - gsl_cdf_lognormal_P (range[i], mu, sigma);
1507  expected[i] *= N_MEASUREMENTS;
1508  }
1509 
1510  double chiSquared = ChiSquared (h, expected, rng);
1511 
1512  gsl_histogram_free (h);
1513  return chiSquared;
1514 }
1515 
1516 void
1518 {
1519  NS_LOG_FUNCTION (this);
1520  SetTestSuiteSeed ();
1521 
1522  auto generator = RngGenerator<LogNormalRandomVariable> (true);
1523  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1524  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1525  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1526 
1527  double mu = 5.0;
1528  double sigma = 2.0;
1529 
1530  // Create the RNG with the specified range.
1531  Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> ();
1532  x->SetAttribute ("Mu", DoubleValue (mu));
1533  x->SetAttribute ("Sigma", DoubleValue (sigma));
1534 
1535  // Make this generate antithetic values.
1536  x->SetAttribute ("Antithetic", BooleanValue (true));
1537 
1538  // Calculate the mean of these values.
1539  double valueMean = Average (x);
1540 
1541  // The expected value for the mean of the values returned by a
1542  // log-normally distributed random variable is equal to
1543  //
1544  // 2
1545  // mu + sigma / 2
1546  // E[value] = e .
1547  //
1548  double expectedMean = std::exp (mu + sigma * sigma / 2.0);
1549 
1550  // Test that values have approximately the right mean value.
1551  //
1558  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1559 }
1560 
1566 {
1567 public:
1568  // Constructor
1569  GammaTestCase ();
1570 
1571  // Inherited
1573 
1574 private:
1575  // Inherited
1576  virtual void DoRun (void);
1577 
1582  static constexpr double TOLERANCE {1e-2};
1583 };
1584 
1586  : TestCaseBase ("Gamma Random Variable Stream Generator")
1587 {}
1588 
1589 double
1591 {
1592  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1593  auto range = UniformHistogramBins (h, 0, 10, false);
1594 
1595  std::vector<double> expected (N_BINS);
1596 
1597  // Note that this assumes that n has alpha equal to one and beta
1598  // equal to one, which are their default values for this
1599  // distribution.
1600  double alpha = 1.0;
1601  double beta = 1.0;
1602 
1603  for (std::size_t i = 0; i < N_BINS; ++i)
1604  {
1605  expected[i] = gsl_cdf_gamma_P (range[i + 1], alpha, beta) - gsl_cdf_gamma_P (range[i], alpha, beta);
1606  expected[i] *= N_MEASUREMENTS;
1607  }
1608 
1609  double chiSquared = ChiSquared (h, expected, rng);
1610 
1611  gsl_histogram_free (h);
1612  return chiSquared;
1613 }
1614 
1615 void
1617 {
1618  NS_LOG_FUNCTION (this);
1619  SetTestSuiteSeed ();
1620 
1621  auto generator = RngGenerator<GammaRandomVariable> ();
1622  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1623  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1624  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1625 
1626  double alpha = 5.0;
1627  double beta = 2.0;
1628 
1629  // Create the RNG with the specified range.
1630  Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> ();
1631  x->SetAttribute ("Alpha", DoubleValue (alpha));
1632  x->SetAttribute ("Beta", DoubleValue (beta));
1633 
1634  // Calculate the mean of these values.
1635  double valueMean = Average (x);
1636 
1637  // The expected value for the mean of the values returned by a
1638  // gammaly distributed random variable is equal to
1639  //
1640  // E[value] = alpha * beta .
1641  //
1642  double expectedMean = alpha * beta;
1643 
1644  // Test that values have approximately the right mean value.
1645  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1646 }
1647 
1653 {
1654 public:
1655  // Constructor
1657 
1658  // Inherited
1660 
1661 private:
1662  // Inherited
1663  virtual void DoRun (void);
1664 
1669  static constexpr double TOLERANCE {1e-2};
1670 };
1671 
1673  : TestCaseBase ("Antithetic Gamma Random Variable Stream Generator")
1674 {}
1675 
1676 double
1678 {
1679  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1680  auto range = UniformHistogramBins (h, 0, 10, false);
1681 
1682  std::vector<double> expected (N_BINS);
1683 
1684  // Note that this assumes that n has alpha equal to one and beta
1685  // equal to one, which are their default values for this
1686  // distribution.
1687  double alpha = 1.0;
1688  double beta = 1.0;
1689 
1690  for (std::size_t i = 0; i < N_BINS; ++i)
1691  {
1692  expected[i] = gsl_cdf_gamma_P (range[i + 1], alpha, beta) - gsl_cdf_gamma_P (range[i], alpha, beta);
1693  expected[i] *= N_MEASUREMENTS;
1694  }
1695 
1696  double chiSquared = ChiSquared (h, expected, rng);
1697 
1698  gsl_histogram_free (h);
1699  return chiSquared;
1700 }
1701 
1702 void
1704 {
1705  NS_LOG_FUNCTION (this);
1706  SetTestSuiteSeed ();
1707 
1708  auto generator = RngGenerator<GammaRandomVariable> (true);
1709  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1710  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1711  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1712 
1713  double alpha = 5.0;
1714  double beta = 2.0;
1715 
1716  // Create the RNG with the specified range.
1717  Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> ();
1718 
1719  // Make this generate antithetic values.
1720  x->SetAttribute ("Antithetic", BooleanValue (true));
1721 
1722  x->SetAttribute ("Alpha", DoubleValue (alpha));
1723  x->SetAttribute ("Beta", DoubleValue (beta));
1724 
1725  // Calculate the mean of these values.
1726  double valueMean = Average (x);
1727 
1728  // The expected value for the mean of the values returned by a
1729  // gammaly distributed random variable is equal to
1730  //
1731  // E[value] = alpha * beta .
1732  //
1733  double expectedMean = alpha * beta;
1734 
1735  // Test that values have approximately the right mean value.
1736  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1737 }
1738 
1744 {
1745 public:
1746  // Constructor
1747  ErlangTestCase ();
1748 
1749  // Inherited
1751 
1752 private:
1753  // Inherited
1754  virtual void DoRun (void);
1755 
1760  static constexpr double TOLERANCE {1e-2};
1761 };
1762 
1764  : TestCaseBase ("Erlang Random Variable Stream Generator")
1765 {}
1766 
1767 double
1769 {
1770  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1771  auto range = UniformHistogramBins (h, 0, 10, false);
1772 
1773  std::vector<double> expected (N_BINS);
1774 
1775  // Note that this assumes that n has k equal to one and lambda
1776  // equal to one, which are their default values for this
1777  // distribution.
1778  uint32_t k = 1;
1779  double lambda = 1.0;
1780 
1781  // Note that Erlang distribution is equal to the gamma distribution
1782  // when k is an iteger, which is why the gamma distribution's cdf
1783  // function can be used here.
1784  for (std::size_t i = 0; i < N_BINS; ++i)
1785  {
1786  expected[i] = gsl_cdf_gamma_P (range[i + 1], k, lambda) - gsl_cdf_gamma_P (range[i], k, lambda);
1787  expected[i] *= N_MEASUREMENTS;
1788  }
1789 
1790  double chiSquared = ChiSquared (h, expected, rng);
1791 
1792  gsl_histogram_free (h);
1793  return chiSquared;
1794 }
1795 
1796 void
1798 {
1799  NS_LOG_FUNCTION (this);
1800  SetTestSuiteSeed ();
1801 
1802  auto generator = RngGenerator<ErlangRandomVariable> ();
1803  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1804  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1805  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1806 
1807  uint32_t k = 5;
1808  double lambda = 2.0;
1809 
1810  // Create the RNG with the specified range.
1811  Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> ();
1812  x->SetAttribute ("K", IntegerValue (k));
1813  x->SetAttribute ("Lambda", DoubleValue (lambda));
1814 
1815  // Calculate the mean of these values.
1816  double valueMean = Average (x);
1817 
1818  // The expected value for the mean of the values returned by a
1819  // Erlangly distributed random variable is equal to
1820  //
1821  // E[value] = k * lambda .
1822  //
1823  double expectedMean = k * lambda;
1824 
1825  // Test that values have approximately the right mean value.
1826  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1827 }
1828 
1834 {
1835 public:
1836  // Constructor
1838 
1839  // Inherited
1841 
1842 private:
1843  // Inherited
1844  virtual void DoRun (void);
1845 
1850  static constexpr double TOLERANCE {1e-2};
1851 };
1852 
1854  : TestCaseBase ("Antithetic Erlang Random Variable Stream Generator")
1855 {}
1856 
1857 double
1859 {
1860  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1861  auto range = UniformHistogramBins (h, 0, 10, false);
1862 
1863  std::vector<double> expected (N_BINS);
1864 
1865  // Note that this assumes that n has k equal to one and lambda
1866  // equal to one, which are their default values for this
1867  // distribution.
1868  uint32_t k = 1;
1869  double lambda = 1.0;
1870 
1871  // Note that Erlang distribution is equal to the gamma distribution
1872  // when k is an iteger, which is why the gamma distribution's cdf
1873  // function can be used here.
1874  for (std::size_t i = 0; i < N_BINS; ++i)
1875  {
1876  expected[i] = gsl_cdf_gamma_P (range[i + 1], k, lambda) - gsl_cdf_gamma_P (range[i], k, lambda);
1877  expected[i] *= N_MEASUREMENTS;
1878  }
1879 
1880  double chiSquared = ChiSquared (h, expected, rng);
1881 
1882  gsl_histogram_free (h);
1883  return chiSquared;
1884 }
1885 
1886 void
1888 {
1889  NS_LOG_FUNCTION (this);
1890  SetTestSuiteSeed ();
1891 
1892  auto generator = RngGenerator<ErlangRandomVariable> (true);
1893  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1894  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1895  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1896 
1897  uint32_t k = 5;
1898  double lambda = 2.0;
1899 
1900  // Create the RNG with the specified range.
1901  Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> ();
1902 
1903  // Make this generate antithetic values.
1904  x->SetAttribute ("Antithetic", BooleanValue (true));
1905 
1906  x->SetAttribute ("K", IntegerValue (k));
1907  x->SetAttribute ("Lambda", DoubleValue (lambda));
1908 
1909  // Calculate the mean of these values.
1910  double valueMean = Average (x);
1911 
1912  // The expected value for the mean of the values returned by a
1913  // Erlangly distributed random variable is equal to
1914  //
1915  // E[value] = k * lambda .
1916  //
1917  double expectedMean = k * lambda;
1918 
1919  // Test that values have approximately the right mean value.
1920  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1921 }
1922 
1928 {
1929 public:
1930  // Constructor
1931  ZipfTestCase ();
1932 
1933 private:
1934  // Inherited
1935  virtual void DoRun (void);
1936 
1941  static constexpr double TOLERANCE {1e-2};
1942 };
1943 
1945  : TestCaseBase ("Zipf Random Variable Stream Generator")
1946 {}
1947 
1948 void
1950 {
1951  NS_LOG_FUNCTION (this);
1952  SetTestSuiteSeed ();
1953 
1954  uint32_t n = 1;
1955  double alpha = 2.0;
1956 
1957  // Create the RNG with the specified range.
1958  Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> ();
1959  x->SetAttribute ("N", IntegerValue (n));
1960  x->SetAttribute ("Alpha", DoubleValue (alpha));
1961 
1962  // Calculate the mean of these values.
1963  double valueMean = Average (x);
1964 
1965  // The expected value for the mean of the values returned by a
1966  // Zipfly distributed random variable is equal to
1967  //
1968  // H
1969  // N, alpha - 1
1970  // E[value] = ---------------
1971  // H
1972  // N, alpha
1973  //
1974  // where
1975  //
1976  // N
1977  // ---
1978  // \ -alpha
1979  // H = / m .
1980  // N, alpha ---
1981  // m=1
1982  //
1983  // For this test,
1984  //
1985  // -(alpha - 1)
1986  // 1
1987  // E[value] = ---------------
1988  // -alpha
1989  // 1
1990  //
1991  // = 1 .
1992  //
1993  double expectedMean = 1.0;
1994 
1995  // Test that values have approximately the right mean value.
1996  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1997 }
1998 
2004 {
2005 public:
2006  // Constructor
2008 
2009 private:
2010  // Inherited
2011  virtual void DoRun (void);
2012 
2017  static constexpr double TOLERANCE {1e-2};
2018 };
2019 
2021  : TestCaseBase ("Antithetic Zipf Random Variable Stream Generator")
2022 {}
2023 
2024 void
2026 {
2027  NS_LOG_FUNCTION (this);
2028  SetTestSuiteSeed ();
2029 
2030  uint32_t n = 1;
2031  double alpha = 2.0;
2032 
2033  // Create the RNG with the specified range.
2034  Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> ();
2035  x->SetAttribute ("N", IntegerValue (n));
2036  x->SetAttribute ("Alpha", DoubleValue (alpha));
2037 
2038  // Make this generate antithetic values.
2039  x->SetAttribute ("Antithetic", BooleanValue (true));
2040 
2041  // Calculate the mean of these values.
2042  double valueMean = Average (x);
2043 
2044  // The expected value for the mean of the values returned by a
2045  // Zipfly distributed random variable is equal to
2046  //
2047  // H
2048  // N, alpha - 1
2049  // E[value] = ---------------
2050  // H
2051  // N, alpha
2052  //
2053  // where
2054  //
2055  // N
2056  // ---
2057  // \ -alpha
2058  // H = / m .
2059  // N, alpha ---
2060  // m=1
2061  //
2062  // For this test,
2063  //
2064  // -(alpha - 1)
2065  // 1
2066  // E[value] = ---------------
2067  // -alpha
2068  // 1
2069  //
2070  // = 1 .
2071  //
2072  double expectedMean = 1.0;
2073 
2074  // Test that values have approximately the right mean value.
2075  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2076 }
2077 
2083 {
2084 public:
2085  // Constructor
2086  ZetaTestCase ();
2087 
2088 private:
2089  // Inherited
2090  virtual void DoRun (void);
2091 
2096  static constexpr double TOLERANCE {1e-2};
2097 };
2098 
2100  : TestCaseBase ("Zeta Random Variable Stream Generator")
2101 {}
2102 
2103 void
2105 {
2106  NS_LOG_FUNCTION (this);
2107  SetTestSuiteSeed ();
2108 
2109  double alpha = 5.0;
2110 
2111  // Create the RNG with the specified range.
2112  Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> ();
2113  x->SetAttribute ("Alpha", DoubleValue (alpha));
2114 
2115  // Calculate the mean of these values.
2116  double valueMean = Average (x);
2117 
2118  // The expected value for the mean of the values returned by a
2119  // zetaly distributed random variable is equal to
2120  //
2121  // zeta(alpha - 1)
2122  // E[value] = --------------- for alpha > 2 ,
2123  // zeta(alpha)
2124  //
2125  // where zeta(alpha) is the Riemann zeta function.
2126  //
2127  // There are no simple analytic forms for the Riemann zeta function,
2128  // which is why the gsl library is used in this test to calculate
2129  // the known mean of the values.
2130  double expectedMean =
2131  gsl_sf_zeta_int (static_cast<int> (alpha - 1)) /
2132  gsl_sf_zeta_int (static_cast<int> (alpha) );
2133 
2134  // Test that values have approximately the right mean value.
2135  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2136 }
2137 
2143 {
2144 public:
2145  // Constructor
2147 
2148 private:
2149  // Inherited
2150  virtual void DoRun (void);
2151 
2156  static constexpr double TOLERANCE {1e-2};
2157 };
2158 
2160  : TestCaseBase ("Antithetic Zeta Random Variable Stream Generator")
2161 {}
2162 
2163 void
2165 {
2166  NS_LOG_FUNCTION (this);
2167  SetTestSuiteSeed ();
2168 
2169  double alpha = 5.0;
2170 
2171  // Create the RNG with the specified range.
2172  Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> ();
2173  x->SetAttribute ("Alpha", DoubleValue (alpha));
2174 
2175  // Make this generate antithetic values.
2176  x->SetAttribute ("Antithetic", BooleanValue (true));
2177 
2178  // Calculate the mean of these values.
2179  double valueMean = Average (x);
2180 
2181  // The expected value for the mean of the values returned by a
2182  // zetaly distributed random variable is equal to
2183  //
2184  // zeta(alpha - 1)
2185  // E[value] = --------------- for alpha > 2 ,
2186  // zeta(alpha)
2187  //
2188  // where zeta(alpha) is the Riemann zeta function.
2189  //
2190  // There are no simple analytic forms for the Riemann zeta function,
2191  // which is why the gsl library is used in this test to calculate
2192  // the known mean of the values.
2193  double expectedMean =
2194  gsl_sf_zeta_int (static_cast<int> (alpha) - 1) /
2195  gsl_sf_zeta_int (static_cast<int> (alpha) );
2196 
2197  // Test that values have approximately the right mean value.
2198  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2199 }
2200 
2206 {
2207 public:
2208  // Constructor
2210 
2211 private:
2212  // Inherited
2213  virtual void DoRun (void);
2214 
2216  static constexpr double TOLERANCE {1e-8};
2217 };
2218 
2220  : TestCaseBase ("Deterministic Random Variable Stream Generator")
2221 {}
2222 
2223 void
2225 {
2226  NS_LOG_FUNCTION (this);
2227  SetTestSuiteSeed ();
2228 
2229  Ptr<DeterministicRandomVariable> s = CreateObject<DeterministicRandomVariable> ();
2230 
2231  // The following array should give the sequence
2232  //
2233  // 4, 4, 7, 7, 10, 10 .
2234  //
2235  double array1 [] = { 4, 4, 7, 7, 10, 10};
2236  std::size_t count1 = 6;
2237  s->SetValueArray (array1, count1);
2238 
2239  double value;
2240 
2241  // Test that the first sequence is correct.
2242  value = s->GetValue ();
2243  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence 1 value 1 wrong.");
2244  value = s->GetValue ();
2245  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence 1 value 2 wrong.");
2246  value = s->GetValue ();
2247  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence 1 value 3 wrong.");
2248  value = s->GetValue ();
2249  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence 1 value 4 wrong.");
2250  value = s->GetValue ();
2251  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence 1 value 5 wrong.");
2252  value = s->GetValue ();
2253  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence 1 value 6 wrong.");
2254 
2255  // The following array should give the sequence
2256  //
2257  // 1000, 2000, 7, 7 .
2258  //
2259  double array2 [] = { 1000, 2000, 3000, 4000};
2260  std::size_t count2 = 4;
2261  s->SetValueArray (array2, count2);
2262 
2263  // Test that the second sequence is correct.
2264  value = s->GetValue ();
2265  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1000, TOLERANCE, "Sequence 2 value 1 wrong.");
2266  value = s->GetValue ();
2267  NS_TEST_ASSERT_MSG_EQ_TOL (value, 2000, TOLERANCE, "Sequence 2 value 2 wrong.");
2268  value = s->GetValue ();
2269  NS_TEST_ASSERT_MSG_EQ_TOL (value, 3000, TOLERANCE, "Sequence 2 value 3 wrong.");
2270  value = s->GetValue ();
2271  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4000, TOLERANCE, "Sequence 2 value 4 wrong.");
2272  value = s->GetValue ();
2273 }
2274 
2280 {
2281 public:
2282  // Constructor
2283  EmpiricalTestCase ();
2284 
2285 private:
2286  // Inherited
2287  virtual void DoRun (void);
2288 
2293  static constexpr double TOLERANCE {1e-2};
2294 };
2295 
2297  : TestCaseBase ("Empirical Random Variable Stream Generator")
2298 {}
2299 
2300 void
2302 {
2303  NS_LOG_FUNCTION (this);
2304  SetTestSuiteSeed ();
2305 
2306  // Create the RNG with a uniform distribution between 0 and 10.
2307  Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> ();
2308  x->SetInterpolate (false);
2309  x->CDF ( 0.0, 0.0);
2310  x->CDF ( 5.0, 0.25);
2311  x->CDF (10.0, 1.0);
2312 
2313  // Check that only the correct values are returned
2314  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2315  {
2316  double value = x->GetValue ();
2317  NS_TEST_EXPECT_MSG_EQ ( (value == 5) || (value == 10), true,
2318  "Incorrect value returned, expected only 5 or 10.");
2319  }
2320 
2321  // Calculate the mean of the sampled values.
2322  double valueMean = Average (x);
2323 
2324  // The expected distribution with sampled values is
2325  // Value Probability
2326  // 5 25%
2327  // 10 75%
2328  //
2329  // The expected mean is
2330  //
2331  // E[value] = 5 * 25% + 10 * 75% = 8.75
2332  //
2333  // Test that values have approximately the right mean value.
2334  double expectedMean = 8.75;
2335  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2336 
2337 
2338  // Calculate the mean of the interpolated values.
2339  x->SetInterpolate (true);
2340  valueMean = Average (x);
2341 
2342  // The expected distribution (with interpolation) is
2343  // Bin Probability
2344  // [0, 5) 25%
2345  // [5, 10) 75%
2346  //
2347  // Each bin is uniformly sampled, so the average of the samples in the
2348  // bin is the center of the bin.
2349  //
2350  // The expected mean is
2351  //
2352  // E[value] = 2.5 * 25% + 7.5 * 75% = 6.25
2353  //
2354  expectedMean = 6.25;
2355 
2356  // Test that values have approximately the right mean value.
2357  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2358 
2359  // Bug 2082: Create the RNG with a uniform distribution between -1 and 1.
2360  Ptr<EmpiricalRandomVariable> y = CreateObject<EmpiricalRandomVariable> ();
2361  y->SetInterpolate (false);
2362  y->CDF (-1.0, 0.0);
2363  y->CDF (0.0, 0.5);
2364  y->CDF (1.0, 1.0);
2365  NS_TEST_ASSERT_MSG_LT (y->GetValue (), 2, "Empirical variable with negative domain");
2366 }
2367 
2373 {
2374 public:
2375  // Constructor
2377 
2378 private:
2379  // Inherited
2380  virtual void DoRun (void);
2381 
2386  static constexpr double TOLERANCE {1e-2};
2387 };
2388 
2390  : TestCaseBase ("EmpiricalAntithetic Random Variable Stream Generator")
2391 {}
2392 
2393 void
2395 {
2396  NS_LOG_FUNCTION (this);
2397  SetTestSuiteSeed ();
2398 
2399  // Create the RNG with a uniform distribution between 0 and 10.
2400  Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> ();
2401  x->SetInterpolate (false);
2402  x->CDF ( 0.0, 0.0);
2403  x->CDF ( 5.0, 0.25);
2404  x->CDF (10.0, 1.0);
2405 
2406  // Make this generate antithetic values.
2407  x->SetAttribute ("Antithetic", BooleanValue (true));
2408 
2409  // Check that only the correct values are returned
2410  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2411  {
2412  double value = x->GetValue ();
2413  NS_TEST_EXPECT_MSG_EQ ( (value == 5) || (value == 10), true,
2414  "Incorrect value returned, expected only 5 or 10.");
2415  }
2416 
2417  // Calculate the mean of these values.
2418  double valueMean = Average (x);
2419  // Expected
2420  // E[value] = 5 * 25% + 10 * 75% = 8.75
2421  double expectedMean = 8.75;
2422  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2423 
2424  // Check interpolated sampling
2425  x->SetInterpolate (true);
2426  valueMean = Average (x);
2427 
2428  // The expected value for the mean of the values returned by this
2429  // empirical distribution with interpolation is
2430  //
2431  // E[value] = 2.5 * 25% + 7.5 * 75% = 6.25
2432  //
2433  expectedMean = 6.25;
2434 
2435  // Test that values have approximately the right mean value.
2436  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2437 }
2438 
2444 {
2445 public:
2446  // Constructor
2448 
2449 private:
2450  // Inherited
2451  virtual void DoRun (void);
2452 };
2453 
2455  : TestCaseBase ("NormalRandomVariable caching of parameters")
2456 {}
2457 
2458 void
2460 {
2461  NS_LOG_FUNCTION (this);
2462  SetTestSuiteSeed ();
2463 
2464  Ptr<NormalRandomVariable> n = CreateObject<NormalRandomVariable> ();
2465  double v1 = n->GetValue (-10, 1, 10); // Mean -10, variance 1, bounded to [-20,0]
2466  double v2 = n->GetValue (10, 1, 10); // Mean 10, variance 1, bounded to [0,20]
2467 
2468  NS_TEST_ASSERT_MSG_LT (v1, 0, "Incorrect value returned, expected < 0");
2469  NS_TEST_ASSERT_MSG_GT (v2, 0, "Incorrect value returned, expected > 0");
2470 }
2471 
2478 {
2479 public:
2480  // Constructor
2482 };
2483 
2485  : TestSuite ("random-variable-stream-generators", UNIT)
2486 {
2503  /*
2504  AddTestCase (new LogNormalAntitheticTestCase);
2505  */
2506  AddTestCase (new GammaTestCase);
2510  /*
2511  AddTestCase (new GammaAntitheticTestCase);
2512  */
2515  AddTestCase (new ZipfTestCase);
2517  AddTestCase (new ZetaTestCase);
2524 }
2525 
2527 
2528 } // namespace RandomVariable
2529 
2530 } // namespace test
2531 
2532 } // namespace ns3
2533 
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
AttributeValue implementation for Boolean.
Definition: boolean.h:37
double GetValue(double constant)
Get the next random value, as a double equal to the argument.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Hold a signed integer type.
Definition: integer.h:44
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:256
static uint32_t GetSeed(void)
Get the current seed value which will be used by all subsequently instantiated RandomVariableStream o...
static void SetSeed(uint32_t seed)
Set the seed.
static uint64_t GetRun(void)
Get the current run number.
Hold variables of type string.
Definition: string.h:41
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Test case for constant random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for deterministic random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for antithetic empirical distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for empirical distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
Test case for antithetic Erlang distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
Test case for Erlang distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
Test case for antithetic exponential distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, in rms.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for exponential distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, in rms.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
Test case for antithetic gamma distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
Test case for gamma distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for antithetic log-normal distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
Test case for log-normal distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
Test case for antithetic normal distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, in rms.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for caching of Normal RV parameters (see issue #302)
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for normal distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, in rms.
Test case for antithetic Pareto distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for Pareto distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
RandomVariableStream test suite, covering all random number variable stream generator types.
Test case for sequential random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
A factory base class to create new instances of a random variable.
virtual Ptr< RandomVariableStream > Create(void) const =0
Create a new instance of a random variable stream.
Factory class to create new instances of a particular random variable stream.
bool m_anti
Whether to create antithetic random variable streams.
Ptr< RandomVariableStream > Create(void) const
Create a new instance of a random variable stream.
Base class for RandomVariableStream test suites.
double ChiSquared(gsl_histogram *h, const std::vector< double > &expected, Ptr< RandomVariableStream > rng) const
Compute the chi squared value of a sampled distribution compared to the expected distribution.
static const uint32_t N_MEASUREMENTS
Number of samples to draw when populating the distributions.
double ChiSquaredsAverage(const RngGeneratorBase *generator, std::size_t nRuns) const
Average the chi squared value over some number of runs, each run with a new instance of the random nu...
virtual double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
static const uint32_t N_BINS
Number of bins for sampling the distributions.
void SetTestSuiteSeed(void)
Set the seed used for this test suite.
std::vector< double > UniformHistogramBins(gsl_histogram *h, double start, double end, bool underflow=true, bool overflow=true) const
Configure a GSL histogram with uniform bins, with optional under/over-flow bins.
bool m_seedSet
true if we've already set the seed the correctly.
static const uint32_t N_RUNS
Number of retry attempts to pass a chi-square test.
double Average(Ptr< RandomVariableStream > rng) const
Compute the average of a random variable.
Test case for antithetic uniform distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for uniform distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for antithetic Weibull distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
Test case for Weibull distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
Test case for antithetic Zeta distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
Test case for Zeta distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for antithetic Zipf distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for Zipf distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_TEST_ASSERT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report and abort if not.
Definition: test.h:675
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:141
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:240
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:542
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:825
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:323
static RandomVariableSuite randomVariableSuite
Static variable for test initialization.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
float alpha
Plot alpha value (transparency)
list x
Random number samples.
rng
Random number generator.
def start()
Definition: core.py:1853