1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.random;
23
24 import java.text.DecimalFormat;
25 import java.util.ArrayList;
26 import java.util.HashSet;
27 import java.util.List;
28
29 import org.hipparchus.RetryRunner;
30 import org.hipparchus.UnitTestUtils;
31 import org.hipparchus.distribution.continuous.BetaDistribution;
32 import org.hipparchus.distribution.continuous.EnumeratedRealDistribution;
33 import org.hipparchus.distribution.continuous.ExponentialDistribution;
34 import org.hipparchus.distribution.continuous.GammaDistribution;
35 import org.hipparchus.distribution.continuous.NormalDistribution;
36 import org.hipparchus.distribution.discrete.EnumeratedIntegerDistribution;
37 import org.hipparchus.distribution.discrete.PoissonDistribution;
38 import org.hipparchus.distribution.discrete.ZipfDistribution;
39 import org.hipparchus.exception.MathIllegalArgumentException;
40 import org.hipparchus.util.FastMath;
41 import org.junit.Assert;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44
45
46
47
48
49 @RunWith(RetryRunner.class)
50 public class RandomDataGeneratorTest {
51
52 public RandomDataGeneratorTest() {
53 randomData = RandomDataGenerator.of(new Well19937c());
54 randomData.setSeed(100);
55 }
56
57 protected final long smallSampleSize = 1000;
58 protected final double[] expected = { 250, 250, 250, 250 };
59 protected final int largeSampleSize = 10000;
60 private final String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
61 "a", "b", "c", "d", "e", "f" };
62 protected RandomDataGenerator randomData = null;
63
64 @Test
65 public void testNextIntExtremeValues() {
66 int x = randomData.nextInt(Integer.MIN_VALUE, Integer.MAX_VALUE);
67 int y = randomData.nextInt(Integer.MIN_VALUE, Integer.MAX_VALUE);
68 Assert.assertFalse(x == y);
69 }
70
71 @Test
72 public void testNextLongExtremeValues() {
73 long x = randomData.nextLong(Long.MIN_VALUE, Long.MAX_VALUE);
74 long y = randomData.nextLong(Long.MIN_VALUE, Long.MAX_VALUE);
75 Assert.assertFalse(x == y);
76 }
77
78 @Test
79 public void testNextUniformExtremeValues() {
80 double x = randomData.nextUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
81 double y = randomData.nextUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
82 Assert.assertFalse(x == y);
83 Assert.assertFalse(Double.isNaN(x));
84 Assert.assertFalse(Double.isNaN(y));
85 Assert.assertFalse(Double.isInfinite(x));
86 Assert.assertFalse(Double.isInfinite(y));
87 }
88
89 @Test
90 public void testNextIntIAE() {
91 try {
92 randomData.nextInt(4, 3);
93 Assert.fail("MathIllegalArgumentException expected");
94 } catch (MathIllegalArgumentException ex) {
95
96 }
97 }
98
99 @Test
100 public void testNextIntNegativeToPositiveRange() {
101 for (int i = 0; i < 5; i++) {
102 checkNextIntUniform(-3, 5);
103 checkNextIntUniform(-3, 6);
104 }
105 }
106
107 @Test
108 public void testNextIntNegativeRange() {
109 for (int i = 0; i < 5; i++) {
110 checkNextIntUniform(-7, -4);
111 checkNextIntUniform(-15, -2);
112 checkNextIntUniform(Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 12);
113 }
114 }
115
116 @Test
117 public void testNextIntPositiveRange() {
118 for (int i = 0; i < 5; i++) {
119 checkNextIntUniform(0, 3);
120 checkNextIntUniform(2, 12);
121 checkNextIntUniform(1,2);
122 checkNextIntUniform(Integer.MAX_VALUE - 12, Integer.MAX_VALUE - 1);
123 }
124 }
125
126 private void checkNextIntUniform(int min, int max) {
127 final int len = max - min + 1;
128 final UnitTestUtils.Frequency<Integer> freq = new UnitTestUtils.Frequency<Integer>();
129 for (int i = 0; i < smallSampleSize; i++) {
130 final int value = randomData.nextInt(min, max);
131 Assert.assertTrue("nextInt range", (value >= min) && (value <= max));
132 freq.addValue(value);
133 }
134 final long[] observed = new long[len];
135 for (int i = 0; i < len; i++) {
136 observed[i] = freq.getCount(min + i);
137 }
138 final double[] expected = new double[len];
139 for (int i = 0; i < len; i++) {
140 expected[i] = 1d / len;
141 }
142
143 UnitTestUtils.assertChiSquareAccept(expected, observed, 0.001);
144 }
145
146 @Test
147 public void testNextIntWideRange() {
148 int lower = -0x6543210F;
149 int upper = 0x456789AB;
150 int max = Integer.MIN_VALUE;
151 int min = Integer.MAX_VALUE;
152 for (int i = 0; i < 1000000; ++i) {
153 int r = randomData.nextInt(lower, upper);
154 max = FastMath.max(max, r);
155 min = FastMath.min(min, r);
156 Assert.assertTrue(r >= lower);
157 Assert.assertTrue(r <= upper);
158 }
159 double ratio = (((double) max) - ((double) min)) /
160 (((double) upper) - ((double) lower));
161 Assert.assertTrue(ratio > 0.99999);
162 }
163
164 @Test
165 public void testNextLongIAE() {
166 try {
167 randomData.nextLong(4, 3);
168 Assert.fail("MathIllegalArgumentException expected");
169 } catch (MathIllegalArgumentException ex) {
170
171 }
172 }
173
174 @Test
175 public void testNextLongNegativeToPositiveRange() {
176 for (int i = 0; i < 5; i++) {
177 checkNextLongUniform(-3, 5);
178 checkNextLongUniform(-3, 6);
179 }
180 }
181
182 @Test
183 public void testNextLongNegativeRange() {
184 for (int i = 0; i < 5; i++) {
185 checkNextLongUniform(-7, -4);
186 checkNextLongUniform(-15, -2);
187 checkNextLongUniform(Long.MIN_VALUE + 1, Long.MIN_VALUE + 12);
188 }
189 }
190
191 @Test
192 public void testNextLongPositiveRange() {
193 for (int i = 0; i < 5; i++) {
194 checkNextLongUniform(0, 3);
195 checkNextLongUniform(2, 12);
196 checkNextLongUniform(Long.MAX_VALUE - 12, Long.MAX_VALUE - 1);
197 }
198 }
199
200 private void checkNextLongUniform(long min, long max) {
201 final int len = ((int) (max - min)) + 1;
202 final UnitTestUtils.Frequency<Integer> freq = new UnitTestUtils.Frequency<Integer>();
203 for (int i = 0; i < smallSampleSize; i++) {
204 final long value = randomData.nextLong(min, max);
205 Assert.assertTrue("nextLong range: " + value + " " + min + " " + max,
206 (value >= min) && (value <= max));
207 freq.addValue((int)value);
208 }
209 final long[] observed = new long[len];
210 for (int i = 0; i < len; i++) {
211 observed[i] = freq.getCount((int) min + i);
212 }
213 final double[] expected = new double[len];
214 for (int i = 0; i < len; i++) {
215 expected[i] = 1d / len;
216 }
217
218 UnitTestUtils.assertChiSquareAccept(expected, observed, 0.01);
219 }
220
221 @Test
222 public void testNextLongWideRange() {
223 long lower = -0x6543210FEDCBA987L;
224 long upper = 0x456789ABCDEF0123L;
225 long max = Long.MIN_VALUE;
226 long min = Long.MAX_VALUE;
227 for (int i = 0; i < 10000000; ++i) {
228 long r = randomData.nextLong(lower, upper);
229 max = FastMath.max(max, r);
230 min = FastMath.min(min, r);
231 Assert.assertTrue(r >= lower);
232 Assert.assertTrue(r <= upper);
233 }
234 double ratio = (((double) max) - ((double) min)) /
235 (((double) upper) - ((double) lower));
236 Assert.assertTrue(ratio > 0.99999);
237 }
238
239
240
241
242
243
244 @Test
245 public void testNextPoisson() {
246 try {
247 randomData.nextPoisson(0);
248 Assert.fail("zero mean -- expecting MathIllegalArgumentException");
249 } catch (MathIllegalArgumentException ex) {
250
251 }
252 try {
253 randomData.nextPoisson(-1);
254 Assert.fail("negative mean supplied -- MathIllegalArgumentException expected");
255 } catch (MathIllegalArgumentException ex) {
256
257 }
258 try {
259 randomData.nextPoisson(0);
260 Assert.fail("0 mean supplied -- MathIllegalArgumentException expected");
261 } catch (MathIllegalArgumentException ex) {
262
263 }
264
265 final double mean = 4.0d;
266 final int len = 5;
267 PoissonDistribution poissonDistribution = new PoissonDistribution(mean);
268 final UnitTestUtils.Frequency<Integer> freq = new UnitTestUtils.Frequency<Integer>();
269 randomData.setSeed(1000);
270 for (int i = 0; i < largeSampleSize; i++) {
271 freq.addValue(randomData.nextPoisson(mean));
272 }
273 final long[] observed = new long[len];
274 for (int i = 0; i < len; i++) {
275 observed[i] = freq.getCount(i + 1);
276 }
277 final double[] expected = new double[len];
278 for (int i = 0; i < len; i++) {
279 expected[i] = poissonDistribution.probability(i + 1) * largeSampleSize;
280 }
281
282 UnitTestUtils.assertChiSquareAccept(expected, observed, 0.0001);
283 }
284
285 @Test
286 public void testNextPoissonConsistency() {
287
288
289 for (int i = 1; i < 100; i++) {
290 checkNextPoissonConsistency(i);
291 }
292
293 for (int i = 1; i < 10; i++) {
294 checkNextPoissonConsistency(randomData.nextUniform(1, 1000));
295 }
296
297 for (int i = 1; i < 10; i++) {
298 checkNextPoissonConsistency(randomData.nextUniform(1000, 10000));
299 }
300 }
301
302
303
304
305
306
307
308
309
310
311 public void checkNextPoissonConsistency(double mean) {
312
313 final int sampleSize = 1000;
314 final int minExpectedCount = 7;
315 long maxObservedValue = 0;
316 final double alpha = 0.001;
317 UnitTestUtils.Frequency<Long> frequency = new UnitTestUtils.Frequency<Long>();
318 for (int i = 0; i < sampleSize; i++) {
319 long value = randomData.nextPoisson(mean);
320 if (value > maxObservedValue) {
321 maxObservedValue = value;
322 }
323 frequency.addValue(value);
324 }
325
326
327
328
329
330
331
332 PoissonDistribution poissonDistribution = new PoissonDistribution(mean);
333 int lower = 1;
334 while (poissonDistribution.cumulativeProbability(lower - 1) * sampleSize < minExpectedCount) {
335 lower++;
336 }
337 int upper = (int) (5 * mean);
338 while ((1 - poissonDistribution.cumulativeProbability(upper - 1)) * sampleSize < minExpectedCount) {
339 upper--;
340 }
341
342
343 int binWidth = 0;
344 boolean widthSufficient = false;
345 double lowerBinMass = 0;
346 double upperBinMass = 0;
347 while (!widthSufficient) {
348 binWidth++;
349 lowerBinMass = poissonDistribution.probability(lower - 1, lower + binWidth - 1);
350 upperBinMass = poissonDistribution.probability(upper - binWidth - 1, upper - 1);
351 widthSufficient = FastMath.min(lowerBinMass, upperBinMass) * sampleSize >= minExpectedCount;
352 }
353
354
355
356
357
358
359
360 List<Integer> binBounds = new ArrayList<Integer>();
361 binBounds.add(lower);
362 int bound = lower + binWidth;
363 while (bound < upper - binWidth) {
364 binBounds.add(bound);
365 bound += binWidth;
366 }
367 binBounds.add(upper);
368
369
370 final int binCount = binBounds.size() + 1;
371 long[] observed = new long[binCount];
372 double[] expected = new double[binCount];
373
374
375 observed[0] = 0;
376 for (int i = 0; i < lower; i++) {
377 observed[0] += frequency.getCount((long)i);
378 }
379 expected[0] = poissonDistribution.cumulativeProbability(lower - 1) * sampleSize;
380
381
382 observed[binCount - 1] = 0;
383 for (int i = upper; i <= maxObservedValue; i++) {
384 observed[binCount - 1] += frequency.getCount((long)i);
385 }
386 expected[binCount - 1] = (1 - poissonDistribution.cumulativeProbability(upper - 1)) * sampleSize;
387
388
389 for (int i = 1; i < binCount - 1; i++) {
390 observed[i] = 0;
391 for (int j = binBounds.get(i - 1); j < binBounds.get(i); j++) {
392 observed[i] += frequency.getCount((long)j);
393 }
394 expected[i] = (poissonDistribution.cumulativeProbability(binBounds.get(i) - 1) -
395 poissonDistribution.cumulativeProbability(binBounds.get(i - 1) -1)) * sampleSize;
396 }
397
398
399
400 if (UnitTestUtils.chiSquareTest(expected, observed) < alpha) {
401 StringBuilder msgBuffer = new StringBuilder();
402 DecimalFormat df = new DecimalFormat("#.##");
403 msgBuffer.append("Chisquare test failed for mean = ");
404 msgBuffer.append(mean);
405 msgBuffer.append(" p-value = ");
406 msgBuffer.append(UnitTestUtils.chiSquareTest(expected, observed));
407 msgBuffer.append(" chisquare statistic = ");
408 msgBuffer.append(UnitTestUtils.chiSquare(expected, observed));
409 msgBuffer.append(". \n");
410 msgBuffer.append("bin\t\texpected\tobserved\n");
411 for (int i = 0; i < expected.length; i++) {
412 msgBuffer.append("[");
413 msgBuffer.append(i == 0 ? 1: binBounds.get(i - 1));
414 msgBuffer.append(",");
415 msgBuffer.append(i == binBounds.size() ? "inf": binBounds.get(i));
416 msgBuffer.append(")");
417 msgBuffer.append("\t\t");
418 msgBuffer.append(df.format(expected[i]));
419 msgBuffer.append("\t\t");
420 msgBuffer.append(observed[i]);
421 msgBuffer.append("\n");
422 }
423 msgBuffer.append("This test can fail randomly due to sampling error with probability ");
424 msgBuffer.append(alpha);
425 msgBuffer.append(".");
426 Assert.fail(msgBuffer.toString());
427 }
428 }
429
430
431 @Test
432 public void testNextHex() {
433 try {
434 randomData.nextHexString(-1);
435 Assert.fail("negative length supplied -- MathIllegalArgumentException expected");
436 } catch (MathIllegalArgumentException ex) {
437
438 }
439 try {
440 randomData.nextHexString(0);
441 Assert.fail("zero length supplied -- MathIllegalArgumentException expected");
442 } catch (MathIllegalArgumentException ex) {
443
444 }
445 String hexString = randomData.nextHexString(3);
446 if (hexString.length() != 3) {
447 Assert.fail("incorrect length for generated string");
448 }
449 hexString = randomData.nextHexString(1);
450 if (hexString.length() != 1) {
451 Assert.fail("incorrect length for generated string");
452 }
453 try {
454 hexString = randomData.nextHexString(0);
455 Assert.fail("zero length requested -- expecting MathIllegalArgumentException");
456 } catch (MathIllegalArgumentException ex) {
457
458 }
459 UnitTestUtils.Frequency<String> f = new UnitTestUtils.Frequency<String> ();
460 for (int i = 0; i < smallSampleSize; i++) {
461 hexString = randomData.nextHexString(100);
462 if (hexString.length() != 100) {
463 Assert.fail("incorrect length for generated string");
464 }
465 for (int j = 0; j < hexString.length(); j++) {
466 f.addValue(hexString.substring(j, j + 1));
467 }
468 }
469 double[] expected = new double[16];
470 long[] observed = new long[16];
471 for (int i = 0; i < 16; i++) {
472 expected[i] = (double) smallSampleSize * 100 / 16;
473 observed[i] = f.getCount(hex[i]);
474 }
475 UnitTestUtils.assertChiSquareAccept(expected, observed, 0.001);
476 }
477
478 @Test
479 public void testNextUniformIAE() {
480 try {
481 randomData.nextUniform(4, 3);
482 Assert.fail("MathIllegalArgumentException expected");
483 } catch (MathIllegalArgumentException ex) {
484
485 }
486 try {
487 randomData.nextUniform(0, Double.POSITIVE_INFINITY);
488 Assert.fail("MathIllegalArgumentException expected");
489 } catch (MathIllegalArgumentException ex) {
490
491 }
492 try {
493 randomData.nextUniform(Double.NEGATIVE_INFINITY, 0);
494 Assert.fail("MathIllegalArgumentException expected");
495 } catch (MathIllegalArgumentException ex) {
496
497 }
498 try {
499 randomData.nextUniform(0, Double.NaN);
500 Assert.fail("MathIllegalArgumentException expected");
501 } catch (MathIllegalArgumentException ex) {
502
503 }
504 try {
505 randomData.nextUniform(Double.NaN, 0);
506 Assert.fail("MathIllegalArgumentException expected");
507 } catch (MathIllegalArgumentException ex) {
508
509 }
510 }
511
512 @Test
513 public void testNextUniformUniformPositiveBounds() {
514 for (int i = 0; i < 5; i++) {
515 checkNextUniformUniform(0, 10);
516 }
517 }
518
519 @Test
520 public void testNextUniformUniformNegativeToPositiveBounds() {
521 for (int i = 0; i < 5; i++) {
522 checkNextUniformUniform(-3, 5);
523 }
524 }
525
526 @Test
527 public void testNextUniformUniformNegaiveBounds() {
528 for (int i = 0; i < 5; i++) {
529 checkNextUniformUniform(-7, -3);
530 }
531 }
532
533 @Test
534 public void testNextUniformUniformMaximalInterval() {
535 for (int i = 0; i < 5; i++) {
536 checkNextUniformUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
537 }
538 }
539
540 private void checkNextUniformUniform(double min, double max) {
541
542 final int binCount = 5;
543 final double binSize = max / binCount - min/binCount;
544 final double[] binBounds = new double[binCount - 1];
545 binBounds[0] = min + binSize;
546 for (int i = 1; i < binCount - 1; i++) {
547 binBounds[i] = binBounds[i - 1] + binSize;
548 }
549
550 UnitTestUtils.Frequency<Integer> freq = new UnitTestUtils.Frequency<Integer>();
551 for (int i = 0; i < smallSampleSize; i++) {
552 final double value = randomData.nextUniform(min, max);
553 Assert.assertTrue("nextUniform range", (value > min) && (value < max));
554
555 int j = 0;
556 while (j < binCount - 1 && value > binBounds[j]) {
557 j++;
558 }
559 freq.addValue(j);
560 }
561
562 final long[] observed = new long[binCount];
563 for (int i = 0; i < binCount; i++) {
564 observed[i] = freq.getCount(i);
565 }
566 final double[] expected = new double[binCount];
567 for (int i = 0; i < binCount; i++) {
568 expected[i] = 1d / binCount;
569 }
570
571 UnitTestUtils.assertChiSquareAccept(expected, observed, 0.01);
572 }
573
574
575 @Test
576 public void testNextUniformExclusiveEndpoints() {
577 for (int i = 0; i < 1000; i++) {
578 double u = randomData.nextUniform(0.99, 1);
579 Assert.assertTrue(u > 0.99 && u < 1);
580 }
581 }
582
583
584 @Test
585 public void testNextGaussian() {
586 try {
587 randomData.nextNormal(0, 0);
588 Assert.fail("zero sigma -- MathIllegalArgumentException expected");
589 } catch (MathIllegalArgumentException ex) {
590
591 }
592 double[] quartiles = UnitTestUtils.getDistributionQuartiles(new NormalDistribution(0,1));
593 long[] counts = new long[4];
594 randomData.setSeed(1000);
595 for (int i = 0; i < 1000; i++) {
596 double value = randomData.nextNormal(0, 1);
597 UnitTestUtils.updateCounts(value, counts, quartiles);
598 }
599 UnitTestUtils.assertChiSquareAccept(expected, counts, 0.001);
600 }
601
602
603 @Test
604 public void testNextExponential() {
605 try {
606 randomData.nextExponential(-1);
607 Assert.fail("negative mean -- expecting MathIllegalArgumentException");
608 } catch (MathIllegalArgumentException ex) {
609
610 }
611 try {
612 randomData.nextExponential(0);
613 Assert.fail("zero mean -- expecting MathIllegalArgumentException");
614 } catch (MathIllegalArgumentException ex) {
615
616 }
617 double[] quartiles;
618 long[] counts;
619
620
621 quartiles = UnitTestUtils.getDistributionQuartiles(new ExponentialDistribution(1));
622 counts = new long[4];
623 randomData.setSeed(1000);
624 for (int i = 0; i < 1000; i++) {
625 double value = randomData.nextExponential(1);
626 UnitTestUtils.updateCounts(value, counts, quartiles);
627 }
628 UnitTestUtils.assertChiSquareAccept(expected, counts, 0.001);
629
630
631 quartiles = UnitTestUtils.getDistributionQuartiles(new ExponentialDistribution(5));
632 counts = new long[4];
633 randomData.setSeed(1000);
634 for (int i = 0; i < 1000; i++) {
635 double value = randomData.nextExponential(5);
636 UnitTestUtils.updateCounts(value, counts, quartiles);
637 }
638 UnitTestUtils.assertChiSquareAccept(expected, counts, 0.001);
639 }
640
641
642 @Test
643 public void testConfig() {
644 randomData.setSeed(1000);
645 double v = randomData.nextUniform(0, 1);
646 randomData.setSeed(System.currentTimeMillis());
647 Assert.assertTrue("different seeds", FastMath.abs(v - randomData.nextUniform(0, 1)) > 10E-12);
648 randomData.setSeed(1000);
649 Assert.assertEquals("same seeds", v, randomData.nextUniform(0, 1), 10E-12);
650 }
651
652
653 @Test
654 public void testNextSample() {
655 Object[][] c = { { "0", "1" }, { "0", "2" }, { "0", "3" },
656 { "0", "4" }, { "1", "2" }, { "1", "3" }, { "1", "4" },
657 { "2", "3" }, { "2", "4" }, { "3", "4" } };
658 long[] observed = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
659 double[] expected = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 };
660
661 HashSet<Object> cPop = new HashSet<Object>();
662 for (int i = 0; i < 5; i++) {
663 cPop.add(Integer.toString(i));
664 }
665
666 Object[] sets = new Object[10];
667 for (int i = 0; i < 10; i++) {
668 HashSet<Object> hs = new HashSet<Object>();
669 hs.add(c[i][0]);
670 hs.add(c[i][1]);
671 sets[i] = hs;
672 }
673
674 for (int i = 0; i < 1000; i++) {
675 Object[] cSamp = randomData.nextSample(cPop, 2);
676 observed[findSample(sets, cSamp)]++;
677 }
678
679
680
681
682
683 Assert.assertTrue("chi-square test -- will fail about 1 in 1000 times",
684 UnitTestUtils.chiSquare(expected, observed) < 27.88);
685
686
687 HashSet<Object> hs = new HashSet<Object>();
688 hs.add("one");
689 Object[] one = randomData.nextSample(hs, 1);
690 String oneString = (String) one[0];
691 if ((one.length != 1) || !oneString.equals("one")) {
692 Assert.fail("bad sample for set size = 1, sample size = 1");
693 }
694
695
696 try {
697 one = randomData.nextSample(hs, 2);
698 Assert.fail("sample size > set size, expecting MathIllegalArgumentException");
699 } catch (MathIllegalArgumentException ex) {
700
701 }
702
703
704 try {
705 hs = new HashSet<Object>();
706 one = randomData.nextSample(hs, 0);
707 Assert.fail("n = k = 0, expecting MathIllegalArgumentException");
708 } catch (MathIllegalArgumentException ex) {
709
710 }
711 }
712
713 @SuppressWarnings("unchecked")
714 private int findSample(Object[] u, Object[] samp) {
715 for (int i = 0; i < u.length; i++) {
716 HashSet<Object> set = (HashSet<Object>) u[i];
717 HashSet<Object> sampSet = new HashSet<Object>();
718 for (int j = 0; j < samp.length; j++) {
719 sampSet.add(samp[j]);
720 }
721 if (set.equals(sampSet)) {
722 return i;
723 }
724 }
725 Assert.fail("sample not found:{" + samp[0] + "," + samp[1] + "}");
726 return -1;
727 }
728
729
730 @Test
731 public void testNextPermutation() {
732 int[][] p = { { 0, 1, 2 }, { 0, 2, 1 }, { 1, 0, 2 }, { 1, 2, 0 },
733 { 2, 0, 1 }, { 2, 1, 0 } };
734 long[] observed = { 0, 0, 0, 0, 0, 0 };
735 double[] expected = { 100, 100, 100, 100, 100, 100 };
736
737 for (int i = 0; i < 600; i++) {
738 int[] perm = randomData.nextPermutation(3, 3);
739 observed[findPerm(p, perm)]++;
740 }
741
742 String[] labels = {"{0, 1, 2}", "{ 0, 2, 1 }", "{ 1, 0, 2 }",
743 "{ 1, 2, 0 }", "{ 2, 0, 1 }", "{ 2, 1, 0 }"};
744 UnitTestUtils.assertChiSquareAccept(labels, expected, observed, 0.001);
745
746
747 int[] perm = randomData.nextPermutation(1, 1);
748 if ((perm.length != 1) || (perm[0] != 0)) {
749 Assert.fail("bad permutation for n = 1, sample k = 1");
750
751
752 try {
753 perm = randomData.nextPermutation(2, 3);
754 Assert.fail("permutation k > n, expecting MathIllegalArgumentException");
755 } catch (MathIllegalArgumentException ex) {
756
757 }
758
759
760 try {
761 perm = randomData.nextPermutation(0, 0);
762 Assert.fail("permutation k = n = 0, expecting MathIllegalArgumentException");
763 } catch (MathIllegalArgumentException ex) {
764
765 }
766
767
768 try {
769 perm = randomData.nextPermutation(-1, -3);
770 Assert.fail("permutation k < n < 0, expecting MathIllegalArgumentException");
771 } catch (MathIllegalArgumentException ex) {
772
773 }
774
775 }
776 }
777
778 private int findPerm(int[][] p, int[] samp) {
779 for (int i = 0; i < p.length; i++) {
780 boolean good = true;
781 for (int j = 0; j < samp.length; j++) {
782 if (samp[j] != p[i][j]) {
783 good = false;
784 }
785 }
786 if (good) {
787 return i;
788 }
789 }
790 Assert.fail("permutation not found");
791 return -1;
792 }
793
794 @Test
795 public void testNextBeta() {
796 double[] quartiles = UnitTestUtils.getDistributionQuartiles(new BetaDistribution(2,5));
797 long[] counts = new long[4];
798 randomData.setSeed(1000);
799 for (int i = 0; i < 1000; i++) {
800 double value = randomData.nextBeta(2, 5);
801 UnitTestUtils.updateCounts(value, counts, quartiles);
802 }
803 UnitTestUtils.assertChiSquareAccept(expected, counts, 0.001);
804 }
805
806 @Test
807 public void testNextGamma() {
808 double[] quartiles;
809 long[] counts;
810
811
812 quartiles = UnitTestUtils.getDistributionQuartiles(new GammaDistribution(4, 2));
813 counts = new long[4];
814 randomData.setSeed(1000);
815 for (int i = 0; i < 1000; i++) {
816 double value = randomData.nextGamma(4, 2);
817 UnitTestUtils.updateCounts(value, counts, quartiles);
818 }
819 UnitTestUtils.assertChiSquareAccept(expected, counts, 0.001);
820
821
822 quartiles = UnitTestUtils.getDistributionQuartiles(new GammaDistribution(0.3, 3));
823 counts = new long[4];
824 randomData.setSeed(1000);
825 for (int i = 0; i < 1000; i++) {
826 double value = randomData.nextGamma(0.3, 3);
827 UnitTestUtils.updateCounts(value, counts, quartiles);
828 }
829 UnitTestUtils.assertChiSquareAccept(expected, counts, 0.001);
830 }
831
832 @Test
833 public void testNextGamma2() {
834 final RandomDataGenerator randomDataGenerator = new RandomDataGenerator(1000);
835 final int sampleSize = 1000;
836 final double alpha = 0.001;
837 GammaDistribution dist = new GammaDistribution(3, 1);
838 double[] values = randomDataGenerator.nextDeviates(dist, sampleSize);
839 UnitTestUtils.assertGTest(dist, values, alpha);
840 dist = new GammaDistribution(.4, 2);
841 values = randomDataGenerator.nextDeviates(dist, sampleSize);
842 UnitTestUtils.assertGTest(dist, values, alpha);
843 }
844
845 @Test
846 public void testNextBeta2() {
847 final double[] alphaBetas = {0.1, 1, 10, 100, 1000};
848 final RandomGenerator random = new Well1024a(0x7829862c82fec2dal);
849 final RandomDataGenerator randomDataGenerator = RandomDataGenerator.of(random);
850 final int sampleSize = 1000;
851 final double alphaCrit = 0.001;
852 for (final double alpha : alphaBetas) {
853 for (final double beta : alphaBetas) {
854 final BetaDistribution betaDistribution = new BetaDistribution(alpha, beta);
855 final double[] values = randomDataGenerator.nextDeviates(betaDistribution, sampleSize);
856 UnitTestUtils.assertGTest(betaDistribution, values, alphaCrit);
857 }
858 }
859 }
860
861 @Test
862 public void testNextZipf() {
863 int sampleSize = 1000;
864
865 int[] numPointsValues = {
866 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100
867 };
868 double[] exponentValues = {
869 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 2e-1, 5e-1,
870 1. - 1e-9, 1.0, 1. + 1e-9, 1.1, 1.2, 1.3, 1.5, 1.6, 1.7, 1.8, 2.0,
871 2.5, 3.0, 4., 5., 6., 7., 8., 9., 10., 20., 30., 100., 150.
872 };
873
874 for (int numPoints : numPointsValues) {
875 for (double exponent : exponentValues) {
876 double weightSum = 0.;
877 double[] weights = new double[numPoints];
878 for (int i = numPoints; i>=1; i-=1) {
879 weights[i-1] = Math.pow(i, -exponent);
880 weightSum += weights[i-1];
881 }
882
883
884 ZipfDistribution distribution = new ZipfDistribution(numPoints, exponent);
885 randomData.setSeed(1001);
886 double[] expectedCounts = new double[numPoints];
887 long[] observedCounts = new long[numPoints];
888 for (int i = 0; i < numPoints; i++) {
889 expectedCounts[i] = sampleSize * (weights[i]/weightSum);
890 }
891 int[] sample = randomData.nextDeviates(distribution,sampleSize);
892 for (int s : sample) {
893 observedCounts[s-1]++;
894 }
895 UnitTestUtils.assertChiSquareAccept(expectedCounts, observedCounts, 0.001);
896 }
897 }
898 }
899
900 @Test
901 public void testNextSampleWithReplacement() {
902 final int sampleSize = 1000;
903 final double[] weights = {1, 2, 3, 4};
904 final int[] sample = randomData.nextSampleWithReplacement(sampleSize, weights);
905 final double[] expected = {sampleSize/10d, sampleSize/5d, 3*sampleSize/10d, 2*sampleSize/5d};
906 final long[] observed = {0, 0, 0, 0};
907 for (int i = 0; i < sampleSize; i++) {
908 observed[sample[i]]++;
909 }
910 UnitTestUtils.assertChiSquareAccept(new String[] {"0", "1", "2","3"}, expected, observed, 0.01);
911 }
912
913 @Test
914 public void testNextSampleWithReplacementPointMass() {
915 final int sampleSize = 2;
916 double[] weights = {1};
917 final int[] expected = new int[] {0, 0};
918 UnitTestUtils.assertEquals(expected, randomData.nextSampleWithReplacement(sampleSize, weights));
919 weights = new double[] {1, 0};
920 UnitTestUtils.assertEquals(expected, randomData.nextSampleWithReplacement(sampleSize, weights));
921 }
922
923 @Test(expected=MathIllegalArgumentException.class)
924 public void testNextSampleWithReplacementAllZeroWeights() {
925 final double[] weights = {0, 0, 0};
926 randomData.nextSampleWithReplacement(1, weights);
927 }
928
929 @Test(expected=MathIllegalArgumentException.class)
930 public void testNextSampleWithReplacementNegativeWeights() {
931 final double[] weights = {-1, 1, 0};
932 randomData.nextSampleWithReplacement(1, weights);
933 }
934
935 @Test
936 public void testNextSampleWithReplacement0SampleSize() {
937 final double[] weights = {1, 0};
938 final int[] expected = {};
939 UnitTestUtils.assertEquals(expected, randomData.nextSampleWithReplacement(0, weights));
940 }
941
942 @Test(expected=MathIllegalArgumentException.class)
943 public void testNextSampleWithReplacementNegativeSampleSize() {
944 final double[] weights = {1, 0};
945 randomData.nextSampleWithReplacement(-1, weights);
946 }
947
948 @Test(expected=MathIllegalArgumentException.class)
949 public void testNextSampleWithReplacementNaNWeights() {
950 final double[] weights = {1, Double.NaN};
951 randomData.nextSampleWithReplacement(0, weights);
952 }
953
954 @Test
955 public void testNextDeviateEnumeratedIntegerDistribution() {
956 final int sampleSize = 1000;
957 final int[] data = new int[] {0, 1, 1, 2, 2, 2};
958 final EnumeratedIntegerDistribution dist = new EnumeratedIntegerDistribution(data);
959 final int[] sample = randomData.nextDeviates(dist, sampleSize);
960 final double[] expected = {sampleSize/6d, sampleSize/3d, sampleSize/2d};
961 final long[] observed = {0, 0, 0};
962 for (int i = 0; i < sampleSize; i++) {
963 observed[sample[i]]++;
964 }
965 UnitTestUtils.assertChiSquareAccept(new String[] {"0", "1", "2"}, expected, observed, 0.01);
966 }
967
968 @Test
969 public void testNextDeviateEnumeratedRealDistribution() {
970 final int sampleSize = 1000;
971 final double[] data = new double[] {0, 1, 1, 2, 2, 2};
972 final EnumeratedRealDistribution dist = new EnumeratedRealDistribution(data);
973 final double[] sample = randomData.nextDeviates(dist, sampleSize);
974 final double[] expected = {sampleSize/6d, sampleSize/3d, sampleSize/2d};
975 final long[] observed = {0, 0, 0};
976 for (int i = 0; i < sampleSize; i++) {
977 observed[(int)sample[i]]++;
978 }
979 UnitTestUtils.assertChiSquareAccept(new String[] {"0", "1", "2"}, expected, observed, 0.01);
980 }
981
982 }