A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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/rng-seed-manager.h"
38 #include "ns3/random-variable-stream.h"
39 
40 using namespace ns3;
41 
42 namespace {
43 
44 void
45 FillHistoRangeUniformly (double *array, uint32_t n, double start, double end)
46 {
47  double increment = (end - start) / (n - 1.);
48  double d = start;
49 
50  for (uint32_t i = 0; i < n; ++i)
51  {
52  array[i] = d;
53  d += increment;
54  }
55 }
56 
57 } // anonymous namespace
58 
59 // ===========================================================================
60 // Test case for uniform distribution random variable stream generator
61 // ===========================================================================
63 {
64 public:
65  static const uint32_t N_RUNS = 5;
66  static const uint32_t N_BINS = 50;
67  static const uint32_t N_MEASUREMENTS = 1000000;
68 
71 
72  double ChiSquaredTest (Ptr<UniformRandomVariable> u);
73 
74 private:
75  virtual void DoRun (void);
76 };
77 
79  : TestCase ("Uniform Random Variable Stream Generator")
80 {
81 }
82 
84 {
85 }
86 
87 double
89 {
90  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
91 
92  // Note that this assumes that the range for u is [0,1], which is
93  // the default range for this distribution.
94  gsl_histogram_set_ranges_uniform (h, 0., 1.);
95 
96  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
97  {
98  gsl_histogram_increment (h, u->GetValue ());
99  }
100 
101  double tmp[N_BINS];
102 
103  double expected = ((double)N_MEASUREMENTS / (double)N_BINS);
104 
105  for (uint32_t i = 0; i < N_BINS; ++i)
106  {
107  tmp[i] = gsl_histogram_get (h, i);
108  tmp[i] -= expected;
109  tmp[i] *= tmp[i];
110  tmp[i] /= expected;
111  }
112 
113  gsl_histogram_free (h);
114 
115  double chiSquared = 0;
116 
117  for (uint32_t i = 0; i < N_BINS; ++i)
118  {
119  chiSquared += tmp[i];
120  }
121 
122  return chiSquared;
123 }
124 
125 void
127 {
128  SeedManager::SetSeed (time (0));
129 
130  double sum = 0.;
131  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
132 
133  for (uint32_t i = 0; i < N_RUNS; ++i)
134  {
135  Ptr<UniformRandomVariable> u = CreateObject<UniformRandomVariable> ();
136  double result = ChiSquaredTest (u);
137  sum += result;
138  }
139 
140  sum /= (double)N_RUNS;
141 
142  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
143 
144  double min = 0.0;
145  double max = 10.0;
146  double value;
147 
148  // Create the RNG with the specified range.
149  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
150 
151  x->SetAttribute ("Min", DoubleValue (min));
152  x->SetAttribute ("Max", DoubleValue (max));
153 
154  // Test that values are always within the range:
155  //
156  // [min, max)
157  //
158  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
159  {
160  value = x->GetValue ();
161  NS_TEST_ASSERT_MSG_EQ ((value >= min), true, "Value less than minimum.");
162  NS_TEST_ASSERT_MSG_LT (value, max, "Value greater than or equal to maximum.");
163  }
164 
165 
166 }
167 
168 // ===========================================================================
169 // Test case for antithetic uniform distribution random variable stream generator
170 // ===========================================================================
172 {
173 public:
174  static const uint32_t N_RUNS = 5;
175  static const uint32_t N_BINS = 50;
176  static const uint32_t N_MEASUREMENTS = 1000000;
177 
180 
182 
183 private:
184  virtual void DoRun (void);
185 };
186 
188  : TestCase ("Antithetic Uniform Random Variable Stream Generator")
189 {
190 }
191 
193 {
194 }
195 
196 double
198 {
199  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
200 
201  // Note that this assumes that the range for u is [0,1], which is
202  // the default range for this distribution.
203  gsl_histogram_set_ranges_uniform (h, 0., 1.);
204 
205  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
206  {
207  gsl_histogram_increment (h, u->GetValue ());
208  }
209 
210  double tmp[N_BINS];
211 
212  double expected = ((double)N_MEASUREMENTS / (double)N_BINS);
213 
214  for (uint32_t i = 0; i < N_BINS; ++i)
215  {
216  tmp[i] = gsl_histogram_get (h, i);
217  tmp[i] -= expected;
218  tmp[i] *= tmp[i];
219  tmp[i] /= expected;
220  }
221 
222  gsl_histogram_free (h);
223 
224  double chiSquared = 0;
225 
226  for (uint32_t i = 0; i < N_BINS; ++i)
227  {
228  chiSquared += tmp[i];
229  }
230 
231  return chiSquared;
232 }
233 
234 void
236 {
237  SeedManager::SetSeed (time (0));
238 
239  double sum = 0.;
240  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
241 
242  for (uint32_t i = 0; i < N_RUNS; ++i)
243  {
244  Ptr<UniformRandomVariable> u = CreateObject<UniformRandomVariable> ();
245 
246  // Make this generate antithetic values.
247  u->SetAttribute ("Antithetic", BooleanValue (true));
248 
249  double result = ChiSquaredTest (u);
250  sum += result;
251  }
252 
253  sum /= (double)N_RUNS;
254 
255  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
256 
257  double min = 0.0;
258  double max = 10.0;
259  double value;
260 
261  // Create the RNG with the specified range.
262  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
263 
264  // Make this generate antithetic values.
265  x->SetAttribute ("Antithetic", BooleanValue (true));
266 
267  x->SetAttribute ("Min", DoubleValue (min));
268  x->SetAttribute ("Max", DoubleValue (max));
269 
270  // Test that values are always within the range:
271  //
272  // [min, max)
273  //
274  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
275  {
276  value = x->GetValue ();
277  NS_TEST_ASSERT_MSG_EQ ((value >= min), true, "Value less than minimum.");
278  NS_TEST_ASSERT_MSG_LT (value, max, "Value greater than or equal to maximum.");
279  }
280 
281 
282 }
283 
284 // ===========================================================================
285 // Test case for constant random variable stream generator
286 // ===========================================================================
288 {
289 public:
290  static const uint32_t N_MEASUREMENTS = 1000000;
291  static const double TOLERANCE = 1e-8;
292 
295 
296 private:
297  virtual void DoRun (void);
298 };
299 
301  : TestCase ("Constant Random Variable Stream Generator")
302 {
303 }
304 
306 {
307 }
308 
309 void
311 {
312  SeedManager::SetSeed (time (0));
313 
314  Ptr<ConstantRandomVariable> c = CreateObject<ConstantRandomVariable> ();
315 
316  double constant;
317 
318  // Test that the constant value can be changed using its attribute.
319  constant = 10.0;
320  c->SetAttribute ("Constant", DoubleValue (constant));
321  NS_TEST_ASSERT_MSG_EQ_TOL (c->GetValue (), constant, TOLERANCE, "Constant value changed");
322  c->SetAttribute ("Constant", DoubleValue (20.0));
323  NS_TEST_ASSERT_MSG_NE (c->GetValue (), constant, "Constant value not changed");
324 
325  // Test that the constant value does not change.
326  constant = c->GetValue ();
327  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
328  {
329  NS_TEST_ASSERT_MSG_EQ_TOL (c->GetValue (), constant, TOLERANCE, "Constant value changed in loop");
330  }
331 }
332 
333 // ===========================================================================
334 // Test case for sequential random variable stream generator
335 // ===========================================================================
337 {
338 public:
339  static const double TOLERANCE = 1e-8;
340 
343 
344 private:
345  virtual void DoRun (void);
346 };
347 
349  : TestCase ("Sequential Random Variable Stream Generator")
350 {
351 }
352 
354 {
355 }
356 
357 void
359 {
360  SeedManager::SetSeed (time (0));
361 
362  Ptr<SequentialRandomVariable> s = CreateObject<SequentialRandomVariable> ();
363 
364  // The following four attributes should give the sequence
365  //
366  // 4, 4, 7, 7, 10, 10
367  //
368  s->SetAttribute ("Min", DoubleValue (4));
369  s->SetAttribute ("Max", DoubleValue (11));
370  s->SetAttribute ("Increment", StringValue("ns3::UniformRandomVariable[Min=3.0|Max=3.0]"));
371  s->SetAttribute ("Consecutive", IntegerValue (2));
372 
373  double value;
374 
375  // Test that the sequencet is correct.
376  value = s->GetValue ();
377  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence value 1 wrong.");
378  value = s->GetValue ();
379  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence value 2 wrong.");
380  value = s->GetValue ();
381  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence value 3 wrong.");
382  value = s->GetValue ();
383  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence value 4 wrong.");
384  value = s->GetValue ();
385  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence value 5 wrong.");
386  value = s->GetValue ();
387  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence value 6 wrong.");
388 
389 }
390 
391 // ===========================================================================
392 // Test case for normal distribution random variable stream generator
393 // ===========================================================================
395 {
396 public:
397  static const uint32_t N_RUNS = 5;
398  static const uint32_t N_BINS = 50;
399  static const uint32_t N_MEASUREMENTS = 1000000;
400 
403 
405 
406 private:
407  virtual void DoRun (void);
408 };
409 
411  : TestCase ("Normal Random Variable Stream Generator")
412 {
413 }
414 
416 {
417 }
418 
419 double
421 {
422  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
423 
424  double range[N_BINS + 1];
425  FillHistoRangeUniformly (range, N_BINS + 1, -4., 4.);
426  range[0] = -std::numeric_limits<double>::max ();
427  range[N_BINS] = std::numeric_limits<double>::max ();
428 
429  gsl_histogram_set_ranges (h, range, N_BINS + 1);
430 
431  double expected[N_BINS];
432 
433  // Note that this assumes that n has mean equal to zero and standard
434  // deviation equal to one, which are their default values for this
435  // distribution.
436  double sigma = 1.;
437 
438  for (uint32_t i = 0; i < N_BINS; ++i)
439  {
440  expected[i] = gsl_cdf_gaussian_P (range[i + 1], sigma) - gsl_cdf_gaussian_P (range[i], sigma);
441  expected[i] *= N_MEASUREMENTS;
442  }
443 
444  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
445  {
446  gsl_histogram_increment (h, n->GetValue ());
447  }
448 
449  double tmp[N_BINS];
450 
451  for (uint32_t i = 0; i < N_BINS; ++i)
452  {
453  tmp[i] = gsl_histogram_get (h, i);
454  tmp[i] -= expected[i];
455  tmp[i] *= tmp[i];
456  tmp[i] /= expected[i];
457  }
458 
459  gsl_histogram_free (h);
460 
461  double chiSquared = 0;
462 
463  for (uint32_t i = 0; i < N_BINS; ++i)
464  {
465  chiSquared += tmp[i];
466  }
467 
468  return chiSquared;
469 }
470 
471 void
473 {
474  SeedManager::SetSeed (time (0));
475 
476  double sum = 0.;
477  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
478 
479  for (uint32_t i = 0; i < N_RUNS; ++i)
480  {
481  Ptr<NormalRandomVariable> n = CreateObject<NormalRandomVariable> ();
482  double result = ChiSquaredTest (n);
483  sum += result;
484  }
485 
486  sum /= (double)N_RUNS;
487 
488  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
489 
490  double mean = 5.0;
491  double variance = 2.0;
492  double value;
493 
494  // Create the RNG with the specified range.
495  Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> ();
496  x->SetAttribute ("Mean", DoubleValue (mean));
497  x->SetAttribute ("Variance", DoubleValue (variance));
498 
499  // Calculate the mean of these values.
500  sum = 0.0;
501  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
502  {
503  value = x->GetValue ();
504  sum += value;
505  }
506  double valueMean = sum / N_MEASUREMENTS;
507 
508  // The expected value for the mean of the values returned by a
509  // normally distributed random variable is equal to mean.
510  double expectedMean = mean;
511 
512  // Test that values have approximately the right mean value.
513  double TOLERANCE = expectedMean * 1e-2;
514  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
515 }
516 
517 // ===========================================================================
518 // Test case for antithetic normal distribution random variable stream generator
519 // ===========================================================================
521 {
522 public:
523  static const uint32_t N_RUNS = 5;
524  static const uint32_t N_BINS = 50;
525  static const uint32_t N_MEASUREMENTS = 1000000;
526 
529 
531 
532 private:
533  virtual void DoRun (void);
534 };
535 
537  : TestCase ("Antithetic Normal Random Variable Stream Generator")
538 {
539 }
540 
542 {
543 }
544 
545 double
547 {
548  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
549 
550  double range[N_BINS + 1];
551  FillHistoRangeUniformly (range, N_BINS + 1, -4., 4.);
552  range[0] = -std::numeric_limits<double>::max ();
553  range[N_BINS] = std::numeric_limits<double>::max ();
554 
555  gsl_histogram_set_ranges (h, range, N_BINS + 1);
556 
557  double expected[N_BINS];
558 
559  // Note that this assumes that n has mean equal to zero and standard
560  // deviation equal to one, which are their default values for this
561  // distribution.
562  double sigma = 1.;
563 
564  for (uint32_t i = 0; i < N_BINS; ++i)
565  {
566  expected[i] = gsl_cdf_gaussian_P (range[i + 1], sigma) - gsl_cdf_gaussian_P (range[i], sigma);
567  expected[i] *= N_MEASUREMENTS;
568  }
569 
570  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
571  {
572  gsl_histogram_increment (h, n->GetValue ());
573  }
574 
575  double tmp[N_BINS];
576 
577  for (uint32_t i = 0; i < N_BINS; ++i)
578  {
579  tmp[i] = gsl_histogram_get (h, i);
580  tmp[i] -= expected[i];
581  tmp[i] *= tmp[i];
582  tmp[i] /= expected[i];
583  }
584 
585  gsl_histogram_free (h);
586 
587  double chiSquared = 0;
588 
589  for (uint32_t i = 0; i < N_BINS; ++i)
590  {
591  chiSquared += tmp[i];
592  }
593 
594  return chiSquared;
595 }
596 
597 void
599 {
600  SeedManager::SetSeed (time (0));
601 
602  double sum = 0.;
603  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
604 
605  for (uint32_t i = 0; i < N_RUNS; ++i)
606  {
607  Ptr<NormalRandomVariable> n = CreateObject<NormalRandomVariable> ();
608 
609  // Make this generate antithetic values.
610  n->SetAttribute ("Antithetic", BooleanValue (true));
611 
612  double result = ChiSquaredTest (n);
613  sum += result;
614  }
615 
616  sum /= (double)N_RUNS;
617 
618  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
619 
620  double mean = 5.0;
621  double variance = 2.0;
622  double value;
623 
624  // Create the RNG with the specified range.
625  Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> ();
626  x->SetAttribute ("Mean", DoubleValue (mean));
627  x->SetAttribute ("Variance", DoubleValue (variance));
628 
629  // Make this generate antithetic values.
630  x->SetAttribute ("Antithetic", BooleanValue (true));
631 
632  // Calculate the mean of these values.
633  sum = 0.0;
634  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
635  {
636  value = x->GetValue ();
637  sum += value;
638  }
639  double valueMean = sum / N_MEASUREMENTS;
640 
641  // The expected value for the mean of the values returned by a
642  // normally distributed random variable is equal to mean.
643  double expectedMean = mean;
644 
645  // Test that values have approximately the right mean value.
646  double TOLERANCE = expectedMean * 1e-2;
647  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
648 }
649 
650 // ===========================================================================
651 // Test case for exponential distribution random variable stream generator
652 // ===========================================================================
654 {
655 public:
656  static const uint32_t N_RUNS = 5;
657  static const uint32_t N_BINS = 50;
658  static const uint32_t N_MEASUREMENTS = 1000000;
659 
662 
664 
665 private:
666  virtual void DoRun (void);
667 };
668 
670  : TestCase ("Exponential Random Variable Stream Generator")
671 {
672 }
673 
675 {
676 }
677 
678 double
680 {
681  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
682 
683  double range[N_BINS + 1];
684  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
685  range[N_BINS] = std::numeric_limits<double>::max ();
686 
687  gsl_histogram_set_ranges (h, range, N_BINS + 1);
688 
689  double expected[N_BINS];
690 
691  // Note that this assumes that e has mean equal to one, which is the
692  // default value for this distribution.
693  double mu = 1.;
694 
695  for (uint32_t i = 0; i < N_BINS; ++i)
696  {
697  expected[i] = gsl_cdf_exponential_P (range[i + 1], mu) - gsl_cdf_exponential_P (range[i], mu);
698  expected[i] *= N_MEASUREMENTS;
699  }
700 
701  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
702  {
703  gsl_histogram_increment (h, e->GetValue ());
704  }
705 
706  double tmp[N_BINS];
707 
708  for (uint32_t i = 0; i < N_BINS; ++i)
709  {
710  tmp[i] = gsl_histogram_get (h, i);
711  tmp[i] -= expected[i];
712  tmp[i] *= tmp[i];
713  tmp[i] /= expected[i];
714  }
715 
716  gsl_histogram_free (h);
717 
718  double chiSquared = 0;
719 
720  for (uint32_t i = 0; i < N_BINS; ++i)
721  {
722  chiSquared += tmp[i];
723  }
724 
725  return chiSquared;
726 }
727 
728 void
730 {
731  SeedManager::SetSeed (time (0));
732 
733  double sum = 0.;
734  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
735 
736  for (uint32_t i = 0; i < N_RUNS; ++i)
737  {
738  Ptr<ExponentialRandomVariable> e = CreateObject<ExponentialRandomVariable> ();
739  double result = ChiSquaredTest (e);
740  sum += result;
741  }
742 
743  sum /= (double)N_RUNS;
744 
745  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
746 
747  double mean = 3.14;
748  double bound = 0.0;
749  double value;
750 
751  // Create the RNG with the specified range.
752  Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> ();
753  x->SetAttribute ("Mean", DoubleValue (mean));
754  x->SetAttribute ("Bound", DoubleValue (bound));
755 
756  // Calculate the mean of these values.
757  sum = 0.0;
758  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
759  {
760  value = x->GetValue ();
761  sum += value;
762  }
763  double valueMean = sum / N_MEASUREMENTS;
764 
765  // Test that values have approximately the right mean value.
766  double TOLERANCE = mean * 1e-2;
767  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, mean, TOLERANCE, "Wrong mean value.");
768 }
769 
770 // ===========================================================================
771 // Test case for antithetic exponential distribution random variable stream generator
772 // ===========================================================================
774 {
775 public:
776  static const uint32_t N_RUNS = 5;
777  static const uint32_t N_BINS = 50;
778  static const uint32_t N_MEASUREMENTS = 1000000;
779 
782 
784 
785 private:
786  virtual void DoRun (void);
787 };
788 
790  : TestCase ("Antithetic Exponential Random Variable Stream Generator")
791 {
792 }
793 
795 {
796 }
797 
798 double
800 {
801  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
802 
803  double range[N_BINS + 1];
804  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
805  range[N_BINS] = std::numeric_limits<double>::max ();
806 
807  gsl_histogram_set_ranges (h, range, N_BINS + 1);
808 
809  double expected[N_BINS];
810 
811  // Note that this assumes that e has mean equal to one, which is the
812  // default value for this distribution.
813  double mu = 1.;
814 
815  for (uint32_t i = 0; i < N_BINS; ++i)
816  {
817  expected[i] = gsl_cdf_exponential_P (range[i + 1], mu) - gsl_cdf_exponential_P (range[i], mu);
818  expected[i] *= N_MEASUREMENTS;
819  }
820 
821  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
822  {
823  gsl_histogram_increment (h, e->GetValue ());
824  }
825 
826  double tmp[N_BINS];
827 
828  for (uint32_t i = 0; i < N_BINS; ++i)
829  {
830  tmp[i] = gsl_histogram_get (h, i);
831  tmp[i] -= expected[i];
832  tmp[i] *= tmp[i];
833  tmp[i] /= expected[i];
834  }
835 
836  gsl_histogram_free (h);
837 
838  double chiSquared = 0;
839 
840  for (uint32_t i = 0; i < N_BINS; ++i)
841  {
842  chiSquared += tmp[i];
843  }
844 
845  return chiSquared;
846 }
847 
848 void
850 {
851  SeedManager::SetSeed (time (0));
852 
853  double sum = 0.;
854  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
855 
856  for (uint32_t i = 0; i < N_RUNS; ++i)
857  {
858  Ptr<ExponentialRandomVariable> e = CreateObject<ExponentialRandomVariable> ();
859 
860  // Make this generate antithetic values.
861  e->SetAttribute ("Antithetic", BooleanValue (true));
862 
863  double result = ChiSquaredTest (e);
864  sum += result;
865  }
866 
867  sum /= (double)N_RUNS;
868 
869  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
870 
871  double mean = 3.14;
872  double bound = 0.0;
873  double value;
874 
875  // Create the RNG with the specified range.
876  Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> ();
877  x->SetAttribute ("Mean", DoubleValue (mean));
878  x->SetAttribute ("Bound", DoubleValue (bound));
879 
880  // Make this generate antithetic values.
881  x->SetAttribute ("Antithetic", BooleanValue (true));
882 
883  // Calculate the mean of these values.
884  sum = 0.0;
885  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
886  {
887  value = x->GetValue ();
888  sum += value;
889  }
890  double valueMean = sum / N_MEASUREMENTS;
891 
892  // Test that values have approximately the right mean value.
893  double TOLERANCE = mean * 1e-2;
894  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, mean, TOLERANCE, "Wrong mean value.");
895 }
896 
897 // ===========================================================================
898 // Test case for Pareto distribution random variable stream generator
899 // ===========================================================================
901 {
902 public:
903  static const uint32_t N_RUNS = 5;
904  static const uint32_t N_BINS = 50;
905  static const uint32_t N_MEASUREMENTS = 1000000;
906 
909 
911 
912 private:
913  virtual void DoRun (void);
914 };
915 
917  : TestCase ("Pareto Random Variable Stream Generator")
918 {
919 }
920 
922 {
923 }
924 
925 double
927 {
928  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
929 
930  double range[N_BINS + 1];
931  FillHistoRangeUniformly (range, N_BINS + 1, 1., 10.);
932  range[N_BINS] = std::numeric_limits<double>::max ();
933 
934  gsl_histogram_set_ranges (h, range, N_BINS + 1);
935 
936  double expected[N_BINS];
937 
938  // Note that this assumes that p has mean equal to 1 and shape equal
939  // to 2, which are their default values for this distribution.
940  double mean = 1.0;
941  double shape = 2.0;
942  double scale = mean * (shape - 1.0) / shape;
943 
944  for (uint32_t i = 0; i < N_BINS; ++i)
945  {
946  expected[i] = gsl_cdf_pareto_P (range[i + 1], shape, scale) - gsl_cdf_pareto_P (range[i], shape, scale);
947  expected[i] *= N_MEASUREMENTS;
948  }
949 
950  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
951  {
952  gsl_histogram_increment (h, p->GetValue ());
953  }
954 
955  double tmp[N_BINS];
956 
957  for (uint32_t i = 0; i < N_BINS; ++i)
958  {
959  tmp[i] = gsl_histogram_get (h, i);
960  tmp[i] -= expected[i];
961  tmp[i] *= tmp[i];
962  tmp[i] /= expected[i];
963  }
964 
965  gsl_histogram_free (h);
966 
967  double chiSquared = 0;
968 
969  for (uint32_t i = 0; i < N_BINS; ++i)
970  {
971  chiSquared += tmp[i];
972  }
973 
974  return chiSquared;
975 }
976 
977 void
979 {
980  SeedManager::SetSeed (time (0));
981 
982  double sum = 0.;
983  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
984 
985  for (uint32_t i = 0; i < N_RUNS; ++i)
986  {
987  Ptr<ParetoRandomVariable> e = CreateObject<ParetoRandomVariable> ();
988  double result = ChiSquaredTest (e);
989  sum += result;
990  }
991 
992  sum /= (double)N_RUNS;
993 
994  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
995 
996  double mean = 5.0;
997  double shape = 2.0;
998  double scale = mean * (shape - 1.0) / shape;
999  double value;
1000 
1001  // Create the RNG with the specified range.
1002  Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
1003  x->SetAttribute ("Mean", DoubleValue (mean));
1004  x->SetAttribute ("Shape", DoubleValue (shape));
1005 
1006  // Calculate the mean of these values.
1007  sum = 0.0;
1008  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1009  {
1010  value = x->GetValue ();
1011  sum += value;
1012  }
1013  double valueMean = sum / N_MEASUREMENTS;
1014 
1015  // The expected value for the mean is given by
1016  //
1017  // shape * scale
1018  // E[value] = --------------- ,
1019  // shape - 1
1020  //
1021  // where
1022  //
1023  // scale = mean * (shape - 1.0) / shape .
1024  double expectedMean = (shape * scale) / (shape - 1.0);
1025 
1026  // Test that values have approximately the right mean value.
1027  double TOLERANCE = expectedMean * 1e-2;
1028  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1029 }
1030 
1031 // ===========================================================================
1032 // Test case for antithetic Pareto distribution random variable stream generator
1033 // ===========================================================================
1035 {
1036 public:
1037  static const uint32_t N_RUNS = 5;
1038  static const uint32_t N_BINS = 50;
1039  static const uint32_t N_MEASUREMENTS = 1000000;
1040 
1043 
1045 
1046 private:
1047  virtual void DoRun (void);
1048 };
1049 
1051  : TestCase ("Antithetic Pareto Random Variable Stream Generator")
1052 {
1053 }
1054 
1056 {
1057 }
1058 
1059 double
1061 {
1062  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1063 
1064  double range[N_BINS + 1];
1065  FillHistoRangeUniformly (range, N_BINS + 1, 1., 10.);
1066  range[N_BINS] = std::numeric_limits<double>::max ();
1067 
1068  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1069 
1070  double expected[N_BINS];
1071 
1072  // Note that this assumes that p has mean equal to 1 and shape equal
1073  // to 2, which are their default values for this distribution.
1074  double mean = 1.0;
1075  double shape = 2.0;
1076  double scale = mean * (shape - 1.0) / shape;
1077 
1078  for (uint32_t i = 0; i < N_BINS; ++i)
1079  {
1080  expected[i] = gsl_cdf_pareto_P (range[i + 1], shape, scale) - gsl_cdf_pareto_P (range[i], shape, scale);
1081  expected[i] *= N_MEASUREMENTS;
1082  }
1083 
1084  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1085  {
1086  gsl_histogram_increment (h, p->GetValue ());
1087  }
1088 
1089  double tmp[N_BINS];
1090 
1091  for (uint32_t i = 0; i < N_BINS; ++i)
1092  {
1093  tmp[i] = gsl_histogram_get (h, i);
1094  tmp[i] -= expected[i];
1095  tmp[i] *= tmp[i];
1096  tmp[i] /= expected[i];
1097  }
1098 
1099  gsl_histogram_free (h);
1100 
1101  double chiSquared = 0;
1102 
1103  for (uint32_t i = 0; i < N_BINS; ++i)
1104  {
1105  chiSquared += tmp[i];
1106  }
1107 
1108  return chiSquared;
1109 }
1110 
1111 void
1113 {
1114  SeedManager::SetSeed (time (0));
1115 
1116  double sum = 0.;
1117  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1118 
1119  for (uint32_t i = 0; i < N_RUNS; ++i)
1120  {
1121  Ptr<ParetoRandomVariable> e = CreateObject<ParetoRandomVariable> ();
1122 
1123  // Make this generate antithetic values.
1124  e->SetAttribute ("Antithetic", BooleanValue (true));
1125 
1126  double result = ChiSquaredTest (e);
1127  sum += result;
1128  }
1129 
1130  sum /= (double)N_RUNS;
1131 
1132  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1133 
1134  double mean = 5.0;
1135  double shape = 2.0;
1136  double scale = mean * (shape - 1.0) / shape;
1137  double value;
1138 
1139  // Create the RNG with the specified range.
1140  Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
1141  x->SetAttribute ("Mean", DoubleValue (mean));
1142  x->SetAttribute ("Shape", DoubleValue (shape));
1143 
1144  // Make this generate antithetic values.
1145  x->SetAttribute ("Antithetic", BooleanValue (true));
1146 
1147  // Calculate the mean of these values.
1148  sum = 0.0;
1149  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1150  {
1151  value = x->GetValue ();
1152  sum += value;
1153  }
1154  double valueMean = sum / N_MEASUREMENTS;
1155 
1156  // The expected value for the mean is given by
1157  //
1158  // shape * scale
1159  // E[value] = --------------- ,
1160  // shape - 1
1161  //
1162  // where
1163  //
1164  // scale = mean * (shape - 1.0) / shape .
1165  //
1166  double expectedMean = (shape * scale) / (shape - 1.0);
1167 
1168  // Test that values have approximately the right mean value.
1169  double TOLERANCE = expectedMean * 1e-2;
1170  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1171 }
1172 
1173 // ===========================================================================
1174 // Test case for Weibull distribution random variable stream generator
1175 // ===========================================================================
1177 {
1178 public:
1179  static const uint32_t N_RUNS = 5;
1180  static const uint32_t N_BINS = 50;
1181  static const uint32_t N_MEASUREMENTS = 1000000;
1182 
1185 
1187 
1188 private:
1189  virtual void DoRun (void);
1190 };
1191 
1193  : TestCase ("Weibull Random Variable Stream Generator")
1194 {
1195 }
1196 
1198 {
1199 }
1200 
1201 double
1203 {
1204  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1205 
1206  double range[N_BINS + 1];
1207  FillHistoRangeUniformly (range, N_BINS + 1, 1., 10.);
1208  range[N_BINS] = std::numeric_limits<double>::max ();
1209 
1210  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1211 
1212  double expected[N_BINS];
1213 
1214  // Note that this assumes that p has shape equal to one and scale
1215  // equal to one, which are their default values for this
1216  // distribution.
1217  double a = 1.0;
1218  double b = 1.0;
1219 
1220  for (uint32_t i = 0; i < N_BINS; ++i)
1221  {
1222  expected[i] = gsl_cdf_weibull_P (range[i + 1], a, b) - gsl_cdf_weibull_P (range[i], a, b);
1223  expected[i] *= N_MEASUREMENTS;
1224  }
1225 
1226  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1227  {
1228  gsl_histogram_increment (h, p->GetValue ());
1229  }
1230 
1231  double tmp[N_BINS];
1232 
1233  for (uint32_t i = 0; i < N_BINS; ++i)
1234  {
1235  tmp[i] = gsl_histogram_get (h, i);
1236  tmp[i] -= expected[i];
1237  tmp[i] *= tmp[i];
1238  tmp[i] /= expected[i];
1239  }
1240 
1241  gsl_histogram_free (h);
1242 
1243  double chiSquared = 0;
1244 
1245  for (uint32_t i = 0; i < N_BINS; ++i)
1246  {
1247  chiSquared += tmp[i];
1248  }
1249 
1250  return chiSquared;
1251 }
1252 
1253 void
1255 {
1256  SeedManager::SetSeed (time (0));
1257 
1258  double sum = 0.;
1259  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1260 
1261  for (uint32_t i = 0; i < N_RUNS; ++i)
1262  {
1263  Ptr<WeibullRandomVariable> e = CreateObject<WeibullRandomVariable> ();
1264  double result = ChiSquaredTest (e);
1265  sum += result;
1266  }
1267 
1268  sum /= (double)N_RUNS;
1269 
1270  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1271 
1272  double scale = 5.0;
1273  double shape = 1.0;
1274  double value;
1275 
1276  // Create the RNG with the specified range.
1277  Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> ();
1278  x->SetAttribute ("Scale", DoubleValue (scale));
1279  x->SetAttribute ("Shape", DoubleValue (shape));
1280 
1281  // Calculate the mean of these values.
1282  sum = 0.0;
1283  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1284  {
1285  value = x->GetValue ();
1286  sum += value;
1287  }
1288  double valueMean = sum / N_MEASUREMENTS;
1289 
1290  // The expected value for the mean of the values returned by a
1291  // Weibull distributed random variable is
1292  //
1293  // E[value] = scale * Gamma(1 + 1 / shape) ,
1294  //
1295  // where Gamma() is the Gamma function. Note that
1296  //
1297  // Gamma(n) = (n - 1)!
1298  //
1299  // if n is a positive integer.
1300  //
1301  // For this test,
1302  //
1303  // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1304  // = Gamma(2)
1305  // = (2 - 1)!
1306  // = 1
1307  //
1308  // which means
1309  //
1310  // E[value] = scale .
1311  //
1312  double expectedMean = scale;
1313 
1314  // Test that values have approximately the right mean value.
1315  double TOLERANCE = expectedMean * 1e-2;
1316  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1317 }
1318 
1319 // ===========================================================================
1320 // Test case for antithetic Weibull distribution random variable stream generator
1321 // ===========================================================================
1323 {
1324 public:
1325  static const uint32_t N_RUNS = 5;
1326  static const uint32_t N_BINS = 50;
1327  static const uint32_t N_MEASUREMENTS = 1000000;
1328 
1331 
1333 
1334 private:
1335  virtual void DoRun (void);
1336 };
1337 
1339  : TestCase ("Antithetic Weibull Random Variable Stream Generator")
1340 {
1341 }
1342 
1344 {
1345 }
1346 
1347 double
1349 {
1350  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1351 
1352  double range[N_BINS + 1];
1353  FillHistoRangeUniformly (range, N_BINS + 1, 1., 10.);
1354  range[N_BINS] = std::numeric_limits<double>::max ();
1355 
1356  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1357 
1358  double expected[N_BINS];
1359 
1360  // Note that this assumes that p has shape equal to one and scale
1361  // equal to one, which are their default values for this
1362  // distribution.
1363  double a = 1.0;
1364  double b = 1.0;
1365 
1366  for (uint32_t i = 0; i < N_BINS; ++i)
1367  {
1368  expected[i] = gsl_cdf_weibull_P (range[i + 1], a, b) - gsl_cdf_weibull_P (range[i], a, b);
1369  expected[i] *= N_MEASUREMENTS;
1370  }
1371 
1372  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1373  {
1374  gsl_histogram_increment (h, p->GetValue ());
1375  }
1376 
1377  double tmp[N_BINS];
1378 
1379  for (uint32_t i = 0; i < N_BINS; ++i)
1380  {
1381  tmp[i] = gsl_histogram_get (h, i);
1382  tmp[i] -= expected[i];
1383  tmp[i] *= tmp[i];
1384  tmp[i] /= expected[i];
1385  }
1386 
1387  gsl_histogram_free (h);
1388 
1389  double chiSquared = 0;
1390 
1391  for (uint32_t i = 0; i < N_BINS; ++i)
1392  {
1393  chiSquared += tmp[i];
1394  }
1395 
1396  return chiSquared;
1397 }
1398 
1399 void
1401 {
1402  SeedManager::SetSeed (time (0));
1403 
1404  double sum = 0.;
1405  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1406 
1407  for (uint32_t i = 0; i < N_RUNS; ++i)
1408  {
1409  Ptr<WeibullRandomVariable> e = CreateObject<WeibullRandomVariable> ();
1410 
1411  // Make this generate antithetic values.
1412  e->SetAttribute ("Antithetic", BooleanValue (true));
1413 
1414  double result = ChiSquaredTest (e);
1415  sum += result;
1416  }
1417 
1418  sum /= (double)N_RUNS;
1419 
1420  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1421 
1422  double scale = 5.0;
1423  double shape = 1.0;
1424  double value;
1425 
1426  // Create the RNG with the specified range.
1427  Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> ();
1428  x->SetAttribute ("Scale", DoubleValue (scale));
1429  x->SetAttribute ("Shape", DoubleValue (shape));
1430 
1431  // Make this generate antithetic values.
1432  x->SetAttribute ("Antithetic", BooleanValue (true));
1433 
1434  // Calculate the mean of these values.
1435  sum = 0.0;
1436  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1437  {
1438  value = x->GetValue ();
1439  sum += value;
1440  }
1441  double valueMean = sum / N_MEASUREMENTS;
1442 
1443  // The expected value for the mean of the values returned by a
1444  // Weibull distributed random variable is
1445  //
1446  // E[value] = scale * Gamma(1 + 1 / shape) ,
1447  //
1448  // where Gamma() is the Gamma function. Note that
1449  //
1450  // Gamma(n) = (n - 1)!
1451  //
1452  // if n is a positive integer.
1453  //
1454  // For this test,
1455  //
1456  // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1457  // = Gamma(2)
1458  // = (2 - 1)!
1459  // = 1
1460  //
1461  // which means
1462  //
1463  // E[value] = scale .
1464  //
1465  double expectedMean = scale;
1466 
1467  // Test that values have approximately the right mean value.
1468  double TOLERANCE = expectedMean * 1e-2;
1469  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1470 }
1471 
1472 // ===========================================================================
1473 // Test case for log-normal distribution random variable stream generator
1474 // ===========================================================================
1476 {
1477 public:
1478  static const uint32_t N_RUNS = 5;
1479  static const uint32_t N_BINS = 50;
1480  static const uint32_t N_MEASUREMENTS = 1000000;
1481 
1484 
1486 
1487 private:
1488  virtual void DoRun (void);
1489 };
1490 
1492  : TestCase ("Log-Normal Random Variable Stream Generator")
1493 {
1494 }
1495 
1497 {
1498 }
1499 
1500 double
1502 {
1503  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1504 
1505  double range[N_BINS + 1];
1506  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
1507  range[N_BINS] = std::numeric_limits<double>::max ();
1508 
1509  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1510 
1511  double expected[N_BINS];
1512 
1513  // Note that this assumes that n has mu equal to zero and sigma
1514  // equal to one, which are their default values for this
1515  // distribution.
1516  double mu = 0.0;
1517  double sigma = 1.0;
1518 
1519  for (uint32_t i = 0; i < N_BINS; ++i)
1520  {
1521  expected[i] = gsl_cdf_lognormal_P (range[i + 1], mu, sigma) - gsl_cdf_lognormal_P (range[i], mu, sigma);
1522  expected[i] *= N_MEASUREMENTS;
1523  }
1524 
1525  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1526  {
1527  gsl_histogram_increment (h, n->GetValue ());
1528  }
1529 
1530  double tmp[N_BINS];
1531 
1532  for (uint32_t i = 0; i < N_BINS; ++i)
1533  {
1534  tmp[i] = gsl_histogram_get (h, i);
1535  tmp[i] -= expected[i];
1536  tmp[i] *= tmp[i];
1537  tmp[i] /= expected[i];
1538  }
1539 
1540  gsl_histogram_free (h);
1541 
1542  double chiSquared = 0;
1543 
1544  for (uint32_t i = 0; i < N_BINS; ++i)
1545  {
1546  chiSquared += tmp[i];
1547  }
1548 
1549  return chiSquared;
1550 }
1551 
1552 void
1554 {
1555  SeedManager::SetSeed (time (0));
1556 
1557  double sum = 0.;
1558  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1559 
1560  for (uint32_t i = 0; i < N_RUNS; ++i)
1561  {
1562  Ptr<LogNormalRandomVariable> n = CreateObject<LogNormalRandomVariable> ();
1563  double result = ChiSquaredTest (n);
1564  sum += result;
1565  }
1566 
1567  sum /= (double)N_RUNS;
1568 
1569  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1570 
1571  double mu = 5.0;
1572  double sigma = 2.0;
1573  double value;
1574 
1575  // Create the RNG with the specified range.
1576  Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> ();
1577  x->SetAttribute ("Mu", DoubleValue (mu));
1578  x->SetAttribute ("Sigma", DoubleValue (sigma));
1579 
1580  // Calculate the mean of these values.
1581  sum = 0.0;
1582  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1583  {
1584  value = x->GetValue ();
1585  sum += value;
1586  }
1587  double valueMean = sum / N_MEASUREMENTS;
1588 
1589  // The expected value for the mean of the values returned by a
1590  // log-normally distributed random variable is equal to
1591  //
1592  // 2
1593  // mu + sigma / 2
1594  // E[value] = e .
1595  //
1596  double expectedMean = std::exp(mu + sigma * sigma / 2.0);
1597 
1598  // Test that values have approximately the right mean value.
1599  //
1604  double TOLERANCE = expectedMean * 3e-2;
1605  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1606 }
1607 
1608 // ===========================================================================
1609 // Test case for antithetic log-normal distribution random variable stream generator
1610 // ===========================================================================
1612 {
1613 public:
1614  static const uint32_t N_RUNS = 5;
1615  static const uint32_t N_BINS = 50;
1616  static const uint32_t N_MEASUREMENTS = 1000000;
1617 
1620 
1622 
1623 private:
1624  virtual void DoRun (void);
1625 };
1626 
1628  : TestCase ("Antithetic Log-Normal Random Variable Stream Generator")
1629 {
1630 }
1631 
1633 {
1634 }
1635 
1636 double
1638 {
1639  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1640 
1641  double range[N_BINS + 1];
1642  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
1643  range[N_BINS] = std::numeric_limits<double>::max ();
1644 
1645  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1646 
1647  double expected[N_BINS];
1648 
1649  // Note that this assumes that n has mu equal to zero and sigma
1650  // equal to one, which are their default values for this
1651  // distribution.
1652  double mu = 0.0;
1653  double sigma = 1.0;
1654 
1655  for (uint32_t i = 0; i < N_BINS; ++i)
1656  {
1657  expected[i] = gsl_cdf_lognormal_P (range[i + 1], mu, sigma) - gsl_cdf_lognormal_P (range[i], mu, sigma);
1658  expected[i] *= N_MEASUREMENTS;
1659  }
1660 
1661  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1662  {
1663  gsl_histogram_increment (h, n->GetValue ());
1664  }
1665 
1666  double tmp[N_BINS];
1667 
1668  for (uint32_t i = 0; i < N_BINS; ++i)
1669  {
1670  tmp[i] = gsl_histogram_get (h, i);
1671  tmp[i] -= expected[i];
1672  tmp[i] *= tmp[i];
1673  tmp[i] /= expected[i];
1674  }
1675 
1676  gsl_histogram_free (h);
1677 
1678  double chiSquared = 0;
1679 
1680  for (uint32_t i = 0; i < N_BINS; ++i)
1681  {
1682  chiSquared += tmp[i];
1683  }
1684 
1685  return chiSquared;
1686 }
1687 
1688 void
1690 {
1691  SeedManager::SetSeed (time (0));
1692 
1693  double sum = 0.;
1694  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1695 
1696  for (uint32_t i = 0; i < N_RUNS; ++i)
1697  {
1698  Ptr<LogNormalRandomVariable> n = CreateObject<LogNormalRandomVariable> ();
1699 
1700  // Make this generate antithetic values.
1701  n->SetAttribute ("Antithetic", BooleanValue (true));
1702 
1703  double result = ChiSquaredTest (n);
1704  sum += result;
1705  }
1706 
1707  sum /= (double)N_RUNS;
1708 
1709  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1710 
1711  double mu = 5.0;
1712  double sigma = 2.0;
1713  double value;
1714 
1715  // Create the RNG with the specified range.
1716  Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> ();
1717  x->SetAttribute ("Mu", DoubleValue (mu));
1718  x->SetAttribute ("Sigma", DoubleValue (sigma));
1719 
1720  // Make this generate antithetic values.
1721  x->SetAttribute ("Antithetic", BooleanValue (true));
1722 
1723  // Calculate the mean of these values.
1724  sum = 0.0;
1725  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1726  {
1727  value = x->GetValue ();
1728  sum += value;
1729  }
1730  double valueMean = sum / N_MEASUREMENTS;
1731 
1732  // The expected value for the mean of the values returned by a
1733  // log-normally distributed random variable is equal to
1734  //
1735  // 2
1736  // mu + sigma / 2
1737  // E[value] = e .
1738  //
1739  double expectedMean = std::exp(mu + sigma * sigma / 2.0);
1740 
1741  // Test that values have approximately the right mean value.
1742  //
1747  double TOLERANCE = expectedMean * 3e-2;
1748  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1749 }
1750 
1751 // ===========================================================================
1752 // Test case for gamma distribution random variable stream generator
1753 // ===========================================================================
1755 {
1756 public:
1757  static const uint32_t N_RUNS = 5;
1758  static const uint32_t N_BINS = 50;
1759  static const uint32_t N_MEASUREMENTS = 1000000;
1760 
1763 
1765 
1766 private:
1767  virtual void DoRun (void);
1768 };
1769 
1771  : TestCase ("Gamma Random Variable Stream Generator")
1772 {
1773 }
1774 
1776 {
1777 }
1778 
1779 double
1781 {
1782  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1783 
1784  double range[N_BINS + 1];
1785  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
1786  range[N_BINS] = std::numeric_limits<double>::max ();
1787 
1788  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1789 
1790  double expected[N_BINS];
1791 
1792  // Note that this assumes that n has alpha equal to one and beta
1793  // equal to one, which are their default values for this
1794  // distribution.
1795  double alpha = 1.0;
1796  double beta = 1.0;
1797 
1798  for (uint32_t i = 0; i < N_BINS; ++i)
1799  {
1800  expected[i] = gsl_cdf_gamma_P (range[i + 1], alpha, beta) - gsl_cdf_gamma_P (range[i], alpha, beta);
1801  expected[i] *= N_MEASUREMENTS;
1802  }
1803 
1804  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1805  {
1806  gsl_histogram_increment (h, n->GetValue ());
1807  }
1808 
1809  double tmp[N_BINS];
1810 
1811  for (uint32_t i = 0; i < N_BINS; ++i)
1812  {
1813  tmp[i] = gsl_histogram_get (h, i);
1814  tmp[i] -= expected[i];
1815  tmp[i] *= tmp[i];
1816  tmp[i] /= expected[i];
1817  }
1818 
1819  gsl_histogram_free (h);
1820 
1821  double chiSquared = 0;
1822 
1823  for (uint32_t i = 0; i < N_BINS; ++i)
1824  {
1825  chiSquared += tmp[i];
1826  }
1827 
1828  return chiSquared;
1829 }
1830 
1831 void
1833 {
1834  SeedManager::SetSeed (time (0));
1835 
1836  double sum = 0.;
1837  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1838 
1839  for (uint32_t i = 0; i < N_RUNS; ++i)
1840  {
1841  Ptr<GammaRandomVariable> n = CreateObject<GammaRandomVariable> ();
1842  double result = ChiSquaredTest (n);
1843  sum += result;
1844  }
1845 
1846  sum /= (double)N_RUNS;
1847 
1848  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1849 
1850  double alpha = 5.0;
1851  double beta = 2.0;
1852  double value;
1853 
1854  // Create the RNG with the specified range.
1855  Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> ();
1856  x->SetAttribute ("Alpha", DoubleValue (alpha));
1857  x->SetAttribute ("Beta", DoubleValue (beta));
1858 
1859  // Calculate the mean of these values.
1860  sum = 0.0;
1861  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1862  {
1863  value = x->GetValue ();
1864  sum += value;
1865  }
1866  double valueMean = sum / N_MEASUREMENTS;
1867 
1868  // The expected value for the mean of the values returned by a
1869  // gammaly distributed random variable is equal to
1870  //
1871  // E[value] = alpha * beta .
1872  //
1873  double expectedMean = alpha * beta;
1874 
1875  // Test that values have approximately the right mean value.
1876  double TOLERANCE = expectedMean * 1e-2;
1877  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1878 }
1879 
1880 // ===========================================================================
1881 // Test case for antithetic gamma distribution random variable stream generator
1882 // ===========================================================================
1884 {
1885 public:
1886  static const uint32_t N_RUNS = 5;
1887  static const uint32_t N_BINS = 50;
1888  static const uint32_t N_MEASUREMENTS = 1000000;
1889 
1892 
1894 
1895 private:
1896  virtual void DoRun (void);
1897 };
1898 
1900  : TestCase ("Antithetic Gamma Random Variable Stream Generator")
1901 {
1902 }
1903 
1905 {
1906 }
1907 
1908 double
1910 {
1911  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1912 
1913  double range[N_BINS + 1];
1914  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
1915  range[N_BINS] = std::numeric_limits<double>::max ();
1916 
1917  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1918 
1919  double expected[N_BINS];
1920 
1921  // Note that this assumes that n has alpha equal to one and beta
1922  // equal to one, which are their default values for this
1923  // distribution.
1924  double alpha = 1.0;
1925  double beta = 1.0;
1926 
1927  for (uint32_t i = 0; i < N_BINS; ++i)
1928  {
1929  expected[i] = gsl_cdf_gamma_P (range[i + 1], alpha, beta) - gsl_cdf_gamma_P (range[i], alpha, beta);
1930  expected[i] *= N_MEASUREMENTS;
1931  }
1932 
1933  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1934  {
1935  gsl_histogram_increment (h, n->GetValue ());
1936  }
1937 
1938  double tmp[N_BINS];
1939 
1940  for (uint32_t i = 0; i < N_BINS; ++i)
1941  {
1942  tmp[i] = gsl_histogram_get (h, i);
1943  tmp[i] -= expected[i];
1944  tmp[i] *= tmp[i];
1945  tmp[i] /= expected[i];
1946  }
1947 
1948  gsl_histogram_free (h);
1949 
1950  double chiSquared = 0;
1951 
1952  for (uint32_t i = 0; i < N_BINS; ++i)
1953  {
1954  chiSquared += tmp[i];
1955  }
1956 
1957  return chiSquared;
1958 }
1959 
1960 void
1962 {
1963  SeedManager::SetSeed (time (0));
1964 
1965  double sum = 0.;
1966  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1967 
1968  for (uint32_t i = 0; i < N_RUNS; ++i)
1969  {
1970  Ptr<GammaRandomVariable> n = CreateObject<GammaRandomVariable> ();
1971 
1972  // Make this generate antithetic values.
1973  n->SetAttribute ("Antithetic", BooleanValue (true));
1974 
1975  double result = ChiSquaredTest (n);
1976  sum += result;
1977  }
1978 
1979  sum /= (double)N_RUNS;
1980 
1981  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1982 
1983  double alpha = 5.0;
1984  double beta = 2.0;
1985  double value;
1986 
1987  // Create the RNG with the specified range.
1988  Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> ();
1989 
1990  // Make this generate antithetic values.
1991  x->SetAttribute ("Antithetic", BooleanValue (true));
1992 
1993  x->SetAttribute ("Alpha", DoubleValue (alpha));
1994  x->SetAttribute ("Beta", DoubleValue (beta));
1995 
1996  // Calculate the mean of these values.
1997  sum = 0.0;
1998  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1999  {
2000  value = x->GetValue ();
2001  sum += value;
2002  }
2003  double valueMean = sum / N_MEASUREMENTS;
2004 
2005  // The expected value for the mean of the values returned by a
2006  // gammaly distributed random variable is equal to
2007  //
2008  // E[value] = alpha * beta .
2009  //
2010  double expectedMean = alpha * beta;
2011 
2012  // Test that values have approximately the right mean value.
2013  double TOLERANCE = expectedMean * 1e-2;
2014  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2015 }
2016 
2017 // ===========================================================================
2018 // Test case for Erlang distribution random variable stream generator
2019 // ===========================================================================
2021 {
2022 public:
2023  static const uint32_t N_RUNS = 5;
2024  static const uint32_t N_BINS = 50;
2025  static const uint32_t N_MEASUREMENTS = 1000000;
2026 
2029 
2031 
2032 private:
2033  virtual void DoRun (void);
2034 };
2035 
2037  : TestCase ("Erlang Random Variable Stream Generator")
2038 {
2039 }
2040 
2042 {
2043 }
2044 
2045 double
2047 {
2048  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
2049 
2050  double range[N_BINS + 1];
2051  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
2052  range[N_BINS] = std::numeric_limits<double>::max ();
2053 
2054  gsl_histogram_set_ranges (h, range, N_BINS + 1);
2055 
2056  double expected[N_BINS];
2057 
2058  // Note that this assumes that n has k equal to one and lambda
2059  // equal to one, which are their default values for this
2060  // distribution.
2061  uint32_t k = 1;
2062  double lambda = 1.0;
2063 
2064  // Note that Erlang distribution is equal to the gamma distribution
2065  // when k is an iteger, which is why the gamma distribution's cdf
2066  // function can be used here.
2067  for (uint32_t i = 0; i < N_BINS; ++i)
2068  {
2069  expected[i] = gsl_cdf_gamma_P (range[i + 1], k, lambda) - gsl_cdf_gamma_P (range[i], k, lambda);
2070  expected[i] *= N_MEASUREMENTS;
2071  }
2072 
2073  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2074  {
2075  gsl_histogram_increment (h, n->GetValue ());
2076  }
2077 
2078  double tmp[N_BINS];
2079 
2080  for (uint32_t i = 0; i < N_BINS; ++i)
2081  {
2082  tmp[i] = gsl_histogram_get (h, i);
2083  tmp[i] -= expected[i];
2084  tmp[i] *= tmp[i];
2085  tmp[i] /= expected[i];
2086  }
2087 
2088  gsl_histogram_free (h);
2089 
2090  double chiSquared = 0;
2091 
2092  for (uint32_t i = 0; i < N_BINS; ++i)
2093  {
2094  chiSquared += tmp[i];
2095  }
2096 
2097  return chiSquared;
2098 }
2099 
2100 void
2102 {
2103  SeedManager::SetSeed (time (0));
2104 
2105  double sum = 0.;
2106  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
2107 
2108  for (uint32_t i = 0; i < N_RUNS; ++i)
2109  {
2110  Ptr<ErlangRandomVariable> n = CreateObject<ErlangRandomVariable> ();
2111  double result = ChiSquaredTest (n);
2112  sum += result;
2113  }
2114 
2115  sum /= (double)N_RUNS;
2116 
2117  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
2118 
2119  uint32_t k = 5;
2120  double lambda = 2.0;
2121  double value;
2122 
2123  // Create the RNG with the specified range.
2124  Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> ();
2125  x->SetAttribute ("K", IntegerValue (k));
2126  x->SetAttribute ("Lambda", DoubleValue (lambda));
2127 
2128  // Calculate the mean of these values.
2129  sum = 0.0;
2130  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2131  {
2132  value = x->GetValue ();
2133  sum += value;
2134  }
2135  double valueMean = sum / N_MEASUREMENTS;
2136 
2137  // The expected value for the mean of the values returned by a
2138  // Erlangly distributed random variable is equal to
2139  //
2140  // E[value] = k * lambda .
2141  //
2142  double expectedMean = k * lambda;
2143 
2144  // Test that values have approximately the right mean value.
2145  double TOLERANCE = expectedMean * 1e-2;
2146  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2147 }
2148 
2149 // ===========================================================================
2150 // Test case for antithetic Erlang distribution random variable stream generator
2151 // ===========================================================================
2153 {
2154 public:
2155  static const uint32_t N_RUNS = 5;
2156  static const uint32_t N_BINS = 50;
2157  static const uint32_t N_MEASUREMENTS = 1000000;
2158 
2161 
2163 
2164 private:
2165  virtual void DoRun (void);
2166 };
2167 
2169  : TestCase ("Antithetic Erlang Random Variable Stream Generator")
2170 {
2171 }
2172 
2174 {
2175 }
2176 
2177 double
2179 {
2180  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
2181 
2182  double range[N_BINS + 1];
2183  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
2184  range[N_BINS] = std::numeric_limits<double>::max ();
2185 
2186  gsl_histogram_set_ranges (h, range, N_BINS + 1);
2187 
2188  double expected[N_BINS];
2189 
2190  // Note that this assumes that n has k equal to one and lambda
2191  // equal to one, which are their default values for this
2192  // distribution.
2193  uint32_t k = 1;
2194  double lambda = 1.0;
2195 
2196  // Note that Erlang distribution is equal to the gamma distribution
2197  // when k is an iteger, which is why the gamma distribution's cdf
2198  // function can be used here.
2199  for (uint32_t i = 0; i < N_BINS; ++i)
2200  {
2201  expected[i] = gsl_cdf_gamma_P (range[i + 1], k, lambda) - gsl_cdf_gamma_P (range[i], k, lambda);
2202  expected[i] *= N_MEASUREMENTS;
2203  }
2204 
2205  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2206  {
2207  gsl_histogram_increment (h, n->GetValue ());
2208  }
2209 
2210  double tmp[N_BINS];
2211 
2212  for (uint32_t i = 0; i < N_BINS; ++i)
2213  {
2214  tmp[i] = gsl_histogram_get (h, i);
2215  tmp[i] -= expected[i];
2216  tmp[i] *= tmp[i];
2217  tmp[i] /= expected[i];
2218  }
2219 
2220  gsl_histogram_free (h);
2221 
2222  double chiSquared = 0;
2223 
2224  for (uint32_t i = 0; i < N_BINS; ++i)
2225  {
2226  chiSquared += tmp[i];
2227  }
2228 
2229  return chiSquared;
2230 }
2231 
2232 void
2234 {
2235  SeedManager::SetSeed (time (0));
2236 
2237  double sum = 0.;
2238  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
2239 
2240  for (uint32_t i = 0; i < N_RUNS; ++i)
2241  {
2242  Ptr<ErlangRandomVariable> n = CreateObject<ErlangRandomVariable> ();
2243 
2244  // Make this generate antithetic values.
2245  n->SetAttribute ("Antithetic", BooleanValue (true));
2246 
2247  double result = ChiSquaredTest (n);
2248  sum += result;
2249  }
2250 
2251  sum /= (double)N_RUNS;
2252 
2253  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
2254 
2255  uint32_t k = 5;
2256  double lambda = 2.0;
2257  double value;
2258 
2259  // Create the RNG with the specified range.
2260  Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> ();
2261 
2262  // Make this generate antithetic values.
2263  x->SetAttribute ("Antithetic", BooleanValue (true));
2264 
2265  x->SetAttribute ("K", IntegerValue (k));
2266  x->SetAttribute ("Lambda", DoubleValue (lambda));
2267 
2268  // Calculate the mean of these values.
2269  sum = 0.0;
2270  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2271  {
2272  value = x->GetValue ();
2273  sum += value;
2274  }
2275  double valueMean = sum / N_MEASUREMENTS;
2276 
2277  // The expected value for the mean of the values returned by a
2278  // Erlangly distributed random variable is equal to
2279  //
2280  // E[value] = k * lambda .
2281  //
2282  double expectedMean = k * lambda;
2283 
2284  // Test that values have approximately the right mean value.
2285  double TOLERANCE = expectedMean * 1e-2;
2286  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2287 }
2288 
2289 // ===========================================================================
2290 // Test case for Zipf distribution random variable stream generator
2291 // ===========================================================================
2293 {
2294 public:
2295  static const uint32_t N_MEASUREMENTS = 1000000;
2296 
2299 
2300 private:
2301  virtual void DoRun (void);
2302 };
2303 
2305  : TestCase ("Zipf Random Variable Stream Generator")
2306 {
2307 }
2308 
2310 {
2311 }
2312 
2313 void
2315 {
2316  SeedManager::SetSeed (time (0));
2317 
2318  uint32_t n = 1;
2319  double alpha = 2.0;
2320  double value;
2321 
2322  // Create the RNG with the specified range.
2323  Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> ();
2324  x->SetAttribute ("N", IntegerValue (n));
2325  x->SetAttribute ("Alpha", DoubleValue (alpha));
2326 
2327  // Calculate the mean of these values.
2328  double sum = 0.0;
2329  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2330  {
2331  value = x->GetValue ();
2332  sum += value;
2333  }
2334  double valueMean = sum / N_MEASUREMENTS;
2335 
2336  // The expected value for the mean of the values returned by a
2337  // Zipfly distributed random variable is equal to
2338  //
2339  // H
2340  // N, alpha - 1
2341  // E[value] = ---------------
2342  // H
2343  // N, alpha
2344  //
2345  // where
2346  //
2347  // N
2348  // ---
2349  // \ -alpha
2350  // H = / m .
2351  // N, alpha ---
2352  // m=1
2353  //
2354  // For this test,
2355  //
2356  // -(alpha - 1)
2357  // 1
2358  // E[value] = ---------------
2359  // -alpha
2360  // 1
2361  //
2362  // = 1 .
2363  //
2364  double expectedMean = 1.0;
2365 
2366  // Test that values have approximately the right mean value.
2367  double TOLERANCE = expectedMean * 1e-2;
2368  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2369 }
2370 
2371 // ===========================================================================
2372 // Test case for antithetic Zipf distribution random variable stream generator
2373 // ===========================================================================
2375 {
2376 public:
2377  static const uint32_t N_MEASUREMENTS = 1000000;
2378 
2381 
2382 private:
2383  virtual void DoRun (void);
2384 };
2385 
2387  : TestCase ("Antithetic Zipf Random Variable Stream Generator")
2388 {
2389 }
2390 
2392 {
2393 }
2394 
2395 void
2397 {
2398  SeedManager::SetSeed (time (0));
2399 
2400  uint32_t n = 1;
2401  double alpha = 2.0;
2402  double value;
2403 
2404  // Create the RNG with the specified range.
2405  Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> ();
2406  x->SetAttribute ("N", IntegerValue (n));
2407  x->SetAttribute ("Alpha", DoubleValue (alpha));
2408 
2409  // Make this generate antithetic values.
2410  x->SetAttribute ("Antithetic", BooleanValue (true));
2411 
2412  // Calculate the mean of these values.
2413  double sum = 0.0;
2414  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2415  {
2416  value = x->GetValue ();
2417  sum += value;
2418  }
2419  double valueMean = sum / N_MEASUREMENTS;
2420 
2421  // The expected value for the mean of the values returned by a
2422  // Zipfly distributed random variable is equal to
2423  //
2424  // H
2425  // N, alpha - 1
2426  // E[value] = ---------------
2427  // H
2428  // N, alpha
2429  //
2430  // where
2431  //
2432  // N
2433  // ---
2434  // \ -alpha
2435  // H = / m .
2436  // N, alpha ---
2437  // m=1
2438  //
2439  // For this test,
2440  //
2441  // -(alpha - 1)
2442  // 1
2443  // E[value] = ---------------
2444  // -alpha
2445  // 1
2446  //
2447  // = 1 .
2448  //
2449  double expectedMean = 1.0;
2450 
2451  // Test that values have approximately the right mean value.
2452  double TOLERANCE = expectedMean * 1e-2;
2453  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2454 }
2455 
2456 // ===========================================================================
2457 // Test case for Zeta distribution random variable stream generator
2458 // ===========================================================================
2460 {
2461 public:
2462  static const uint32_t N_MEASUREMENTS = 1000000;
2463 
2466 
2467 private:
2468  virtual void DoRun (void);
2469 };
2470 
2472  : TestCase ("Zeta Random Variable Stream Generator")
2473 {
2474 }
2475 
2477 {
2478 }
2479 
2480 void
2482 {
2483  SeedManager::SetSeed (time (0));
2484 
2485  double alpha = 5.0;
2486  double value;
2487 
2488  // Create the RNG with the specified range.
2489  Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> ();
2490  x->SetAttribute ("Alpha", DoubleValue (alpha));
2491 
2492  // Calculate the mean of these values.
2493  double sum = 0.0;
2494  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2495  {
2496  value = x->GetValue ();
2497  sum += value;
2498  }
2499  double valueMean = sum / N_MEASUREMENTS;
2500 
2501  // The expected value for the mean of the values returned by a
2502  // zetaly distributed random variable is equal to
2503  //
2504  // zeta(alpha - 1)
2505  // E[value] = --------------- for alpha > 2 ,
2506  // zeta(alpha)
2507  //
2508  // where zeta(alpha) is the Riemann zeta function.
2509  //
2510  // There are no simple analytic forms for the Riemann zeta function,
2511  // which is why the gsl library is used in this test to calculate
2512  // the known mean of the values.
2513  double expectedMean = gsl_sf_zeta_int (alpha - 1) / gsl_sf_zeta_int (alpha);
2514 
2515  // Test that values have approximately the right mean value.
2516  double TOLERANCE = expectedMean * 1e-2;
2517  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2518 }
2519 
2520 // ===========================================================================
2521 // Test case for antithetic Zeta distribution random variable stream generator
2522 // ===========================================================================
2524 {
2525 public:
2526  static const uint32_t N_MEASUREMENTS = 1000000;
2527 
2530 
2531 private:
2532  virtual void DoRun (void);
2533 };
2534 
2536  : TestCase ("Antithetic Zeta Random Variable Stream Generator")
2537 {
2538 }
2539 
2541 {
2542 }
2543 
2544 void
2546 {
2547  SeedManager::SetSeed (time (0));
2548 
2549  double alpha = 5.0;
2550  double value;
2551 
2552  // Create the RNG with the specified range.
2553  Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> ();
2554  x->SetAttribute ("Alpha", DoubleValue (alpha));
2555 
2556  // Make this generate antithetic values.
2557  x->SetAttribute ("Antithetic", BooleanValue (true));
2558 
2559  // Calculate the mean of these values.
2560  double sum = 0.0;
2561  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2562  {
2563  value = x->GetValue ();
2564  sum += value;
2565  }
2566  double valueMean = sum / N_MEASUREMENTS;
2567 
2568  // The expected value for the mean of the values returned by a
2569  // zetaly distributed random variable is equal to
2570  //
2571  // zeta(alpha - 1)
2572  // E[value] = --------------- for alpha > 2 ,
2573  // zeta(alpha)
2574  //
2575  // where zeta(alpha) is the Riemann zeta function.
2576  //
2577  // There are no simple analytic forms for the Riemann zeta function,
2578  // which is why the gsl library is used in this test to calculate
2579  // the known mean of the values.
2580  double expectedMean = gsl_sf_zeta_int (alpha - 1) / gsl_sf_zeta_int (alpha);
2581 
2582  // Test that values have approximately the right mean value.
2583  double TOLERANCE = expectedMean * 1e-2;
2584  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2585 }
2586 
2587 // ===========================================================================
2588 // Test case for deterministic random variable stream generator
2589 // ===========================================================================
2591 {
2592 public:
2593  static const double TOLERANCE = 1e-8;
2594 
2597 
2598 private:
2599  virtual void DoRun (void);
2600 };
2601 
2603  : TestCase ("Deterministic Random Variable Stream Generator")
2604 {
2605 }
2606 
2608 {
2609 }
2610 
2611 void
2613 {
2614  SeedManager::SetSeed (time (0));
2615 
2616  Ptr<DeterministicRandomVariable> s = CreateObject<DeterministicRandomVariable> ();
2617 
2618  // The following array should give the sequence
2619  //
2620  // 4, 4, 7, 7, 10, 10 .
2621  //
2622  double array1 [] = { 4, 4, 7, 7, 10, 10};
2623  uint64_t count1 = 6;
2624  s->SetValueArray (array1, count1);
2625 
2626  double value;
2627 
2628  // Test that the first sequence is correct.
2629  value = s->GetValue ();
2630  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence 1 value 1 wrong.");
2631  value = s->GetValue ();
2632  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence 1 value 2 wrong.");
2633  value = s->GetValue ();
2634  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence 1 value 3 wrong.");
2635  value = s->GetValue ();
2636  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence 1 value 4 wrong.");
2637  value = s->GetValue ();
2638  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence 1 value 5 wrong.");
2639  value = s->GetValue ();
2640  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence 1 value 6 wrong.");
2641 
2642  // The following array should give the sequence
2643  //
2644  // 1000, 2000, 7, 7 .
2645  //
2646  double array2 [] = { 1000, 2000, 3000, 4000};
2647  uint64_t count2 = 4;
2648  s->SetValueArray (array2, count2);
2649 
2650  // Test that the second sequence is correct.
2651  value = s->GetValue ();
2652  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1000, TOLERANCE, "Sequence 2 value 1 wrong.");
2653  value = s->GetValue ();
2654  NS_TEST_ASSERT_MSG_EQ_TOL (value, 2000, TOLERANCE, "Sequence 2 value 2 wrong.");
2655  value = s->GetValue ();
2656  NS_TEST_ASSERT_MSG_EQ_TOL (value, 3000, TOLERANCE, "Sequence 2 value 3 wrong.");
2657  value = s->GetValue ();
2658  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4000, TOLERANCE, "Sequence 2 value 4 wrong.");
2659  value = s->GetValue ();
2660 }
2661 
2662 // ===========================================================================
2663 // Test case for empirical distribution random variable stream generator
2664 // ===========================================================================
2666 {
2667 public:
2668  static const uint32_t N_MEASUREMENTS = 1000000;
2669 
2672 
2673 private:
2674  virtual void DoRun (void);
2675 };
2676 
2678  : TestCase ("Empirical Random Variable Stream Generator")
2679 {
2680 }
2681 
2683 {
2684 }
2685 
2686 void
2688 {
2689  SeedManager::SetSeed (time (0));
2690 
2691  // Create the RNG with a uniform distribution between 0 and 10.
2692  Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> ();
2693  x->CDF ( 0.0, 0.0);
2694  x->CDF ( 5.0, 0.5);
2695  x->CDF (10.0, 1.0);
2696 
2697  // Calculate the mean of these values.
2698  double sum = 0.0;
2699  double value;
2700  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2701  {
2702  value = x->GetValue ();
2703  sum += value;
2704  }
2705  double valueMean = sum / N_MEASUREMENTS;
2706 
2707  // The expected value for the mean of the values returned by this
2708  // empirical distribution is the midpoint of the distribution
2709  //
2710  // E[value] = 5 .
2711  //
2712  double expectedMean = 5.0;
2713 
2714  // Test that values have approximately the right mean value.
2715  double TOLERANCE = expectedMean * 1e-2;
2716  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2717 }
2718 
2719 // ===========================================================================
2720 // Test case for antithetic empirical distribution random variable stream generator
2721 // ===========================================================================
2723 {
2724 public:
2725  static const uint32_t N_MEASUREMENTS = 1000000;
2726 
2729 
2730 private:
2731  virtual void DoRun (void);
2732 };
2733 
2735  : TestCase ("EmpiricalAntithetic Random Variable Stream Generator")
2736 {
2737 }
2738 
2740 {
2741 }
2742 
2743 void
2745 {
2746  SeedManager::SetSeed (time (0));
2747 
2748  // Create the RNG with a uniform distribution between 0 and 10.
2749  Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> ();
2750  x->CDF ( 0.0, 0.0);
2751  x->CDF ( 5.0, 0.5);
2752  x->CDF (10.0, 1.0);
2753 
2754  // Make this generate antithetic values.
2755  x->SetAttribute ("Antithetic", BooleanValue (true));
2756 
2757  // Calculate the mean of these values.
2758  double sum = 0.0;
2759  double value;
2760  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2761  {
2762  value = x->GetValue ();
2763  sum += value;
2764  }
2765  double valueMean = sum / N_MEASUREMENTS;
2766 
2767  // The expected value for the mean of the values returned by this
2768  // empirical distribution is the midpoint of the distribution
2769  //
2770  // E[value] = 5 .
2771  //
2772  double expectedMean = 5.0;
2773 
2774  // Test that values have approximately the right mean value.
2775  double TOLERANCE = expectedMean * 1e-2;
2776  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2777 }
2778 
2780 {
2781 public:
2783 };
2784 
2786  : TestSuite ("random-variable-stream-generators", UNIT)
2787 {
2788  AddTestCase (new RandomVariableStreamUniformTestCase, TestCase::QUICK);
2790  AddTestCase (new RandomVariableStreamConstantTestCase, TestCase::QUICK);
2791  AddTestCase (new RandomVariableStreamSequentialTestCase, TestCase::QUICK);
2792  AddTestCase (new RandomVariableStreamNormalTestCase, TestCase::QUICK);
2796  AddTestCase (new RandomVariableStreamParetoTestCase, TestCase::QUICK);
2798  AddTestCase (new RandomVariableStreamWeibullTestCase, TestCase::QUICK);
2800  AddTestCase (new RandomVariableStreamLogNormalTestCase, TestCase::QUICK);
2804  /*
2805  AddTestCase (new RandomVariableStreamLogNormalAntitheticTestCase, TestCase::QUICK);
2806  */
2807  AddTestCase (new RandomVariableStreamGammaTestCase, TestCase::QUICK);
2811  /*
2812  AddTestCase (new RandomVariableStreamGammaAntitheticTestCase, TestCase::QUICK);
2813  */
2814  AddTestCase (new RandomVariableStreamErlangTestCase, TestCase::QUICK);
2816  AddTestCase (new RandomVariableStreamZipfTestCase, TestCase::QUICK);
2818  AddTestCase (new RandomVariableStreamZetaTestCase, TestCase::QUICK);
2821  AddTestCase (new RandomVariableStreamEmpiricalTestCase, TestCase::QUICK);
2823 }
2824 
virtual double GetValue(void)
Returns the next value in the empirical distribution.
double GetValue(double constant)
Returns the value passed in.
double ChiSquaredTest(Ptr< LogNormalRandomVariable > n)
void FillHistoRangeUniformly(double *array, uint32_t n, double start, double end)
Hold a bool native type.
Definition: boolean.h:38
hold variables of type string
Definition: string.h:19
#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:326
static RandomVariableStreamTestSuite randomVariableStreamTestSuite
#define TOLERANCE
A suite of tests to run.
Definition: test.h:1025
Hold a signed integer type.
Definition: integer.h:45
double GetValue(uint32_t k, double lambda)
Returns a random double from an Erlang distribution with the specified k and lambda.
double GetValue(double mean, double shape, double bound)
Returns a random double from a Pareto distribution with the specified mean, shape, and upper bound.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double GetValue(double mean, double variance, double bound=NormalRandomVariable::INFINITE_VALUE)
Returns a random double from a normal distribution with the specified mean, variance, and bound.
#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:539
double GetValue(double alpha)
Returns a random double from a zeta distribution with the specified alpha.
double ChiSquaredTest(Ptr< NormalRandomVariable > n)
encapsulates test code
Definition: test.h:849
double ChiSquaredTest(Ptr< ExponentialRandomVariable > e)
double ChiSquaredTest(Ptr< WeibullRandomVariable > p)
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual double GetValue(void)
Returns the next value in the sequence returned by this RNG stream.
virtual double GetValue(void)
Returns the next value in the sequence.
double ChiSquaredTest(Ptr< ErlangRandomVariable > n)
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< SampleEmitter > s
double GetValue(double alpha, double beta)
Returns a random double from a gamma distribution with the specified alpha and beta.
void CDF(double v, double c)
Specifies a point in the empirical distribution.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< GammaRandomVariable > n)
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double GetValue(double mu, double sigma)
Returns a random double from a log-normal distribution with the specified mu and sigma.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SetValueArray(double *values, uint64_t length)
Sets the array of values that holds the predetermined sequence.
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
Definition: test.cc:173
double ChiSquaredTest(Ptr< UniformRandomVariable > u)
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double ChiSquaredTest(Ptr< ParetoRandomVariable > p)
double GetValue(double mean, double bound)
Returns a random double from an exponential distribution with the specified mean and upper bound...
#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:688
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double GetValue(uint32_t n, double alpha)
Returns a random double from a Zipf distribution with the specified n and alpha.
Hold a floating point type.
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:161
virtual void DoRun(void)
Implementation to actually run this TestCase.
double GetValue(double scale, double shape, double bound)
Returns a random double from a Weibull distribution with the specified scale, shape, and upper bound.
#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:137