A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
random-variable-stream-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009-12 University of Washington
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * This file is based on rng-test-suite.cc.
18 *
19 * Modified by Mitch Watrous <watrous@u.washington.edu>
20 *
21 */
22
23#include "ns3/boolean.h"
24#include "ns3/double.h"
25#include "ns3/integer.h"
26#include "ns3/log.h"
27#include "ns3/random-variable-stream.h"
28#include "ns3/rng-seed-manager.h"
29#include "ns3/string.h"
30#include "ns3/test.h"
31
32#include <cmath>
33#include <ctime>
34#include <fstream>
35#include <gsl/gsl_cdf.h>
36#include <gsl/gsl_histogram.h>
37#include <gsl/gsl_sf_zeta.h>
38
39using namespace ns3;
40
41NS_LOG_COMPONENT_DEFINE("RandomVariableStreamGenerators");
42
43namespace ns3
44{
45
46namespace test
47{
48
49namespace RandomVariable
50{
51
62class TestCaseBase : public TestCase
63{
64 public:
66 static const uint32_t N_BINS{50};
68 static const uint32_t N_MEASUREMENTS{1000000};
70 static const uint32_t N_RUNS{5};
71
76 TestCaseBase(std::string name)
77 : TestCase(name)
78 {
79 }
80
92 std::vector<double> UniformHistogramBins(gsl_histogram* h,
93 double start,
94 double end,
95 bool underflow = true,
96 bool overflow = true) const
97 {
98 NS_LOG_FUNCTION(this << h << start << end);
99 std::size_t nBins = gsl_histogram_bins(h);
100 double increment = (end - start) / (nBins - 1.);
101 double d = start;
102
103 std::vector<double> range(nBins + 1);
104
105 for (auto& r : range)
106 {
107 r = d;
108 d += increment;
109 }
110 if (underflow)
111 {
112 range[0] = -std::numeric_limits<double>::max();
113 }
114 if (overflow)
115 {
116 range[nBins] = std::numeric_limits<double>::max();
117 }
118
119 gsl_histogram_set_ranges(h, range.data(), nBins + 1);
120 return range;
121 }
122
129 {
130 NS_LOG_FUNCTION(this << rng);
131 double sum = 0.0;
132 for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
133 {
134 double value = rng->GetValue();
135 sum += value;
136 }
137 double valueMean = sum / N_MEASUREMENTS;
138 return valueMean;
139 }
140
143 {
144 public:
150 };
151
157 template <typename RNG>
159 {
160 public:
165 RngGenerator(bool anti = false)
166 : m_anti(anti)
167 {
168 }
169
170 // Inherited
172 {
173 auto rng = CreateObject<RNG>();
174 rng->SetAttribute("Antithetic", BooleanValue(m_anti));
175 return rng;
176 }
177
178 private:
180 bool m_anti;
181 };
182
198 double ChiSquared(gsl_histogram* h,
199 const std::vector<double>& expected,
201 {
202 NS_LOG_FUNCTION(this << h << expected.size() << rng);
203 NS_ASSERT_MSG(gsl_histogram_bins(h) == expected.size(),
204 "Histogram and expected vector have different sizes.");
205
206 // Sample the rng into the histogram
207 for (std::size_t i = 0; i < N_MEASUREMENTS; ++i)
208 {
209 double value = rng->GetValue();
210 gsl_histogram_increment(h, value);
211 }
212
213 // Compute the chi square value
214 double chiSquared = 0;
215 std::size_t nBins = gsl_histogram_bins(h);
216 for (std::size_t i = 0; i < nBins; ++i)
217 {
218 double hbin = gsl_histogram_get(h, i);
219 double tmp = hbin - expected[i];
220 tmp *= tmp;
221 tmp /= expected[i];
222 chiSquared += tmp;
223 }
224
225 return chiSquared;
226 }
227
259 {
260 return 0;
261 }
262
271 double ChiSquaredsAverage(const RngGeneratorBase* generator, std::size_t nRuns) const
272 {
273 NS_LOG_FUNCTION(this << generator << nRuns);
274
275 double sum = 0.;
276 for (std::size_t i = 0; i < nRuns; ++i)
277 {
278 auto rng = generator->Create();
279 double result = ChiSquaredTest(rng);
280 sum += result;
281 }
282 sum /= (double)nRuns;
283 return sum;
284 }
285
318 {
319 if (m_seedSet == false)
320 {
321 uint32_t seed;
322 if (RngSeedManager::GetRun() == 0)
323 {
324 seed = static_cast<uint32_t>(time(nullptr));
325 m_seedSet = true;
327 "Special run number value of zero; seeding with time of day: " << seed);
328 }
329 else
330 {
332 m_seedSet = true;
333 NS_LOG_DEBUG("Using the values seed: " << seed
334 << " and run: " << RngSeedManager::GetRun());
335 }
337 }
338 }
339
340 private:
342 bool m_seedSet = false;
343
344}; // class TestCaseBase
345
351{
352 public:
353 // Constructor
355
356 // Inherited
357 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
358
359 private:
360 // Inherited
361 void DoRun() override;
362};
363
365 : TestCaseBase("Uniform Random Variable Stream Generator")
366{
367}
368
369double
371{
372 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
373
374 // Note that this assumes that the range for u is [0,1], which is
375 // the default range for this distribution.
376 gsl_histogram_set_ranges_uniform(h, 0., 1.);
377
378 std::vector<double> expected(N_BINS, ((double)N_MEASUREMENTS / (double)N_BINS));
379
380 double chiSquared = ChiSquared(h, expected, rng);
381 gsl_histogram_free(h);
382 return chiSquared;
383}
384
385void
387{
388 NS_LOG_FUNCTION(this);
390
391 double confidence = 0.99;
392 double maxStatistic = gsl_cdf_chisq_Pinv(confidence, (N_BINS - 1));
393 NS_LOG_DEBUG("Chi square required at " << confidence << " confidence for " << N_BINS
394 << " bins is " << maxStatistic);
395
396 double result = maxStatistic;
397 // If chi-squared test fails, re-try it up to N_RUNS times
398 for (uint32_t i = 0; i < N_RUNS; ++i)
399 {
400 Ptr<UniformRandomVariable> rng = CreateObject<UniformRandomVariable>();
401 result = ChiSquaredTest(rng);
402 NS_LOG_DEBUG("Chi square result is " << result);
403 if (result < maxStatistic)
404 {
405 break;
406 }
407 }
408
409 NS_TEST_ASSERT_MSG_LT(result, maxStatistic, "Chi-squared statistic out of range");
410
411 double min = 0.0;
412 double max = 10.0;
413 double value;
414
415 // Create the RNG with the specified range.
416 Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable>();
417
418 x->SetAttribute("Min", DoubleValue(min));
419 x->SetAttribute("Max", DoubleValue(max));
420
421 // Test that values are always within the range:
422 //
423 // [min, max)
424 //
425 for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
426 {
427 value = x->GetValue();
428 NS_TEST_ASSERT_MSG_EQ((value >= min), true, "Value less than minimum.");
429 NS_TEST_ASSERT_MSG_LT(value, max, "Value greater than or equal to maximum.");
430 }
431
432 // Boundary checking on GetInteger; should be [min,max]; from bug 1964
433 static const uint32_t UNIFORM_INTEGER_MIN{0};
434 static const uint32_t UNIFORM_INTEGER_MAX{4294967295U};
435 // [0,0] should return 0
436 uint32_t intValue;
437 intValue = x->GetInteger(UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MIN);
438 NS_TEST_ASSERT_MSG_EQ(intValue, UNIFORM_INTEGER_MIN, "Uniform RV GetInteger boundary testing");
439 // [UNIFORM_INTEGER_MAX, UNIFORM_INTEGER_MAX] should return UNIFORM_INTEGER_MAX
440 intValue = x->GetInteger(UNIFORM_INTEGER_MAX, UNIFORM_INTEGER_MAX);
441 NS_TEST_ASSERT_MSG_EQ(intValue, UNIFORM_INTEGER_MAX, "Uniform RV GetInteger boundary testing");
442 // [0,1] should return mix of 0 or 1
443 intValue = 0;
444 for (int i = 0; i < 20; i++)
445 {
446 intValue += x->GetInteger(UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MIN + 1);
447 }
448 NS_TEST_ASSERT_MSG_GT(intValue, 0, "Uniform RV GetInteger boundary testing");
449 NS_TEST_ASSERT_MSG_LT(intValue, 20, "Uniform RV GetInteger boundary testing");
450 // [MAX-1,MAX] should return mix of MAX-1 or MAX
451 uint32_t count = 0;
452 for (int i = 0; i < 20; i++)
453 {
454 intValue = x->GetInteger(UNIFORM_INTEGER_MAX - 1, UNIFORM_INTEGER_MAX);
455 if (intValue == UNIFORM_INTEGER_MAX)
456 {
457 count++;
458 }
459 }
460 NS_TEST_ASSERT_MSG_GT(count, 0, "Uniform RV GetInteger boundary testing");
461 NS_TEST_ASSERT_MSG_LT(count, 20, "Uniform RV GetInteger boundary testing");
462 // multiple [0,UNIFORM_INTEGER_MAX] should return non-zero
463 intValue = x->GetInteger(UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MAX);
464 uint32_t intValue2 = x->GetInteger(UNIFORM_INTEGER_MIN, UNIFORM_INTEGER_MAX);
465 NS_TEST_ASSERT_MSG_GT(intValue + intValue2, 0, "Uniform RV GetInteger boundary testing");
466}
467
473{
474 public:
475 // Constructor
477
478 // Inherited
479 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
480
481 private:
482 // Inherited
483 void DoRun() override;
484};
485
487 : TestCaseBase("Antithetic Uniform Random Variable Stream Generator")
488{
489}
490
491double
493{
494 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
495
496 // Note that this assumes that the range for u is [0,1], which is
497 // the default range for this distribution.
498 gsl_histogram_set_ranges_uniform(h, 0., 1.);
499
500 std::vector<double> expected(N_BINS, ((double)N_MEASUREMENTS / (double)N_BINS));
501
502 double chiSquared = ChiSquared(h, expected, rng);
503 gsl_histogram_free(h);
504 return chiSquared;
505}
506
507void
509{
510 NS_LOG_FUNCTION(this);
512
513 auto generator = RngGenerator<UniformRandomVariable>(true);
514 double sum = ChiSquaredsAverage(&generator, N_RUNS);
515 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
516 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
517
518 double min = 0.0;
519 double max = 10.0;
520 double value;
521
522 // Create the RNG with the specified range.
523 Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable>();
524
525 // Make this generate antithetic values.
526 x->SetAttribute("Antithetic", BooleanValue(true));
527
528 x->SetAttribute("Min", DoubleValue(min));
529 x->SetAttribute("Max", DoubleValue(max));
530
531 // Test that values are always within the range:
532 //
533 // [min, max)
534 //
535 for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
536 {
537 value = x->GetValue();
538 NS_TEST_ASSERT_MSG_EQ((value >= min), true, "Value less than minimum.");
539 NS_TEST_ASSERT_MSG_LT(value, max, "Value greater than or equal to maximum.");
540 }
541}
542
548{
549 public:
550 // Constructor
552
553 private:
554 // Inherited
555 void DoRun() override;
556
558 static constexpr double TOLERANCE{1e-8};
559};
560
562 : TestCaseBase("Constant Random Variable Stream Generator")
563{
564}
565
566void
568{
569 NS_LOG_FUNCTION(this);
571
572 Ptr<ConstantRandomVariable> c = CreateObject<ConstantRandomVariable>();
573
574 double constant;
575
576 // Test that the constant value can be changed using its attribute.
577 constant = 10.0;
578 c->SetAttribute("Constant", DoubleValue(constant));
579 NS_TEST_ASSERT_MSG_EQ_TOL(c->GetValue(), constant, TOLERANCE, "Constant value changed");
580 c->SetAttribute("Constant", DoubleValue(20.0));
581 NS_TEST_ASSERT_MSG_NE(c->GetValue(), constant, "Constant value not changed");
582
583 // Test that the constant value does not change.
584 constant = c->GetValue();
585 for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
586 {
587 NS_TEST_ASSERT_MSG_EQ_TOL(c->GetValue(),
588 constant,
589 TOLERANCE,
590 "Constant value changed in loop");
591 }
592}
593
599{
600 public:
601 // Constructor
603
604 private:
605 // Inherited
606 void DoRun() override;
607
609 static constexpr double TOLERANCE{1e-8};
610};
611
613 : TestCaseBase("Sequential Random Variable Stream Generator")
614{
615}
616
617void
619{
620 NS_LOG_FUNCTION(this);
622
623 Ptr<SequentialRandomVariable> s = CreateObject<SequentialRandomVariable>();
624
625 // The following four attributes should give the sequence
626 //
627 // 4, 4, 7, 7, 10, 10
628 //
629 s->SetAttribute("Min", DoubleValue(4));
630 s->SetAttribute("Max", DoubleValue(11));
631 s->SetAttribute("Increment", StringValue("ns3::UniformRandomVariable[Min=3.0|Max=3.0]"));
632 s->SetAttribute("Consecutive", IntegerValue(2));
633
634 double value;
635
636 // Test that the sequencet is correct.
637 value = s->GetValue();
638 NS_TEST_ASSERT_MSG_EQ_TOL(value, 4, TOLERANCE, "Sequence value 1 wrong.");
639 value = s->GetValue();
640 NS_TEST_ASSERT_MSG_EQ_TOL(value, 4, TOLERANCE, "Sequence value 2 wrong.");
641 value = s->GetValue();
642 NS_TEST_ASSERT_MSG_EQ_TOL(value, 7, TOLERANCE, "Sequence value 3 wrong.");
643 value = s->GetValue();
644 NS_TEST_ASSERT_MSG_EQ_TOL(value, 7, TOLERANCE, "Sequence value 4 wrong.");
645 value = s->GetValue();
646 NS_TEST_ASSERT_MSG_EQ_TOL(value, 10, TOLERANCE, "Sequence value 5 wrong.");
647 value = s->GetValue();
648 NS_TEST_ASSERT_MSG_EQ_TOL(value, 10, TOLERANCE, "Sequence value 6 wrong.");
649}
650
656{
657 public:
658 // Constructor
660
661 // Inherited
662 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
663
664 private:
665 // Inherited
666 void DoRun() override;
667
669 static constexpr double TOLERANCE{5};
670};
671
673 : TestCaseBase("Normal Random Variable Stream Generator")
674{
675}
676
677double
679{
680 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
681 auto range = UniformHistogramBins(h, -4., 4.);
682
683 std::vector<double> expected(N_BINS);
684
685 // Note that this assumes that n has mean equal to zero and standard
686 // deviation equal to one, which are their default values for this
687 // distribution.
688 double sigma = 1.;
689
690 for (std::size_t i = 0; i < N_BINS; ++i)
691 {
692 expected[i] = gsl_cdf_gaussian_P(range[i + 1], sigma) - gsl_cdf_gaussian_P(range[i], sigma);
693 expected[i] *= N_MEASUREMENTS;
694 }
695
696 double chiSquared = ChiSquared(h, expected, rng);
697 gsl_histogram_free(h);
698 return chiSquared;
699}
700
701void
703{
704 NS_LOG_FUNCTION(this);
706
707 auto generator = RngGenerator<NormalRandomVariable>();
708 auto rng = generator.Create();
709
710 double sum = ChiSquaredsAverage(&generator, N_RUNS);
711 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
712 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
713
714 double mean = 5.0;
715 double variance = 2.0;
716
717 // Create the RNG with the specified range.
718 Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable>();
719 x->SetAttribute("Mean", DoubleValue(mean));
720 x->SetAttribute("Variance", DoubleValue(variance));
721
722 // Calculate the mean of these values.
723 double valueMean = Average(x);
724
725 // The expected value for the mean of the values returned by a
726 // normally distributed random variable is equal to mean.
727 double expectedMean = mean;
728 double expectedRms = mean / std::sqrt(variance * N_MEASUREMENTS);
729
730 // Test that values have approximately the right mean value.
732 expectedMean,
733 expectedRms * TOLERANCE,
734 "Wrong mean value.");
735}
736
742{
743 public:
744 // Constructor
746
747 // Inherited
748 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
749
750 private:
751 // Inherited
752 void DoRun() override;
753
755 static constexpr double TOLERANCE{5};
756};
757
759 : TestCaseBase("Antithetic Normal Random Variable Stream Generator")
760{
761}
762
763double
765{
766 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
767 auto range = UniformHistogramBins(h, -4, 4);
768
769 std::vector<double> expected(N_BINS);
770
771 // Note that this assumes that n has mean equal to zero and standard
772 // deviation equal to one, which are their default values for this
773 // distribution.
774 double sigma = 1.;
775
776 for (std::size_t i = 0; i < N_BINS; ++i)
777 {
778 expected[i] = gsl_cdf_gaussian_P(range[i + 1], sigma) - gsl_cdf_gaussian_P(range[i], sigma);
779 expected[i] *= N_MEASUREMENTS;
780 }
781
782 double chiSquared = ChiSquared(h, expected, rng);
783
784 gsl_histogram_free(h);
785 return chiSquared;
786}
787
788void
790{
791 NS_LOG_FUNCTION(this);
793
794 auto generator = RngGenerator<NormalRandomVariable>(true);
795 double sum = ChiSquaredsAverage(&generator, N_RUNS);
796 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
797 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
798
799 double mean = 5.0;
800 double variance = 2.0;
801
802 // Create the RNG with the specified range.
803 Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable>();
804 x->SetAttribute("Mean", DoubleValue(mean));
805 x->SetAttribute("Variance", DoubleValue(variance));
806
807 // Make this generate antithetic values.
808 x->SetAttribute("Antithetic", BooleanValue(true));
809
810 // Calculate the mean of these values.
811 double valueMean = Average(x);
812
813 // The expected value for the mean of the values returned by a
814 // normally distributed random variable is equal to mean.
815 double expectedMean = mean;
816 double expectedRms = mean / std::sqrt(variance * N_MEASUREMENTS);
817
818 // Test that values have approximately the right mean value.
820 expectedMean,
821 expectedRms * TOLERANCE,
822 "Wrong mean value.");
823}
824
830{
831 public:
832 // Constructor
834
835 // Inherited
836 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
837
838 private:
839 // Inherited
840 void DoRun() override;
841
843 static constexpr double TOLERANCE{5};
844};
845
847 : TestCaseBase("Exponential Random Variable Stream Generator")
848{
849}
850
851double
853{
854 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
855 auto range = UniformHistogramBins(h, 0, 10, false);
856
857 std::vector<double> expected(N_BINS);
858
859 // Note that this assumes that e has mean equal to one, which is the
860 // default value for this distribution.
861 double mu = 1.;
862
863 for (std::size_t i = 0; i < N_BINS; ++i)
864 {
865 expected[i] = gsl_cdf_exponential_P(range[i + 1], mu) - gsl_cdf_exponential_P(range[i], mu);
866 expected[i] *= N_MEASUREMENTS;
867 }
868
869 double chiSquared = ChiSquared(h, expected, rng);
870
871 gsl_histogram_free(h);
872 return chiSquared;
873}
874
875void
877{
878 NS_LOG_FUNCTION(this);
880
882 double sum = ChiSquaredsAverage(&generator, N_RUNS);
883 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
884 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
885
886 double mean = 3.14;
887 double bound = 0.0;
888
889 // Create the RNG with the specified range.
890 Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable>();
891 x->SetAttribute("Mean", DoubleValue(mean));
892 x->SetAttribute("Bound", DoubleValue(bound));
893
894 // Calculate the mean of these values.
895 double valueMean = Average(x);
896 double expectedMean = mean;
897 double expectedRms = std::sqrt(mean / N_MEASUREMENTS);
898
899 // Test that values have approximately the right mean value.
901 expectedMean,
902 expectedRms * TOLERANCE,
903 "Wrong mean value.");
904}
905
911{
912 public:
913 // Constructor
915
916 // Inherited
917 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
918
919 private:
920 // Inherited
921 void DoRun() override;
922
924 static constexpr double TOLERANCE{5};
925};
926
928 : TestCaseBase("Antithetic Exponential Random Variable Stream Generator")
929{
930}
931
932double
934{
935 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
936 auto range = UniformHistogramBins(h, 0, 10, false);
937
938 std::vector<double> expected(N_BINS);
939
940 // Note that this assumes that e has mean equal to one, which is the
941 // default value for this distribution.
942 double mu = 1.;
943
944 for (std::size_t i = 0; i < N_BINS; ++i)
945 {
946 expected[i] = gsl_cdf_exponential_P(range[i + 1], mu) - gsl_cdf_exponential_P(range[i], mu);
947 expected[i] *= N_MEASUREMENTS;
948 }
949
950 double chiSquared = ChiSquared(h, expected, rng);
951
952 gsl_histogram_free(h);
953 return chiSquared;
954}
955
956void
958{
959 NS_LOG_FUNCTION(this);
961
962 auto generator = RngGenerator<ExponentialRandomVariable>(true);
963 double sum = ChiSquaredsAverage(&generator, N_RUNS);
964 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
965 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
966
967 double mean = 3.14;
968 double bound = 0.0;
969
970 // Create the RNG with the specified range.
971 Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable>();
972 x->SetAttribute("Mean", DoubleValue(mean));
973 x->SetAttribute("Bound", DoubleValue(bound));
974
975 // Make this generate antithetic values.
976 x->SetAttribute("Antithetic", BooleanValue(true));
977
978 // Calculate the mean of these values.
979 double valueMean = Average(x);
980 double expectedMean = mean;
981 double expectedRms = std::sqrt(mean / N_MEASUREMENTS);
982
983 // Test that values have approximately the right mean value.
985 expectedMean,
986 expectedRms * TOLERANCE,
987 "Wrong mean value.");
988}
989
995{
996 public:
997 // Constructor
999
1000 // Inherited
1001 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1002
1003 private:
1004 // Inherited
1005 void DoRun() override;
1006
1011 static constexpr double TOLERANCE{1e-2};
1012};
1013
1015 : TestCaseBase("Pareto Random Variable Stream Generator")
1016{
1017}
1018
1019double
1021{
1022 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1023 auto range = UniformHistogramBins(h, 1, 10, false);
1024
1025 std::vector<double> expected(N_BINS);
1026
1027 double shape = 2.0;
1028 double scale = 1.0;
1029
1030 for (std::size_t i = 0; i < N_BINS; ++i)
1031 {
1032 expected[i] =
1033 gsl_cdf_pareto_P(range[i + 1], shape, scale) - gsl_cdf_pareto_P(range[i], shape, scale);
1034 expected[i] *= N_MEASUREMENTS;
1035 }
1036
1037 double chiSquared = ChiSquared(h, expected, rng);
1038
1039 gsl_histogram_free(h);
1040 return chiSquared;
1041}
1042
1043void
1045{
1046 NS_LOG_FUNCTION(this);
1048
1049 auto generator = RngGenerator<ParetoRandomVariable>();
1050 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1051 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1052 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1053
1054 double shape = 2.0;
1055 double scale = 1.0;
1056
1057 // Create the RNG with the specified range.
1058 Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable>();
1059 x->SetAttribute("Shape", DoubleValue(shape));
1060 x->SetAttribute("Scale", DoubleValue(scale));
1061
1062 // Calculate the mean of these values.
1063 double valueMean = Average(x);
1064
1065 // The expected value for the mean is given by
1066 //
1067 // shape * scale
1068 // E[value] = --------------- ,
1069 // shape - 1
1070 //
1071 // where
1072 //
1073 // scale = mean * (shape - 1.0) / shape .
1074 double expectedMean = (shape * scale) / (shape - 1.0);
1075
1076 // Test that values have approximately the right mean value.
1077 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1078 expectedMean,
1079 expectedMean * TOLERANCE,
1080 "Wrong mean value.");
1081}
1082
1088{
1089 public:
1090 // Constructor
1092
1093 // Inherited
1094 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1095
1096 private:
1097 // Inherited
1098 void DoRun() override;
1099
1104 static constexpr double TOLERANCE{1e-2};
1105};
1106
1108 : TestCaseBase("Antithetic Pareto Random Variable Stream Generator")
1109{
1110}
1111
1112double
1114{
1115 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1116 auto range = UniformHistogramBins(h, 1, 10, false);
1117
1118 std::vector<double> expected(N_BINS);
1119
1120 double shape = 2.0;
1121 double scale = 1.0;
1122
1123 for (std::size_t i = 0; i < N_BINS; ++i)
1124 {
1125 expected[i] =
1126 gsl_cdf_pareto_P(range[i + 1], shape, scale) - gsl_cdf_pareto_P(range[i], shape, scale);
1127 expected[i] *= N_MEASUREMENTS;
1128 }
1129
1130 double chiSquared = ChiSquared(h, expected, rng);
1131
1132 gsl_histogram_free(h);
1133 return chiSquared;
1134}
1135
1136void
1138{
1139 NS_LOG_FUNCTION(this);
1141
1142 auto generator = RngGenerator<ParetoRandomVariable>(true);
1143 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1144 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1145 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1146
1147 double shape = 2.0;
1148 double scale = 1.0;
1149
1150 // Create the RNG with the specified range.
1151 Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable>();
1152 x->SetAttribute("Shape", DoubleValue(shape));
1153 x->SetAttribute("Scale", DoubleValue(scale));
1154
1155 // Make this generate antithetic values.
1156 x->SetAttribute("Antithetic", BooleanValue(true));
1157
1158 // Calculate the mean of these values.
1159 double valueMean = Average(x);
1160
1161 // The expected value for the mean is given by
1162 //
1163 // shape * scale
1164 // E[value] = --------------- ,
1165 // shape - 1
1166 //
1167 // where
1168 //
1169 // scale = mean * (shape - 1.0) / shape .
1170 //
1171 double expectedMean = (shape * scale) / (shape - 1.0);
1172
1173 // Test that values have approximately the right mean value.
1174 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1175 expectedMean,
1176 expectedMean * TOLERANCE,
1177 "Wrong mean value.");
1178}
1179
1185{
1186 public:
1187 // Constructor
1189
1190 // Inherited
1191 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1192
1193 private:
1194 // Inherited
1195 void DoRun() override;
1196
1201 static constexpr double TOLERANCE{1e-2};
1202};
1203
1205 : TestCaseBase("Weibull Random Variable Stream Generator")
1206{
1207}
1208
1209double
1211{
1212 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1213 auto range = UniformHistogramBins(h, 1, 10, false);
1214
1215 std::vector<double> expected(N_BINS);
1216
1217 // Note that this assumes that p has shape equal to one and scale
1218 // equal to one, which are their default values for this
1219 // distribution.
1220 double a = 1.0;
1221 double b = 1.0;
1222
1223 for (std::size_t i = 0; i < N_BINS; ++i)
1224 {
1225 expected[i] = gsl_cdf_weibull_P(range[i + 1], a, b) - gsl_cdf_weibull_P(range[i], a, b);
1226 expected[i] *= N_MEASUREMENTS;
1227 NS_LOG_INFO("weibull: " << expected[i]);
1228 }
1229
1230 double chiSquared = ChiSquared(h, expected, rng);
1231
1232 gsl_histogram_free(h);
1233 return chiSquared;
1234}
1235
1236void
1238{
1239 NS_LOG_FUNCTION(this);
1241
1242 auto generator = RngGenerator<WeibullRandomVariable>();
1243 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1244 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1245 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1246
1247 double scale = 5.0;
1248 double shape = 1.0;
1249
1250 // Create the RNG with the specified range.
1251 Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable>();
1252 x->SetAttribute("Scale", DoubleValue(scale));
1253 x->SetAttribute("Shape", DoubleValue(shape));
1254
1255 // Calculate the mean of these values.
1256 double valueMean = Average(x);
1257
1258 // The expected value for the mean of the values returned by a
1259 // Weibull distributed random variable is
1260 //
1261 // E[value] = scale * Gamma(1 + 1 / shape) ,
1262 //
1263 // where Gamma() is the Gamma function. Note that
1264 //
1265 // Gamma(n) = (n - 1)!
1266 //
1267 // if n is a positive integer.
1268 //
1269 // For this test,
1270 //
1271 // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1272 // = Gamma(2)
1273 // = (2 - 1)!
1274 // = 1
1275 //
1276 // which means
1277 //
1278 // E[value] = scale .
1279 //
1280 double expectedMean = scale;
1281
1282 // Test that values have approximately the right mean value.
1283 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1284 expectedMean,
1285 expectedMean * TOLERANCE,
1286 "Wrong mean value.");
1287}
1288
1294{
1295 public:
1296 // Constructor
1298
1299 // Inherited
1300 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1301
1302 private:
1303 // Inherited
1304 void DoRun() override;
1305
1310 static constexpr double TOLERANCE{1e-2};
1311};
1312
1314 : TestCaseBase("Antithetic Weibull Random Variable Stream Generator")
1315{
1316}
1317
1318double
1320{
1321 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1322 auto range = UniformHistogramBins(h, 1, 10, false);
1323
1324 std::vector<double> expected(N_BINS);
1325
1326 // Note that this assumes that p has shape equal to one and scale
1327 // equal to one, which are their default values for this
1328 // distribution.
1329 double a = 1.0;
1330 double b = 1.0;
1331
1332 for (std::size_t i = 0; i < N_BINS; ++i)
1333 {
1334 expected[i] = gsl_cdf_weibull_P(range[i + 1], a, b) - gsl_cdf_weibull_P(range[i], a, b);
1335 expected[i] *= N_MEASUREMENTS;
1336 }
1337
1338 double chiSquared = ChiSquared(h, expected, rng);
1339
1340 gsl_histogram_free(h);
1341 return chiSquared;
1342}
1343
1344void
1346{
1347 NS_LOG_FUNCTION(this);
1349
1350 auto generator = RngGenerator<WeibullRandomVariable>(true);
1351 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1352 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1353 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1354
1355 double scale = 5.0;
1356 double shape = 1.0;
1357
1358 // Create the RNG with the specified range.
1359 Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable>();
1360 x->SetAttribute("Scale", DoubleValue(scale));
1361 x->SetAttribute("Shape", DoubleValue(shape));
1362
1363 // Make this generate antithetic values.
1364 x->SetAttribute("Antithetic", BooleanValue(true));
1365
1366 // Calculate the mean of these values.
1367 double valueMean = Average(x);
1368
1369 // The expected value for the mean of the values returned by a
1370 // Weibull distributed random variable is
1371 //
1372 // E[value] = scale * Gamma(1 + 1 / shape) ,
1373 //
1374 // where Gamma() is the Gamma function. Note that
1375 //
1376 // Gamma(n) = (n - 1)!
1377 //
1378 // if n is a positive integer.
1379 //
1380 // For this test,
1381 //
1382 // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1383 // = Gamma(2)
1384 // = (2 - 1)!
1385 // = 1
1386 //
1387 // which means
1388 //
1389 // E[value] = scale .
1390 //
1391 double expectedMean = scale;
1392
1393 // Test that values have approximately the right mean value.
1394 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1395 expectedMean,
1396 expectedMean * TOLERANCE,
1397 "Wrong mean value.");
1398}
1399
1405{
1406 public:
1407 // Constructor
1409
1410 // Inherited
1411 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1412
1413 private:
1414 // Inherited
1415 void DoRun() override;
1416
1421 static constexpr double TOLERANCE{3e-2};
1422};
1423
1425 : TestCaseBase("Log-Normal Random Variable Stream Generator")
1426{
1427}
1428
1429double
1431{
1432 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1433 auto range = UniformHistogramBins(h, 0, 10, false);
1434
1435 std::vector<double> expected(N_BINS);
1436
1437 // Note that this assumes that n has mu equal to zero and sigma
1438 // equal to one, which are their default values for this
1439 // distribution.
1440 double mu = 0.0;
1441 double sigma = 1.0;
1442
1443 for (std::size_t i = 0; i < N_BINS; ++i)
1444 {
1445 expected[i] =
1446 gsl_cdf_lognormal_P(range[i + 1], mu, sigma) - gsl_cdf_lognormal_P(range[i], mu, sigma);
1447 expected[i] *= N_MEASUREMENTS;
1448 }
1449
1450 double chiSquared = ChiSquared(h, expected, rng);
1451
1452 gsl_histogram_free(h);
1453 return chiSquared;
1454}
1455
1456void
1458{
1459 NS_LOG_FUNCTION(this);
1461
1462 auto generator = RngGenerator<LogNormalRandomVariable>();
1463 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1464 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1465
1466 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1467
1468 double mu = 5.0;
1469 double sigma = 2.0;
1470
1471 // Create the RNG with the specified range.
1472 Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable>();
1473 x->SetAttribute("Mu", DoubleValue(mu));
1474 x->SetAttribute("Sigma", DoubleValue(sigma));
1475
1476 // Calculate the mean of these values.
1477 double valueMean = Average(x);
1478
1479 // The expected value for the mean of the values returned by a
1480 // log-normally distributed random variable is equal to
1481 //
1482 // 2
1483 // mu + sigma / 2
1484 // E[value] = e .
1485 //
1486 double expectedMean = std::exp(mu + sigma * sigma / 2.0);
1487
1488 // Test that values have approximately the right mean value.
1489 //
1496 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1497 expectedMean,
1498 expectedMean * TOLERANCE,
1499 "Wrong mean value.");
1500}
1501
1507{
1508 public:
1509 // Constructor
1511
1512 // Inherited
1513 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1514
1515 private:
1516 // Inherited
1517 void DoRun() override;
1518
1523 static constexpr double TOLERANCE{3e-2};
1524};
1525
1527 : TestCaseBase("Antithetic Log-Normal Random Variable Stream Generator")
1528{
1529}
1530
1531double
1533{
1534 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1535 auto range = UniformHistogramBins(h, 0, 10, false);
1536
1537 std::vector<double> expected(N_BINS);
1538
1539 // Note that this assumes that n has mu equal to zero and sigma
1540 // equal to one, which are their default values for this
1541 // distribution.
1542 double mu = 0.0;
1543 double sigma = 1.0;
1544
1545 for (std::size_t i = 0; i < N_BINS; ++i)
1546 {
1547 expected[i] =
1548 gsl_cdf_lognormal_P(range[i + 1], mu, sigma) - gsl_cdf_lognormal_P(range[i], mu, sigma);
1549 expected[i] *= N_MEASUREMENTS;
1550 }
1551
1552 double chiSquared = ChiSquared(h, expected, rng);
1553
1554 gsl_histogram_free(h);
1555 return chiSquared;
1556}
1557
1558void
1560{
1561 NS_LOG_FUNCTION(this);
1563
1564 auto generator = RngGenerator<LogNormalRandomVariable>(true);
1565 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1566 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1567 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1568
1569 double mu = 5.0;
1570 double sigma = 2.0;
1571
1572 // Create the RNG with the specified range.
1573 Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable>();
1574 x->SetAttribute("Mu", DoubleValue(mu));
1575 x->SetAttribute("Sigma", DoubleValue(sigma));
1576
1577 // Make this generate antithetic values.
1578 x->SetAttribute("Antithetic", BooleanValue(true));
1579
1580 // Calculate the mean of these values.
1581 double valueMean = Average(x);
1582
1583 // The expected value for the mean of the values returned by a
1584 // log-normally distributed random variable is equal to
1585 //
1586 // 2
1587 // mu + sigma / 2
1588 // E[value] = e .
1589 //
1590 double expectedMean = std::exp(mu + sigma * sigma / 2.0);
1591
1592 // Test that values have approximately the right mean value.
1593 //
1600 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1601 expectedMean,
1602 expectedMean * TOLERANCE,
1603 "Wrong mean value.");
1604}
1605
1611{
1612 public:
1613 // Constructor
1614 GammaTestCase();
1615
1616 // Inherited
1617 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1618
1619 private:
1620 // Inherited
1621 void DoRun() override;
1622
1627 static constexpr double TOLERANCE{1e-2};
1628};
1629
1631 : TestCaseBase("Gamma Random Variable Stream Generator")
1632{
1633}
1634
1635double
1637{
1638 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1639 auto range = UniformHistogramBins(h, 0, 10, false);
1640
1641 std::vector<double> expected(N_BINS);
1642
1643 // Note that this assumes that n has alpha equal to one and beta
1644 // equal to one, which are their default values for this
1645 // distribution.
1646 double alpha = 1.0;
1647 double beta = 1.0;
1648
1649 for (std::size_t i = 0; i < N_BINS; ++i)
1650 {
1651 expected[i] =
1652 gsl_cdf_gamma_P(range[i + 1], alpha, beta) - gsl_cdf_gamma_P(range[i], alpha, beta);
1653 expected[i] *= N_MEASUREMENTS;
1654 }
1655
1656 double chiSquared = ChiSquared(h, expected, rng);
1657
1658 gsl_histogram_free(h);
1659 return chiSquared;
1660}
1661
1662void
1664{
1665 NS_LOG_FUNCTION(this);
1667
1668 auto generator = RngGenerator<GammaRandomVariable>();
1669 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1670 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1671 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1672
1673 double alpha = 5.0;
1674 double beta = 2.0;
1675
1676 // Create the RNG with the specified range.
1677 Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable>();
1678 x->SetAttribute("Alpha", DoubleValue(alpha));
1679 x->SetAttribute("Beta", DoubleValue(beta));
1680
1681 // Calculate the mean of these values.
1682 double valueMean = Average(x);
1683
1684 // The expected value for the mean of the values returned by a
1685 // gammaly distributed random variable is equal to
1686 //
1687 // E[value] = alpha * beta .
1688 //
1689 double expectedMean = alpha * beta;
1690
1691 // Test that values have approximately the right mean value.
1692 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1693 expectedMean,
1694 expectedMean * TOLERANCE,
1695 "Wrong mean value.");
1696}
1697
1703{
1704 public:
1705 // Constructor
1707
1708 // Inherited
1709 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1710
1711 private:
1712 // Inherited
1713 void DoRun() override;
1714
1719 static constexpr double TOLERANCE{1e-2};
1720};
1721
1723 : TestCaseBase("Antithetic Gamma Random Variable Stream Generator")
1724{
1725}
1726
1727double
1729{
1730 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1731 auto range = UniformHistogramBins(h, 0, 10, false);
1732
1733 std::vector<double> expected(N_BINS);
1734
1735 // Note that this assumes that n has alpha equal to one and beta
1736 // equal to one, which are their default values for this
1737 // distribution.
1738 double alpha = 1.0;
1739 double beta = 1.0;
1740
1741 for (std::size_t i = 0; i < N_BINS; ++i)
1742 {
1743 expected[i] =
1744 gsl_cdf_gamma_P(range[i + 1], alpha, beta) - gsl_cdf_gamma_P(range[i], alpha, beta);
1745 expected[i] *= N_MEASUREMENTS;
1746 }
1747
1748 double chiSquared = ChiSquared(h, expected, rng);
1749
1750 gsl_histogram_free(h);
1751 return chiSquared;
1752}
1753
1754void
1756{
1757 NS_LOG_FUNCTION(this);
1759
1760 auto generator = RngGenerator<GammaRandomVariable>(true);
1761 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1762 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1763 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1764
1765 double alpha = 5.0;
1766 double beta = 2.0;
1767
1768 // Create the RNG with the specified range.
1769 Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable>();
1770
1771 // Make this generate antithetic values.
1772 x->SetAttribute("Antithetic", BooleanValue(true));
1773
1774 x->SetAttribute("Alpha", DoubleValue(alpha));
1775 x->SetAttribute("Beta", DoubleValue(beta));
1776
1777 // Calculate the mean of these values.
1778 double valueMean = Average(x);
1779
1780 // The expected value for the mean of the values returned by a
1781 // gammaly distributed random variable is equal to
1782 //
1783 // E[value] = alpha * beta .
1784 //
1785 double expectedMean = alpha * beta;
1786
1787 // Test that values have approximately the right mean value.
1788 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1789 expectedMean,
1790 expectedMean * TOLERANCE,
1791 "Wrong mean value.");
1792}
1793
1799{
1800 public:
1801 // Constructor
1803
1804 // Inherited
1805 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1806
1807 private:
1808 // Inherited
1809 void DoRun() override;
1810
1815 static constexpr double TOLERANCE{1e-2};
1816};
1817
1819 : TestCaseBase("Erlang Random Variable Stream Generator")
1820{
1821}
1822
1823double
1825{
1826 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1827 auto range = UniformHistogramBins(h, 0, 10, false);
1828
1829 std::vector<double> expected(N_BINS);
1830
1831 // Note that this assumes that n has k equal to one and lambda
1832 // equal to one, which are their default values for this
1833 // distribution.
1834 uint32_t k = 1;
1835 double lambda = 1.0;
1836
1837 // Note that Erlang distribution is equal to the gamma distribution
1838 // when k is an integer, which is why the gamma distribution's cdf
1839 // function can be used here.
1840 for (std::size_t i = 0; i < N_BINS; ++i)
1841 {
1842 expected[i] =
1843 gsl_cdf_gamma_P(range[i + 1], k, lambda) - gsl_cdf_gamma_P(range[i], k, lambda);
1844 expected[i] *= N_MEASUREMENTS;
1845 }
1846
1847 double chiSquared = ChiSquared(h, expected, rng);
1848
1849 gsl_histogram_free(h);
1850 return chiSquared;
1851}
1852
1853void
1855{
1856 NS_LOG_FUNCTION(this);
1858
1859 auto generator = RngGenerator<ErlangRandomVariable>();
1860 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1861 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1862 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1863
1864 uint32_t k = 5;
1865 double lambda = 2.0;
1866
1867 // Create the RNG with the specified range.
1868 Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable>();
1869 x->SetAttribute("K", IntegerValue(k));
1870 x->SetAttribute("Lambda", DoubleValue(lambda));
1871
1872 // Calculate the mean of these values.
1873 double valueMean = Average(x);
1874
1875 // The expected value for the mean of the values returned by a
1876 // Erlangly distributed random variable is equal to
1877 //
1878 // E[value] = k * lambda .
1879 //
1880 double expectedMean = k * lambda;
1881
1882 // Test that values have approximately the right mean value.
1883 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1884 expectedMean,
1885 expectedMean * TOLERANCE,
1886 "Wrong mean value.");
1887}
1888
1894{
1895 public:
1896 // Constructor
1898
1899 // Inherited
1900 double ChiSquaredTest(Ptr<RandomVariableStream> rng) const override;
1901
1902 private:
1903 // Inherited
1904 void DoRun() override;
1905
1910 static constexpr double TOLERANCE{1e-2};
1911};
1912
1914 : TestCaseBase("Antithetic Erlang Random Variable Stream Generator")
1915{
1916}
1917
1918double
1920{
1921 gsl_histogram* h = gsl_histogram_alloc(N_BINS);
1922 auto range = UniformHistogramBins(h, 0, 10, false);
1923
1924 std::vector<double> expected(N_BINS);
1925
1926 // Note that this assumes that n has k equal to one and lambda
1927 // equal to one, which are their default values for this
1928 // distribution.
1929 uint32_t k = 1;
1930 double lambda = 1.0;
1931
1932 // Note that Erlang distribution is equal to the gamma distribution
1933 // when k is an integer, which is why the gamma distribution's cdf
1934 // function can be used here.
1935 for (std::size_t i = 0; i < N_BINS; ++i)
1936 {
1937 expected[i] =
1938 gsl_cdf_gamma_P(range[i + 1], k, lambda) - gsl_cdf_gamma_P(range[i], k, lambda);
1939 expected[i] *= N_MEASUREMENTS;
1940 }
1941
1942 double chiSquared = ChiSquared(h, expected, rng);
1943
1944 gsl_histogram_free(h);
1945 return chiSquared;
1946}
1947
1948void
1950{
1951 NS_LOG_FUNCTION(this);
1953
1954 auto generator = RngGenerator<ErlangRandomVariable>(true);
1955 double sum = ChiSquaredsAverage(&generator, N_RUNS);
1956 double maxStatistic = gsl_cdf_chisq_Qinv(0.05, N_BINS);
1957 NS_TEST_ASSERT_MSG_LT(sum, maxStatistic, "Chi-squared statistic out of range");
1958
1959 uint32_t k = 5;
1960 double lambda = 2.0;
1961
1962 // Create the RNG with the specified range.
1963 Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable>();
1964
1965 // Make this generate antithetic values.
1966 x->SetAttribute("Antithetic", BooleanValue(true));
1967
1968 x->SetAttribute("K", IntegerValue(k));
1969 x->SetAttribute("Lambda", DoubleValue(lambda));
1970
1971 // Calculate the mean of these values.
1972 double valueMean = Average(x);
1973
1974 // The expected value for the mean of the values returned by a
1975 // Erlangly distributed random variable is equal to
1976 //
1977 // E[value] = k * lambda .
1978 //
1979 double expectedMean = k * lambda;
1980
1981 // Test that values have approximately the right mean value.
1982 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
1983 expectedMean,
1984 expectedMean * TOLERANCE,
1985 "Wrong mean value.");
1986}
1987
1993{
1994 public:
1995 // Constructor
1996 ZipfTestCase();
1997
1998 private:
1999 // Inherited
2000 void DoRun() override;
2001
2006 static constexpr double TOLERANCE{1e-2};
2007};
2008
2010 : TestCaseBase("Zipf Random Variable Stream Generator")
2011{
2012}
2013
2014void
2016{
2017 NS_LOG_FUNCTION(this);
2019
2020 uint32_t n = 1;
2021 double alpha = 2.0;
2022
2023 // Create the RNG with the specified range.
2024 Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable>();
2025 x->SetAttribute("N", IntegerValue(n));
2026 x->SetAttribute("Alpha", DoubleValue(alpha));
2027
2028 // Calculate the mean of these values.
2029 double valueMean = Average(x);
2030
2031 // The expected value for the mean of the values returned by a
2032 // Zipfly distributed random variable is equal to
2033 //
2034 // H
2035 // N, alpha - 1
2036 // E[value] = ---------------
2037 // H
2038 // N, alpha
2039 //
2040 // where
2041 //
2042 // N
2043 // ---
2044 // \ -alpha
2045 // H = / m .
2046 // N, alpha ---
2047 // m=1
2048 //
2049 // For this test,
2050 //
2051 // -(alpha - 1)
2052 // 1
2053 // E[value] = ---------------
2054 // -alpha
2055 // 1
2056 //
2057 // = 1 .
2058 //
2059 double expectedMean = 1.0;
2060
2061 // Test that values have approximately the right mean value.
2062 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
2063 expectedMean,
2064 expectedMean * TOLERANCE,
2065 "Wrong mean value.");
2066}
2067
2073{
2074 public:
2075 // Constructor
2077
2078 private:
2079 // Inherited
2080 void DoRun() override;
2081
2086 static constexpr double TOLERANCE{1e-2};
2087};
2088
2090 : TestCaseBase("Antithetic Zipf Random Variable Stream Generator")
2091{
2092}
2093
2094void
2096{
2097 NS_LOG_FUNCTION(this);
2099
2100 uint32_t n = 1;
2101 double alpha = 2.0;
2102
2103 // Create the RNG with the specified range.
2104 Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable>();
2105 x->SetAttribute("N", IntegerValue(n));
2106 x->SetAttribute("Alpha", DoubleValue(alpha));
2107
2108 // Make this generate antithetic values.
2109 x->SetAttribute("Antithetic", BooleanValue(true));
2110
2111 // Calculate the mean of these values.
2112 double valueMean = Average(x);
2113
2114 // The expected value for the mean of the values returned by a
2115 // Zipfly distributed random variable is equal to
2116 //
2117 // H
2118 // N, alpha - 1
2119 // E[value] = ---------------
2120 // H
2121 // N, alpha
2122 //
2123 // where
2124 //
2125 // N
2126 // ---
2127 // \ -alpha
2128 // H = / m .
2129 // N, alpha ---
2130 // m=1
2131 //
2132 // For this test,
2133 //
2134 // -(alpha - 1)
2135 // 1
2136 // E[value] = ---------------
2137 // -alpha
2138 // 1
2139 //
2140 // = 1 .
2141 //
2142 double expectedMean = 1.0;
2143
2144 // Test that values have approximately the right mean value.
2145 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
2146 expectedMean,
2147 expectedMean * TOLERANCE,
2148 "Wrong mean value.");
2149}
2150
2156{
2157 public:
2158 // Constructor
2159 ZetaTestCase();
2160
2161 private:
2162 // Inherited
2163 void DoRun() override;
2164
2169 static constexpr double TOLERANCE{1e-2};
2170};
2171
2173 : TestCaseBase("Zeta Random Variable Stream Generator")
2174{
2175}
2176
2177void
2179{
2180 NS_LOG_FUNCTION(this);
2182
2183 double alpha = 5.0;
2184
2185 // Create the RNG with the specified range.
2186 Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable>();
2187 x->SetAttribute("Alpha", DoubleValue(alpha));
2188
2189 // Calculate the mean of these values.
2190 double valueMean = Average(x);
2191
2192 // The expected value for the mean of the values returned by a
2193 // zetaly distributed random variable is equal to
2194 //
2195 // zeta(alpha - 1)
2196 // E[value] = --------------- for alpha > 2 ,
2197 // zeta(alpha)
2198 //
2199 // where zeta(alpha) is the Riemann zeta function.
2200 //
2201 // There are no simple analytic forms for the Riemann zeta function,
2202 // which is why the gsl library is used in this test to calculate
2203 // the known mean of the values.
2204 double expectedMean =
2205 gsl_sf_zeta_int(static_cast<int>(alpha - 1)) / gsl_sf_zeta_int(static_cast<int>(alpha));
2206
2207 // Test that values have approximately the right mean value.
2208 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
2209 expectedMean,
2210 expectedMean * TOLERANCE,
2211 "Wrong mean value.");
2212}
2213
2219{
2220 public:
2221 // Constructor
2223
2224 private:
2225 // Inherited
2226 void DoRun() override;
2227
2232 static constexpr double TOLERANCE{1e-2};
2233};
2234
2236 : TestCaseBase("Antithetic Zeta Random Variable Stream Generator")
2237{
2238}
2239
2240void
2242{
2243 NS_LOG_FUNCTION(this);
2245
2246 double alpha = 5.0;
2247
2248 // Create the RNG with the specified range.
2249 Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable>();
2250 x->SetAttribute("Alpha", DoubleValue(alpha));
2251
2252 // Make this generate antithetic values.
2253 x->SetAttribute("Antithetic", BooleanValue(true));
2254
2255 // Calculate the mean of these values.
2256 double valueMean = Average(x);
2257
2258 // The expected value for the mean of the values returned by a
2259 // zetaly distributed random variable is equal to
2260 //
2261 // zeta(alpha - 1)
2262 // E[value] = --------------- for alpha > 2 ,
2263 // zeta(alpha)
2264 //
2265 // where zeta(alpha) is the Riemann zeta function.
2266 //
2267 // There are no simple analytic forms for the Riemann zeta function,
2268 // which is why the gsl library is used in this test to calculate
2269 // the known mean of the values.
2270 double expectedMean =
2271 gsl_sf_zeta_int(static_cast<int>(alpha) - 1) / gsl_sf_zeta_int(static_cast<int>(alpha));
2272
2273 // Test that values have approximately the right mean value.
2274 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
2275 expectedMean,
2276 expectedMean * TOLERANCE,
2277 "Wrong mean value.");
2278}
2279
2285{
2286 public:
2287 // Constructor
2289
2290 private:
2291 // Inherited
2292 void DoRun() override;
2293
2295 static constexpr double TOLERANCE{1e-8};
2296};
2297
2299 : TestCaseBase("Deterministic Random Variable Stream Generator")
2300{
2301}
2302
2303void
2305{
2306 NS_LOG_FUNCTION(this);
2308
2309 Ptr<DeterministicRandomVariable> s = CreateObject<DeterministicRandomVariable>();
2310
2311 // The following array should give the sequence
2312 //
2313 // 4, 4, 7, 7, 10, 10 .
2314 //
2315 double array1[] = {4, 4, 7, 7, 10, 10};
2316 std::size_t count1 = 6;
2317 s->SetValueArray(array1, count1);
2318
2319 double value;
2320
2321 // Test that the first sequence is correct.
2322 value = s->GetValue();
2323 NS_TEST_ASSERT_MSG_EQ_TOL(value, 4, TOLERANCE, "Sequence 1 value 1 wrong.");
2324 value = s->GetValue();
2325 NS_TEST_ASSERT_MSG_EQ_TOL(value, 4, TOLERANCE, "Sequence 1 value 2 wrong.");
2326 value = s->GetValue();
2327 NS_TEST_ASSERT_MSG_EQ_TOL(value, 7, TOLERANCE, "Sequence 1 value 3 wrong.");
2328 value = s->GetValue();
2329 NS_TEST_ASSERT_MSG_EQ_TOL(value, 7, TOLERANCE, "Sequence 1 value 4 wrong.");
2330 value = s->GetValue();
2331 NS_TEST_ASSERT_MSG_EQ_TOL(value, 10, TOLERANCE, "Sequence 1 value 5 wrong.");
2332 value = s->GetValue();
2333 NS_TEST_ASSERT_MSG_EQ_TOL(value, 10, TOLERANCE, "Sequence 1 value 6 wrong.");
2334
2335 // The following array should give the sequence
2336 //
2337 // 1000, 2000, 7, 7 .
2338 //
2339 double array2[] = {1000, 2000, 3000, 4000};
2340 std::size_t count2 = 4;
2341 s->SetValueArray(array2, count2);
2342
2343 // Test that the second sequence is correct.
2344 value = s->GetValue();
2345 NS_TEST_ASSERT_MSG_EQ_TOL(value, 1000, TOLERANCE, "Sequence 2 value 1 wrong.");
2346 value = s->GetValue();
2347 NS_TEST_ASSERT_MSG_EQ_TOL(value, 2000, TOLERANCE, "Sequence 2 value 2 wrong.");
2348 value = s->GetValue();
2349 NS_TEST_ASSERT_MSG_EQ_TOL(value, 3000, TOLERANCE, "Sequence 2 value 3 wrong.");
2350 value = s->GetValue();
2351 NS_TEST_ASSERT_MSG_EQ_TOL(value, 4000, TOLERANCE, "Sequence 2 value 4 wrong.");
2352 value = s->GetValue();
2353}
2354
2360{
2361 public:
2362 // Constructor
2364
2365 private:
2366 // Inherited
2367 void DoRun() override;
2368
2373 static constexpr double TOLERANCE{1e-2};
2374};
2375
2377 : TestCaseBase("Empirical Random Variable Stream Generator")
2378{
2379}
2380
2381void
2383{
2384 NS_LOG_FUNCTION(this);
2386
2387 // Create the RNG with a uniform distribution between 0 and 10.
2388 Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable>();
2389 x->SetInterpolate(false);
2390 x->CDF(0.0, 0.0);
2391 x->CDF(5.0, 0.25);
2392 x->CDF(10.0, 1.0);
2393
2394 // Check that only the correct values are returned
2395 for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2396 {
2397 double value = x->GetValue();
2398 NS_TEST_EXPECT_MSG_EQ((value == 5) || (value == 10),
2399 true,
2400 "Incorrect value returned, expected only 5 or 10.");
2401 }
2402
2403 // Calculate the mean of the sampled values.
2404 double valueMean = Average(x);
2405
2406 // The expected distribution with sampled values is
2407 // Value Probability
2408 // 5 25%
2409 // 10 75%
2410 //
2411 // The expected mean is
2412 //
2413 // E[value] = 5 * 25% + 10 * 75% = 8.75
2414 //
2415 // Test that values have approximately the right mean value.
2416 double expectedMean = 8.75;
2417 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
2418 expectedMean,
2419 expectedMean * TOLERANCE,
2420 "Wrong mean value.");
2421
2422 // Calculate the mean of the interpolated values.
2423 x->SetInterpolate(true);
2424 valueMean = Average(x);
2425
2426 // The expected distribution (with interpolation) is
2427 // Bin Probability
2428 // [0, 5) 25%
2429 // [5, 10) 75%
2430 //
2431 // Each bin is uniformly sampled, so the average of the samples in the
2432 // bin is the center of the bin.
2433 //
2434 // The expected mean is
2435 //
2436 // E[value] = 2.5 * 25% + 7.5 * 75% = 6.25
2437 //
2438 expectedMean = 6.25;
2439
2440 // Test that values have approximately the right mean value.
2441 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
2442 expectedMean,
2443 expectedMean * TOLERANCE,
2444 "Wrong mean value.");
2445
2446 // Bug 2082: Create the RNG with a uniform distribution between -1 and 1.
2447 Ptr<EmpiricalRandomVariable> y = CreateObject<EmpiricalRandomVariable>();
2448 y->SetInterpolate(false);
2449 y->CDF(-1.0, 0.0);
2450 y->CDF(0.0, 0.5);
2451 y->CDF(1.0, 1.0);
2452 NS_TEST_ASSERT_MSG_LT(y->GetValue(), 2, "Empirical variable with negative domain");
2453}
2454
2460{
2461 public:
2462 // Constructor
2464
2465 private:
2466 // Inherited
2467 void DoRun() override;
2468
2473 static constexpr double TOLERANCE{1e-2};
2474};
2475
2477 : TestCaseBase("EmpiricalAntithetic Random Variable Stream Generator")
2478{
2479}
2480
2481void
2483{
2484 NS_LOG_FUNCTION(this);
2486
2487 // Create the RNG with a uniform distribution between 0 and 10.
2488 Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable>();
2489 x->SetInterpolate(false);
2490 x->CDF(0.0, 0.0);
2491 x->CDF(5.0, 0.25);
2492 x->CDF(10.0, 1.0);
2493
2494 // Make this generate antithetic values.
2495 x->SetAttribute("Antithetic", BooleanValue(true));
2496
2497 // Check that only the correct values are returned
2498 for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2499 {
2500 double value = x->GetValue();
2501 NS_TEST_EXPECT_MSG_EQ((value == 5) || (value == 10),
2502 true,
2503 "Incorrect value returned, expected only 5 or 10.");
2504 }
2505
2506 // Calculate the mean of these values.
2507 double valueMean = Average(x);
2508 // Expected
2509 // E[value] = 5 * 25% + 10 * 75% = 8.75
2510 double expectedMean = 8.75;
2511 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
2512 expectedMean,
2513 expectedMean * TOLERANCE,
2514 "Wrong mean value.");
2515
2516 // Check interpolated sampling
2517 x->SetInterpolate(true);
2518 valueMean = Average(x);
2519
2520 // The expected value for the mean of the values returned by this
2521 // empirical distribution with interpolation is
2522 //
2523 // E[value] = 2.5 * 25% + 7.5 * 75% = 6.25
2524 //
2525 expectedMean = 6.25;
2526
2527 // Test that values have approximately the right mean value.
2528 NS_TEST_ASSERT_MSG_EQ_TOL(valueMean,
2529 expectedMean,
2530 expectedMean * TOLERANCE,
2531 "Wrong mean value.");
2532}
2533
2539{
2540 public:
2541 // Constructor
2543
2544 private:
2545 // Inherited
2546 void DoRun() override;
2547};
2548
2550 : TestCaseBase("NormalRandomVariable caching of parameters")
2551{
2552}
2553
2554void
2556{
2557 NS_LOG_FUNCTION(this);
2559
2560 Ptr<NormalRandomVariable> n = CreateObject<NormalRandomVariable>();
2561 double v1 = n->GetValue(-10, 1, 10); // Mean -10, variance 1, bounded to [-20,0]
2562 double v2 = n->GetValue(10, 1, 10); // Mean 10, variance 1, bounded to [0,20]
2563
2564 NS_TEST_ASSERT_MSG_LT(v1, 0, "Incorrect value returned, expected < 0");
2565 NS_TEST_ASSERT_MSG_GT(v2, 0, "Incorrect value returned, expected > 0");
2566}
2567
2574{
2575 public:
2576 // Constructor
2578};
2579
2581 : TestSuite("random-variable-stream-generators", UNIT)
2582{
2599 /*
2600 AddTestCase (new LogNormalAntitheticTestCase);
2601 */
2606 /*
2607 AddTestCase (new GammaAntitheticTestCase);
2608 */
2620}
2621
2623
2624} // namespace RandomVariable
2625
2626} // namespace test
2627
2628} // namespace ns3
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
Simple average, min, max and std.
Definition: average.h:42
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold a signed integer type.
Definition: integer.h:45
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void SetSeed(uint32_t seed)
Set the seed.
static uint64_t GetRun()
Get the current run number.
static uint32_t GetSeed()
Get the current seed value which will be used by all subsequently instantiated RandomVariableStream o...
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
Test case for constant random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation.
void DoRun() override
Implementation to actually run this TestCase.
Test case for deterministic random variable stream generator.
void DoRun() override
Implementation to actually run this TestCase.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation.
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.
void DoRun() override
Implementation to actually run this TestCase.
Test case for empirical distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
void DoRun() override
Implementation to actually run this TestCase.
Test case for antithetic Erlang distribution random variable stream generator.
void DoRun() override
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 override
Compute the chi square value from a random variable.
Test case for Erlang distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
Compute the chi square value from a random variable.
void DoRun() override
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 exponential distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, in rms.
void DoRun() override
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
Compute the chi square value from a random variable.
Test case for exponential distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, in rms.
void DoRun() override
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
Compute the chi square value from a random variable.
Test case for antithetic gamma distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
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.
void DoRun() override
Implementation to actually run this TestCase.
Test case for gamma distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
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.
void DoRun() override
Implementation to actually run this TestCase.
Test case for antithetic log-normal distribution random variable stream generator.
void DoRun() override
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
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 log-normal distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
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.
void DoRun() override
Implementation to actually run this TestCase.
Test case for antithetic normal distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, in rms.
void DoRun() override
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
Compute the chi square value from a random variable.
Test case for caching of Normal RV parameters (see issue #302)
void DoRun() override
Implementation to actually run this TestCase.
Test case for normal distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
Compute the chi square value from a random variable.
void DoRun() override
Implementation to actually run this TestCase.
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 override
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.
void DoRun() override
Implementation to actually run this TestCase.
Test case for Pareto distribution random variable stream generator.
void DoRun() override
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
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.
void DoRun() override
Implementation to actually run this TestCase.
A factory base class to create new instances of a random variable.
virtual Ptr< RandomVariableStream > Create() const =0
Create a new instance of a random variable stream.
Factory class to create new instances of a particular random variable stream.
Ptr< RandomVariableStream > Create() const override
Create a new instance of a random variable stream.
bool m_anti
Whether to create antithetic random variable streams.
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.
void SetTestSuiteSeed()
Set the seed used for this test suite.
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.
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.
void DoRun() override
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
Compute the chi square value from a random variable.
Test case for uniform distribution random variable stream generator.
void DoRun() override
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
Compute the chi square value from a random variable.
Test case for antithetic Weibull distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
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.
void DoRun() override
Implementation to actually run this TestCase.
Test case for Weibull distribution random variable stream generator.
double ChiSquaredTest(Ptr< RandomVariableStream > rng) const override
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.
void DoRun() override
Implementation to actually run this TestCase.
Test case for antithetic Zeta distribution random variable stream generator.
void DoRun() override
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.
void DoRun() override
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 Zipf distribution random variable stream generator.
void DoRun() override
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 Zipf distribution random variable stream generator.
static constexpr double TOLERANCE
Tolerance for testing rng values against expectation, as a fraction of mean value.
void DoRun() override
Implementation to actually run this TestCase.
#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:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:275
#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:709
#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:144
#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:251
#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:564
#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:874
#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:337
static RandomVariableSuite randomVariableSuite
Static variable for test initialization.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
-ns3 Test suite for the ns3 wrapper script