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
41using namespace ns3;
42
43NS_LOG_COMPONENT_DEFINE ("RandomVariableStreamGenerators");
44
45namespace ns3 {
46
47namespace test {
48
49namespace RandomVariable {
50
61class TestCaseBase : public TestCase
62{
63public:
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 {
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 }
338 }
339 }
340
341private:
343 bool m_seedSet = false;
344
345}; // class TestCaseBase
346
347
353{
354public:
355
356 // Constructor
358
359 // Inherited
360 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
361
362private:
363 // Inherited
364 virtual void DoRun (void);
365};
366
368 : TestCaseBase ("Uniform Random Variable Stream Generator")
369{}
370
371double
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
387void
389{
390 NS_LOG_FUNCTION (this);
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> ();
402 result = ChiSquaredTest (rng);
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{
476public:
477
478 // Constructor
480
481 // Inherited
482 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
483
484private:
485 // Inherited
486 virtual void DoRun (void);
487};
488
490 : TestCaseBase ("Antithetic Uniform Random Variable Stream Generator")
491{}
492
493double
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
509void
511{
512 NS_LOG_FUNCTION (this);
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{
552public:
553 // Constructor
555
556private:
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
568void
570{
571 NS_LOG_FUNCTION (this);
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{
599public:
600 // Constructor
602
603private:
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
615void
617{
618 NS_LOG_FUNCTION (this);
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{
656public:
657 // Constructor
659
660 // Inherited
661 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
662
663private:
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
675double
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
699void
701{
702 NS_LOG_FUNCTION (this);
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{
738public:
739 // Constructor
741
742 // Inherited
743 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
744
745private:
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
757double
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
782void
784{
785 NS_LOG_FUNCTION (this);
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{
822public:
823 // Constructor
825
826 // Inherited
827 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
828
829private:
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
841double
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
865void
867{
868 NS_LOG_FUNCTION (this);
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{
899public:
900 // Constructor
902
903 // Inherited
904 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
905
906private:
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
918double
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
942void
944{
945 NS_LOG_FUNCTION (this);
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{
979public:
980 // Constructor
982
983 // Inherited
984 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
985
986private:
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
1001double
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
1024void
1026{
1027 NS_LOG_FUNCTION (this);
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{
1067public:
1068 // Constructor
1070
1071 // Inherited
1072 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1073
1074private:
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
1089double
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
1112void
1114{
1115 NS_LOG_FUNCTION (this);
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{
1159public:
1160 // Constructor
1161 WeibullTestCase ();
1162
1163 // Inherited
1164 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1165
1166private:
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
1181double
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
1208void
1210{
1211 NS_LOG_FUNCTION (this);
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{
1264public:
1265 // Constructor
1267
1268 // Inherited
1269 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1270
1271private:
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
1286double
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
1312void
1314{
1315 NS_LOG_FUNCTION (this);
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{
1371public:
1372 // Constructor
1374
1375 // Inherited
1376 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1377
1378private:
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
1393double
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
1419void
1421{
1422 NS_LOG_FUNCTION (this);
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{
1468public:
1469 // Constructor
1471
1472 // Inherited
1473 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1474
1475private:
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
1490double
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
1516void
1518{
1519 NS_LOG_FUNCTION (this);
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{
1567public:
1568 // Constructor
1569 GammaTestCase ();
1570
1571 // Inherited
1572 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1573
1574private:
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
1589double
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
1615void
1617{
1618 NS_LOG_FUNCTION (this);
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{
1654public:
1655 // Constructor
1657
1658 // Inherited
1659 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1660
1661private:
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
1676double
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
1702void
1704{
1705 NS_LOG_FUNCTION (this);
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{
1745public:
1746 // Constructor
1747 ErlangTestCase ();
1748
1749 // Inherited
1750 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1751
1752private:
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
1767double
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
1796void
1798{
1799 NS_LOG_FUNCTION (this);
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{
1835public:
1836 // Constructor
1838
1839 // Inherited
1840 double ChiSquaredTest (Ptr<RandomVariableStream> rng) const;
1841
1842private:
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
1857double
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
1886void
1888{
1889 NS_LOG_FUNCTION (this);
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{
1929public:
1930 // Constructor
1931 ZipfTestCase ();
1932
1933private:
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
1948void
1950{
1951 NS_LOG_FUNCTION (this);
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{
2005public:
2006 // Constructor
2008
2009private:
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
2024void
2026{
2027 NS_LOG_FUNCTION (this);
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{
2084public:
2085 // Constructor
2086 ZetaTestCase ();
2087
2088private:
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
2103void
2105{
2106 NS_LOG_FUNCTION (this);
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{
2144public:
2145 // Constructor
2147
2148private:
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
2163void
2165{
2166 NS_LOG_FUNCTION (this);
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{
2207public:
2208 // Constructor
2210
2211private:
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
2223void
2225{
2226 NS_LOG_FUNCTION (this);
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{
2281public:
2282 // Constructor
2284
2285private:
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
2300void
2302{
2303 NS_LOG_FUNCTION (this);
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{
2374public:
2375 // Constructor
2377
2378private:
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
2393void
2395{
2396 NS_LOG_FUNCTION (this);
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{
2445public:
2446 // Constructor
2448
2449private:
2450 // Inherited
2451 virtual void DoRun (void);
2452};
2453
2455 : TestCaseBase ("NormalRandomVariable caching of parameters")
2456{}
2457
2458void
2460{
2461 NS_LOG_FUNCTION (this);
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{
2479public:
2480 // Constructor
2482};
2483
2485 : TestSuite ("random-variable-stream-generators", UNIT)
2486{
2503 /*
2504 AddTestCase (new LogNormalAntitheticTestCase);
2505 */
2510 /*
2511 AddTestCase (new GammaAntitheticTestCase);
2512 */
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
virtual double GetValue(void)=0
Get the next random value as a double drawn from the distribution.
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
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value, as an unsigned integer in the specified range .
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...
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.
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.
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.
def start()
Definition: core.py:1852