1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math.random;
18
19 import junit.framework.Test;
20 import junit.framework.TestSuite;
21 import java.util.HashSet;
22
23 import org.apache.commons.math.RetryTestCase;
24 import org.apache.commons.math.stat.Frequency;
25 import org.apache.commons.math.stat.inference.ChiSquareTestImpl;
26 import org.apache.commons.math.stat.descriptive.SummaryStatistics;
27
28
29
30
31
32
33
34
35 public class RandomDataTest extends RetryTestCase {
36
37 public RandomDataTest(String name) {
38 super(name);
39 randomData = new RandomDataImpl();
40 }
41
42 protected long smallSampleSize = 1000;
43 protected double[] expected = { 250, 250, 250, 250 };
44 protected int largeSampleSize = 10000;
45 private String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
46 "a", "b", "c", "d", "e", "f" };
47 protected RandomDataImpl randomData = null;
48 protected ChiSquareTestImpl testStatistic = new ChiSquareTestImpl();
49
50 public static Test suite() {
51 TestSuite suite = new TestSuite(RandomDataTest.class);
52 suite.setName("RandomData Tests");
53 return suite;
54 }
55
56 public void testNextIntExtremeValues() {
57 int x = randomData.nextInt(Integer.MIN_VALUE, Integer.MAX_VALUE);
58 int y = randomData.nextInt(Integer.MIN_VALUE, Integer.MAX_VALUE);
59 assertFalse(x == y);
60 }
61
62 public void testNextLongExtremeValues() {
63 long x = randomData.nextLong(Long.MIN_VALUE, Long.MAX_VALUE);
64 long y = randomData.nextLong(Long.MIN_VALUE, Long.MAX_VALUE);
65 assertFalse(x == y);
66 }
67
68
69 public void testNextInt() {
70 try {
71 randomData.nextInt(4, 3);
72 fail("IllegalArgumentException expected");
73 } catch (IllegalArgumentException ex) {
74
75 }
76 Frequency freq = new Frequency();
77 int value = 0;
78 for (int i = 0; i < smallSampleSize; i++) {
79 value = randomData.nextInt(0, 3);
80 assertTrue("nextInt range", (value >= 0) && (value <= 3));
81 freq.addValue(value);
82 }
83 long[] observed = new long[4];
84 for (int i = 0; i < 4; i++) {
85 observed[i] = freq.getCount(i);
86 }
87
88
89
90
91
92 assertTrue("chi-square test -- will fail about 1 in 1000 times",
93 testStatistic.chiSquare(expected, observed) < 16.27);
94 }
95
96
97 public void testNextLong() {
98 try {
99 randomData.nextLong(4, 3);
100 fail("IllegalArgumentException expected");
101 } catch (IllegalArgumentException ex) {
102
103 }
104 Frequency freq = new Frequency();
105 long value = 0;
106 for (int i = 0; i < smallSampleSize; i++) {
107 value = randomData.nextLong(0, 3);
108 assertTrue("nextInt range", (value >= 0) && (value <= 3));
109 freq.addValue(value);
110 }
111 long[] observed = new long[4];
112 for (int i = 0; i < 4; i++) {
113 observed[i] = freq.getCount(i);
114 }
115
116
117
118
119
120 assertTrue("chi-square test -- will fail about 1 in 1000 times",
121 testStatistic.chiSquare(expected, observed) < 16.27);
122 }
123
124
125 public void testNextSecureLong() {
126 try {
127 randomData.nextSecureLong(4, 3);
128 fail("IllegalArgumentException expected");
129 } catch (IllegalArgumentException ex) {
130
131 }
132 Frequency freq = new Frequency();
133 long value = 0;
134 for (int i = 0; i < smallSampleSize; i++) {
135 value = randomData.nextSecureLong(0, 3);
136 assertTrue("nextInt range", (value >= 0) && (value <= 3));
137 freq.addValue(value);
138 }
139 long[] observed = new long[4];
140 for (int i = 0; i < 4; i++) {
141 observed[i] = freq.getCount(i);
142 }
143
144
145
146
147
148 assertTrue("chi-square test -- will fail about 1 in 1000 times",
149 testStatistic.chiSquare(expected, observed) < 16.27);
150 }
151
152
153 public void testNextSecureInt() {
154 try {
155 randomData.nextSecureInt(4, 3);
156 fail("IllegalArgumentException expected");
157 } catch (IllegalArgumentException ex) {
158
159 }
160 Frequency freq = new Frequency();
161 int value = 0;
162 for (int i = 0; i < smallSampleSize; i++) {
163 value = randomData.nextSecureInt(0, 3);
164 assertTrue("nextInt range", (value >= 0) && (value <= 3));
165 freq.addValue(value);
166 }
167 long[] observed = new long[4];
168 for (int i = 0; i < 4; i++) {
169 observed[i] = freq.getCount(i);
170 }
171
172
173
174
175
176 assertTrue("chi-square test -- will fail about 1 in 1000 times",
177 testStatistic.chiSquare(expected, observed) < 16.27);
178 }
179
180
181
182
183
184
185
186 public void testNextPoisson() {
187 try {
188 randomData.nextPoisson(0);
189 fail("zero mean -- expecting IllegalArgumentException");
190 } catch (IllegalArgumentException ex) {
191
192 }
193 Frequency f = new Frequency();
194 for (int i = 0; i < largeSampleSize; i++) {
195 try {
196 f.addValue(randomData.nextPoisson(4.0d));
197 } catch (Exception ex) {
198 fail(ex.getMessage());
199 }
200 }
201 long cumFreq = f.getCount(0) + f.getCount(1) + f.getCount(2)
202 + f.getCount(3) + f.getCount(4) + f.getCount(5);
203 long sumFreq = f.getSumFreq();
204 double cumPct = Double.valueOf(cumFreq).doubleValue()
205 / Double.valueOf(sumFreq).doubleValue();
206 assertEquals("cum Poisson(4)", cumPct, 0.7851, 0.2);
207 try {
208 randomData.nextPoisson(-1);
209 fail("negative mean supplied -- IllegalArgumentException expected");
210 } catch (IllegalArgumentException ex) {
211
212 }
213 try {
214 randomData.nextPoisson(0);
215 fail("0 mean supplied -- IllegalArgumentException expected");
216 } catch (IllegalArgumentException ex) {
217
218 }
219
220 }
221
222 public void testNextPoissonLargeMean() {
223 for (int i = 0; i < 1000; i++) {
224 long n = randomData.nextPoisson(1500.0);
225 assertTrue(0 <= n);
226 }
227 }
228
229
230 public void testNextHex() {
231 try {
232 randomData.nextHexString(-1);
233 fail("negative length supplied -- IllegalArgumentException expected");
234 } catch (IllegalArgumentException ex) {
235
236 }
237 try {
238 randomData.nextHexString(0);
239 fail("zero length supplied -- IllegalArgumentException expected");
240 } catch (IllegalArgumentException ex) {
241
242 }
243 String hexString = randomData.nextHexString(3);
244 if (hexString.length() != 3) {
245 fail("incorrect length for generated string");
246 }
247 hexString = randomData.nextHexString(1);
248 if (hexString.length() != 1) {
249 fail("incorrect length for generated string");
250 }
251 try {
252 hexString = randomData.nextHexString(0);
253 fail("zero length requested -- expecting IllegalArgumentException");
254 } catch (IllegalArgumentException ex) {
255
256 }
257 if (hexString.length() != 1) {
258 fail("incorrect length for generated string");
259 }
260 Frequency f = new Frequency();
261 for (int i = 0; i < smallSampleSize; i++) {
262 hexString = randomData.nextHexString(100);
263 if (hexString.length() != 100) {
264 fail("incorrect length for generated string");
265 }
266 for (int j = 0; j < hexString.length(); j++) {
267 f.addValue(hexString.substring(j, j + 1));
268 }
269 }
270 double[] expected = new double[16];
271 long[] observed = new long[16];
272 for (int i = 0; i < 16; i++) {
273 expected[i] = (double) smallSampleSize * 100 / 16;
274 observed[i] = f.getCount(hex[i]);
275 }
276
277
278
279
280 assertTrue("chi-square test -- will fail about 1 in 1000 times",
281 testStatistic.chiSquare(expected, observed) < 37.70);
282 }
283
284
285 public void testNextSecureHex() {
286 try {
287 randomData.nextSecureHexString(-1);
288 fail("negative length -- IllegalArgumentException expected");
289 } catch (IllegalArgumentException ex) {
290
291 }
292 try {
293 randomData.nextSecureHexString(0);
294 fail("zero length -- IllegalArgumentException expected");
295 } catch (IllegalArgumentException ex) {
296
297 }
298 String hexString = randomData.nextSecureHexString(3);
299 if (hexString.length() != 3) {
300 fail("incorrect length for generated string");
301 }
302 hexString = randomData.nextSecureHexString(1);
303 if (hexString.length() != 1) {
304 fail("incorrect length for generated string");
305 }
306 try {
307 hexString = randomData.nextSecureHexString(0);
308 fail("zero length requested -- expecting IllegalArgumentException");
309 } catch (IllegalArgumentException ex) {
310
311 }
312 if (hexString.length() != 1) {
313 fail("incorrect length for generated string");
314 }
315 Frequency f = new Frequency();
316 for (int i = 0; i < smallSampleSize; i++) {
317 hexString = randomData.nextSecureHexString(100);
318 if (hexString.length() != 100) {
319 fail("incorrect length for generated string");
320 }
321 for (int j = 0; j < hexString.length(); j++) {
322 f.addValue(hexString.substring(j, j + 1));
323 }
324 }
325 double[] expected = new double[16];
326 long[] observed = new long[16];
327 for (int i = 0; i < 16; i++) {
328 expected[i] = (double) smallSampleSize * 100 / 16;
329 observed[i] = f.getCount(hex[i]);
330 }
331
332
333
334
335 assertTrue("chi-square test -- will fail about 1 in 1000 times",
336 testStatistic.chiSquare(expected, observed) < 37.70);
337 }
338
339
340 public void testNextUniform() {
341 try {
342 randomData.nextUniform(4, 3);
343 fail("IllegalArgumentException expected");
344 } catch (IllegalArgumentException ex) {
345
346 }
347 try {
348 randomData.nextUniform(3, 3);
349 fail("IllegalArgumentException expected");
350 } catch (IllegalArgumentException ex) {
351
352 }
353 double[] expected = { 500, 500 };
354 long[] observed = { 0, 0 };
355 double lower = -1d;
356 double upper = 20d;
357 double midpoint = (lower + upper) / 2d;
358 double result = 0;
359 for (int i = 0; i < 1000; i++) {
360 result = randomData.nextUniform(lower, upper);
361 if ((result == lower) || (result == upper)) {
362 fail("generated value equal to an endpoint: " + result);
363 }
364 if (result < midpoint) {
365 observed[0]++;
366 } else {
367 observed[1]++;
368 }
369 }
370
371
372
373
374 assertTrue("chi-square test -- will fail about 1 in 1000 times",
375 testStatistic.chiSquare(expected, observed) < 10.83);
376 }
377
378
379 public void testNextUniformExclusiveEndpoints() {
380 for (int i = 0; i < 1000; i++) {
381 double u = randomData.nextUniform(0.99, 1);
382 assertTrue(u > 0.99 && u < 1);
383 }
384 }
385
386
387 public void testNextGaussian() {
388 try {
389 randomData.nextGaussian(0, 0);
390 fail("zero sigma -- IllegalArgumentException expected");
391 } catch (IllegalArgumentException ex) {
392
393 }
394 SummaryStatistics u = new SummaryStatistics();
395 for (int i = 0; i < largeSampleSize; i++) {
396 u.addValue(randomData.nextGaussian(0, 1));
397 }
398 double xbar = u.getMean();
399 double s = u.getStandardDeviation();
400 double n = u.getN();
401
402
403
404
405 assertTrue(Math.abs(xbar) / (s / Math.sqrt(n)) < 3.29);
406 }
407
408
409 public void testNextExponential() {
410 try {
411 randomData.nextExponential(-1);
412 fail("negative mean -- expecting IllegalArgumentException");
413 } catch (IllegalArgumentException ex) {
414
415 }
416 assertEquals("0 mean", 0, randomData.nextExponential(0), 10E-8);
417 long cumFreq = 0;
418 double v = 0;
419 for (int i = 0; i < largeSampleSize; i++) {
420 v = randomData.nextExponential(1);
421 assertTrue("exponential deviate postive", v > 0);
422 if (v < 2)
423 cumFreq++;
424 }
425
426
427
428
429
430 assertEquals("exponential cumulative distribution", (double) cumFreq
431 / (double) largeSampleSize, 0.8646647167633873, .2);
432 }
433
434
435 public void testConfig() {
436 randomData.reSeed(1000);
437 double v = randomData.nextUniform(0, 1);
438 randomData.reSeed();
439 assertTrue("different seeds", Math
440 .abs(v - randomData.nextUniform(0, 1)) > 10E-12);
441 randomData.reSeed(1000);
442 assertEquals("same seeds", v, randomData.nextUniform(0, 1), 10E-12);
443 randomData.reSeedSecure(1000);
444 String hex = randomData.nextSecureHexString(40);
445 randomData.reSeedSecure();
446 assertTrue("different seeds", !hex.equals(randomData
447 .nextSecureHexString(40)));
448 randomData.reSeedSecure(1000);
449 assertTrue("same seeds", !hex
450 .equals(randomData.nextSecureHexString(40)));
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469 RandomDataImpl rd = new RandomDataImpl();
470 rd.reSeed(100);
471 rd.nextLong(1, 2);
472 RandomDataImpl rd2 = new RandomDataImpl();
473 rd2.reSeedSecure(2000);
474 rd2.nextSecureLong(1, 2);
475 rd = new RandomDataImpl();
476 rd.reSeed();
477 rd.nextLong(1, 2);
478 rd2 = new RandomDataImpl();
479 rd2.reSeedSecure();
480 rd2.nextSecureLong(1, 2);
481 }
482
483
484 public void testNextSample() {
485 Object[][] c = { { "0", "1" }, { "0", "2" }, { "0", "3" },
486 { "0", "4" }, { "1", "2" }, { "1", "3" }, { "1", "4" },
487 { "2", "3" }, { "2", "4" }, { "3", "4" } };
488 long[] observed = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
489 double[] expected = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 };
490
491 HashSet<Object> cPop = new HashSet<Object>();
492 for (int i = 0; i < 5; i++) {
493 cPop.add(Integer.toString(i));
494 }
495
496 Object[] sets = new Object[10];
497 for (int i = 0; i < 10; i++) {
498 HashSet<Object> hs = new HashSet<Object>();
499 hs.add(c[i][0]);
500 hs.add(c[i][1]);
501 sets[i] = hs;
502 }
503
504 for (int i = 0; i < 1000; i++) {
505 Object[] cSamp = randomData.nextSample(cPop, 2);
506 observed[findSample(sets, cSamp)]++;
507 }
508
509
510
511
512
513 assertTrue("chi-square test -- will fail about 1 in 1000 times",
514 testStatistic.chiSquare(expected, observed) < 27.88);
515
516
517 HashSet<Object> hs = new HashSet<Object>();
518 hs.add("one");
519 Object[] one = randomData.nextSample(hs, 1);
520 String oneString = (String) one[0];
521 if ((one.length != 1) || !oneString.equals("one")) {
522 fail("bad sample for set size = 1, sample size = 1");
523 }
524
525
526 try {
527 one = randomData.nextSample(hs, 2);
528 fail("sample size > set size, expecting IllegalArgumentException");
529 } catch (IllegalArgumentException ex) {
530
531 }
532
533
534 try {
535 hs = new HashSet<Object>();
536 one = randomData.nextSample(hs, 0);
537 fail("n = k = 0, expecting IllegalArgumentException");
538 } catch (IllegalArgumentException ex) {
539
540 }
541 }
542
543 @SuppressWarnings("unchecked")
544 private int findSample(Object[] u, Object[] samp) {
545 for (int i = 0; i < u.length; i++) {
546 HashSet<Object> set = (HashSet<Object>) u[i];
547 HashSet<Object> sampSet = new HashSet<Object>();
548 for (int j = 0; j < samp.length; j++) {
549 sampSet.add(samp[j]);
550 }
551 if (set.equals(sampSet)) {
552 return i;
553 }
554 }
555 fail("sample not found:{" + samp[0] + "," + samp[1] + "}");
556 return -1;
557 }
558
559
560 public void testNextPermutation() {
561 int[][] p = { { 0, 1, 2 }, { 0, 2, 1 }, { 1, 0, 2 }, { 1, 2, 0 },
562 { 2, 0, 1 }, { 2, 1, 0 } };
563 long[] observed = { 0, 0, 0, 0, 0, 0 };
564 double[] expected = { 100, 100, 100, 100, 100, 100 };
565
566 for (int i = 0; i < 600; i++) {
567 int[] perm = randomData.nextPermutation(3, 3);
568 observed[findPerm(p, perm)]++;
569 }
570
571
572
573
574
575 assertTrue("chi-square test -- will fail about 1 in 1000 times",
576 testStatistic.chiSquare(expected, observed) < 20.52);
577
578
579 int[] perm = randomData.nextPermutation(1, 1);
580 if ((perm.length != 1) || (perm[0] != 0)) {
581 fail("bad permutation for n = 1, sample k = 1");
582
583
584 try {
585 perm = randomData.nextPermutation(2, 3);
586 fail("permutation k > n, expecting IllegalArgumentException");
587 } catch (IllegalArgumentException ex) {
588
589 }
590
591
592 try {
593 perm = randomData.nextPermutation(0, 0);
594 fail("permutation k = n = 0, expecting IllegalArgumentException");
595 } catch (IllegalArgumentException ex) {
596
597 }
598
599
600 try {
601 perm = randomData.nextPermutation(-1, -3);
602 fail("permutation k < n < 0, expecting IllegalArgumentException");
603 } catch (IllegalArgumentException ex) {
604
605 }
606
607 }
608 }
609
610
611
612
613
614
615 private int findPerm(int[][] p, int[] samp) {
616 for (int i = 0; i < p.length; i++) {
617 boolean good = true;
618 for (int j = 0; j < samp.length; j++) {
619 if (samp[j] != p[i][j]) {
620 good = false;
621 }
622 }
623 if (good) {
624 return i;
625 }
626 }
627 fail("permutation not found");
628 return -1;
629 }
630 }