~ubuntu-branches/ubuntu/quantal/commons-math/quantal

« back to all changes in this revision

Viewing changes to src/test/org/apache/commons/math/random/RandomDataTest.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2009-03-15 20:20:21 UTC
  • Revision ID: james.westby@ubuntu.com-20090315202021-zto3nmvqgcf3ami4
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 * contributor license agreements.  See the NOTICE file distributed with
 
4
 * this work for additional information regarding copyright ownership.
 
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
6
 * (the "License"); you may not use this file except in compliance with
 
7
 * the License.  You may obtain a copy of the License at
 
8
 * 
 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
 
10
 * 
 
11
 * Unless required by applicable law or agreed to in writing, software
 
12
 * distributed under the License is distributed on an "AS IS" BASIS,
 
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
14
 * See the License for the specific language governing permissions and
 
15
 * limitations under the License.
 
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
 * Test cases for the RandomData class.
 
32
 *
 
33
 * @version $Revision: 610789 $ $Date: 2008-01-10 06:46:49 -0700 (Thu, 10 Jan 2008) $
 
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
    /** test dispersion and failure modes for nextInt() */
 
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
        /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
 
93
         * Change to 11.34 for alpha = .01
 
94
         */
 
95
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
96
            testStatistic.chiSquare(expected,observed) < 16.27);    
 
97
    }
 
98
    
 
99
    /** test dispersion and failure modes for nextLong() */
 
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
        /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
 
120
         * Change to 11.34 for alpha = .01
 
121
         */
 
122
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
123
            testStatistic.chiSquare(expected,observed) < 16.27);    
 
124
    }
 
125
    
 
126
    /** test dispersion and failure modes for nextSecureLong() */
 
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
        /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
 
147
         * Change to 11.34 for alpha = .01
 
148
         */
 
149
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
150
            testStatistic.chiSquare(expected,observed) < 16.27);    
 
151
    }
 
152
    
 
153
    /** test dispersion and failure modes for nextSecureInt() */
 
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
        /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
 
174
         * Change to 11.34 for alpha = .01
 
175
         */
 
176
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
177
            testStatistic.chiSquare(expected,observed) < 16.27);    
 
178
    }
 
179
    
 
180
    /** 
 
181
     * Make sure that empirical distribution of random Poisson(4)'s 
 
182
     * has P(X <= 5) close to actual cumulative Poisson probablity
 
183
     * and that nextPoisson fails when mean is non-positive
 
184
     * TODO: replace with statistical test, adding test stat to TestStatistic
 
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
    /** test dispersion and failute modes for nextHex() */
 
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
        /* Use ChiSquare dist with df = 16-1 = 15, alpha = .001
 
270
         * Change to 30.58 for alpha = .01
 
271
         */
 
272
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
273
            testStatistic.chiSquare(expected,observed) < 37.70);    
 
274
    }
 
275
    
 
276
    /** test dispersion and failute modes for nextHex() */
 
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
        /* Use ChiSquare dist with df = 16-1 = 15, alpha = .001
 
324
         * Change to 30.58 for alpha = .01
 
325
         */
 
326
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
327
            testStatistic.chiSquare(expected,observed) < 37.70);    
 
328
    }
 
329
    
 
330
    /** test failure modes and dispersion of nextUniform() */  
 
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
        /* Use ChiSquare dist with df = 2-1 = 1, alpha = .001
 
362
         * Change to 6.64 for alpha = .01
 
363
         */
 
364
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
365
            testStatistic.chiSquare(expected,observed) < 10.83);  
 
366
    }
 
367
    
 
368
    /** test exclusive endpoints of nextUniform **/
 
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
    /** test failure modes and distribution of nextGaussian() */  
 
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
        /* t-test at .001-level TODO: replace with externalized t-test, with
 
392
         * test statistic defined in TestStatistic
 
393
         */
 
394
        assertTrue(Math.abs(xbar)/(s/Math.sqrt(n))< 3.29);
 
395
    }
 
396
    
 
397
    /** test failure modes and distribution of nextExponential() */  
 
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
        /* TODO: Replace with a statistical test, with statistic added to
 
414
         * TestStatistic.  Check below compares observed cumulative distribution
 
415
         * evaluated at 2 with exponential CDF 
 
416
         */
 
417
        assertEquals("exponential cumulative distribution",
 
418
            (double)cumFreq/(double)largeSampleSize,0.8646647167633873,.2);
 
419
    } 
 
420
    
 
421
    /** test reseeding, algorithm/provider games */
 
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
        /* remove this test back soon,
 
441
         * since it takes about 4 seconds 
 
442
 
 
443
        try {
 
444
            randomData.setSecureAlgorithm("SHA1PRNG","SUN");
 
445
        } catch (NoSuchProviderException ex) {
 
446
            ;
 
447
        }
 
448
        assertTrue("different seeds",
 
449
            !hex.equals(randomData.nextSecureHexString(40)));
 
450
        try {
 
451
            randomData.setSecureAlgorithm("NOSUCHTHING","SUN");
 
452
            fail("expecting NoSuchAlgorithmException");
 
453
        } catch (NoSuchProviderException ex) {
 
454
            ;
 
455
        } catch (NoSuchAlgorithmException ex) {
 
456
            ;
 
457
        }
 
458
        
 
459
        try {
 
460
            randomData.setSecureAlgorithm("SHA1PRNG","NOSUCHPROVIDER");
 
461
            fail("expecting NoSuchProviderException");
 
462
        } catch (NoSuchProviderException ex) {
 
463
            ;
 
464
        } 
 
465
        */
 
466
        
 
467
        // test reseeding without first using the generators
 
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
    /** tests for nextSample() sampling from Collection */
 
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();  //{0,1,2,3,4}
 
490
       for (int i = 0; i < 5; i++) {
 
491
           cPop.add(Integer.toString(i));
 
492
       }
 
493
       
 
494
       Object[] sets = new Object[10]; // 2-sets from 5
 
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
        /* Use ChiSquare dist with df = 10-1 = 9, alpha = .001
 
508
         * Change to 21.67 for alpha = .01
 
509
         */
 
510
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
511
            testStatistic.chiSquare(expected,observed) < 27.88);  
 
512
       
 
513
       // Make sure sample of size = size of collection returns same collection
 
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
       // Make sure we fail for sample size > collection size
 
523
       try {
 
524
           one = randomData.nextSample(hs,2);
 
525
           fail("sample size > set size, expecting IllegalArgumentException");
 
526
       } catch (IllegalArgumentException ex) {
 
527
           ;
 
528
       }
 
529
       
 
530
       // Make sure we fail for empty collection
 
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
    /** tests for nextPermutation */
 
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
        /* Use ChiSquare dist with df = 6-1 = 5, alpha = .001
 
567
         * Change to 15.09 for alpha = .01
 
568
         */
 
569
        assertTrue("chi-square test -- will fail about 1 in 1000 times",
 
570
                testStatistic.chiSquare(expected,observed) < 20.52); 
 
571
        
 
572
        // Check size = 1 boundary case
 
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
            // Make sure we fail for k size > n 
 
578
            try {
 
579
                perm = randomData.nextPermutation(2,3);
 
580
                fail("permutation k > n, expecting IllegalArgumentException");
 
581
            } catch (IllegalArgumentException ex) {
 
582
                ;
 
583
            }
 
584
            
 
585
            // Make sure we fail for n = 0
 
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