KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > math > random > RandomDataTest


1 /*
2  * Copyright 2003-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.math.random;
17
18 import junit.framework.Test;
19 import junit.framework.TestSuite;
20 import java.security.NoSuchProviderException JavaDoc;
21 import java.security.NoSuchAlgorithmException JavaDoc;
22 import java.util.HashSet JavaDoc;
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  * Test cases for the RandomData class.
31  *
32  * @version $Revision$ $Date: 2005-05-15 11:23:35 -0700 (Sun, 15 May 2005) $
33  */

34
35 public class RandomDataTest extends RetryTestCase {
36
37     public RandomDataTest(String JavaDoc name) {
38         super(name);
39         randomData = new RandomDataImpl();
40     }
41
42     private long smallSampleSize = 1000;
43     private double[] expected = {250,250,250,250};
44     private int largeSampleSize = 10000;
45     private int tolerance = 50;
46     private String JavaDoc[] hex =
47         {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
48     protected RandomDataImpl randomData = null;
49     private 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     /** test dispersion and failure modes for nextInt() */
61     public void testNextInt() {
62         try {
63             int x = randomData.nextInt(4,3);
64             fail("IllegalArgumentException expected");
65         } catch (IllegalArgumentException JavaDoc 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         /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
81          * Change to 11.34 for alpha = .01
82          */

83         assertTrue("chi-square test -- will fail about 1 in 1000 times",
84             testStatistic.chiSquare(expected,observed) < 16.27);
85     }
86     
87     /** test dispersion and failure modes for nextLong() */
88     public void testNextLong() {
89        try {
90             long x = randomData.nextLong(4,3);
91             fail("IllegalArgumentException expected");
92         } catch (IllegalArgumentException JavaDoc 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         /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
108          * Change to 11.34 for alpha = .01
109          */

110         assertTrue("chi-square test -- will fail about 1 in 1000 times",
111             testStatistic.chiSquare(expected,observed) < 16.27);
112     }
113     
114     /** test dispersion and failure modes for nextSecureLong() */
115     public void testNextSecureLong() {
116         try {
117             long x = randomData.nextSecureLong(4,3);
118             fail("IllegalArgumentException expected");
119         } catch (IllegalArgumentException JavaDoc 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         /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
135          * Change to 11.34 for alpha = .01
136          */

137         assertTrue("chi-square test -- will fail about 1 in 1000 times",
138             testStatistic.chiSquare(expected,observed) < 16.27);
139     }
140     
141     /** test dispersion and failure modes for nextSecureInt() */
142     public void testNextSecureInt() {
143         try {
144             long x = randomData.nextSecureInt(4,3);
145             fail("IllegalArgumentException expected");
146         } catch (IllegalArgumentException JavaDoc 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         /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
162          * Change to 11.34 for alpha = .01
163          */

164         assertTrue("chi-square test -- will fail about 1 in 1000 times",
165             testStatistic.chiSquare(expected,observed) < 16.27);
166     }
167     
168     /**
169      * Make sure that empirical distribution of random Poisson(4)'s
170      * has P(X <= 5) close to actual cumulative Poisson probablity
171      * and that nextPoisson fails when mean is non-positive
172      * TODO: replace with statistical test, adding test stat to TestStatistic
173      */

174     public void testNextPoisson() {
175         try {
176             long x = randomData.nextPoisson(0);
177             fail("zero mean -- expecting IllegalArgumentException");
178         } catch (IllegalArgumentException JavaDoc 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 JavaDoc 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 JavaDoc(cumFreq).doubleValue()/new Double JavaDoc(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 JavaDoc ex) {
200             ;
201         }
202         try {
203             long x = randomData.nextPoisson(0);
204             fail("0 mean supplied -- IllegalArgumentException expected");
205         } catch (IllegalArgumentException JavaDoc ex) {
206             ;
207         }
208         
209     }
210     
211     /** test dispersion and failute modes for nextHex() */
212     public void testNextHex() {
213         try {
214             String JavaDoc x = randomData.nextHexString(-1);
215             fail("negative length supplied -- IllegalArgumentException expected");
216         } catch (IllegalArgumentException JavaDoc ex) {
217             ;
218         }
219         try {
220             String JavaDoc x = randomData.nextHexString(0);
221             fail("zero length supplied -- IllegalArgumentException expected");
222         } catch (IllegalArgumentException JavaDoc ex) {
223             ;
224         }
225         String JavaDoc 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 JavaDoc 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         /* Use ChiSquare dist with df = 16-1 = 15, alpha = .001
259          * Change to 30.58 for alpha = .01
260          */

261         assertTrue("chi-square test -- will fail about 1 in 1000 times",
262             testStatistic.chiSquare(expected,observed) < 37.70);
263     }
264     
265     /** test dispersion and failute modes for nextHex() */
266     public void testNextSecureHex() {
267         try {
268             String JavaDoc x = randomData.nextSecureHexString(-1);
269             fail("negative length -- IllegalArgumentException expected");
270         } catch (IllegalArgumentException JavaDoc ex) {
271             ;
272         }
273         try {
274             String JavaDoc x = randomData.nextSecureHexString(0);
275             fail("zero length -- IllegalArgumentException expected");
276         } catch (IllegalArgumentException JavaDoc ex) {
277             ;
278         }
279         String JavaDoc 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 JavaDoc 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         /* Use ChiSquare dist with df = 16-1 = 15, alpha = .001
313          * Change to 30.58 for alpha = .01
314          */

315         assertTrue("chi-square test -- will fail about 1 in 1000 times",
316             testStatistic.chiSquare(expected,observed) < 37.70);
317     }
318     
319     /** test failure modes and dispersion of nextUniform() */
320     public void testNextUniform() {
321         try {
322             double x = randomData.nextUniform(4,3);
323             fail("IllegalArgumentException expected");
324         } catch (IllegalArgumentException JavaDoc ex) {
325             ;
326         }
327         try {
328             double x = randomData.nextUniform(3,3);
329             fail("IllegalArgumentException expected");
330         } catch (IllegalArgumentException JavaDoc 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         /* Use ChiSquare dist with df = 2-1 = 1, alpha = .001
351          * Change to 6.64 for alpha = .01
352          */

353         assertTrue("chi-square test -- will fail about 1 in 1000 times",
354             testStatistic.chiSquare(expected,observed) < 10.83);
355     }
356     
357     /** test failure modes and distribution of nextGaussian() */
358     public void testNextGaussian() {
359         try {
360             double x = randomData.nextGaussian(0,0);
361             fail("zero sigma -- IllegalArgumentException expected");
362         } catch (IllegalArgumentException JavaDoc 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         /* t-test at .001-level TODO: replace with externalized t-test, with
373          * test statistic defined in TestStatistic
374          */

375         assertTrue(Math.abs(xbar)/(s/Math.sqrt(n))< 3.29);
376     }
377     
378     /** test failure modes and distribution of nextExponential() */
379     public void testNextExponential() {
380         try {
381             double x = randomData.nextExponential(-1);
382             fail("negative mean -- expecting IllegalArgumentException");
383         } catch (IllegalArgumentException JavaDoc 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         /* TODO: Replace with a statistical test, with statistic added to
395          * TestStatistic. Check below compares observed cumulative distribution
396          * evaluated at 2 with exponential CDF
397          */

398         assertEquals("exponential cumulative distribution",
399             (double)cumFreq/(double)largeSampleSize,0.8646647167633873,.2);
400     }
401     
402     /** test reseeding, algorithm/provider games */
403     public void testConfig() throws NoSuchProviderException JavaDoc,
404       NoSuchAlgorithmException JavaDoc {
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 JavaDoc 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         /* remove this test back soon,
422          * since it takes about 4 seconds */

423          
424         randomData.setSecureAlgorithm("SHA1PRNG","SUN");
425         assertTrue("different seeds",
426             !hex.equals(randomData.nextSecureHexString(40)));
427         try {
428             randomData.setSecureAlgorithm("NOSUCHTHING","SUN");
429             fail("expecting NoSuchAlgorithmException");
430         } catch (NoSuchAlgorithmException JavaDoc ex) {
431             ;
432         }
433         
434         try {
435             randomData.setSecureAlgorithm("SHA1PRNG","NOSUCHPROVIDER");
436             fail("expecting NoSuchProviderException");
437         } catch (NoSuchProviderException JavaDoc ex) {
438             ;
439         }
440         
441         // test reseeding without first using the generators
442
RandomDataImpl rd = new RandomDataImpl();
443         rd.reSeed(100);
444         double ret = rd.nextLong(1,2);
445         RandomDataImpl rd2 = new RandomDataImpl();
446         rd2.reSeedSecure(2000);
447         ret = rd2.nextSecureLong(1,2);
448         rd = new RandomDataImpl();
449         rd.reSeed();
450         ret = rd.nextLong(1,2);
451         rd2 = new RandomDataImpl();
452         rd2.reSeedSecure();
453         ret = rd2.nextSecureLong(1,2);
454     }
455     
456     /** tests for nextSample() sampling from Collection */
457     public void testNextSample() {
458        Object JavaDoc[][] c = {{"0","1"},{"0","2"},{"0","3"},{"0","4"},{"1","2"},
459                         {"1","3"},{"1","4"},{"2","3"},{"2","4"},{"3","4"}};
460        long[] observed = {0,0,0,0,0,0,0,0,0,0};
461        double[] expected = {100,100,100,100,100,100,100,100,100,100};
462        
463        HashSet JavaDoc cPop = new HashSet JavaDoc(); //{0,1,2,3,4}
464
for (int i = 0; i < 5; i++) {
465            cPop.add(Integer.toString(i));
466        }
467        
468        Object JavaDoc[] sets = new Object JavaDoc[10]; // 2-sets from 5
469
for (int i = 0; i < 10; i ++) {
470            HashSet JavaDoc hs = new HashSet JavaDoc();
471            hs.add(c[i][0]);
472            hs.add(c[i][1]);
473            sets[i] = hs;
474        }
475        
476        for (int i = 0; i < 1000; i ++) {
477            Object JavaDoc[] cSamp = randomData.nextSample(cPop,2);
478            observed[findSample(sets,cSamp)]++;
479        }
480        
481         /* Use ChiSquare dist with df = 10-1 = 9, alpha = .001
482          * Change to 21.67 for alpha = .01
483          */

484         assertTrue("chi-square test -- will fail about 1 in 1000 times",
485             testStatistic.chiSquare(expected,observed) < 27.88);
486        
487        // Make sure sample of size = size of collection returns same collection
488
HashSet JavaDoc hs = new HashSet JavaDoc();
489        hs.add("one");
490        Object JavaDoc[] one = randomData.nextSample(hs,1);
491        String JavaDoc oneString = (String JavaDoc) one[0];
492        if ((one.length != 1) || !oneString.equals("one")){
493            fail("bad sample for set size = 1, sample size = 1");
494        }
495        
496        // Make sure we fail for sample size > collection size
497
try {
498            one = randomData.nextSample(hs,2);
499            fail("sample size > set size, expecting IllegalArgumentException");
500        } catch (IllegalArgumentException JavaDoc ex) {
501            ;
502        }
503        
504        // Make sure we fail for empty collection
505
try {
506            hs = new HashSet JavaDoc();
507            one = randomData.nextSample(hs,0);
508            fail("n = k = 0, expecting IllegalArgumentException");
509        } catch (IllegalArgumentException JavaDoc ex) {
510            ;
511        }
512     }
513     
514     private int findSample(Object JavaDoc[] u, Object JavaDoc[] samp) {
515         int result = -1;
516         for (int i = 0; i < u.length; i++) {
517             HashSet JavaDoc set = (HashSet JavaDoc) u[i];
518             HashSet JavaDoc sampSet = new HashSet JavaDoc();
519             for (int j = 0; j < samp.length; j++) {
520                 sampSet.add(samp[j]);
521             }
522             if (set.equals(sampSet)) {
523                return i;
524            }
525         }
526         fail("sample not found:{" + samp[0] + "," + samp[1] + "}");
527         return -1;
528     }
529     
530     /** tests for nextPermutation */
531     public void testNextPermutation() {
532         int[][] p = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};
533         long[] observed = {0,0,0,0,0,0};
534         double[] expected = {100,100,100,100,100,100};
535         
536         for (int i = 0; i < 600; i++) {
537             int[] perm = randomData.nextPermutation(3,3);
538             observed[findPerm(p,perm)]++;
539         }
540         
541         /* Use ChiSquare dist with df = 6-1 = 5, alpha = .001
542          * Change to 15.09 for alpha = .01
543          */

544         assertTrue("chi-square test -- will fail about 1 in 1000 times",
545                 testStatistic.chiSquare(expected,observed) < 20.52);
546         
547         // Check size = 1 boundary case
548
int[] perm = randomData.nextPermutation(1,1);
549         if ((perm.length != 1) || (perm[0] != 0)){
550             fail("bad permutation for n = 1, sample k = 1");
551             
552             // Make sure we fail for k size > n
553
try {
554                 perm = randomData.nextPermutation(2,3);
555                 fail("permutation k > n, expecting IllegalArgumentException");
556             } catch (IllegalArgumentException JavaDoc ex) {
557                 ;
558             }
559             
560             // Make sure we fail for n = 0
561
try {
562                 perm = randomData.nextPermutation(0,0);
563                 fail("permutation k = n = 0, expecting IllegalArgumentException");
564             } catch (IllegalArgumentException JavaDoc ex) {
565                 ;
566             }
567         }
568     }
569     
570     private int findPerm(int[][] p, int[] samp) {
571         int result = -1;
572         for (int i = 0; i < p.length; i++) {
573             boolean good = true;
574             for (int j = 0; j < samp.length; j++) {
575                 if (samp[j] != p[i][j]) {
576                     good = false;
577                 }
578             }
579             if (good) {
580                 return i;
581             }
582         }
583         fail("permutation not found");
584         return -1;
585     }
586 }
587
588
Popular Tags