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 
54 class TestCaseBase : public TestCase
55 {
56 public:
58  static const uint32_t N_BINS {50};
60  static const uint32_t N_MEASUREMENTS {1000000};
62  static const uint32_t N_RUNS {5};
63 
68  TestCaseBase (std::string name)
69  : TestCase (name)
70  {}
71 
83  std::vector<double>
84  UniformHistogramBins (gsl_histogram *h, double start, double end,
85  bool underflow = true, bool overflow = true) const
86  {
87  NS_LOG_FUNCTION (this << h << start << end);
88  std::size_t nBins = gsl_histogram_bins (h);
89  double increment = (end - start) / (nBins - 1.);
90  double d = start;
91 
92  std::vector<double> range (nBins + 1);
93 
94  for (auto & r : range)
95  {
96  r = d;
97  d += increment;
98  }
99  if (underflow)
100  {
101  range[0] = -std::numeric_limits<double>::max ();
102  }
103  if (overflow)
104  {
105  range[nBins] = std::numeric_limits<double>::max ();
106  }
107 
108  gsl_histogram_set_ranges (h, range.data (), nBins + 1);
109  return range;
110  }
111 
117  double
119  {
120  NS_LOG_FUNCTION (this << rng);
121  double sum = 0.0;
122  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
123  {
124  double value = rng->GetValue ();
125  sum += value;
126  }
127  double valueMean = sum / N_MEASUREMENTS;
128  return valueMean;
129  }
130 
133  {
134  public:
139  virtual Ptr<RandomVariableStream> Create (void) const = 0;
140  };
141 
147  template <typename RNG>
149  {
150  public:
155  RngGenerator (bool anti = false)
156  : m_anti (anti)
157  {}
158 
159  // Inherited
161  Create (void) const
162  {
163  auto rng = CreateObject<RNG> ();
164  rng->SetAttribute ("Antithetic", BooleanValue (m_anti));
165  return rng;
166  }
167 
168  private:
170  bool m_anti;
171  };
172 
188  double
189  ChiSquared (gsl_histogram * h,
190  const std::vector<double> & expected,
192  {
193  NS_LOG_FUNCTION (this << h << expected.size () << rng);
194  NS_ASSERT_MSG (gsl_histogram_bins (h) == expected.size (),
195  "Histogram and expected vector have different sizes.");
196 
197  // Sample the rng into the histogram
198  for (std::size_t i = 0; i < N_MEASUREMENTS; ++i)
199  {
200  double value = rng->GetValue ();
201  gsl_histogram_increment (h, value);
202  }
203 
204  // Compute the chi square value
205  double chiSquared = 0;
206  std::size_t nBins = gsl_histogram_bins (h);
207  for (std::size_t i = 0; i < nBins; ++i)
208  {
209  double hbin = gsl_histogram_get (h, i);
210  double tmp = hbin - expected[i];
211  tmp *= tmp;
212  tmp /= expected[i];
213  chiSquared += tmp;
214  }
215 
216  return chiSquared;
217  }
218 
249  virtual double
251  {
252  return 0;
253  }
254 
263  double
265  std::size_t nRuns) const
266  {
267  NS_LOG_FUNCTION (this << generator << nRuns);
268 
269  double sum = 0.;
270  for (std::size_t i = 0; i < nRuns; ++i)
271  {
272  auto rng = generator->Create ();
273  double result = ChiSquaredTest (rng);
274  sum += result;
275  }
276  sum /= (double)nRuns;
277  return sum;
278  }
279 
308  void
310  {
311  if (m_seedSet == false)
312  {
313  uint32_t seed;
314  if (RngSeedManager::GetSeed () == 1 && RngSeedManager::GetRun () == 1)
315  {
316  seed = static_cast<uint32_t> (time (0));
317  m_seedSet = true;
318  NS_LOG_DEBUG ("Global seed and run number are default; seeding with time of day: " << seed);
319 
320  }
321  else
322  {
323  seed = RngSeedManager::GetSeed ();
324  m_seedSet = true;
325  NS_LOG_DEBUG ("Global seed and run number are not default; using the non-default values seed: " <<
326  seed << " and run: " << RngSeedManager::GetRun ());
327  }
328  SeedManager::SetSeed (seed);
329  }
330  }
331 
332 private:
334  bool m_seedSet = false;
335 
336 }; // class TestCaseBase
337 
338 
343 {
344 public:
345 
346  // Constructor
347  UniformTestCase ();
348 
349  // Inherited
351 
352 private:
353  // Inherited
354  virtual void DoRun (void);
355 };
356 
358  : TestCaseBase ("Uniform Random Variable Stream Generator")
359 {}
360 
361 double
363 {
364  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
365 
366  // Note that this assumes that the range for u is [0,1], which is
367  // the default range for this distribution.
368  gsl_histogram_set_ranges_uniform (h, 0., 1.);
369 
370  std::vector<double> expected (N_BINS, ((double)N_MEASUREMENTS / (double)N_BINS));
371 
372  double chiSquared = ChiSquared (h, expected, rng);
373  gsl_histogram_free (h);
374  return chiSquared;
375 }
376 
377 void
379 {
380  NS_LOG_FUNCTION (this);
381  SetTestSuiteSeed ();
382 
383  double confidence = 0.99;
384  double maxStatistic = gsl_cdf_chisq_Pinv (confidence, (N_BINS - 1));
385  NS_LOG_DEBUG ("Chi square required at " << confidence << " confidence for " << N_BINS << " bins is " << maxStatistic);
386 
387  double result = maxStatistic;
388  // If chi-squared test fails, re-try it up to N_RUNS times
389  for (uint32_t i = 0; i < N_RUNS; ++i)
390  {
391  Ptr<UniformRandomVariable> rng = CreateObject<UniformRandomVariable> ();
392  result = ChiSquaredTest (rng);
393  NS_LOG_DEBUG ("Chi square result is " << result);
394  if (result < maxStatistic)
395  {
396  break;
397  }
398  }
399 
400  NS_TEST_ASSERT_MSG_LT (result, maxStatistic, "Chi-squared statistic out of range");
401 
402  double min = 0.0;
403  double max = 10.0;
404  double value;
405 
406  // Create the RNG with the specified range.
407  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
408 
409  x->SetAttribute ("Min", DoubleValue (min));
410  x->SetAttribute ("Max", DoubleValue (max));
411 
412  // Test that values are always within the range:
413  //
414  // [min, max)
415  //
416  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
417  {
418  value = x->GetValue ();
419  NS_TEST_ASSERT_MSG_EQ ((value >= min), true, "Value less than minimum.");
420  NS_TEST_ASSERT_MSG_LT (value, max, "Value greater than or equal to maximum.");
421  }
422 
423  // Boundary checking on GetInteger; should be [min,max]; from bug 1964
424  static const uint32_t UNIFORM_INTEGER_MIN {0};
425  static const uint32_t UNIFORM_INTEGER_MAX {4294967295U};
426  // [0,0] should return 0
427  uint32_t intValue;
428  intValue = x->GetInteger (UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MIN);
429  NS_TEST_ASSERT_MSG_EQ (intValue, UNIFORM_INTEGER_MIN, "Uniform RV GetInteger boundary testing");
430  // [UNIFORM_INTEGER_MAX, UNIFORM_INTEGER_MAX] should return UNIFORM_INTEGER_MAX
431  intValue = x->GetInteger (UNIFORM_INTEGER_MAX, UNIFORM_INTEGER_MAX);
432  NS_TEST_ASSERT_MSG_EQ (intValue, UNIFORM_INTEGER_MAX, "Uniform RV GetInteger boundary testing");
433  // [0,1] should return mix of 0 or 1
434  intValue = 0;
435  for (int i = 0; i < 20; i++)
436  {
437  intValue += x->GetInteger (UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MIN + 1);
438  }
439  NS_TEST_ASSERT_MSG_GT (intValue, 0, "Uniform RV GetInteger boundary testing");
440  NS_TEST_ASSERT_MSG_LT (intValue, 20, "Uniform RV GetInteger boundary testing");
441  // [MAX-1,MAX] should return mix of MAX-1 or MAX
442  uint32_t count = 0;
443  for (int i = 0; i < 20; i++)
444  {
445  intValue = x->GetInteger (UNIFORM_INTEGER_MAX - 1, UNIFORM_INTEGER_MAX);
446  if (intValue == UNIFORM_INTEGER_MAX)
447  {
448  count++;
449  }
450  }
451  NS_TEST_ASSERT_MSG_GT (count, 0, "Uniform RV GetInteger boundary testing");
452  NS_TEST_ASSERT_MSG_LT (count, 20, "Uniform RV GetInteger boundary testing");
453  // multiple [0,UNIFORM_INTEGER_MAX] should return non-zero
454  intValue = x->GetInteger (UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MAX);
455  uint32_t intValue2 = x->GetInteger (UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MAX);
456  NS_TEST_ASSERT_MSG_GT (intValue + intValue2, 0, "Uniform RV GetInteger boundary testing");
457 
458 }
459 
464 {
465 public:
466 
467  // Constructor
469 
470  // Inherited
472 
473 private:
474  // Inherited
475  virtual void DoRun (void);
476 };
477 
479  : TestCaseBase ("Antithetic Uniform Random Variable Stream Generator")
480 {}
481 
482 double
484 {
485  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
486 
487  // Note that this assumes that the range for u is [0,1], which is
488  // the default range for this distribution.
489  gsl_histogram_set_ranges_uniform (h, 0., 1.);
490 
491  std::vector<double> expected (N_BINS, ((double)N_MEASUREMENTS / (double)N_BINS));
492 
493  double chiSquared = ChiSquared (h, expected, rng);
494  gsl_histogram_free (h);
495  return chiSquared;
496 }
497 
498 void
500 {
501  NS_LOG_FUNCTION (this);
502  SetTestSuiteSeed ();
503 
504  auto generator = RngGenerator<UniformRandomVariable> (true);
505  double sum = ChiSquaredsAverage (&generator, N_RUNS);
506  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
507  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
508 
509  double min = 0.0;
510  double max = 10.0;
511  double value;
512 
513  // Create the RNG with the specified range.
514  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
515 
516  // Make this generate antithetic values.
517  x->SetAttribute ("Antithetic", BooleanValue (true));
518 
519  x->SetAttribute ("Min", DoubleValue (min));
520  x->SetAttribute ("Max", DoubleValue (max));
521 
522  // Test that values are always within the range:
523  //
524  // [min, max)
525  //
526  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
527  {
528  value = x->GetValue ();
529  NS_TEST_ASSERT_MSG_EQ ((value >= min), true, "Value less than minimum.");
530  NS_TEST_ASSERT_MSG_LT (value, max, "Value greater than or equal to maximum.");
531  }
532 
533 
534 }
539 {
540 public:
541  // Constructor
542  ConstantTestCase ();
543 
544 private:
545  // Inherited
546  virtual void DoRun (void);
547 
549  static constexpr double TOLERANCE {1e-8};
550 };
551 
553  : TestCaseBase ("Constant Random Variable Stream Generator")
554 {}
555 
556 void
558 {
559  NS_LOG_FUNCTION (this);
560  SetTestSuiteSeed ();
561 
562  Ptr<ConstantRandomVariable> c = CreateObject<ConstantRandomVariable> ();
563 
564  double constant;
565 
566  // Test that the constant value can be changed using its attribute.
567  constant = 10.0;
568  c->SetAttribute ("Constant", DoubleValue (constant));
569  NS_TEST_ASSERT_MSG_EQ_TOL (c->GetValue (), constant, TOLERANCE, "Constant value changed");
570  c->SetAttribute ("Constant", DoubleValue (20.0));
571  NS_TEST_ASSERT_MSG_NE (c->GetValue (), constant, "Constant value not changed");
572 
573  // Test that the constant value does not change.
574  constant = c->GetValue ();
575  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
576  {
577  NS_TEST_ASSERT_MSG_EQ_TOL (c->GetValue (), constant, TOLERANCE, "Constant value changed in loop");
578  }
579 }
580 
585 {
586 public:
587  // Constructor
589 
590 private:
591  // Inherited
592  virtual void DoRun (void);
593 
595  static constexpr double TOLERANCE {1e-8};
596 };
597 
599  : TestCaseBase ("Sequential Random Variable Stream Generator")
600 {}
601 
602 void
604 {
605  NS_LOG_FUNCTION (this);
606  SetTestSuiteSeed ();
607 
608  Ptr<SequentialRandomVariable> s = CreateObject<SequentialRandomVariable> ();
609 
610  // The following four attributes should give the sequence
611  //
612  // 4, 4, 7, 7, 10, 10
613  //
614  s->SetAttribute ("Min", DoubleValue (4));
615  s->SetAttribute ("Max", DoubleValue (11));
616  s->SetAttribute ("Increment", StringValue ("ns3::UniformRandomVariable[Min=3.0|Max=3.0]"));
617  s->SetAttribute ("Consecutive", IntegerValue (2));
618 
619  double value;
620 
621  // Test that the sequencet is correct.
622  value = s->GetValue ();
623  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence value 1 wrong.");
624  value = s->GetValue ();
625  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence value 2 wrong.");
626  value = s->GetValue ();
627  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence value 3 wrong.");
628  value = s->GetValue ();
629  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence value 4 wrong.");
630  value = s->GetValue ();
631  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence value 5 wrong.");
632  value = s->GetValue ();
633  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence value 6 wrong.");
634 
635 }
636 
641 {
642 public:
643  // Constructor
644  NormalTestCase ();
645 
646  // Inherited
648 
649 private:
650  // Inherited
651  virtual void DoRun (void);
652 
654  static constexpr double TOLERANCE {5};
655 };
656 
658  : TestCaseBase ("Normal Random Variable Stream Generator")
659 {}
660 
661 double
663 {
664  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
665  auto range = UniformHistogramBins (h, -4., 4.);
666 
667  std::vector<double> expected (N_BINS);
668 
669  // Note that this assumes that n has mean equal to zero and standard
670  // deviation equal to one, which are their default values for this
671  // distribution.
672  double sigma = 1.;
673 
674  for (std::size_t i = 0; i < N_BINS; ++i)
675  {
676  expected[i] = gsl_cdf_gaussian_P (range[i + 1], sigma) - gsl_cdf_gaussian_P (range[i], sigma);
677  expected[i] *= N_MEASUREMENTS;
678  }
679 
680  double chiSquared = ChiSquared (h, expected, rng);
681  gsl_histogram_free (h);
682  return chiSquared;
683 }
684 
685 void
687 {
688  NS_LOG_FUNCTION (this);
689  SetTestSuiteSeed ();
690 
691  auto generator = RngGenerator<NormalRandomVariable> ();
692  auto rng = generator.Create ();
693 
694  double sum = ChiSquaredsAverage (&generator, N_RUNS);
695  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
696  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
697 
698  double mean = 5.0;
699  double variance = 2.0;
700 
701  // Create the RNG with the specified range.
702  Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> ();
703  x->SetAttribute ("Mean", DoubleValue (mean));
704  x->SetAttribute ("Variance", DoubleValue (variance));
705 
706  // Calculate the mean of these values.
707  double valueMean = Average (x);
708 
709  // The expected value for the mean of the values returned by a
710  // normally distributed random variable is equal to mean.
711  double expectedMean = mean;
712  double expectedRms = mean / std::sqrt (variance * N_MEASUREMENTS);
713 
714  // Test that values have approximately the right mean value.
715  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedRms * TOLERANCE, "Wrong mean value.");
716 }
717 
722 {
723 public:
724  // Constructor
726 
727  // Inherited
729 
730 private:
731  // Inherited
732  virtual void DoRun (void);
733 
735  static constexpr double TOLERANCE {5};
736 };
737 
739  : TestCaseBase ("Antithetic Normal Random Variable Stream Generator")
740 {}
741 
742 double
744 {
745  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
746  auto range = UniformHistogramBins (h, -4, 4);
747 
748  std::vector<double> expected (N_BINS);
749 
750  // Note that this assumes that n has mean equal to zero and standard
751  // deviation equal to one, which are their default values for this
752  // distribution.
753  double sigma = 1.;
754 
755  for (std::size_t i = 0; i < N_BINS; ++i)
756  {
757  expected[i] = gsl_cdf_gaussian_P (range[i + 1], sigma) - gsl_cdf_gaussian_P (range[i], sigma);
758  expected[i] *= N_MEASUREMENTS;
759  }
760 
761  double chiSquared = ChiSquared (h, expected, rng);
762 
763  gsl_histogram_free (h);
764  return chiSquared;
765 }
766 
767 void
769 {
770  NS_LOG_FUNCTION (this);
771  SetTestSuiteSeed ();
772 
773  auto generator = RngGenerator<NormalRandomVariable> (true);
774  double sum = ChiSquaredsAverage (&generator, N_RUNS);
775  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
776  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
777 
778  double mean = 5.0;
779  double variance = 2.0;
780 
781  // Create the RNG with the specified range.
782  Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> ();
783  x->SetAttribute ("Mean", DoubleValue (mean));
784  x->SetAttribute ("Variance", DoubleValue (variance));
785 
786  // Make this generate antithetic values.
787  x->SetAttribute ("Antithetic", BooleanValue (true));
788 
789  // Calculate the mean of these values.
790  double valueMean = Average (x);
791 
792  // The expected value for the mean of the values returned by a
793  // normally distributed random variable is equal to mean.
794  double expectedMean = mean;
795  double expectedRms = mean / std::sqrt (variance * N_MEASUREMENTS);
796 
797  // Test that values have approximately the right mean value.
798  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedRms * TOLERANCE, "Wrong mean value.");
799 }
800 
805 {
806 public:
807  // Constructor
809 
810  // Inherited
812 
813 private:
814  // Inherited
815  virtual void DoRun (void);
816 
818  static constexpr double TOLERANCE {5};
819 };
820 
822  : TestCaseBase ("Exponential Random Variable Stream Generator")
823 {}
824 
825 double
827 {
828  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
829  auto range = UniformHistogramBins (h, 0, 10, false);
830 
831  std::vector<double> expected (N_BINS);
832 
833  // Note that this assumes that e has mean equal to one, which is the
834  // default value for this distribution.
835  double mu = 1.;
836 
837  for (std::size_t i = 0; i < N_BINS; ++i)
838  {
839  expected[i] = gsl_cdf_exponential_P (range[i + 1], mu) - gsl_cdf_exponential_P (range[i], mu);
840  expected[i] *= N_MEASUREMENTS;
841  }
842 
843  double chiSquared = ChiSquared (h, expected, rng);
844 
845  gsl_histogram_free (h);
846  return chiSquared;
847 }
848 
849 void
851 {
852  NS_LOG_FUNCTION (this);
853  SetTestSuiteSeed ();
854 
855  auto generator = RngGenerator<ExponentialRandomVariable> ();
856  double sum = ChiSquaredsAverage (&generator, N_RUNS);
857  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
858  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
859 
860  double mean = 3.14;
861  double bound = 0.0;
862 
863  // Create the RNG with the specified range.
864  Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> ();
865  x->SetAttribute ("Mean", DoubleValue (mean));
866  x->SetAttribute ("Bound", DoubleValue (bound));
867 
868  // Calculate the mean of these values.
869  double valueMean = Average (x);
870  double expectedMean = mean;
871  double expectedRms = std::sqrt (mean / N_MEASUREMENTS);
872 
873  // Test that values have approximately the right mean value.
874  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedRms * TOLERANCE, "Wrong mean value.");
875 }
876 
881 {
882 public:
883  // Constructor
885 
886  // Inherited
888 
889 private:
890  // Inherited
891  virtual void DoRun (void);
892 
894  static constexpr double TOLERANCE {5};
895 };
896 
898  : TestCaseBase ("Antithetic Exponential Random Variable Stream Generator")
899 {}
900 
901 double
903 {
904  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
905  auto range = UniformHistogramBins (h, 0, 10, false);
906 
907  std::vector<double> expected (N_BINS);
908 
909  // Note that this assumes that e has mean equal to one, which is the
910  // default value for this distribution.
911  double mu = 1.;
912 
913  for (std::size_t i = 0; i < N_BINS; ++i)
914  {
915  expected[i] = gsl_cdf_exponential_P (range[i + 1], mu) - gsl_cdf_exponential_P (range[i], mu);
916  expected[i] *= N_MEASUREMENTS;
917  }
918 
919  double chiSquared = ChiSquared (h, expected, rng);
920 
921  gsl_histogram_free (h);
922  return chiSquared;
923 }
924 
925 void
927 {
928  NS_LOG_FUNCTION (this);
929  SetTestSuiteSeed ();
930 
931  auto generator = RngGenerator<ExponentialRandomVariable> (true);
932  double sum = ChiSquaredsAverage (&generator, N_RUNS);
933  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
934  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
935 
936  double mean = 3.14;
937  double bound = 0.0;
938 
939  // Create the RNG with the specified range.
940  Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> ();
941  x->SetAttribute ("Mean", DoubleValue (mean));
942  x->SetAttribute ("Bound", DoubleValue (bound));
943 
944  // Make this generate antithetic values.
945  x->SetAttribute ("Antithetic", BooleanValue (true));
946 
947  // Calculate the mean of these values.
948  double valueMean = Average (x);
949  double expectedMean = mean;
950  double expectedRms = std::sqrt (mean / N_MEASUREMENTS);
951 
952  // Test that values have approximately the right mean value.
953  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedRms * TOLERANCE, "Wrong mean value.");
954 }
955 
960 {
961 public:
962  // Constructor
963  ParetoTestCase ();
964 
965  // Inherited
967 
968 private:
969  // Inherited
970  virtual void DoRun (void);
971 
976  static constexpr double TOLERANCE {1e-2};
977 };
978 
980  : TestCaseBase ("Pareto Random Variable Stream Generator")
981 {}
982 
983 double
985 {
986  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
987  auto range = UniformHistogramBins (h, 1, 10, false);
988 
989  std::vector<double> expected (N_BINS);
990 
991  double shape = 2.0;
992  double scale = 1.0;
993 
994  for (std::size_t i = 0; i < N_BINS; ++i)
995  {
996  expected[i] = gsl_cdf_pareto_P (range[i + 1], shape, scale) - gsl_cdf_pareto_P (range[i], shape, scale);
997  expected[i] *= N_MEASUREMENTS;
998  }
999 
1000  double chiSquared = ChiSquared (h, expected, rng);
1001 
1002  gsl_histogram_free (h);
1003  return chiSquared;
1004 }
1005 
1006 void
1008 {
1009  NS_LOG_FUNCTION (this);
1010  SetTestSuiteSeed ();
1011 
1012  auto generator = RngGenerator<ParetoRandomVariable> ();
1013  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1014  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1015  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1016 
1017  double shape = 2.0;
1018  double scale = 1.0;
1019 
1020  // Create the RNG with the specified range.
1021  Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
1022  x->SetAttribute ("Shape", DoubleValue (shape));
1023  x->SetAttribute ("Scale", DoubleValue (scale));
1024 
1025  // Calculate the mean of these values.
1026  double valueMean = Average (x);
1027 
1028  // The expected value for the mean is given by
1029  //
1030  // shape * scale
1031  // E[value] = --------------- ,
1032  // shape - 1
1033  //
1034  // where
1035  //
1036  // scale = mean * (shape - 1.0) / shape .
1037  double expectedMean = (shape * scale) / (shape - 1.0);
1038 
1039  // Test that values have approximately the right mean value.
1040  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1041 }
1042 
1047 {
1048 public:
1049  // Constructor
1051 
1052  // Inherited
1054 
1055 private:
1056  // Inherited
1057  virtual void DoRun (void);
1058 
1063  static constexpr double TOLERANCE {1e-2};
1064 };
1065 
1067  : TestCaseBase ("Antithetic Pareto Random Variable Stream Generator")
1068 {}
1069 
1070 double
1072 {
1073  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1074  auto range = UniformHistogramBins (h, 1, 10, false);
1075 
1076  std::vector<double> expected (N_BINS);
1077 
1078  double shape = 2.0;
1079  double scale = 1.0;
1080 
1081  for (std::size_t i = 0; i < N_BINS; ++i)
1082  {
1083  expected[i] = gsl_cdf_pareto_P (range[i + 1], shape, scale) - gsl_cdf_pareto_P (range[i], shape, scale);
1084  expected[i] *= N_MEASUREMENTS;
1085  }
1086 
1087  double chiSquared = ChiSquared (h, expected, rng);
1088 
1089  gsl_histogram_free (h);
1090  return chiSquared;
1091 }
1092 
1093 void
1095 {
1096  NS_LOG_FUNCTION (this);
1097  SetTestSuiteSeed ();
1098 
1099  auto generator = RngGenerator<ParetoRandomVariable> (true);
1100  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1101  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1102  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1103 
1104  double shape = 2.0;
1105  double scale = 1.0;
1106 
1107  // Create the RNG with the specified range.
1108  Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
1109  x->SetAttribute ("Shape", DoubleValue (shape));
1110  x->SetAttribute ("Scale", DoubleValue (scale));
1111 
1112  // Make this generate antithetic values.
1113  x->SetAttribute ("Antithetic", BooleanValue (true));
1114 
1115  // Calculate the mean of these values.
1116  double valueMean = Average (x);
1117 
1118  // The expected value for the mean is given by
1119  //
1120  // shape * scale
1121  // E[value] = --------------- ,
1122  // shape - 1
1123  //
1124  // where
1125  //
1126  // scale = mean * (shape - 1.0) / shape .
1127  //
1128  double expectedMean = (shape * scale) / (shape - 1.0);
1129 
1130  // Test that values have approximately the right mean value.
1131  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1132 }
1133 
1138 {
1139 public:
1140  // Constructor
1141  WeibullTestCase ();
1142 
1143  // Inherited
1145 
1146 private:
1147  // Inherited
1148  virtual void DoRun (void);
1149 
1154  static constexpr double TOLERANCE {1e-2};
1155 };
1156 
1158  : TestCaseBase ("Weibull Random Variable Stream Generator")
1159 {}
1160 
1161 double
1163 {
1164  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1165  auto range = UniformHistogramBins (h, 1, 10, false);
1166 
1167  std::vector<double> expected (N_BINS);
1168 
1169  // Note that this assumes that p has shape equal to one and scale
1170  // equal to one, which are their default values for this
1171  // distribution.
1172  double a = 1.0;
1173  double b = 1.0;
1174 
1175  for (std::size_t i = 0; i < N_BINS; ++i)
1176  {
1177  expected[i] = gsl_cdf_weibull_P (range[i + 1], a, b) - gsl_cdf_weibull_P (range[i], a, b);
1178  expected[i] *= N_MEASUREMENTS;
1179  NS_LOG_INFO ("weibull: " << expected[i]);
1180  }
1181 
1182  double chiSquared = ChiSquared (h, expected, rng);
1183 
1184  gsl_histogram_free (h);
1185  return chiSquared;
1186 }
1187 
1188 void
1190 {
1191  NS_LOG_FUNCTION (this);
1192  SetTestSuiteSeed ();
1193 
1194  auto generator = RngGenerator<WeibullRandomVariable> ();
1195  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1196  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1197  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1198 
1199  double scale = 5.0;
1200  double shape = 1.0;
1201 
1202  // Create the RNG with the specified range.
1203  Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> ();
1204  x->SetAttribute ("Scale", DoubleValue (scale));
1205  x->SetAttribute ("Shape", DoubleValue (shape));
1206 
1207  // Calculate the mean of these values.
1208  double valueMean = Average (x);
1209 
1210  // The expected value for the mean of the values returned by a
1211  // Weibull distributed random variable is
1212  //
1213  // E[value] = scale * Gamma(1 + 1 / shape) ,
1214  //
1215  // where Gamma() is the Gamma function. Note that
1216  //
1217  // Gamma(n) = (n - 1)!
1218  //
1219  // if n is a positive integer.
1220  //
1221  // For this test,
1222  //
1223  // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1224  // = Gamma(2)
1225  // = (2 - 1)!
1226  // = 1
1227  //
1228  // which means
1229  //
1230  // E[value] = scale .
1231  //
1232  double expectedMean = scale;
1233 
1234  // Test that values have approximately the right mean value.
1235  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1236 }
1237 
1242 {
1243 public:
1244  // Constructor
1246 
1247  // Inherited
1249 
1250 private:
1251  // Inherited
1252  virtual void DoRun (void);
1253 
1258  static constexpr double TOLERANCE {1e-2};
1259 };
1260 
1262  : TestCaseBase ("Antithetic Weibull Random Variable Stream Generator")
1263 {}
1264 
1265 double
1267 {
1268  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1269  auto range = UniformHistogramBins (h, 1, 10, false);
1270 
1271  std::vector<double> expected (N_BINS);
1272 
1273  // Note that this assumes that p has shape equal to one and scale
1274  // equal to one, which are their default values for this
1275  // distribution.
1276  double a = 1.0;
1277  double b = 1.0;
1278 
1279  for (std::size_t i = 0; i < N_BINS; ++i)
1280  {
1281  expected[i] = gsl_cdf_weibull_P (range[i + 1], a, b) - gsl_cdf_weibull_P (range[i], a, b);
1282  expected[i] *= N_MEASUREMENTS;
1283  }
1284 
1285  double chiSquared = ChiSquared (h, expected, rng);
1286 
1287  gsl_histogram_free (h);
1288  return chiSquared;
1289 }
1290 
1291 void
1293 {
1294  NS_LOG_FUNCTION (this);
1295  SetTestSuiteSeed ();
1296 
1297  auto generator = RngGenerator<WeibullRandomVariable> (true);
1298  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1299  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1300  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1301 
1302  double scale = 5.0;
1303  double shape = 1.0;
1304 
1305  // Create the RNG with the specified range.
1306  Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> ();
1307  x->SetAttribute ("Scale", DoubleValue (scale));
1308  x->SetAttribute ("Shape", DoubleValue (shape));
1309 
1310  // Make this generate antithetic values.
1311  x->SetAttribute ("Antithetic", BooleanValue (true));
1312 
1313  // Calculate the mean of these values.
1314  double valueMean = Average (x);
1315 
1316  // The expected value for the mean of the values returned by a
1317  // Weibull distributed random variable is
1318  //
1319  // E[value] = scale * Gamma(1 + 1 / shape) ,
1320  //
1321  // where Gamma() is the Gamma function. Note that
1322  //
1323  // Gamma(n) = (n - 1)!
1324  //
1325  // if n is a positive integer.
1326  //
1327  // For this test,
1328  //
1329  // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1330  // = Gamma(2)
1331  // = (2 - 1)!
1332  // = 1
1333  //
1334  // which means
1335  //
1336  // E[value] = scale .
1337  //
1338  double expectedMean = scale;
1339 
1340  // Test that values have approximately the right mean value.
1341  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1342 }
1343 
1348 {
1349 public:
1350  // Constructor
1351  LogNormalTestCase ();
1352 
1353  // Inherited
1355 
1356 private:
1357  // Inherited
1358  virtual void DoRun (void);
1359 
1364  static constexpr double TOLERANCE {3e-2};
1365 };
1366 
1368  : TestCaseBase ("Log-Normal Random Variable Stream Generator")
1369 {}
1370 
1371 double
1373 {
1374  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1375  auto range = UniformHistogramBins (h, 0, 10, false);
1376 
1377  std::vector<double> expected (N_BINS);
1378 
1379  // Note that this assumes that n has mu equal to zero and sigma
1380  // equal to one, which are their default values for this
1381  // distribution.
1382  double mu = 0.0;
1383  double sigma = 1.0;
1384 
1385  for (std::size_t i = 0; i < N_BINS; ++i)
1386  {
1387  expected[i] = gsl_cdf_lognormal_P (range[i + 1], mu, sigma) - gsl_cdf_lognormal_P (range[i], mu, sigma);
1388  expected[i] *= N_MEASUREMENTS;
1389  }
1390 
1391  double chiSquared = ChiSquared (h, expected, rng);
1392 
1393  gsl_histogram_free (h);
1394  return chiSquared;
1395 }
1396 
1397 void
1399 {
1400  NS_LOG_FUNCTION (this);
1401  SetTestSuiteSeed ();
1402 
1403  auto generator = RngGenerator<LogNormalRandomVariable> ();
1404  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1405  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1406 
1407  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1408 
1409  double mu = 5.0;
1410  double sigma = 2.0;
1411 
1412  // Create the RNG with the specified range.
1413  Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> ();
1414  x->SetAttribute ("Mu", DoubleValue (mu));
1415  x->SetAttribute ("Sigma", DoubleValue (sigma));
1416 
1417  // Calculate the mean of these values.
1418  double valueMean = Average (x);
1419 
1420  // The expected value for the mean of the values returned by a
1421  // log-normally distributed random variable is equal to
1422  //
1423  // 2
1424  // mu + sigma / 2
1425  // E[value] = e .
1426  //
1427  double expectedMean = std::exp (mu + sigma * sigma / 2.0);
1428 
1429  // Test that values have approximately the right mean value.
1430  //
1437  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1438 }
1439 
1444 {
1445 public:
1446  // Constructor
1448 
1449  // Inherited
1451 
1452 private:
1453  // Inherited
1454  virtual void DoRun (void);
1455 
1460  static constexpr double TOLERANCE {3e-2};
1461 };
1462 
1464  : TestCaseBase ("Antithetic Log-Normal Random Variable Stream Generator")
1465 {}
1466 
1467 double
1469 {
1470  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1471  auto range = UniformHistogramBins (h, 0, 10, false);
1472 
1473  std::vector<double> expected (N_BINS);
1474 
1475  // Note that this assumes that n has mu equal to zero and sigma
1476  // equal to one, which are their default values for this
1477  // distribution.
1478  double mu = 0.0;
1479  double sigma = 1.0;
1480 
1481  for (std::size_t i = 0; i < N_BINS; ++i)
1482  {
1483  expected[i] = gsl_cdf_lognormal_P (range[i + 1], mu, sigma) - gsl_cdf_lognormal_P (range[i], mu, sigma);
1484  expected[i] *= N_MEASUREMENTS;
1485  }
1486 
1487  double chiSquared = ChiSquared (h, expected, rng);
1488 
1489  gsl_histogram_free (h);
1490  return chiSquared;
1491 }
1492 
1493 void
1495 {
1496  NS_LOG_FUNCTION (this);
1497  SetTestSuiteSeed ();
1498 
1499  auto generator = RngGenerator<LogNormalRandomVariable> (true);
1500  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1501  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1502  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1503 
1504  double mu = 5.0;
1505  double sigma = 2.0;
1506 
1507  // Create the RNG with the specified range.
1508  Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> ();
1509  x->SetAttribute ("Mu", DoubleValue (mu));
1510  x->SetAttribute ("Sigma", DoubleValue (sigma));
1511 
1512  // Make this generate antithetic values.
1513  x->SetAttribute ("Antithetic", BooleanValue (true));
1514 
1515  // Calculate the mean of these values.
1516  double valueMean = Average (x);
1517 
1518  // The expected value for the mean of the values returned by a
1519  // log-normally distributed random variable is equal to
1520  //
1521  // 2
1522  // mu + sigma / 2
1523  // E[value] = e .
1524  //
1525  double expectedMean = std::exp (mu + sigma * sigma / 2.0);
1526 
1527  // Test that values have approximately the right mean value.
1528  //
1535  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1536 }
1537 
1542 {
1543 public:
1544  // Constructor
1545  GammaTestCase ();
1546 
1547  // Inherited
1549 
1550 private:
1551  // Inherited
1552  virtual void DoRun (void);
1553 
1558  static constexpr double TOLERANCE {1e-2};
1559 };
1560 
1562  : TestCaseBase ("Gamma Random Variable Stream Generator")
1563 {}
1564 
1565 double
1567 {
1568  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1569  auto range = UniformHistogramBins (h, 0, 10, false);
1570 
1571  std::vector<double> expected (N_BINS);
1572 
1573  // Note that this assumes that n has alpha equal to one and beta
1574  // equal to one, which are their default values for this
1575  // distribution.
1576  double alpha = 1.0;
1577  double beta = 1.0;
1578 
1579  for (std::size_t i = 0; i < N_BINS; ++i)
1580  {
1581  expected[i] = gsl_cdf_gamma_P (range[i + 1], alpha, beta) - gsl_cdf_gamma_P (range[i], alpha, beta);
1582  expected[i] *= N_MEASUREMENTS;
1583  }
1584 
1585  double chiSquared = ChiSquared (h, expected, rng);
1586 
1587  gsl_histogram_free (h);
1588  return chiSquared;
1589 }
1590 
1591 void
1593 {
1594  NS_LOG_FUNCTION (this);
1595  SetTestSuiteSeed ();
1596 
1597  auto generator = RngGenerator<GammaRandomVariable> ();
1598  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1599  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1600  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1601 
1602  double alpha = 5.0;
1603  double beta = 2.0;
1604 
1605  // Create the RNG with the specified range.
1606  Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> ();
1607  x->SetAttribute ("Alpha", DoubleValue (alpha));
1608  x->SetAttribute ("Beta", DoubleValue (beta));
1609 
1610  // Calculate the mean of these values.
1611  double valueMean = Average (x);
1612 
1613  // The expected value for the mean of the values returned by a
1614  // gammaly distributed random variable is equal to
1615  //
1616  // E[value] = alpha * beta .
1617  //
1618  double expectedMean = alpha * beta;
1619 
1620  // Test that values have approximately the right mean value.
1621  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1622 }
1623 
1628 {
1629 public:
1630  // Constructor
1632 
1633  // Inherited
1635 
1636 private:
1637  // Inherited
1638  virtual void DoRun (void);
1639 
1644  static constexpr double TOLERANCE {1e-2};
1645 };
1646 
1648  : TestCaseBase ("Antithetic Gamma Random Variable Stream Generator")
1649 {}
1650 
1651 double
1653 {
1654  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1655  auto range = UniformHistogramBins (h, 0, 10, false);
1656 
1657  std::vector<double> expected (N_BINS);
1658 
1659  // Note that this assumes that n has alpha equal to one and beta
1660  // equal to one, which are their default values for this
1661  // distribution.
1662  double alpha = 1.0;
1663  double beta = 1.0;
1664 
1665  for (std::size_t i = 0; i < N_BINS; ++i)
1666  {
1667  expected[i] = gsl_cdf_gamma_P (range[i + 1], alpha, beta) - gsl_cdf_gamma_P (range[i], alpha, beta);
1668  expected[i] *= N_MEASUREMENTS;
1669  }
1670 
1671  double chiSquared = ChiSquared (h, expected, rng);
1672 
1673  gsl_histogram_free (h);
1674  return chiSquared;
1675 }
1676 
1677 void
1679 {
1680  NS_LOG_FUNCTION (this);
1681  SetTestSuiteSeed ();
1682 
1683  auto generator = RngGenerator<GammaRandomVariable> (true);
1684  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1685  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1686  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1687 
1688  double alpha = 5.0;
1689  double beta = 2.0;
1690 
1691  // Create the RNG with the specified range.
1692  Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> ();
1693 
1694  // Make this generate antithetic values.
1695  x->SetAttribute ("Antithetic", BooleanValue (true));
1696 
1697  x->SetAttribute ("Alpha", DoubleValue (alpha));
1698  x->SetAttribute ("Beta", DoubleValue (beta));
1699 
1700  // Calculate the mean of these values.
1701  double valueMean = Average (x);
1702 
1703  // The expected value for the mean of the values returned by a
1704  // gammaly distributed random variable is equal to
1705  //
1706  // E[value] = alpha * beta .
1707  //
1708  double expectedMean = alpha * beta;
1709 
1710  // Test that values have approximately the right mean value.
1711  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1712 }
1713 
1718 {
1719 public:
1720  // Constructor
1721  ErlangTestCase ();
1722 
1723  // Inherited
1725 
1726 private:
1727  // Inherited
1728  virtual void DoRun (void);
1729 
1734  static constexpr double TOLERANCE {1e-2};
1735 };
1736 
1738  : TestCaseBase ("Erlang Random Variable Stream Generator")
1739 {}
1740 
1741 double
1743 {
1744  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1745  auto range = UniformHistogramBins (h, 0, 10, false);
1746 
1747  std::vector<double> expected (N_BINS);
1748 
1749  // Note that this assumes that n has k equal to one and lambda
1750  // equal to one, which are their default values for this
1751  // distribution.
1752  uint32_t k = 1;
1753  double lambda = 1.0;
1754 
1755  // Note that Erlang distribution is equal to the gamma distribution
1756  // when k is an iteger, which is why the gamma distribution's cdf
1757  // function can be used here.
1758  for (std::size_t i = 0; i < N_BINS; ++i)
1759  {
1760  expected[i] = gsl_cdf_gamma_P (range[i + 1], k, lambda) - gsl_cdf_gamma_P (range[i], k, lambda);
1761  expected[i] *= N_MEASUREMENTS;
1762  }
1763 
1764  double chiSquared = ChiSquared (h, expected, rng);
1765 
1766  gsl_histogram_free (h);
1767  return chiSquared;
1768 }
1769 
1770 void
1772 {
1773  NS_LOG_FUNCTION (this);
1774  SetTestSuiteSeed ();
1775 
1776  auto generator = RngGenerator<ErlangRandomVariable> ();
1777  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1778  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1779  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1780 
1781  uint32_t k = 5;
1782  double lambda = 2.0;
1783 
1784  // Create the RNG with the specified range.
1785  Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> ();
1786  x->SetAttribute ("K", IntegerValue (k));
1787  x->SetAttribute ("Lambda", DoubleValue (lambda));
1788 
1789  // Calculate the mean of these values.
1790  double valueMean = Average (x);
1791 
1792  // The expected value for the mean of the values returned by a
1793  // Erlangly distributed random variable is equal to
1794  //
1795  // E[value] = k * lambda .
1796  //
1797  double expectedMean = k * lambda;
1798 
1799  // Test that values have approximately the right mean value.
1800  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1801 }
1802 
1807 {
1808 public:
1809  // Constructor
1811 
1812  // Inherited
1814 
1815 private:
1816  // Inherited
1817  virtual void DoRun (void);
1818 
1823  static constexpr double TOLERANCE {1e-2};
1824 };
1825 
1827  : TestCaseBase ("Antithetic Erlang Random Variable Stream Generator")
1828 {}
1829 
1830 double
1832 {
1833  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1834  auto range = UniformHistogramBins (h, 0, 10, false);
1835 
1836  std::vector<double> expected (N_BINS);
1837 
1838  // Note that this assumes that n has k equal to one and lambda
1839  // equal to one, which are their default values for this
1840  // distribution.
1841  uint32_t k = 1;
1842  double lambda = 1.0;
1843 
1844  // Note that Erlang distribution is equal to the gamma distribution
1845  // when k is an iteger, which is why the gamma distribution's cdf
1846  // function can be used here.
1847  for (std::size_t i = 0; i < N_BINS; ++i)
1848  {
1849  expected[i] = gsl_cdf_gamma_P (range[i + 1], k, lambda) - gsl_cdf_gamma_P (range[i], k, lambda);
1850  expected[i] *= N_MEASUREMENTS;
1851  }
1852 
1853  double chiSquared = ChiSquared (h, expected, rng);
1854 
1855  gsl_histogram_free (h);
1856  return chiSquared;
1857 }
1858 
1859 void
1861 {
1862  NS_LOG_FUNCTION (this);
1863  SetTestSuiteSeed ();
1864 
1865  auto generator = RngGenerator<ErlangRandomVariable> (true);
1866  double sum = ChiSquaredsAverage (&generator, N_RUNS);
1867  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1868  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1869 
1870  uint32_t k = 5;
1871  double lambda = 2.0;
1872 
1873  // Create the RNG with the specified range.
1874  Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> ();
1875 
1876  // Make this generate antithetic values.
1877  x->SetAttribute ("Antithetic", BooleanValue (true));
1878 
1879  x->SetAttribute ("K", IntegerValue (k));
1880  x->SetAttribute ("Lambda", DoubleValue (lambda));
1881 
1882  // Calculate the mean of these values.
1883  double valueMean = Average (x);
1884 
1885  // The expected value for the mean of the values returned by a
1886  // Erlangly distributed random variable is equal to
1887  //
1888  // E[value] = k * lambda .
1889  //
1890  double expectedMean = k * lambda;
1891 
1892  // Test that values have approximately the right mean value.
1893  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1894 }
1895 
1900 {
1901 public:
1902  // Constructor
1903  ZipfTestCase ();
1904 
1905 private:
1906  // Inherited
1907  virtual void DoRun (void);
1908 
1913  static constexpr double TOLERANCE {1e-2};
1914 };
1915 
1917  : TestCaseBase ("Zipf Random Variable Stream Generator")
1918 {}
1919 
1920 void
1922 {
1923  NS_LOG_FUNCTION (this);
1924  SetTestSuiteSeed ();
1925 
1926  uint32_t n = 1;
1927  double alpha = 2.0;
1928 
1929  // Create the RNG with the specified range.
1930  Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> ();
1931  x->SetAttribute ("N", IntegerValue (n));
1932  x->SetAttribute ("Alpha", DoubleValue (alpha));
1933 
1934  // Calculate the mean of these values.
1935  double valueMean = Average (x);
1936 
1937  // The expected value for the mean of the values returned by a
1938  // Zipfly distributed random variable is equal to
1939  //
1940  // H
1941  // N, alpha - 1
1942  // E[value] = ---------------
1943  // H
1944  // N, alpha
1945  //
1946  // where
1947  //
1948  // N
1949  // ---
1950  // \ -alpha
1951  // H = / m .
1952  // N, alpha ---
1953  // m=1
1954  //
1955  // For this test,
1956  //
1957  // -(alpha - 1)
1958  // 1
1959  // E[value] = ---------------
1960  // -alpha
1961  // 1
1962  //
1963  // = 1 .
1964  //
1965  double expectedMean = 1.0;
1966 
1967  // Test that values have approximately the right mean value.
1968  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
1969 }
1970 
1975 {
1976 public:
1977  // Constructor
1979 
1980 private:
1981  // Inherited
1982  virtual void DoRun (void);
1983 
1988  static constexpr double TOLERANCE {1e-2};
1989 };
1990 
1992  : TestCaseBase ("Antithetic Zipf Random Variable Stream Generator")
1993 {}
1994 
1995 void
1997 {
1998  NS_LOG_FUNCTION (this);
1999  SetTestSuiteSeed ();
2000 
2001  uint32_t n = 1;
2002  double alpha = 2.0;
2003 
2004  // Create the RNG with the specified range.
2005  Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> ();
2006  x->SetAttribute ("N", IntegerValue (n));
2007  x->SetAttribute ("Alpha", DoubleValue (alpha));
2008 
2009  // Make this generate antithetic values.
2010  x->SetAttribute ("Antithetic", BooleanValue (true));
2011 
2012  // Calculate the mean of these values.
2013  double valueMean = Average (x);
2014 
2015  // The expected value for the mean of the values returned by a
2016  // Zipfly distributed random variable is equal to
2017  //
2018  // H
2019  // N, alpha - 1
2020  // E[value] = ---------------
2021  // H
2022  // N, alpha
2023  //
2024  // where
2025  //
2026  // N
2027  // ---
2028  // \ -alpha
2029  // H = / m .
2030  // N, alpha ---
2031  // m=1
2032  //
2033  // For this test,
2034  //
2035  // -(alpha - 1)
2036  // 1
2037  // E[value] = ---------------
2038  // -alpha
2039  // 1
2040  //
2041  // = 1 .
2042  //
2043  double expectedMean = 1.0;
2044 
2045  // Test that values have approximately the right mean value.
2046  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2047 }
2048 
2053 {
2054 public:
2055  // Constructor
2056  ZetaTestCase ();
2057 
2058 private:
2059  // Inherited
2060  virtual void DoRun (void);
2061 
2066  static constexpr double TOLERANCE {1e-2};
2067 };
2068 
2070  : TestCaseBase ("Zeta Random Variable Stream Generator")
2071 {}
2072 
2073 void
2075 {
2076  NS_LOG_FUNCTION (this);
2077  SetTestSuiteSeed ();
2078 
2079  double alpha = 5.0;
2080 
2081  // Create the RNG with the specified range.
2082  Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> ();
2083  x->SetAttribute ("Alpha", DoubleValue (alpha));
2084 
2085  // Calculate the mean of these values.
2086  double valueMean = Average (x);
2087 
2088  // The expected value for the mean of the values returned by a
2089  // zetaly distributed random variable is equal to
2090  //
2091  // zeta(alpha - 1)
2092  // E[value] = --------------- for alpha > 2 ,
2093  // zeta(alpha)
2094  //
2095  // where zeta(alpha) is the Riemann zeta function.
2096  //
2097  // There are no simple analytic forms for the Riemann zeta function,
2098  // which is why the gsl library is used in this test to calculate
2099  // the known mean of the values.
2100  double expectedMean =
2101  gsl_sf_zeta_int (static_cast<int> (alpha - 1)) /
2102  gsl_sf_zeta_int (static_cast<int> (alpha) );
2103 
2104  // Test that values have approximately the right mean value.
2105  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2106 }
2107 
2112 {
2113 public:
2114  // Constructor
2116 
2117 private:
2118  // Inherited
2119  virtual void DoRun (void);
2120 
2125  static constexpr double TOLERANCE {1e-2};
2126 };
2127 
2129  : TestCaseBase ("Antithetic Zeta Random Variable Stream Generator")
2130 {}
2131 
2132 void
2134 {
2135  NS_LOG_FUNCTION (this);
2136  SetTestSuiteSeed ();
2137 
2138  double alpha = 5.0;
2139 
2140  // Create the RNG with the specified range.
2141  Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> ();
2142  x->SetAttribute ("Alpha", DoubleValue (alpha));
2143 
2144  // Make this generate antithetic values.
2145  x->SetAttribute ("Antithetic", BooleanValue (true));
2146 
2147  // Calculate the mean of these values.
2148  double valueMean = Average (x);
2149 
2150  // The expected value for the mean of the values returned by a
2151  // zetaly distributed random variable is equal to
2152  //
2153  // zeta(alpha - 1)
2154  // E[value] = --------------- for alpha > 2 ,
2155  // zeta(alpha)
2156  //
2157  // where zeta(alpha) is the Riemann zeta function.
2158  //
2159  // There are no simple analytic forms for the Riemann zeta function,
2160  // which is why the gsl library is used in this test to calculate
2161  // the known mean of the values.
2162  double expectedMean =
2163  gsl_sf_zeta_int (static_cast<int> (alpha) - 1) /
2164  gsl_sf_zeta_int (static_cast<int> (alpha) );
2165 
2166  // Test that values have approximately the right mean value.
2167  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2168 }
2169 
2174 {
2175 public:
2176  // Constructor
2178 
2179 private:
2180  // Inherited
2181  virtual void DoRun (void);
2182 
2184  static constexpr double TOLERANCE {1e-8};
2185 };
2186 
2188  : TestCaseBase ("Deterministic Random Variable Stream Generator")
2189 {}
2190 
2191 void
2193 {
2194  NS_LOG_FUNCTION (this);
2195  SetTestSuiteSeed ();
2196 
2197  Ptr<DeterministicRandomVariable> s = CreateObject<DeterministicRandomVariable> ();
2198 
2199  // The following array should give the sequence
2200  //
2201  // 4, 4, 7, 7, 10, 10 .
2202  //
2203  double array1 [] = { 4, 4, 7, 7, 10, 10};
2204  std::size_t count1 = 6;
2205  s->SetValueArray (array1, count1);
2206 
2207  double value;
2208 
2209  // Test that the first sequence is correct.
2210  value = s->GetValue ();
2211  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence 1 value 1 wrong.");
2212  value = s->GetValue ();
2213  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence 1 value 2 wrong.");
2214  value = s->GetValue ();
2215  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence 1 value 3 wrong.");
2216  value = s->GetValue ();
2217  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence 1 value 4 wrong.");
2218  value = s->GetValue ();
2219  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence 1 value 5 wrong.");
2220  value = s->GetValue ();
2221  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence 1 value 6 wrong.");
2222 
2223  // The following array should give the sequence
2224  //
2225  // 1000, 2000, 7, 7 .
2226  //
2227  double array2 [] = { 1000, 2000, 3000, 4000};
2228  std::size_t count2 = 4;
2229  s->SetValueArray (array2, count2);
2230 
2231  // Test that the second sequence is correct.
2232  value = s->GetValue ();
2233  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1000, TOLERANCE, "Sequence 2 value 1 wrong.");
2234  value = s->GetValue ();
2235  NS_TEST_ASSERT_MSG_EQ_TOL (value, 2000, TOLERANCE, "Sequence 2 value 2 wrong.");
2236  value = s->GetValue ();
2237  NS_TEST_ASSERT_MSG_EQ_TOL (value, 3000, TOLERANCE, "Sequence 2 value 3 wrong.");
2238  value = s->GetValue ();
2239  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4000, TOLERANCE, "Sequence 2 value 4 wrong.");
2240  value = s->GetValue ();
2241 }
2242 
2247 {
2248 public:
2249  // Constructor
2250  EmpiricalTestCase ();
2251 
2252 private:
2253  // Inherited
2254  virtual void DoRun (void);
2255 
2260  static constexpr double TOLERANCE {1e-2};
2261 };
2262 
2264  : TestCaseBase ("Empirical Random Variable Stream Generator")
2265 {}
2266 
2267 void
2269 {
2270  NS_LOG_FUNCTION (this);
2271  SetTestSuiteSeed ();
2272 
2273  // Create the RNG with a uniform distribution between 0 and 10.
2274  Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> ();
2275  x->SetInterpolate (false);
2276  x->CDF ( 0.0, 0.0);
2277  x->CDF ( 5.0, 0.25);
2278  x->CDF (10.0, 1.0);
2279 
2280  // Check that only the correct values are returned
2281  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2282  {
2283  double value = x->GetValue ();
2284  NS_TEST_EXPECT_MSG_EQ ( (value == 5) || (value == 10), true,
2285  "Incorrect value returned, expected only 5 or 10.");
2286  }
2287 
2288  // Calculate the mean of the sampled values.
2289  double valueMean = Average (x);
2290 
2291  // The expected distribution with sampled values is
2292  // Value Probability
2293  // 5 25%
2294  // 10 75%
2295  //
2296  // The expected mean is
2297  //
2298  // E[value] = 5 * 25% + 10 * 75% = 8.75
2299  //
2300  // Test that values have approximately the right mean value.
2301  double expectedMean = 8.75;
2302  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2303 
2304 
2305  // Calculate the mean of the interpolated values.
2306  x->SetInterpolate (true);
2307  valueMean = Average (x);
2308 
2309  // The expected distribution (with interpolation) is
2310  // Bin Probability
2311  // [0, 5) 25%
2312  // [5, 10) 75%
2313  //
2314  // Each bin is uniformly sampled, so the average of the samples in the
2315  // bin is the center of the bin.
2316  //
2317  // The expected mean is
2318  //
2319  // E[value] = 2.5 * 25% + 7.5 * 75% = 6.25
2320  //
2321  expectedMean = 6.25;
2322 
2323  // Test that values have approximately the right mean value.
2324  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2325 
2326  // Bug 2082: Create the RNG with a uniform distribution between -1 and 1.
2327  Ptr<EmpiricalRandomVariable> y = CreateObject<EmpiricalRandomVariable> ();
2328  y->SetInterpolate (false);
2329  y->CDF (-1.0, 0.0);
2330  y->CDF (0.0, 0.5);
2331  y->CDF (1.0, 1.0);
2332  NS_TEST_ASSERT_MSG_LT (y->GetValue (), 2, "Empirical variable with negative domain");
2333 }
2334 
2339 {
2340 public:
2341  // Constructor
2343 
2344 private:
2345  // Inherited
2346  virtual void DoRun (void);
2347 
2352  static constexpr double TOLERANCE {1e-2};
2353 };
2354 
2356  : TestCaseBase ("EmpiricalAntithetic Random Variable Stream Generator")
2357 {}
2358 
2359 void
2361 {
2362  NS_LOG_FUNCTION (this);
2363  SetTestSuiteSeed ();
2364 
2365  // Create the RNG with a uniform distribution between 0 and 10.
2366  Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> ();
2367  x->SetInterpolate (false);
2368  x->CDF ( 0.0, 0.0);
2369  x->CDF ( 5.0, 0.25);
2370  x->CDF (10.0, 1.0);
2371 
2372  // Make this generate antithetic values.
2373  x->SetAttribute ("Antithetic", BooleanValue (true));
2374 
2375  // Check that only the correct values are returned
2376  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2377  {
2378  double value = x->GetValue ();
2379  NS_TEST_EXPECT_MSG_EQ ( (value == 5) || (value == 10), true,
2380  "Incorrect value returned, expected only 5 or 10.");
2381  }
2382 
2383  // Calculate the mean of these values.
2384  double valueMean = Average (x);
2385  // Expected
2386  // E[value] = 5 * 25% + 10 * 75% = 8.75
2387  double expectedMean = 8.75;
2388  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2389 
2390  // Check interpolated sampling
2391  x->SetInterpolate (true);
2392  valueMean = Average (x);
2393 
2394  // The expected value for the mean of the values returned by this
2395  // empirical distribution with interpolation is
2396  //
2397  // E[value] = 2.5 * 25% + 7.5 * 75% = 6.25
2398  //
2399  expectedMean = 6.25;
2400 
2401  // Test that values have approximately the right mean value.
2402  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, expectedMean * TOLERANCE, "Wrong mean value.");
2403 }
2404 
2410 {
2411 public:
2412  // Constructor
2414 };
2415 
2417  : TestSuite ("random-variable-stream-generators", UNIT)
2418 {
2435  /*
2436  AddTestCase (new LogNormalAntitheticTestCase);
2437  */
2438  AddTestCase (new GammaTestCase);
2442  /*
2443  AddTestCase (new GammaAntitheticTestCase);
2444  */
2447  AddTestCase (new ZipfTestCase);
2449  AddTestCase (new ZetaTestCase);
2454 }
2455 
2457 
2458 } // namespace RandomVariable
2459 
2460 } // namespace test
2461 
2462 } // namespace ns3
2463 
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.
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
A factory base class to create new instances of a random variable.
virtual double GetValue(void)
Returns the next value in the empirical distribution.
double GetValue(double constant)
Get the next random value, as a double equal to the argument.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Test case for Weibull distribution random variable stream generator.
Test case for antithetic log-normal distribution random variable stream generator.
static const uint32_t N_BINS
Number of bins for sampling the distributions.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
virtual 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.
double Average(Ptr< RandomVariableStream > rng) const
Compute the average of a random variable.
Test case for constant random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, in rms.
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
Hold variables of type string.
Definition: string.h:41
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
A suite of tests to run.
Definition: test.h:1343
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
def start()
Definition: core.py:1855
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.
Base class for RandomVariableStream test suites.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Hold a signed integer type.
Definition: integer.h:44
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
bool m_seedSet
true if we&#39;ve already set the seed the correctly.
#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:283
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
encapsulates test code
Definition: test.h:1153
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for gamma distribution random variable stream generator.
static uint64_t GetRun(void)
Get the current run number.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
void SetValueArray(double *values, std::size_t length)
Sets the array of values that holds the predetermined sequence.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
Test case for normal distribution random variable stream generator.
Test case for Erlang distribution random variable stream generator.
virtual double GetValue(void)
Get the next random value as a double drawn from the distribution.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
#define max(a, b)
Definition: 80211b.c:43
virtual double GetValue(void)
Returns the next value in the sequence.
Test case for antithetic empirical distribution random variable stream generator. ...
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Factory class to create new instances of a particular random variable stream.
#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:166
void CDF(double v, double c)
Specifies a point in the empirical distribution.
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.
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.
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.
#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:378
Test case for log-normal distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
Test case for antithetic uniform distribution random variable stream generator.
bool SetInterpolate(bool interpolate)
Switch the mode between sampling the CDF and interpolating.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Test case for deterministic random variable stream generator.
static RandomVariableSuite randomVariableSuite
Test case for antithetic gamma distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
virtual Ptr< RandomVariableStream > Create(void) const =0
Create a new instance of a random variable stream.
Test case for sequential random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
Test case for uniform distribution random variable stream generator.
Test case for Zipf 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.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
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 empirical distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static uint32_t GetSeed(void)
Get the current seed value which will be used by all subsequently instantiated RandomVariableStream o...
void SetTestSuiteSeed(void)
Set the seed used for this test suite.
Test case for antithetic Pareto distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
static void SetSeed(uint32_t seed)
Set the seed.
double max(double x, double y)
static const uint32_t N_MEASUREMENTS
Number of samples to draw when populating the distributions.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const
Compute the chi square value from a random variable.
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.
Test case for antithetic normal distribution random variable stream generator.
#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:622
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 Zeta distribution random variable stream generator.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Test case for antithetic Weibull distribution random variable stream generator.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
RandomVariableStream test suite, covering all random number variable stream generator types...
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.
Ptr< RandomVariableStream > Create(void) const
Create a new instance of a random variable stream.
double min(double x, double y)
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...
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
static const uint32_t N_RUNS
Number of retry attempts to pass a chi-square test.
Test case for antithetic exponential distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
bool m_anti
Whether to create antithetic random variable streams.
#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:995
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
Test case for exponential distribution random variable stream generator.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
Test case for antithetic Zeta distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
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.
Test case for Pareto distribution random variable stream generator.
#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:809