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