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