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;
292 
295 
296 private:
297  virtual void DoRun (void);
298 };
299 
301 
303  : TestCase ("Constant Random Variable Stream Generator")
304 {
305 }
306 
308 {
309 }
310 
311 void
313 {
314  SeedManager::SetSeed (time (0));
315 
316  Ptr<ConstantRandomVariable> c = CreateObject<ConstantRandomVariable> ();
317 
318  double constant;
319 
320  // Test that the constant value can be changed using its attribute.
321  constant = 10.0;
322  c->SetAttribute ("Constant", DoubleValue (constant));
323  NS_TEST_ASSERT_MSG_EQ_TOL (c->GetValue (), constant, TOLERANCE, "Constant value changed");
324  c->SetAttribute ("Constant", DoubleValue (20.0));
325  NS_TEST_ASSERT_MSG_NE (c->GetValue (), constant, "Constant value not changed");
326 
327  // Test that the constant value does not change.
328  constant = c->GetValue ();
329  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
330  {
331  NS_TEST_ASSERT_MSG_EQ_TOL (c->GetValue (), constant, TOLERANCE, "Constant value changed in loop");
332  }
333 }
334 
335 // ===========================================================================
336 // Test case for sequential random variable stream generator
337 // ===========================================================================
339 {
340 public:
341  static const double TOLERANCE;
342 
345 
346 private:
347  virtual void DoRun (void);
348 };
349 
351 
353  : TestCase ("Sequential Random Variable Stream Generator")
354 {
355 }
356 
358 {
359 }
360 
361 void
363 {
364  SeedManager::SetSeed (time (0));
365 
366  Ptr<SequentialRandomVariable> s = CreateObject<SequentialRandomVariable> ();
367 
368  // The following four attributes should give the sequence
369  //
370  // 4, 4, 7, 7, 10, 10
371  //
372  s->SetAttribute ("Min", DoubleValue (4));
373  s->SetAttribute ("Max", DoubleValue (11));
374  s->SetAttribute ("Increment", StringValue("ns3::UniformRandomVariable[Min=3.0|Max=3.0]"));
375  s->SetAttribute ("Consecutive", IntegerValue (2));
376 
377  double value;
378 
379  // Test that the sequencet is correct.
380  value = s->GetValue ();
381  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence value 1 wrong.");
382  value = s->GetValue ();
383  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence value 2 wrong.");
384  value = s->GetValue ();
385  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence value 3 wrong.");
386  value = s->GetValue ();
387  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence value 4 wrong.");
388  value = s->GetValue ();
389  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence value 5 wrong.");
390  value = s->GetValue ();
391  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence value 6 wrong.");
392 
393 }
394 
395 // ===========================================================================
396 // Test case for normal distribution random variable stream generator
397 // ===========================================================================
399 {
400 public:
401  static const uint32_t N_RUNS = 5;
402  static const uint32_t N_BINS = 50;
403  static const uint32_t N_MEASUREMENTS = 1000000;
404 
407 
409 
410 private:
411  virtual void DoRun (void);
412 };
413 
415  : TestCase ("Normal Random Variable Stream Generator")
416 {
417 }
418 
420 {
421 }
422 
423 double
425 {
426  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
427 
428  double range[N_BINS + 1];
429  FillHistoRangeUniformly (range, N_BINS + 1, -4., 4.);
430  range[0] = -std::numeric_limits<double>::max ();
431  range[N_BINS] = std::numeric_limits<double>::max ();
432 
433  gsl_histogram_set_ranges (h, range, N_BINS + 1);
434 
435  double expected[N_BINS];
436 
437  // Note that this assumes that n has mean equal to zero and standard
438  // deviation equal to one, which are their default values for this
439  // distribution.
440  double sigma = 1.;
441 
442  for (uint32_t i = 0; i < N_BINS; ++i)
443  {
444  expected[i] = gsl_cdf_gaussian_P (range[i + 1], sigma) - gsl_cdf_gaussian_P (range[i], sigma);
445  expected[i] *= N_MEASUREMENTS;
446  }
447 
448  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
449  {
450  gsl_histogram_increment (h, n->GetValue ());
451  }
452 
453  double tmp[N_BINS];
454 
455  for (uint32_t i = 0; i < N_BINS; ++i)
456  {
457  tmp[i] = gsl_histogram_get (h, i);
458  tmp[i] -= expected[i];
459  tmp[i] *= tmp[i];
460  tmp[i] /= expected[i];
461  }
462 
463  gsl_histogram_free (h);
464 
465  double chiSquared = 0;
466 
467  for (uint32_t i = 0; i < N_BINS; ++i)
468  {
469  chiSquared += tmp[i];
470  }
471 
472  return chiSquared;
473 }
474 
475 void
477 {
478  SeedManager::SetSeed (time (0));
479 
480  double sum = 0.;
481  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
482 
483  for (uint32_t i = 0; i < N_RUNS; ++i)
484  {
485  Ptr<NormalRandomVariable> n = CreateObject<NormalRandomVariable> ();
486  double result = ChiSquaredTest (n);
487  sum += result;
488  }
489 
490  sum /= (double)N_RUNS;
491 
492  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
493 
494  double mean = 5.0;
495  double variance = 2.0;
496  double value;
497 
498  // Create the RNG with the specified range.
499  Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> ();
500  x->SetAttribute ("Mean", DoubleValue (mean));
501  x->SetAttribute ("Variance", DoubleValue (variance));
502 
503  // Calculate the mean of these values.
504  sum = 0.0;
505  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
506  {
507  value = x->GetValue ();
508  sum += value;
509  }
510  double valueMean = sum / N_MEASUREMENTS;
511 
512  // The expected value for the mean of the values returned by a
513  // normally distributed random variable is equal to mean.
514  double expectedMean = mean;
515 
516  // Test that values have approximately the right mean value.
517  double TOLERANCE = expectedMean * 1e-2;
518  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
519 }
520 
521 // ===========================================================================
522 // Test case for antithetic normal distribution random variable stream generator
523 // ===========================================================================
525 {
526 public:
527  static const uint32_t N_RUNS = 5;
528  static const uint32_t N_BINS = 50;
529  static const uint32_t N_MEASUREMENTS = 1000000;
530 
533 
535 
536 private:
537  virtual void DoRun (void);
538 };
539 
541  : TestCase ("Antithetic Normal Random Variable Stream Generator")
542 {
543 }
544 
546 {
547 }
548 
549 double
551 {
552  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
553 
554  double range[N_BINS + 1];
555  FillHistoRangeUniformly (range, N_BINS + 1, -4., 4.);
556  range[0] = -std::numeric_limits<double>::max ();
557  range[N_BINS] = std::numeric_limits<double>::max ();
558 
559  gsl_histogram_set_ranges (h, range, N_BINS + 1);
560 
561  double expected[N_BINS];
562 
563  // Note that this assumes that n has mean equal to zero and standard
564  // deviation equal to one, which are their default values for this
565  // distribution.
566  double sigma = 1.;
567 
568  for (uint32_t i = 0; i < N_BINS; ++i)
569  {
570  expected[i] = gsl_cdf_gaussian_P (range[i + 1], sigma) - gsl_cdf_gaussian_P (range[i], sigma);
571  expected[i] *= N_MEASUREMENTS;
572  }
573 
574  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
575  {
576  gsl_histogram_increment (h, n->GetValue ());
577  }
578 
579  double tmp[N_BINS];
580 
581  for (uint32_t i = 0; i < N_BINS; ++i)
582  {
583  tmp[i] = gsl_histogram_get (h, i);
584  tmp[i] -= expected[i];
585  tmp[i] *= tmp[i];
586  tmp[i] /= expected[i];
587  }
588 
589  gsl_histogram_free (h);
590 
591  double chiSquared = 0;
592 
593  for (uint32_t i = 0; i < N_BINS; ++i)
594  {
595  chiSquared += tmp[i];
596  }
597 
598  return chiSquared;
599 }
600 
601 void
603 {
604  SeedManager::SetSeed (time (0));
605 
606  double sum = 0.;
607  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
608 
609  for (uint32_t i = 0; i < N_RUNS; ++i)
610  {
611  Ptr<NormalRandomVariable> n = CreateObject<NormalRandomVariable> ();
612 
613  // Make this generate antithetic values.
614  n->SetAttribute ("Antithetic", BooleanValue (true));
615 
616  double result = ChiSquaredTest (n);
617  sum += result;
618  }
619 
620  sum /= (double)N_RUNS;
621 
622  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
623 
624  double mean = 5.0;
625  double variance = 2.0;
626  double value;
627 
628  // Create the RNG with the specified range.
629  Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> ();
630  x->SetAttribute ("Mean", DoubleValue (mean));
631  x->SetAttribute ("Variance", DoubleValue (variance));
632 
633  // Make this generate antithetic values.
634  x->SetAttribute ("Antithetic", BooleanValue (true));
635 
636  // Calculate the mean of these values.
637  sum = 0.0;
638  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
639  {
640  value = x->GetValue ();
641  sum += value;
642  }
643  double valueMean = sum / N_MEASUREMENTS;
644 
645  // The expected value for the mean of the values returned by a
646  // normally distributed random variable is equal to mean.
647  double expectedMean = mean;
648 
649  // Test that values have approximately the right mean value.
650  double TOLERANCE = expectedMean * 1e-2;
651  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
652 }
653 
654 // ===========================================================================
655 // Test case for exponential distribution random variable stream generator
656 // ===========================================================================
658 {
659 public:
660  static const uint32_t N_RUNS = 5;
661  static const uint32_t N_BINS = 50;
662  static const uint32_t N_MEASUREMENTS = 1000000;
663 
666 
668 
669 private:
670  virtual void DoRun (void);
671 };
672 
674  : TestCase ("Exponential Random Variable Stream Generator")
675 {
676 }
677 
679 {
680 }
681 
682 double
684 {
685  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
686 
687  double range[N_BINS + 1];
688  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
689  range[N_BINS] = std::numeric_limits<double>::max ();
690 
691  gsl_histogram_set_ranges (h, range, N_BINS + 1);
692 
693  double expected[N_BINS];
694 
695  // Note that this assumes that e has mean equal to one, which is the
696  // default value for this distribution.
697  double mu = 1.;
698 
699  for (uint32_t i = 0; i < N_BINS; ++i)
700  {
701  expected[i] = gsl_cdf_exponential_P (range[i + 1], mu) - gsl_cdf_exponential_P (range[i], mu);
702  expected[i] *= N_MEASUREMENTS;
703  }
704 
705  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
706  {
707  gsl_histogram_increment (h, e->GetValue ());
708  }
709 
710  double tmp[N_BINS];
711 
712  for (uint32_t i = 0; i < N_BINS; ++i)
713  {
714  tmp[i] = gsl_histogram_get (h, i);
715  tmp[i] -= expected[i];
716  tmp[i] *= tmp[i];
717  tmp[i] /= expected[i];
718  }
719 
720  gsl_histogram_free (h);
721 
722  double chiSquared = 0;
723 
724  for (uint32_t i = 0; i < N_BINS; ++i)
725  {
726  chiSquared += tmp[i];
727  }
728 
729  return chiSquared;
730 }
731 
732 void
734 {
735  SeedManager::SetSeed (time (0));
736 
737  double sum = 0.;
738  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
739 
740  for (uint32_t i = 0; i < N_RUNS; ++i)
741  {
742  Ptr<ExponentialRandomVariable> e = CreateObject<ExponentialRandomVariable> ();
743  double result = ChiSquaredTest (e);
744  sum += result;
745  }
746 
747  sum /= (double)N_RUNS;
748 
749  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
750 
751  double mean = 3.14;
752  double bound = 0.0;
753  double value;
754 
755  // Create the RNG with the specified range.
756  Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> ();
757  x->SetAttribute ("Mean", DoubleValue (mean));
758  x->SetAttribute ("Bound", DoubleValue (bound));
759 
760  // Calculate the mean of these values.
761  sum = 0.0;
762  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
763  {
764  value = x->GetValue ();
765  sum += value;
766  }
767  double valueMean = sum / N_MEASUREMENTS;
768 
769  // Test that values have approximately the right mean value.
770  double TOLERANCE = mean * 1e-2;
771  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, mean, TOLERANCE, "Wrong mean value.");
772 }
773 
774 // ===========================================================================
775 // Test case for antithetic exponential distribution random variable stream generator
776 // ===========================================================================
778 {
779 public:
780  static const uint32_t N_RUNS = 5;
781  static const uint32_t N_BINS = 50;
782  static const uint32_t N_MEASUREMENTS = 1000000;
783 
786 
788 
789 private:
790  virtual void DoRun (void);
791 };
792 
794  : TestCase ("Antithetic Exponential Random Variable Stream Generator")
795 {
796 }
797 
799 {
800 }
801 
802 double
804 {
805  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
806 
807  double range[N_BINS + 1];
808  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
809  range[N_BINS] = std::numeric_limits<double>::max ();
810 
811  gsl_histogram_set_ranges (h, range, N_BINS + 1);
812 
813  double expected[N_BINS];
814 
815  // Note that this assumes that e has mean equal to one, which is the
816  // default value for this distribution.
817  double mu = 1.;
818 
819  for (uint32_t i = 0; i < N_BINS; ++i)
820  {
821  expected[i] = gsl_cdf_exponential_P (range[i + 1], mu) - gsl_cdf_exponential_P (range[i], mu);
822  expected[i] *= N_MEASUREMENTS;
823  }
824 
825  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
826  {
827  gsl_histogram_increment (h, e->GetValue ());
828  }
829 
830  double tmp[N_BINS];
831 
832  for (uint32_t i = 0; i < N_BINS; ++i)
833  {
834  tmp[i] = gsl_histogram_get (h, i);
835  tmp[i] -= expected[i];
836  tmp[i] *= tmp[i];
837  tmp[i] /= expected[i];
838  }
839 
840  gsl_histogram_free (h);
841 
842  double chiSquared = 0;
843 
844  for (uint32_t i = 0; i < N_BINS; ++i)
845  {
846  chiSquared += tmp[i];
847  }
848 
849  return chiSquared;
850 }
851 
852 void
854 {
855  SeedManager::SetSeed (time (0));
856 
857  double sum = 0.;
858  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
859 
860  for (uint32_t i = 0; i < N_RUNS; ++i)
861  {
862  Ptr<ExponentialRandomVariable> e = CreateObject<ExponentialRandomVariable> ();
863 
864  // Make this generate antithetic values.
865  e->SetAttribute ("Antithetic", BooleanValue (true));
866 
867  double result = ChiSquaredTest (e);
868  sum += result;
869  }
870 
871  sum /= (double)N_RUNS;
872 
873  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
874 
875  double mean = 3.14;
876  double bound = 0.0;
877  double value;
878 
879  // Create the RNG with the specified range.
880  Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> ();
881  x->SetAttribute ("Mean", DoubleValue (mean));
882  x->SetAttribute ("Bound", DoubleValue (bound));
883 
884  // Make this generate antithetic values.
885  x->SetAttribute ("Antithetic", BooleanValue (true));
886 
887  // Calculate the mean of these values.
888  sum = 0.0;
889  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
890  {
891  value = x->GetValue ();
892  sum += value;
893  }
894  double valueMean = sum / N_MEASUREMENTS;
895 
896  // Test that values have approximately the right mean value.
897  double TOLERANCE = mean * 1e-2;
898  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, mean, TOLERANCE, "Wrong mean value.");
899 }
900 
901 // ===========================================================================
902 // Test case for Pareto distribution random variable stream generator
903 // ===========================================================================
905 {
906 public:
907  static const uint32_t N_RUNS = 5;
908  static const uint32_t N_BINS = 50;
909  static const uint32_t N_MEASUREMENTS = 1000000;
910 
913 
915 
916 private:
917  virtual void DoRun (void);
918 };
919 
921  : TestCase ("Pareto Random Variable Stream Generator")
922 {
923 }
924 
926 {
927 }
928 
929 double
931 {
932  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
933 
934  double range[N_BINS + 1];
935  FillHistoRangeUniformly (range, N_BINS + 1, 1., 10.);
936  range[N_BINS] = std::numeric_limits<double>::max ();
937 
938  gsl_histogram_set_ranges (h, range, N_BINS + 1);
939 
940  double expected[N_BINS];
941 
942  // Note that this assumes that p has mean equal to 1 and shape equal
943  // to 2, which are their default values for this distribution.
944  double mean = 1.0;
945  double shape = 2.0;
946  double scale = mean * (shape - 1.0) / shape;
947 
948  for (uint32_t i = 0; i < N_BINS; ++i)
949  {
950  expected[i] = gsl_cdf_pareto_P (range[i + 1], shape, scale) - gsl_cdf_pareto_P (range[i], shape, scale);
951  expected[i] *= N_MEASUREMENTS;
952  }
953 
954  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
955  {
956  gsl_histogram_increment (h, p->GetValue ());
957  }
958 
959  double tmp[N_BINS];
960 
961  for (uint32_t i = 0; i < N_BINS; ++i)
962  {
963  tmp[i] = gsl_histogram_get (h, i);
964  tmp[i] -= expected[i];
965  tmp[i] *= tmp[i];
966  tmp[i] /= expected[i];
967  }
968 
969  gsl_histogram_free (h);
970 
971  double chiSquared = 0;
972 
973  for (uint32_t i = 0; i < N_BINS; ++i)
974  {
975  chiSquared += tmp[i];
976  }
977 
978  return chiSquared;
979 }
980 
981 void
983 {
984  SeedManager::SetSeed (time (0));
985 
986  double sum = 0.;
987  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
988 
989  for (uint32_t i = 0; i < N_RUNS; ++i)
990  {
991  Ptr<ParetoRandomVariable> e = CreateObject<ParetoRandomVariable> ();
992  double result = ChiSquaredTest (e);
993  sum += result;
994  }
995 
996  sum /= (double)N_RUNS;
997 
998  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
999 
1000  double mean = 5.0;
1001  double shape = 2.0;
1002  double scale = mean * (shape - 1.0) / shape;
1003  double value;
1004 
1005  // Create the RNG with the specified range.
1006  Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
1007  x->SetAttribute ("Mean", DoubleValue (mean));
1008  x->SetAttribute ("Shape", DoubleValue (shape));
1009 
1010  // Calculate the mean of these values.
1011  sum = 0.0;
1012  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1013  {
1014  value = x->GetValue ();
1015  sum += value;
1016  }
1017  double valueMean = sum / N_MEASUREMENTS;
1018 
1019  // The expected value for the mean is given by
1020  //
1021  // shape * scale
1022  // E[value] = --------------- ,
1023  // shape - 1
1024  //
1025  // where
1026  //
1027  // scale = mean * (shape - 1.0) / shape .
1028  double expectedMean = (shape * scale) / (shape - 1.0);
1029 
1030  // Test that values have approximately the right mean value.
1031  double TOLERANCE = expectedMean * 1e-2;
1032  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1033 }
1034 
1035 // ===========================================================================
1036 // Test case for antithetic Pareto distribution random variable stream generator
1037 // ===========================================================================
1039 {
1040 public:
1041  static const uint32_t N_RUNS = 5;
1042  static const uint32_t N_BINS = 50;
1043  static const uint32_t N_MEASUREMENTS = 1000000;
1044 
1047 
1049 
1050 private:
1051  virtual void DoRun (void);
1052 };
1053 
1055  : TestCase ("Antithetic Pareto Random Variable Stream Generator")
1056 {
1057 }
1058 
1060 {
1061 }
1062 
1063 double
1065 {
1066  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1067 
1068  double range[N_BINS + 1];
1069  FillHistoRangeUniformly (range, N_BINS + 1, 1., 10.);
1070  range[N_BINS] = std::numeric_limits<double>::max ();
1071 
1072  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1073 
1074  double expected[N_BINS];
1075 
1076  // Note that this assumes that p has mean equal to 1 and shape equal
1077  // to 2, which are their default values for this distribution.
1078  double mean = 1.0;
1079  double shape = 2.0;
1080  double scale = mean * (shape - 1.0) / shape;
1081 
1082  for (uint32_t i = 0; i < N_BINS; ++i)
1083  {
1084  expected[i] = gsl_cdf_pareto_P (range[i + 1], shape, scale) - gsl_cdf_pareto_P (range[i], shape, scale);
1085  expected[i] *= N_MEASUREMENTS;
1086  }
1087 
1088  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1089  {
1090  gsl_histogram_increment (h, p->GetValue ());
1091  }
1092 
1093  double tmp[N_BINS];
1094 
1095  for (uint32_t i = 0; i < N_BINS; ++i)
1096  {
1097  tmp[i] = gsl_histogram_get (h, i);
1098  tmp[i] -= expected[i];
1099  tmp[i] *= tmp[i];
1100  tmp[i] /= expected[i];
1101  }
1102 
1103  gsl_histogram_free (h);
1104 
1105  double chiSquared = 0;
1106 
1107  for (uint32_t i = 0; i < N_BINS; ++i)
1108  {
1109  chiSquared += tmp[i];
1110  }
1111 
1112  return chiSquared;
1113 }
1114 
1115 void
1117 {
1118  SeedManager::SetSeed (time (0));
1119 
1120  double sum = 0.;
1121  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1122 
1123  for (uint32_t i = 0; i < N_RUNS; ++i)
1124  {
1125  Ptr<ParetoRandomVariable> e = CreateObject<ParetoRandomVariable> ();
1126 
1127  // Make this generate antithetic values.
1128  e->SetAttribute ("Antithetic", BooleanValue (true));
1129 
1130  double result = ChiSquaredTest (e);
1131  sum += result;
1132  }
1133 
1134  sum /= (double)N_RUNS;
1135 
1136  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1137 
1138  double mean = 5.0;
1139  double shape = 2.0;
1140  double scale = mean * (shape - 1.0) / shape;
1141  double value;
1142 
1143  // Create the RNG with the specified range.
1144  Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> ();
1145  x->SetAttribute ("Mean", DoubleValue (mean));
1146  x->SetAttribute ("Shape", DoubleValue (shape));
1147 
1148  // Make this generate antithetic values.
1149  x->SetAttribute ("Antithetic", BooleanValue (true));
1150 
1151  // Calculate the mean of these values.
1152  sum = 0.0;
1153  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1154  {
1155  value = x->GetValue ();
1156  sum += value;
1157  }
1158  double valueMean = sum / N_MEASUREMENTS;
1159 
1160  // The expected value for the mean is given by
1161  //
1162  // shape * scale
1163  // E[value] = --------------- ,
1164  // shape - 1
1165  //
1166  // where
1167  //
1168  // scale = mean * (shape - 1.0) / shape .
1169  //
1170  double expectedMean = (shape * scale) / (shape - 1.0);
1171 
1172  // Test that values have approximately the right mean value.
1173  double TOLERANCE = expectedMean * 1e-2;
1174  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1175 }
1176 
1177 // ===========================================================================
1178 // Test case for Weibull distribution random variable stream generator
1179 // ===========================================================================
1181 {
1182 public:
1183  static const uint32_t N_RUNS = 5;
1184  static const uint32_t N_BINS = 50;
1185  static const uint32_t N_MEASUREMENTS = 1000000;
1186 
1189 
1191 
1192 private:
1193  virtual void DoRun (void);
1194 };
1195 
1197  : TestCase ("Weibull Random Variable Stream Generator")
1198 {
1199 }
1200 
1202 {
1203 }
1204 
1205 double
1207 {
1208  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1209 
1210  double range[N_BINS + 1];
1211  FillHistoRangeUniformly (range, N_BINS + 1, 1., 10.);
1212  range[N_BINS] = std::numeric_limits<double>::max ();
1213 
1214  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1215 
1216  double expected[N_BINS];
1217 
1218  // Note that this assumes that p has shape equal to one and scale
1219  // equal to one, which are their default values for this
1220  // distribution.
1221  double a = 1.0;
1222  double b = 1.0;
1223 
1224  for (uint32_t i = 0; i < N_BINS; ++i)
1225  {
1226  expected[i] = gsl_cdf_weibull_P (range[i + 1], a, b) - gsl_cdf_weibull_P (range[i], a, b);
1227  expected[i] *= N_MEASUREMENTS;
1228  }
1229 
1230  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1231  {
1232  gsl_histogram_increment (h, p->GetValue ());
1233  }
1234 
1235  double tmp[N_BINS];
1236 
1237  for (uint32_t i = 0; i < N_BINS; ++i)
1238  {
1239  tmp[i] = gsl_histogram_get (h, i);
1240  tmp[i] -= expected[i];
1241  tmp[i] *= tmp[i];
1242  tmp[i] /= expected[i];
1243  }
1244 
1245  gsl_histogram_free (h);
1246 
1247  double chiSquared = 0;
1248 
1249  for (uint32_t i = 0; i < N_BINS; ++i)
1250  {
1251  chiSquared += tmp[i];
1252  }
1253 
1254  return chiSquared;
1255 }
1256 
1257 void
1259 {
1260  SeedManager::SetSeed (time (0));
1261 
1262  double sum = 0.;
1263  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1264 
1265  for (uint32_t i = 0; i < N_RUNS; ++i)
1266  {
1267  Ptr<WeibullRandomVariable> e = CreateObject<WeibullRandomVariable> ();
1268  double result = ChiSquaredTest (e);
1269  sum += result;
1270  }
1271 
1272  sum /= (double)N_RUNS;
1273 
1274  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1275 
1276  double scale = 5.0;
1277  double shape = 1.0;
1278  double value;
1279 
1280  // Create the RNG with the specified range.
1281  Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> ();
1282  x->SetAttribute ("Scale", DoubleValue (scale));
1283  x->SetAttribute ("Shape", DoubleValue (shape));
1284 
1285  // Calculate the mean of these values.
1286  sum = 0.0;
1287  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1288  {
1289  value = x->GetValue ();
1290  sum += value;
1291  }
1292  double valueMean = sum / N_MEASUREMENTS;
1293 
1294  // The expected value for the mean of the values returned by a
1295  // Weibull distributed random variable is
1296  //
1297  // E[value] = scale * Gamma(1 + 1 / shape) ,
1298  //
1299  // where Gamma() is the Gamma function. Note that
1300  //
1301  // Gamma(n) = (n - 1)!
1302  //
1303  // if n is a positive integer.
1304  //
1305  // For this test,
1306  //
1307  // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1308  // = Gamma(2)
1309  // = (2 - 1)!
1310  // = 1
1311  //
1312  // which means
1313  //
1314  // E[value] = scale .
1315  //
1316  double expectedMean = scale;
1317 
1318  // Test that values have approximately the right mean value.
1319  double TOLERANCE = expectedMean * 1e-2;
1320  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1321 }
1322 
1323 // ===========================================================================
1324 // Test case for antithetic Weibull distribution random variable stream generator
1325 // ===========================================================================
1327 {
1328 public:
1329  static const uint32_t N_RUNS = 5;
1330  static const uint32_t N_BINS = 50;
1331  static const uint32_t N_MEASUREMENTS = 1000000;
1332 
1335 
1337 
1338 private:
1339  virtual void DoRun (void);
1340 };
1341 
1343  : TestCase ("Antithetic Weibull Random Variable Stream Generator")
1344 {
1345 }
1346 
1348 {
1349 }
1350 
1351 double
1353 {
1354  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1355 
1356  double range[N_BINS + 1];
1357  FillHistoRangeUniformly (range, N_BINS + 1, 1., 10.);
1358  range[N_BINS] = std::numeric_limits<double>::max ();
1359 
1360  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1361 
1362  double expected[N_BINS];
1363 
1364  // Note that this assumes that p has shape equal to one and scale
1365  // equal to one, which are their default values for this
1366  // distribution.
1367  double a = 1.0;
1368  double b = 1.0;
1369 
1370  for (uint32_t i = 0; i < N_BINS; ++i)
1371  {
1372  expected[i] = gsl_cdf_weibull_P (range[i + 1], a, b) - gsl_cdf_weibull_P (range[i], a, b);
1373  expected[i] *= N_MEASUREMENTS;
1374  }
1375 
1376  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1377  {
1378  gsl_histogram_increment (h, p->GetValue ());
1379  }
1380 
1381  double tmp[N_BINS];
1382 
1383  for (uint32_t i = 0; i < N_BINS; ++i)
1384  {
1385  tmp[i] = gsl_histogram_get (h, i);
1386  tmp[i] -= expected[i];
1387  tmp[i] *= tmp[i];
1388  tmp[i] /= expected[i];
1389  }
1390 
1391  gsl_histogram_free (h);
1392 
1393  double chiSquared = 0;
1394 
1395  for (uint32_t i = 0; i < N_BINS; ++i)
1396  {
1397  chiSquared += tmp[i];
1398  }
1399 
1400  return chiSquared;
1401 }
1402 
1403 void
1405 {
1406  SeedManager::SetSeed (time (0));
1407 
1408  double sum = 0.;
1409  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1410 
1411  for (uint32_t i = 0; i < N_RUNS; ++i)
1412  {
1413  Ptr<WeibullRandomVariable> e = CreateObject<WeibullRandomVariable> ();
1414 
1415  // Make this generate antithetic values.
1416  e->SetAttribute ("Antithetic", BooleanValue (true));
1417 
1418  double result = ChiSquaredTest (e);
1419  sum += result;
1420  }
1421 
1422  sum /= (double)N_RUNS;
1423 
1424  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1425 
1426  double scale = 5.0;
1427  double shape = 1.0;
1428  double value;
1429 
1430  // Create the RNG with the specified range.
1431  Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> ();
1432  x->SetAttribute ("Scale", DoubleValue (scale));
1433  x->SetAttribute ("Shape", DoubleValue (shape));
1434 
1435  // Make this generate antithetic values.
1436  x->SetAttribute ("Antithetic", BooleanValue (true));
1437 
1438  // Calculate the mean of these values.
1439  sum = 0.0;
1440  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1441  {
1442  value = x->GetValue ();
1443  sum += value;
1444  }
1445  double valueMean = sum / N_MEASUREMENTS;
1446 
1447  // The expected value for the mean of the values returned by a
1448  // Weibull distributed random variable is
1449  //
1450  // E[value] = scale * Gamma(1 + 1 / shape) ,
1451  //
1452  // where Gamma() is the Gamma function. Note that
1453  //
1454  // Gamma(n) = (n - 1)!
1455  //
1456  // if n is a positive integer.
1457  //
1458  // For this test,
1459  //
1460  // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1)
1461  // = Gamma(2)
1462  // = (2 - 1)!
1463  // = 1
1464  //
1465  // which means
1466  //
1467  // E[value] = scale .
1468  //
1469  double expectedMean = scale;
1470 
1471  // Test that values have approximately the right mean value.
1472  double TOLERANCE = expectedMean * 1e-2;
1473  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1474 }
1475 
1476 // ===========================================================================
1477 // Test case for log-normal distribution random variable stream generator
1478 // ===========================================================================
1480 {
1481 public:
1482  static const uint32_t N_RUNS = 5;
1483  static const uint32_t N_BINS = 50;
1484  static const uint32_t N_MEASUREMENTS = 1000000;
1485 
1488 
1490 
1491 private:
1492  virtual void DoRun (void);
1493 };
1494 
1496  : TestCase ("Log-Normal Random Variable Stream Generator")
1497 {
1498 }
1499 
1501 {
1502 }
1503 
1504 double
1506 {
1507  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1508 
1509  double range[N_BINS + 1];
1510  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
1511  range[N_BINS] = std::numeric_limits<double>::max ();
1512 
1513  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1514 
1515  double expected[N_BINS];
1516 
1517  // Note that this assumes that n has mu equal to zero and sigma
1518  // equal to one, which are their default values for this
1519  // distribution.
1520  double mu = 0.0;
1521  double sigma = 1.0;
1522 
1523  for (uint32_t i = 0; i < N_BINS; ++i)
1524  {
1525  expected[i] = gsl_cdf_lognormal_P (range[i + 1], mu, sigma) - gsl_cdf_lognormal_P (range[i], mu, sigma);
1526  expected[i] *= N_MEASUREMENTS;
1527  }
1528 
1529  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1530  {
1531  gsl_histogram_increment (h, n->GetValue ());
1532  }
1533 
1534  double tmp[N_BINS];
1535 
1536  for (uint32_t i = 0; i < N_BINS; ++i)
1537  {
1538  tmp[i] = gsl_histogram_get (h, i);
1539  tmp[i] -= expected[i];
1540  tmp[i] *= tmp[i];
1541  tmp[i] /= expected[i];
1542  }
1543 
1544  gsl_histogram_free (h);
1545 
1546  double chiSquared = 0;
1547 
1548  for (uint32_t i = 0; i < N_BINS; ++i)
1549  {
1550  chiSquared += tmp[i];
1551  }
1552 
1553  return chiSquared;
1554 }
1555 
1556 void
1558 {
1559  SeedManager::SetSeed (time (0));
1560 
1561  double sum = 0.;
1562  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1563 
1564  for (uint32_t i = 0; i < N_RUNS; ++i)
1565  {
1566  Ptr<LogNormalRandomVariable> n = CreateObject<LogNormalRandomVariable> ();
1567  double result = ChiSquaredTest (n);
1568  sum += result;
1569  }
1570 
1571  sum /= (double)N_RUNS;
1572 
1573  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1574 
1575  double mu = 5.0;
1576  double sigma = 2.0;
1577  double value;
1578 
1579  // Create the RNG with the specified range.
1580  Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> ();
1581  x->SetAttribute ("Mu", DoubleValue (mu));
1582  x->SetAttribute ("Sigma", DoubleValue (sigma));
1583 
1584  // Calculate the mean of these values.
1585  sum = 0.0;
1586  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1587  {
1588  value = x->GetValue ();
1589  sum += value;
1590  }
1591  double valueMean = sum / N_MEASUREMENTS;
1592 
1593  // The expected value for the mean of the values returned by a
1594  // log-normally distributed random variable is equal to
1595  //
1596  // 2
1597  // mu + sigma / 2
1598  // E[value] = e .
1599  //
1600  double expectedMean = std::exp(mu + sigma * sigma / 2.0);
1601 
1602  // Test that values have approximately the right mean value.
1603  //
1608  double TOLERANCE = expectedMean * 3e-2;
1609  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1610 }
1611 
1612 // ===========================================================================
1613 // Test case for antithetic log-normal distribution random variable stream generator
1614 // ===========================================================================
1616 {
1617 public:
1618  static const uint32_t N_RUNS = 5;
1619  static const uint32_t N_BINS = 50;
1620  static const uint32_t N_MEASUREMENTS = 1000000;
1621 
1624 
1626 
1627 private:
1628  virtual void DoRun (void);
1629 };
1630 
1632  : TestCase ("Antithetic Log-Normal Random Variable Stream Generator")
1633 {
1634 }
1635 
1637 {
1638 }
1639 
1640 double
1642 {
1643  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1644 
1645  double range[N_BINS + 1];
1646  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
1647  range[N_BINS] = std::numeric_limits<double>::max ();
1648 
1649  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1650 
1651  double expected[N_BINS];
1652 
1653  // Note that this assumes that n has mu equal to zero and sigma
1654  // equal to one, which are their default values for this
1655  // distribution.
1656  double mu = 0.0;
1657  double sigma = 1.0;
1658 
1659  for (uint32_t i = 0; i < N_BINS; ++i)
1660  {
1661  expected[i] = gsl_cdf_lognormal_P (range[i + 1], mu, sigma) - gsl_cdf_lognormal_P (range[i], mu, sigma);
1662  expected[i] *= N_MEASUREMENTS;
1663  }
1664 
1665  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1666  {
1667  gsl_histogram_increment (h, n->GetValue ());
1668  }
1669 
1670  double tmp[N_BINS];
1671 
1672  for (uint32_t i = 0; i < N_BINS; ++i)
1673  {
1674  tmp[i] = gsl_histogram_get (h, i);
1675  tmp[i] -= expected[i];
1676  tmp[i] *= tmp[i];
1677  tmp[i] /= expected[i];
1678  }
1679 
1680  gsl_histogram_free (h);
1681 
1682  double chiSquared = 0;
1683 
1684  for (uint32_t i = 0; i < N_BINS; ++i)
1685  {
1686  chiSquared += tmp[i];
1687  }
1688 
1689  return chiSquared;
1690 }
1691 
1692 void
1694 {
1695  SeedManager::SetSeed (time (0));
1696 
1697  double sum = 0.;
1698  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1699 
1700  for (uint32_t i = 0; i < N_RUNS; ++i)
1701  {
1702  Ptr<LogNormalRandomVariable> n = CreateObject<LogNormalRandomVariable> ();
1703 
1704  // Make this generate antithetic values.
1705  n->SetAttribute ("Antithetic", BooleanValue (true));
1706 
1707  double result = ChiSquaredTest (n);
1708  sum += result;
1709  }
1710 
1711  sum /= (double)N_RUNS;
1712 
1713  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1714 
1715  double mu = 5.0;
1716  double sigma = 2.0;
1717  double value;
1718 
1719  // Create the RNG with the specified range.
1720  Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> ();
1721  x->SetAttribute ("Mu", DoubleValue (mu));
1722  x->SetAttribute ("Sigma", DoubleValue (sigma));
1723 
1724  // Make this generate antithetic values.
1725  x->SetAttribute ("Antithetic", BooleanValue (true));
1726 
1727  // Calculate the mean of these values.
1728  sum = 0.0;
1729  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1730  {
1731  value = x->GetValue ();
1732  sum += value;
1733  }
1734  double valueMean = sum / N_MEASUREMENTS;
1735 
1736  // The expected value for the mean of the values returned by a
1737  // log-normally distributed random variable is equal to
1738  //
1739  // 2
1740  // mu + sigma / 2
1741  // E[value] = e .
1742  //
1743  double expectedMean = std::exp(mu + sigma * sigma / 2.0);
1744 
1745  // Test that values have approximately the right mean value.
1746  //
1751  double TOLERANCE = expectedMean * 3e-2;
1752  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1753 }
1754 
1755 // ===========================================================================
1756 // Test case for gamma distribution random variable stream generator
1757 // ===========================================================================
1759 {
1760 public:
1761  static const uint32_t N_RUNS = 5;
1762  static const uint32_t N_BINS = 50;
1763  static const uint32_t N_MEASUREMENTS = 1000000;
1764 
1767 
1769 
1770 private:
1771  virtual void DoRun (void);
1772 };
1773 
1775  : TestCase ("Gamma Random Variable Stream Generator")
1776 {
1777 }
1778 
1780 {
1781 }
1782 
1783 double
1785 {
1786  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1787 
1788  double range[N_BINS + 1];
1789  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
1790  range[N_BINS] = std::numeric_limits<double>::max ();
1791 
1792  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1793 
1794  double expected[N_BINS];
1795 
1796  // Note that this assumes that n has alpha equal to one and beta
1797  // equal to one, which are their default values for this
1798  // distribution.
1799  double alpha = 1.0;
1800  double beta = 1.0;
1801 
1802  for (uint32_t i = 0; i < N_BINS; ++i)
1803  {
1804  expected[i] = gsl_cdf_gamma_P (range[i + 1], alpha, beta) - gsl_cdf_gamma_P (range[i], alpha, beta);
1805  expected[i] *= N_MEASUREMENTS;
1806  }
1807 
1808  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1809  {
1810  gsl_histogram_increment (h, n->GetValue ());
1811  }
1812 
1813  double tmp[N_BINS];
1814 
1815  for (uint32_t i = 0; i < N_BINS; ++i)
1816  {
1817  tmp[i] = gsl_histogram_get (h, i);
1818  tmp[i] -= expected[i];
1819  tmp[i] *= tmp[i];
1820  tmp[i] /= expected[i];
1821  }
1822 
1823  gsl_histogram_free (h);
1824 
1825  double chiSquared = 0;
1826 
1827  for (uint32_t i = 0; i < N_BINS; ++i)
1828  {
1829  chiSquared += tmp[i];
1830  }
1831 
1832  return chiSquared;
1833 }
1834 
1835 void
1837 {
1838  SeedManager::SetSeed (time (0));
1839 
1840  double sum = 0.;
1841  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1842 
1843  for (uint32_t i = 0; i < N_RUNS; ++i)
1844  {
1845  Ptr<GammaRandomVariable> n = CreateObject<GammaRandomVariable> ();
1846  double result = ChiSquaredTest (n);
1847  sum += result;
1848  }
1849 
1850  sum /= (double)N_RUNS;
1851 
1852  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1853 
1854  double alpha = 5.0;
1855  double beta = 2.0;
1856  double value;
1857 
1858  // Create the RNG with the specified range.
1859  Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> ();
1860  x->SetAttribute ("Alpha", DoubleValue (alpha));
1861  x->SetAttribute ("Beta", DoubleValue (beta));
1862 
1863  // Calculate the mean of these values.
1864  sum = 0.0;
1865  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1866  {
1867  value = x->GetValue ();
1868  sum += value;
1869  }
1870  double valueMean = sum / N_MEASUREMENTS;
1871 
1872  // The expected value for the mean of the values returned by a
1873  // gammaly distributed random variable is equal to
1874  //
1875  // E[value] = alpha * beta .
1876  //
1877  double expectedMean = alpha * beta;
1878 
1879  // Test that values have approximately the right mean value.
1880  double TOLERANCE = expectedMean * 1e-2;
1881  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
1882 }
1883 
1884 // ===========================================================================
1885 // Test case for antithetic gamma distribution random variable stream generator
1886 // ===========================================================================
1888 {
1889 public:
1890  static const uint32_t N_RUNS = 5;
1891  static const uint32_t N_BINS = 50;
1892  static const uint32_t N_MEASUREMENTS = 1000000;
1893 
1896 
1898 
1899 private:
1900  virtual void DoRun (void);
1901 };
1902 
1904  : TestCase ("Antithetic Gamma Random Variable Stream Generator")
1905 {
1906 }
1907 
1909 {
1910 }
1911 
1912 double
1914 {
1915  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
1916 
1917  double range[N_BINS + 1];
1918  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
1919  range[N_BINS] = std::numeric_limits<double>::max ();
1920 
1921  gsl_histogram_set_ranges (h, range, N_BINS + 1);
1922 
1923  double expected[N_BINS];
1924 
1925  // Note that this assumes that n has alpha equal to one and beta
1926  // equal to one, which are their default values for this
1927  // distribution.
1928  double alpha = 1.0;
1929  double beta = 1.0;
1930 
1931  for (uint32_t i = 0; i < N_BINS; ++i)
1932  {
1933  expected[i] = gsl_cdf_gamma_P (range[i + 1], alpha, beta) - gsl_cdf_gamma_P (range[i], alpha, beta);
1934  expected[i] *= N_MEASUREMENTS;
1935  }
1936 
1937  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
1938  {
1939  gsl_histogram_increment (h, n->GetValue ());
1940  }
1941 
1942  double tmp[N_BINS];
1943 
1944  for (uint32_t i = 0; i < N_BINS; ++i)
1945  {
1946  tmp[i] = gsl_histogram_get (h, i);
1947  tmp[i] -= expected[i];
1948  tmp[i] *= tmp[i];
1949  tmp[i] /= expected[i];
1950  }
1951 
1952  gsl_histogram_free (h);
1953 
1954  double chiSquared = 0;
1955 
1956  for (uint32_t i = 0; i < N_BINS; ++i)
1957  {
1958  chiSquared += tmp[i];
1959  }
1960 
1961  return chiSquared;
1962 }
1963 
1964 void
1966 {
1967  SeedManager::SetSeed (time (0));
1968 
1969  double sum = 0.;
1970  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
1971 
1972  for (uint32_t i = 0; i < N_RUNS; ++i)
1973  {
1974  Ptr<GammaRandomVariable> n = CreateObject<GammaRandomVariable> ();
1975 
1976  // Make this generate antithetic values.
1977  n->SetAttribute ("Antithetic", BooleanValue (true));
1978 
1979  double result = ChiSquaredTest (n);
1980  sum += result;
1981  }
1982 
1983  sum /= (double)N_RUNS;
1984 
1985  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
1986 
1987  double alpha = 5.0;
1988  double beta = 2.0;
1989  double value;
1990 
1991  // Create the RNG with the specified range.
1992  Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> ();
1993 
1994  // Make this generate antithetic values.
1995  x->SetAttribute ("Antithetic", BooleanValue (true));
1996 
1997  x->SetAttribute ("Alpha", DoubleValue (alpha));
1998  x->SetAttribute ("Beta", DoubleValue (beta));
1999 
2000  // Calculate the mean of these values.
2001  sum = 0.0;
2002  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2003  {
2004  value = x->GetValue ();
2005  sum += value;
2006  }
2007  double valueMean = sum / N_MEASUREMENTS;
2008 
2009  // The expected value for the mean of the values returned by a
2010  // gammaly distributed random variable is equal to
2011  //
2012  // E[value] = alpha * beta .
2013  //
2014  double expectedMean = alpha * beta;
2015 
2016  // Test that values have approximately the right mean value.
2017  double TOLERANCE = expectedMean * 1e-2;
2018  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2019 }
2020 
2021 // ===========================================================================
2022 // Test case for Erlang distribution random variable stream generator
2023 // ===========================================================================
2025 {
2026 public:
2027  static const uint32_t N_RUNS = 5;
2028  static const uint32_t N_BINS = 50;
2029  static const uint32_t N_MEASUREMENTS = 1000000;
2030 
2033 
2035 
2036 private:
2037  virtual void DoRun (void);
2038 };
2039 
2041  : TestCase ("Erlang Random Variable Stream Generator")
2042 {
2043 }
2044 
2046 {
2047 }
2048 
2049 double
2051 {
2052  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
2053 
2054  double range[N_BINS + 1];
2055  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
2056  range[N_BINS] = std::numeric_limits<double>::max ();
2057 
2058  gsl_histogram_set_ranges (h, range, N_BINS + 1);
2059 
2060  double expected[N_BINS];
2061 
2062  // Note that this assumes that n has k equal to one and lambda
2063  // equal to one, which are their default values for this
2064  // distribution.
2065  uint32_t k = 1;
2066  double lambda = 1.0;
2067 
2068  // Note that Erlang distribution is equal to the gamma distribution
2069  // when k is an iteger, which is why the gamma distribution's cdf
2070  // function can be used here.
2071  for (uint32_t i = 0; i < N_BINS; ++i)
2072  {
2073  expected[i] = gsl_cdf_gamma_P (range[i + 1], k, lambda) - gsl_cdf_gamma_P (range[i], k, lambda);
2074  expected[i] *= N_MEASUREMENTS;
2075  }
2076 
2077  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2078  {
2079  gsl_histogram_increment (h, n->GetValue ());
2080  }
2081 
2082  double tmp[N_BINS];
2083 
2084  for (uint32_t i = 0; i < N_BINS; ++i)
2085  {
2086  tmp[i] = gsl_histogram_get (h, i);
2087  tmp[i] -= expected[i];
2088  tmp[i] *= tmp[i];
2089  tmp[i] /= expected[i];
2090  }
2091 
2092  gsl_histogram_free (h);
2093 
2094  double chiSquared = 0;
2095 
2096  for (uint32_t i = 0; i < N_BINS; ++i)
2097  {
2098  chiSquared += tmp[i];
2099  }
2100 
2101  return chiSquared;
2102 }
2103 
2104 void
2106 {
2107  SeedManager::SetSeed (time (0));
2108 
2109  double sum = 0.;
2110  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
2111 
2112  for (uint32_t i = 0; i < N_RUNS; ++i)
2113  {
2114  Ptr<ErlangRandomVariable> n = CreateObject<ErlangRandomVariable> ();
2115  double result = ChiSquaredTest (n);
2116  sum += result;
2117  }
2118 
2119  sum /= (double)N_RUNS;
2120 
2121  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
2122 
2123  uint32_t k = 5;
2124  double lambda = 2.0;
2125  double value;
2126 
2127  // Create the RNG with the specified range.
2128  Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> ();
2129  x->SetAttribute ("K", IntegerValue (k));
2130  x->SetAttribute ("Lambda", DoubleValue (lambda));
2131 
2132  // Calculate the mean of these values.
2133  sum = 0.0;
2134  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2135  {
2136  value = x->GetValue ();
2137  sum += value;
2138  }
2139  double valueMean = sum / N_MEASUREMENTS;
2140 
2141  // The expected value for the mean of the values returned by a
2142  // Erlangly distributed random variable is equal to
2143  //
2144  // E[value] = k * lambda .
2145  //
2146  double expectedMean = k * lambda;
2147 
2148  // Test that values have approximately the right mean value.
2149  double TOLERANCE = expectedMean * 1e-2;
2150  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2151 }
2152 
2153 // ===========================================================================
2154 // Test case for antithetic Erlang distribution random variable stream generator
2155 // ===========================================================================
2157 {
2158 public:
2159  static const uint32_t N_RUNS = 5;
2160  static const uint32_t N_BINS = 50;
2161  static const uint32_t N_MEASUREMENTS = 1000000;
2162 
2165 
2167 
2168 private:
2169  virtual void DoRun (void);
2170 };
2171 
2173  : TestCase ("Antithetic Erlang Random Variable Stream Generator")
2174 {
2175 }
2176 
2178 {
2179 }
2180 
2181 double
2183 {
2184  gsl_histogram * h = gsl_histogram_alloc (N_BINS);
2185 
2186  double range[N_BINS + 1];
2187  FillHistoRangeUniformly (range, N_BINS + 1, 0., 10.);
2188  range[N_BINS] = std::numeric_limits<double>::max ();
2189 
2190  gsl_histogram_set_ranges (h, range, N_BINS + 1);
2191 
2192  double expected[N_BINS];
2193 
2194  // Note that this assumes that n has k equal to one and lambda
2195  // equal to one, which are their default values for this
2196  // distribution.
2197  uint32_t k = 1;
2198  double lambda = 1.0;
2199 
2200  // Note that Erlang distribution is equal to the gamma distribution
2201  // when k is an iteger, which is why the gamma distribution's cdf
2202  // function can be used here.
2203  for (uint32_t i = 0; i < N_BINS; ++i)
2204  {
2205  expected[i] = gsl_cdf_gamma_P (range[i + 1], k, lambda) - gsl_cdf_gamma_P (range[i], k, lambda);
2206  expected[i] *= N_MEASUREMENTS;
2207  }
2208 
2209  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2210  {
2211  gsl_histogram_increment (h, n->GetValue ());
2212  }
2213 
2214  double tmp[N_BINS];
2215 
2216  for (uint32_t i = 0; i < N_BINS; ++i)
2217  {
2218  tmp[i] = gsl_histogram_get (h, i);
2219  tmp[i] -= expected[i];
2220  tmp[i] *= tmp[i];
2221  tmp[i] /= expected[i];
2222  }
2223 
2224  gsl_histogram_free (h);
2225 
2226  double chiSquared = 0;
2227 
2228  for (uint32_t i = 0; i < N_BINS; ++i)
2229  {
2230  chiSquared += tmp[i];
2231  }
2232 
2233  return chiSquared;
2234 }
2235 
2236 void
2238 {
2239  SeedManager::SetSeed (time (0));
2240 
2241  double sum = 0.;
2242  double maxStatistic = gsl_cdf_chisq_Qinv (0.05, N_BINS);
2243 
2244  for (uint32_t i = 0; i < N_RUNS; ++i)
2245  {
2246  Ptr<ErlangRandomVariable> n = CreateObject<ErlangRandomVariable> ();
2247 
2248  // Make this generate antithetic values.
2249  n->SetAttribute ("Antithetic", BooleanValue (true));
2250 
2251  double result = ChiSquaredTest (n);
2252  sum += result;
2253  }
2254 
2255  sum /= (double)N_RUNS;
2256 
2257  NS_TEST_ASSERT_MSG_LT (sum, maxStatistic, "Chi-squared statistic out of range");
2258 
2259  uint32_t k = 5;
2260  double lambda = 2.0;
2261  double value;
2262 
2263  // Create the RNG with the specified range.
2264  Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> ();
2265 
2266  // Make this generate antithetic values.
2267  x->SetAttribute ("Antithetic", BooleanValue (true));
2268 
2269  x->SetAttribute ("K", IntegerValue (k));
2270  x->SetAttribute ("Lambda", DoubleValue (lambda));
2271 
2272  // Calculate the mean of these values.
2273  sum = 0.0;
2274  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2275  {
2276  value = x->GetValue ();
2277  sum += value;
2278  }
2279  double valueMean = sum / N_MEASUREMENTS;
2280 
2281  // The expected value for the mean of the values returned by a
2282  // Erlangly distributed random variable is equal to
2283  //
2284  // E[value] = k * lambda .
2285  //
2286  double expectedMean = k * lambda;
2287 
2288  // Test that values have approximately the right mean value.
2289  double TOLERANCE = expectedMean * 1e-2;
2290  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2291 }
2292 
2293 // ===========================================================================
2294 // Test case for Zipf distribution random variable stream generator
2295 // ===========================================================================
2297 {
2298 public:
2299  static const uint32_t N_MEASUREMENTS = 1000000;
2300 
2303 
2304 private:
2305  virtual void DoRun (void);
2306 };
2307 
2309  : TestCase ("Zipf Random Variable Stream Generator")
2310 {
2311 }
2312 
2314 {
2315 }
2316 
2317 void
2319 {
2320  SeedManager::SetSeed (time (0));
2321 
2322  uint32_t n = 1;
2323  double alpha = 2.0;
2324  double value;
2325 
2326  // Create the RNG with the specified range.
2327  Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> ();
2328  x->SetAttribute ("N", IntegerValue (n));
2329  x->SetAttribute ("Alpha", DoubleValue (alpha));
2330 
2331  // Calculate the mean of these values.
2332  double sum = 0.0;
2333  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2334  {
2335  value = x->GetValue ();
2336  sum += value;
2337  }
2338  double valueMean = sum / N_MEASUREMENTS;
2339 
2340  // The expected value for the mean of the values returned by a
2341  // Zipfly distributed random variable is equal to
2342  //
2343  // H
2344  // N, alpha - 1
2345  // E[value] = ---------------
2346  // H
2347  // N, alpha
2348  //
2349  // where
2350  //
2351  // N
2352  // ---
2353  // \ -alpha
2354  // H = / m .
2355  // N, alpha ---
2356  // m=1
2357  //
2358  // For this test,
2359  //
2360  // -(alpha - 1)
2361  // 1
2362  // E[value] = ---------------
2363  // -alpha
2364  // 1
2365  //
2366  // = 1 .
2367  //
2368  double expectedMean = 1.0;
2369 
2370  // Test that values have approximately the right mean value.
2371  double TOLERANCE = expectedMean * 1e-2;
2372  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2373 }
2374 
2375 // ===========================================================================
2376 // Test case for antithetic Zipf distribution random variable stream generator
2377 // ===========================================================================
2379 {
2380 public:
2381  static const uint32_t N_MEASUREMENTS = 1000000;
2382 
2385 
2386 private:
2387  virtual void DoRun (void);
2388 };
2389 
2391  : TestCase ("Antithetic Zipf Random Variable Stream Generator")
2392 {
2393 }
2394 
2396 {
2397 }
2398 
2399 void
2401 {
2402  SeedManager::SetSeed (time (0));
2403 
2404  uint32_t n = 1;
2405  double alpha = 2.0;
2406  double value;
2407 
2408  // Create the RNG with the specified range.
2409  Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> ();
2410  x->SetAttribute ("N", IntegerValue (n));
2411  x->SetAttribute ("Alpha", DoubleValue (alpha));
2412 
2413  // Make this generate antithetic values.
2414  x->SetAttribute ("Antithetic", BooleanValue (true));
2415 
2416  // Calculate the mean of these values.
2417  double sum = 0.0;
2418  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2419  {
2420  value = x->GetValue ();
2421  sum += value;
2422  }
2423  double valueMean = sum / N_MEASUREMENTS;
2424 
2425  // The expected value for the mean of the values returned by a
2426  // Zipfly distributed random variable is equal to
2427  //
2428  // H
2429  // N, alpha - 1
2430  // E[value] = ---------------
2431  // H
2432  // N, alpha
2433  //
2434  // where
2435  //
2436  // N
2437  // ---
2438  // \ -alpha
2439  // H = / m .
2440  // N, alpha ---
2441  // m=1
2442  //
2443  // For this test,
2444  //
2445  // -(alpha - 1)
2446  // 1
2447  // E[value] = ---------------
2448  // -alpha
2449  // 1
2450  //
2451  // = 1 .
2452  //
2453  double expectedMean = 1.0;
2454 
2455  // Test that values have approximately the right mean value.
2456  double TOLERANCE = expectedMean * 1e-2;
2457  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2458 }
2459 
2460 // ===========================================================================
2461 // Test case for Zeta distribution random variable stream generator
2462 // ===========================================================================
2464 {
2465 public:
2466  static const uint32_t N_MEASUREMENTS = 1000000;
2467 
2470 
2471 private:
2472  virtual void DoRun (void);
2473 };
2474 
2476  : TestCase ("Zeta Random Variable Stream Generator")
2477 {
2478 }
2479 
2481 {
2482 }
2483 
2484 void
2486 {
2487  SeedManager::SetSeed (time (0));
2488 
2489  double alpha = 5.0;
2490  double value;
2491 
2492  // Create the RNG with the specified range.
2493  Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> ();
2494  x->SetAttribute ("Alpha", DoubleValue (alpha));
2495 
2496  // Calculate the mean of these values.
2497  double sum = 0.0;
2498  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2499  {
2500  value = x->GetValue ();
2501  sum += value;
2502  }
2503  double valueMean = sum / N_MEASUREMENTS;
2504 
2505  // The expected value for the mean of the values returned by a
2506  // zetaly distributed random variable is equal to
2507  //
2508  // zeta(alpha - 1)
2509  // E[value] = --------------- for alpha > 2 ,
2510  // zeta(alpha)
2511  //
2512  // where zeta(alpha) is the Riemann zeta function.
2513  //
2514  // There are no simple analytic forms for the Riemann zeta function,
2515  // which is why the gsl library is used in this test to calculate
2516  // the known mean of the values.
2517  double expectedMean = gsl_sf_zeta_int (alpha - 1) / gsl_sf_zeta_int (alpha);
2518 
2519  // Test that values have approximately the right mean value.
2520  double TOLERANCE = expectedMean * 1e-2;
2521  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2522 }
2523 
2524 // ===========================================================================
2525 // Test case for antithetic Zeta distribution random variable stream generator
2526 // ===========================================================================
2528 {
2529 public:
2530  static const uint32_t N_MEASUREMENTS = 1000000;
2531 
2534 
2535 private:
2536  virtual void DoRun (void);
2537 };
2538 
2540  : TestCase ("Antithetic Zeta Random Variable Stream Generator")
2541 {
2542 }
2543 
2545 {
2546 }
2547 
2548 void
2550 {
2551  SeedManager::SetSeed (time (0));
2552 
2553  double alpha = 5.0;
2554  double value;
2555 
2556  // Create the RNG with the specified range.
2557  Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> ();
2558  x->SetAttribute ("Alpha", DoubleValue (alpha));
2559 
2560  // Make this generate antithetic values.
2561  x->SetAttribute ("Antithetic", BooleanValue (true));
2562 
2563  // Calculate the mean of these values.
2564  double sum = 0.0;
2565  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2566  {
2567  value = x->GetValue ();
2568  sum += value;
2569  }
2570  double valueMean = sum / N_MEASUREMENTS;
2571 
2572  // The expected value for the mean of the values returned by a
2573  // zetaly distributed random variable is equal to
2574  //
2575  // zeta(alpha - 1)
2576  // E[value] = --------------- for alpha > 2 ,
2577  // zeta(alpha)
2578  //
2579  // where zeta(alpha) is the Riemann zeta function.
2580  //
2581  // There are no simple analytic forms for the Riemann zeta function,
2582  // which is why the gsl library is used in this test to calculate
2583  // the known mean of the values.
2584  double expectedMean = gsl_sf_zeta_int (alpha - 1) / gsl_sf_zeta_int (alpha);
2585 
2586  // Test that values have approximately the right mean value.
2587  double TOLERANCE = expectedMean * 1e-2;
2588  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2589 }
2590 
2591 // ===========================================================================
2592 // Test case for deterministic random variable stream generator
2593 // ===========================================================================
2595 {
2596 public:
2597  static const double TOLERANCE;
2598 
2601 
2602 private:
2603  virtual void DoRun (void);
2604 };
2605 
2607 
2609  : TestCase ("Deterministic Random Variable Stream Generator")
2610 {
2611 }
2612 
2614 {
2615 }
2616 
2617 void
2619 {
2620  SeedManager::SetSeed (time (0));
2621 
2622  Ptr<DeterministicRandomVariable> s = CreateObject<DeterministicRandomVariable> ();
2623 
2624  // The following array should give the sequence
2625  //
2626  // 4, 4, 7, 7, 10, 10 .
2627  //
2628  double array1 [] = { 4, 4, 7, 7, 10, 10};
2629  uint64_t count1 = 6;
2630  s->SetValueArray (array1, count1);
2631 
2632  double value;
2633 
2634  // Test that the first sequence is correct.
2635  value = s->GetValue ();
2636  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence 1 value 1 wrong.");
2637  value = s->GetValue ();
2638  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4, TOLERANCE, "Sequence 1 value 2 wrong.");
2639  value = s->GetValue ();
2640  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence 1 value 3 wrong.");
2641  value = s->GetValue ();
2642  NS_TEST_ASSERT_MSG_EQ_TOL (value, 7, TOLERANCE, "Sequence 1 value 4 wrong.");
2643  value = s->GetValue ();
2644  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence 1 value 5 wrong.");
2645  value = s->GetValue ();
2646  NS_TEST_ASSERT_MSG_EQ_TOL (value, 10, TOLERANCE, "Sequence 1 value 6 wrong.");
2647 
2648  // The following array should give the sequence
2649  //
2650  // 1000, 2000, 7, 7 .
2651  //
2652  double array2 [] = { 1000, 2000, 3000, 4000};
2653  uint64_t count2 = 4;
2654  s->SetValueArray (array2, count2);
2655 
2656  // Test that the second sequence is correct.
2657  value = s->GetValue ();
2658  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1000, TOLERANCE, "Sequence 2 value 1 wrong.");
2659  value = s->GetValue ();
2660  NS_TEST_ASSERT_MSG_EQ_TOL (value, 2000, TOLERANCE, "Sequence 2 value 2 wrong.");
2661  value = s->GetValue ();
2662  NS_TEST_ASSERT_MSG_EQ_TOL (value, 3000, TOLERANCE, "Sequence 2 value 3 wrong.");
2663  value = s->GetValue ();
2664  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4000, TOLERANCE, "Sequence 2 value 4 wrong.");
2665  value = s->GetValue ();
2666 }
2667 
2668 // ===========================================================================
2669 // Test case for empirical distribution random variable stream generator
2670 // ===========================================================================
2672 {
2673 public:
2674  static const uint32_t N_MEASUREMENTS = 1000000;
2675 
2678 
2679 private:
2680  virtual void DoRun (void);
2681 };
2682 
2684  : TestCase ("Empirical Random Variable Stream Generator")
2685 {
2686 }
2687 
2689 {
2690 }
2691 
2692 void
2694 {
2695  SeedManager::SetSeed (time (0));
2696 
2697  // Create the RNG with a uniform distribution between 0 and 10.
2698  Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> ();
2699  x->CDF ( 0.0, 0.0);
2700  x->CDF ( 5.0, 0.5);
2701  x->CDF (10.0, 1.0);
2702 
2703  // Calculate the mean of these values.
2704  double sum = 0.0;
2705  double value;
2706  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2707  {
2708  value = x->GetValue ();
2709  sum += value;
2710  }
2711  double valueMean = sum / N_MEASUREMENTS;
2712 
2713  // The expected value for the mean of the values returned by this
2714  // empirical distribution is the midpoint of the distribution
2715  //
2716  // E[value] = 5 .
2717  //
2718  double expectedMean = 5.0;
2719 
2720  // Test that values have approximately the right mean value.
2721  double TOLERANCE = expectedMean * 1e-2;
2722  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2723 }
2724 
2725 // ===========================================================================
2726 // Test case for antithetic empirical distribution random variable stream generator
2727 // ===========================================================================
2729 {
2730 public:
2731  static const uint32_t N_MEASUREMENTS = 1000000;
2732 
2735 
2736 private:
2737  virtual void DoRun (void);
2738 };
2739 
2741  : TestCase ("EmpiricalAntithetic Random Variable Stream Generator")
2742 {
2743 }
2744 
2746 {
2747 }
2748 
2749 void
2751 {
2752  SeedManager::SetSeed (time (0));
2753 
2754  // Create the RNG with a uniform distribution between 0 and 10.
2755  Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> ();
2756  x->CDF ( 0.0, 0.0);
2757  x->CDF ( 5.0, 0.5);
2758  x->CDF (10.0, 1.0);
2759 
2760  // Make this generate antithetic values.
2761  x->SetAttribute ("Antithetic", BooleanValue (true));
2762 
2763  // Calculate the mean of these values.
2764  double sum = 0.0;
2765  double value;
2766  for (uint32_t i = 0; i < N_MEASUREMENTS; ++i)
2767  {
2768  value = x->GetValue ();
2769  sum += value;
2770  }
2771  double valueMean = sum / N_MEASUREMENTS;
2772 
2773  // The expected value for the mean of the values returned by this
2774  // empirical distribution is the midpoint of the distribution
2775  //
2776  // E[value] = 5 .
2777  //
2778  double expectedMean = 5.0;
2779 
2780  // Test that values have approximately the right mean value.
2781  double TOLERANCE = expectedMean * 1e-2;
2782  NS_TEST_ASSERT_MSG_EQ_TOL (valueMean, expectedMean, TOLERANCE, "Wrong mean value.");
2783 }
2784 
2786 {
2787 public:
2789 };
2790 
2792  : TestSuite ("random-variable-stream-generators", UNIT)
2793 {
2794  AddTestCase (new RandomVariableStreamUniformTestCase, TestCase::QUICK);
2796  AddTestCase (new RandomVariableStreamConstantTestCase, TestCase::QUICK);
2797  AddTestCase (new RandomVariableStreamSequentialTestCase, TestCase::QUICK);
2798  AddTestCase (new RandomVariableStreamNormalTestCase, TestCase::QUICK);
2802  AddTestCase (new RandomVariableStreamParetoTestCase, TestCase::QUICK);
2804  AddTestCase (new RandomVariableStreamWeibullTestCase, TestCase::QUICK);
2806  AddTestCase (new RandomVariableStreamLogNormalTestCase, TestCase::QUICK);
2810  /*
2811  AddTestCase (new RandomVariableStreamLogNormalAntitheticTestCase, TestCase::QUICK);
2812  */
2813  AddTestCase (new RandomVariableStreamGammaTestCase, TestCase::QUICK);
2817  /*
2818  AddTestCase (new RandomVariableStreamGammaAntitheticTestCase, TestCase::QUICK);
2819  */
2820  AddTestCase (new RandomVariableStreamErlangTestCase, TestCase::QUICK);
2822  AddTestCase (new RandomVariableStreamZipfTestCase, TestCase::QUICK);
2824  AddTestCase (new RandomVariableStreamZetaTestCase, TestCase::QUICK);
2827  AddTestCase (new RandomVariableStreamEmpiricalTestCase, TestCase::QUICK);
2829 }
2830 
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:18
static RandomVariableStreamTestSuite randomVariableStreamTestSuite
#define TOLERANCE
A suite of tests to run.
Definition: test.h:1105
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.
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:929
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.
#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:148
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.
#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:355
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:184
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.
#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:589
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...
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:176
virtual void DoRun(void)
Implementation to actually run this TestCase.
#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:753
double GetValue(double scale, double shape, double bound)
Returns a random double from a Weibull distribution with the specified scale, shape, and upper bound.