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.math3.random;
18 
19 import java.text.DecimalFormat;
20 import java.util.ArrayList;
21 import java.util.HashSet;
22 import java.util.List;
23 
24 import org.apache.commons.math3.Retry;
25 import org.apache.commons.math3.RetryRunner;
26 import org.apache.commons.math3.TestUtils;
27 import org.apache.commons.math3.distribution.BetaDistribution;
28 import org.apache.commons.math3.distribution.BinomialDistribution;
29 import org.apache.commons.math3.distribution.BinomialDistributionTest;
30 import org.apache.commons.math3.distribution.CauchyDistribution;
31 import org.apache.commons.math3.distribution.ChiSquaredDistribution;
32 import org.apache.commons.math3.distribution.ExponentialDistribution;
33 import org.apache.commons.math3.distribution.FDistribution;
34 import org.apache.commons.math3.distribution.GammaDistribution;
35 import org.apache.commons.math3.distribution.HypergeometricDistribution;
36 import org.apache.commons.math3.distribution.HypergeometricDistributionTest;
37 import org.apache.commons.math3.distribution.NormalDistribution;
38 import org.apache.commons.math3.distribution.PascalDistribution;
39 import org.apache.commons.math3.distribution.PascalDistributionTest;
40 import org.apache.commons.math3.distribution.PoissonDistribution;
41 import org.apache.commons.math3.distribution.TDistribution;
42 import org.apache.commons.math3.distribution.WeibullDistribution;
43 import org.apache.commons.math3.distribution.ZipfDistribution;
44 import org.apache.commons.math3.distribution.ZipfDistributionTest;
45 import org.apache.commons.math3.stat.Frequency;
46 import org.apache.commons.math3.stat.inference.ChiSquareTest;
47 import org.apache.commons.math3.util.FastMath;
48 import org.apache.commons.math3.exception.MathIllegalArgumentException;
49 import org.junit.Assert;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 
53 /**
54  * Test cases for the RandomDataGenerator class.
55  *
56  */
57 @RunWith(RetryRunner.class)
58 public class RandomDataGeneratorTest {
59 
RandomDataGeneratorTest()60     public RandomDataGeneratorTest() {
61         randomData = new RandomDataGenerator();
62         randomData.reSeed(1000);
63     }
64 
65     protected final long smallSampleSize = 1000;
66     protected final double[] expected = { 250, 250, 250, 250 };
67     protected final int largeSampleSize = 10000;
68     private final String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
69             "a", "b", "c", "d", "e", "f" };
70     protected RandomDataGenerator randomData = null;
71     protected final ChiSquareTest testStatistic = new ChiSquareTest();
72 
73     @Test
testNextIntExtremeValues()74     public void testNextIntExtremeValues() {
75         int x = randomData.nextInt(Integer.MIN_VALUE, Integer.MAX_VALUE);
76         int y = randomData.nextInt(Integer.MIN_VALUE, Integer.MAX_VALUE);
77         Assert.assertFalse(x == y);
78     }
79 
80     @Test
testNextLongExtremeValues()81     public void testNextLongExtremeValues() {
82         long x = randomData.nextLong(Long.MIN_VALUE, Long.MAX_VALUE);
83         long y = randomData.nextLong(Long.MIN_VALUE, Long.MAX_VALUE);
84         Assert.assertFalse(x == y);
85     }
86 
87     @Test
testNextUniformExtremeValues()88     public void testNextUniformExtremeValues() {
89         double x = randomData.nextUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
90         double y = randomData.nextUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
91         Assert.assertFalse(x == y);
92         Assert.assertFalse(Double.isNaN(x));
93         Assert.assertFalse(Double.isNaN(y));
94         Assert.assertFalse(Double.isInfinite(x));
95         Assert.assertFalse(Double.isInfinite(y));
96     }
97 
98     @Test
testNextIntIAE()99     public void testNextIntIAE() {
100         try {
101             randomData.nextInt(4, 3);
102             Assert.fail("MathIllegalArgumentException expected");
103         } catch (MathIllegalArgumentException ex) {
104             // ignored
105         }
106     }
107 
108     @Test
testNextIntNegativeToPositiveRange()109     public void testNextIntNegativeToPositiveRange() {
110         for (int i = 0; i < 5; i++) {
111             checkNextIntUniform(-3, 5);
112             checkNextIntUniform(-3, 6);
113         }
114     }
115 
116     @Test
testNextIntNegativeRange()117     public void testNextIntNegativeRange() {
118         for (int i = 0; i < 5; i++) {
119             checkNextIntUniform(-7, -4);
120             checkNextIntUniform(-15, -2);
121             checkNextIntUniform(Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 12);
122         }
123     }
124 
125     @Test
testNextIntPositiveRange()126     public void testNextIntPositiveRange() {
127         for (int i = 0; i < 5; i++) {
128             checkNextIntUniform(0, 3);
129             checkNextIntUniform(2, 12);
130             checkNextIntUniform(1,2);
131             checkNextIntUniform(Integer.MAX_VALUE - 12, Integer.MAX_VALUE - 1);
132         }
133     }
134 
checkNextIntUniform(int min, int max)135     private void checkNextIntUniform(int min, int max) {
136         final Frequency freq = new Frequency();
137         for (int i = 0; i < smallSampleSize; i++) {
138             final int value = randomData.nextInt(min, max);
139             Assert.assertTrue("nextInt range", (value >= min) && (value <= max));
140             freq.addValue(value);
141         }
142         final int len = max - min + 1;
143         final long[] observed = new long[len];
144         for (int i = 0; i < len; i++) {
145             observed[i] = freq.getCount(min + i);
146         }
147         final double[] expected = new double[len];
148         for (int i = 0; i < len; i++) {
149             expected[i] = 1d / len;
150         }
151 
152         TestUtils.assertChiSquareAccept(expected, observed, 0.001);
153     }
154 
155     @Test
testNextIntWideRange()156     public void testNextIntWideRange() {
157         int lower = -0x6543210F;
158         int upper =  0x456789AB;
159         int max   = Integer.MIN_VALUE;
160         int min   = Integer.MAX_VALUE;
161         for (int i = 0; i < 1000000; ++i) {
162             int r = randomData.nextInt(lower, upper);
163             max = FastMath.max(max, r);
164             min = FastMath.min(min, r);
165             Assert.assertTrue(r >= lower);
166             Assert.assertTrue(r <= upper);
167         }
168         double ratio = (((double) max)   - ((double) min)) /
169                        (((double) upper) - ((double) lower));
170         Assert.assertTrue(ratio > 0.99999);
171     }
172 
173     @Test
testNextLongIAE()174     public void testNextLongIAE() {
175         try {
176             randomData.nextLong(4, 3);
177             Assert.fail("MathIllegalArgumentException expected");
178         } catch (MathIllegalArgumentException ex) {
179             // ignored
180         }
181     }
182 
183     @Test
testNextLongNegativeToPositiveRange()184     public void testNextLongNegativeToPositiveRange() {
185         for (int i = 0; i < 5; i++) {
186             checkNextLongUniform(-3, 5);
187             checkNextLongUniform(-3, 6);
188         }
189     }
190 
191     @Test
testNextLongNegativeRange()192     public void testNextLongNegativeRange() {
193         for (int i = 0; i < 5; i++) {
194             checkNextLongUniform(-7, -4);
195             checkNextLongUniform(-15, -2);
196             checkNextLongUniform(Long.MIN_VALUE + 1, Long.MIN_VALUE + 12);
197         }
198     }
199 
200     @Test
testNextLongPositiveRange()201     public void testNextLongPositiveRange() {
202         for (int i = 0; i < 5; i++) {
203             checkNextLongUniform(0, 3);
204             checkNextLongUniform(2, 12);
205             checkNextLongUniform(Long.MAX_VALUE - 12, Long.MAX_VALUE - 1);
206         }
207     }
208 
checkNextLongUniform(long min, long max)209     private void checkNextLongUniform(long min, long max) {
210         final Frequency freq = new Frequency();
211         for (int i = 0; i < smallSampleSize; i++) {
212             final long value = randomData.nextLong(min, max);
213             Assert.assertTrue("nextLong range: " + value + " " + min + " " + max,
214                               (value >= min) && (value <= max));
215             freq.addValue(value);
216         }
217         final int len = ((int) (max - min)) + 1;
218         final long[] observed = new long[len];
219         for (int i = 0; i < len; i++) {
220             observed[i] = freq.getCount(min + i);
221         }
222         final double[] expected = new double[len];
223         for (int i = 0; i < len; i++) {
224             expected[i] = 1d / len;
225         }
226 
227         TestUtils.assertChiSquareAccept(expected, observed, 0.01);
228     }
229 
230     @Test
testNextLongWideRange()231     public void testNextLongWideRange() {
232         long lower = -0x6543210FEDCBA987L;
233         long upper =  0x456789ABCDEF0123L;
234         long max = Long.MIN_VALUE;
235         long min = Long.MAX_VALUE;
236         for (int i = 0; i < 10000000; ++i) {
237             long r = randomData.nextLong(lower, upper);
238             max = FastMath.max(max, r);
239             min = FastMath.min(min, r);
240             Assert.assertTrue(r >= lower);
241             Assert.assertTrue(r <= upper);
242         }
243         double ratio = (((double) max)   - ((double) min)) /
244                        (((double) upper) - ((double) lower));
245         Assert.assertTrue(ratio > 0.99999);
246     }
247 
248     @Test
testNextSecureLongIAE()249     public void testNextSecureLongIAE() {
250         try {
251             randomData.nextSecureLong(4, 3);
252             Assert.fail("MathIllegalArgumentException expected");
253         } catch (MathIllegalArgumentException ex) {
254             // ignored
255         }
256     }
257 
258     @Test
259     @Retry(3)
testNextSecureLongNegativeToPositiveRange()260     public void testNextSecureLongNegativeToPositiveRange() {
261         for (int i = 0; i < 5; i++) {
262             checkNextSecureLongUniform(-3, 5);
263             checkNextSecureLongUniform(-3, 6);
264         }
265     }
266 
267     @Test
268     @Retry(3)
testNextSecureLongNegativeRange()269     public void testNextSecureLongNegativeRange() {
270         for (int i = 0; i < 5; i++) {
271             checkNextSecureLongUniform(-7, -4);
272             checkNextSecureLongUniform(-15, -2);
273         }
274     }
275 
276     @Test
277     @Retry(3)
testNextSecureLongPositiveRange()278     public void testNextSecureLongPositiveRange() {
279         for (int i = 0; i < 5; i++) {
280             checkNextSecureLongUniform(0, 3);
281             checkNextSecureLongUniform(2, 12);
282         }
283     }
284 
checkNextSecureLongUniform(int min, int max)285     private void checkNextSecureLongUniform(int min, int max) {
286         final Frequency freq = new Frequency();
287         for (int i = 0; i < smallSampleSize; i++) {
288             final long value = randomData.nextSecureLong(min, max);
289             Assert.assertTrue("nextLong range", (value >= min) && (value <= max));
290             freq.addValue(value);
291         }
292         final int len = max - min + 1;
293         final long[] observed = new long[len];
294         for (int i = 0; i < len; i++) {
295             observed[i] = freq.getCount(min + i);
296         }
297         final double[] expected = new double[len];
298         for (int i = 0; i < len; i++) {
299             expected[i] = 1d / len;
300         }
301 
302         TestUtils.assertChiSquareAccept(expected, observed, 0.0001);
303     }
304 
305     @Test
testNextSecureIntIAE()306     public void testNextSecureIntIAE() {
307         try {
308             randomData.nextSecureInt(4, 3);
309             Assert.fail("MathIllegalArgumentException expected");
310         } catch (MathIllegalArgumentException ex) {
311             // ignored
312         }
313     }
314 
315     @Test
316     @Retry(3)
testNextSecureIntNegativeToPositiveRange()317     public void testNextSecureIntNegativeToPositiveRange() {
318         for (int i = 0; i < 5; i++) {
319             checkNextSecureIntUniform(-3, 5);
320             checkNextSecureIntUniform(-3, 6);
321         }
322     }
323 
324     @Test
325     @Retry(3)
testNextSecureIntNegativeRange()326     public void testNextSecureIntNegativeRange() {
327         for (int i = 0; i < 5; i++) {
328             checkNextSecureIntUniform(-7, -4);
329             checkNextSecureIntUniform(-15, -2);
330         }
331     }
332 
333     @Test
334     @Retry(3)
testNextSecureIntPositiveRange()335     public void testNextSecureIntPositiveRange() {
336         for (int i = 0; i < 5; i++) {
337             checkNextSecureIntUniform(0, 3);
338             checkNextSecureIntUniform(2, 12);
339         }
340     }
341 
checkNextSecureIntUniform(int min, int max)342     private void checkNextSecureIntUniform(int min, int max) {
343         final Frequency freq = new Frequency();
344         for (int i = 0; i < smallSampleSize; i++) {
345             final int value = randomData.nextSecureInt(min, max);
346             Assert.assertTrue("nextInt range", (value >= min) && (value <= max));
347             freq.addValue(value);
348         }
349         final int len = max - min + 1;
350         final long[] observed = new long[len];
351         for (int i = 0; i < len; i++) {
352             observed[i] = freq.getCount(min + i);
353         }
354         final double[] expected = new double[len];
355         for (int i = 0; i < len; i++) {
356             expected[i] = 1d / len;
357         }
358 
359         TestUtils.assertChiSquareAccept(expected, observed, 0.0001);
360     }
361 
362 
363 
364     /**
365      * Make sure that empirical distribution of random Poisson(4)'s has P(X <=
366      * 5) close to actual cumulative Poisson probability and that nextPoisson
367      * fails when mean is non-positive.
368      */
369     @Test
testNextPoisson()370     public void testNextPoisson() {
371         try {
372             randomData.nextPoisson(0);
373             Assert.fail("zero mean -- expecting MathIllegalArgumentException");
374         } catch (MathIllegalArgumentException ex) {
375             // ignored
376         }
377         try {
378             randomData.nextPoisson(-1);
379             Assert.fail("negative mean supplied -- MathIllegalArgumentException expected");
380         } catch (MathIllegalArgumentException ex) {
381             // ignored
382         }
383         try {
384             randomData.nextPoisson(0);
385             Assert.fail("0 mean supplied -- MathIllegalArgumentException expected");
386         } catch (MathIllegalArgumentException ex) {
387             // ignored
388         }
389 
390         final double mean = 4.0d;
391         final int len = 5;
392         PoissonDistribution poissonDistribution = new PoissonDistribution(mean);
393         Frequency f = new Frequency();
394         randomData.reSeed(1000);
395         for (int i = 0; i < largeSampleSize; i++) {
396             f.addValue(randomData.nextPoisson(mean));
397         }
398         final long[] observed = new long[len];
399         for (int i = 0; i < len; i++) {
400             observed[i] = f.getCount(i + 1);
401         }
402         final double[] expected = new double[len];
403         for (int i = 0; i < len; i++) {
404             expected[i] = poissonDistribution.probability(i + 1) * largeSampleSize;
405         }
406 
407         TestUtils.assertChiSquareAccept(expected, observed, 0.0001);
408     }
409 
410     @Test
testNextPoissonConsistency()411     public void testNextPoissonConsistency() {
412 
413         // Small integral means
414         for (int i = 1; i < 100; i++) {
415             checkNextPoissonConsistency(i);
416         }
417         // non-integer means
418         for (int i = 1; i < 10; i++) {
419             checkNextPoissonConsistency(randomData.nextUniform(1, 1000));
420         }
421         // large means
422         for (int i = 1; i < 10; i++) {
423             checkNextPoissonConsistency(randomData.nextUniform(1000, 10000));
424         }
425     }
426 
427     /**
428      * Verifies that nextPoisson(mean) generates an empirical distribution of values
429      * consistent with PoissonDistributionImpl by generating 1000 values, computing a
430      * grouped frequency distribution of the observed values and comparing this distribution
431      * to the corresponding expected distribution computed using PoissonDistributionImpl.
432      * Uses ChiSquare test of goodness of fit to evaluate the null hypothesis that the
433      * distributions are the same. If the null hypothesis can be rejected with confidence
434      * 1 - alpha, the check fails.
435      */
checkNextPoissonConsistency(double mean)436     public void checkNextPoissonConsistency(double mean) {
437         // Generate sample values
438         final int sampleSize = 1000;        // Number of deviates to generate
439         final int minExpectedCount = 7;     // Minimum size of expected bin count
440         long maxObservedValue = 0;
441         final double alpha = 0.001;         // Probability of false failure
442         Frequency frequency = new Frequency();
443         for (int i = 0; i < sampleSize; i++) {
444             long value = randomData.nextPoisson(mean);
445             if (value > maxObservedValue) {
446                 maxObservedValue = value;
447             }
448             frequency.addValue(value);
449         }
450 
451         /*
452          *  Set up bins for chi-square test.
453          *  Ensure expected counts are all at least minExpectedCount.
454          *  Start with upper and lower tail bins.
455          *  Lower bin = [0, lower); Upper bin = [upper, +inf).
456          */
457         PoissonDistribution poissonDistribution = new PoissonDistribution(mean);
458         int lower = 1;
459         while (poissonDistribution.cumulativeProbability(lower - 1) * sampleSize < minExpectedCount) {
460             lower++;
461         }
462         int upper = (int) (5 * mean);  // Even for mean = 1, not much mass beyond 5
463         while ((1 - poissonDistribution.cumulativeProbability(upper - 1)) * sampleSize < minExpectedCount) {
464             upper--;
465         }
466 
467         // Set bin width for interior bins.  For poisson, only need to look at end bins.
468         int binWidth = 0;
469         boolean widthSufficient = false;
470         double lowerBinMass = 0;
471         double upperBinMass = 0;
472         while (!widthSufficient) {
473             binWidth++;
474             lowerBinMass = poissonDistribution.cumulativeProbability(lower - 1, lower + binWidth - 1);
475             upperBinMass = poissonDistribution.cumulativeProbability(upper - binWidth - 1, upper - 1);
476             widthSufficient = FastMath.min(lowerBinMass, upperBinMass) * sampleSize >= minExpectedCount;
477         }
478 
479         /*
480          *  Determine interior bin bounds.  Bins are
481          *  [1, lower = binBounds[0]), [lower, binBounds[1]), [binBounds[1], binBounds[2]), ... ,
482          *    [binBounds[binCount - 2], upper = binBounds[binCount - 1]), [upper, +inf)
483          *
484          */
485         List<Integer> binBounds = new ArrayList<Integer>();
486         binBounds.add(lower);
487         int bound = lower + binWidth;
488         while (bound < upper - binWidth) {
489             binBounds.add(bound);
490             bound += binWidth;
491         }
492         binBounds.add(upper); // The size of bin [binBounds[binCount - 2], upper) satisfies binWidth <= size < 2*binWidth.
493 
494         // Compute observed and expected bin counts
495         final int binCount = binBounds.size() + 1;
496         long[] observed = new long[binCount];
497         double[] expected = new double[binCount];
498 
499         // Bottom bin
500         observed[0] = 0;
501         for (int i = 0; i < lower; i++) {
502             observed[0] += frequency.getCount(i);
503         }
504         expected[0] = poissonDistribution.cumulativeProbability(lower - 1) * sampleSize;
505 
506         // Top bin
507         observed[binCount - 1] = 0;
508         for (int i = upper; i <= maxObservedValue; i++) {
509             observed[binCount - 1] += frequency.getCount(i);
510         }
511         expected[binCount - 1] = (1 - poissonDistribution.cumulativeProbability(upper - 1)) * sampleSize;
512 
513         // Interior bins
514         for (int i = 1; i < binCount - 1; i++) {
515             observed[i] = 0;
516             for (int j = binBounds.get(i - 1); j < binBounds.get(i); j++) {
517                 observed[i] += frequency.getCount(j);
518             } // Expected count is (mass in [binBounds[i-1], binBounds[i])) * sampleSize
519             expected[i] = (poissonDistribution.cumulativeProbability(binBounds.get(i) - 1) -
520                 poissonDistribution.cumulativeProbability(binBounds.get(i - 1) -1)) * sampleSize;
521         }
522 
523         // Use chisquare test to verify that generated values are poisson(mean)-distributed
524         ChiSquareTest chiSquareTest = new ChiSquareTest();
525             // Fail if we can reject null hypothesis that distributions are the same
526         if (chiSquareTest.chiSquareTest(expected, observed, alpha)) {
527             StringBuilder msgBuffer = new StringBuilder();
528             DecimalFormat df = new DecimalFormat("#.##");
529             msgBuffer.append("Chisquare test failed for mean = ");
530             msgBuffer.append(mean);
531             msgBuffer.append(" p-value = ");
532             msgBuffer.append(chiSquareTest.chiSquareTest(expected, observed));
533             msgBuffer.append(" chisquare statistic = ");
534             msgBuffer.append(chiSquareTest.chiSquare(expected, observed));
535             msgBuffer.append(". \n");
536             msgBuffer.append("bin\t\texpected\tobserved\n");
537             for (int i = 0; i < expected.length; i++) {
538                 msgBuffer.append("[");
539                 msgBuffer.append(i == 0 ? 1: binBounds.get(i - 1));
540                 msgBuffer.append(",");
541                 msgBuffer.append(i == binBounds.size() ? "inf": binBounds.get(i));
542                 msgBuffer.append(")");
543                 msgBuffer.append("\t\t");
544                 msgBuffer.append(df.format(expected[i]));
545                 msgBuffer.append("\t\t");
546                 msgBuffer.append(observed[i]);
547                 msgBuffer.append("\n");
548             }
549             msgBuffer.append("This test can fail randomly due to sampling error with probability ");
550             msgBuffer.append(alpha);
551             msgBuffer.append(".");
552             Assert.fail(msgBuffer.toString());
553         }
554     }
555 
556     /** test dispersion and failure modes for nextHex() */
557     @Test
testNextHex()558     public void testNextHex() {
559         try {
560             randomData.nextHexString(-1);
561             Assert.fail("negative length supplied -- MathIllegalArgumentException expected");
562         } catch (MathIllegalArgumentException ex) {
563             // ignored
564         }
565         try {
566             randomData.nextHexString(0);
567             Assert.fail("zero length supplied -- MathIllegalArgumentException expected");
568         } catch (MathIllegalArgumentException ex) {
569             // ignored
570         }
571         String hexString = randomData.nextHexString(3);
572         if (hexString.length() != 3) {
573             Assert.fail("incorrect length for generated string");
574         }
575         hexString = randomData.nextHexString(1);
576         if (hexString.length() != 1) {
577             Assert.fail("incorrect length for generated string");
578         }
579         try {
580             hexString = randomData.nextHexString(0);
581             Assert.fail("zero length requested -- expecting MathIllegalArgumentException");
582         } catch (MathIllegalArgumentException ex) {
583             // ignored
584         }
585         Frequency f = new Frequency();
586         for (int i = 0; i < smallSampleSize; i++) {
587             hexString = randomData.nextHexString(100);
588             if (hexString.length() != 100) {
589                 Assert.fail("incorrect length for generated string");
590             }
591             for (int j = 0; j < hexString.length(); j++) {
592                 f.addValue(hexString.substring(j, j + 1));
593             }
594         }
595         double[] expected = new double[16];
596         long[] observed = new long[16];
597         for (int i = 0; i < 16; i++) {
598             expected[i] = (double) smallSampleSize * 100 / 16;
599             observed[i] = f.getCount(hex[i]);
600         }
601         TestUtils.assertChiSquareAccept(expected, observed, 0.001);
602     }
603 
604     /** test dispersion and failure modes for nextHex() */
605     @Test
606     @Retry(3)
testNextSecureHex()607     public void testNextSecureHex() {
608         try {
609             randomData.nextSecureHexString(-1);
610             Assert.fail("negative length -- MathIllegalArgumentException expected");
611         } catch (MathIllegalArgumentException ex) {
612             // ignored
613         }
614         try {
615             randomData.nextSecureHexString(0);
616             Assert.fail("zero length -- MathIllegalArgumentException expected");
617         } catch (MathIllegalArgumentException ex) {
618             // ignored
619         }
620         String hexString = randomData.nextSecureHexString(3);
621         if (hexString.length() != 3) {
622             Assert.fail("incorrect length for generated string");
623         }
624         hexString = randomData.nextSecureHexString(1);
625         if (hexString.length() != 1) {
626             Assert.fail("incorrect length for generated string");
627         }
628         try {
629             hexString = randomData.nextSecureHexString(0);
630             Assert.fail("zero length requested -- expecting MathIllegalArgumentException");
631         } catch (MathIllegalArgumentException ex) {
632             // ignored
633         }
634         Frequency f = new Frequency();
635         for (int i = 0; i < smallSampleSize; i++) {
636             hexString = randomData.nextSecureHexString(100);
637             if (hexString.length() != 100) {
638                 Assert.fail("incorrect length for generated string");
639             }
640             for (int j = 0; j < hexString.length(); j++) {
641                 f.addValue(hexString.substring(j, j + 1));
642             }
643         }
644         double[] expected = new double[16];
645         long[] observed = new long[16];
646         for (int i = 0; i < 16; i++) {
647             expected[i] = (double) smallSampleSize * 100 / 16;
648             observed[i] = f.getCount(hex[i]);
649         }
650         TestUtils.assertChiSquareAccept(expected, observed, 0.001);
651     }
652 
653     @Test
testNextUniformIAE()654     public void testNextUniformIAE() {
655         try {
656             randomData.nextUniform(4, 3);
657             Assert.fail("MathIllegalArgumentException expected");
658         } catch (MathIllegalArgumentException ex) {
659             // ignored
660         }
661         try {
662             randomData.nextUniform(0, Double.POSITIVE_INFINITY);
663             Assert.fail("MathIllegalArgumentException expected");
664         } catch (MathIllegalArgumentException ex) {
665             // ignored
666         }
667         try {
668             randomData.nextUniform(Double.NEGATIVE_INFINITY, 0);
669             Assert.fail("MathIllegalArgumentException expected");
670         } catch (MathIllegalArgumentException ex) {
671             // ignored
672         }
673         try {
674             randomData.nextUniform(0, Double.NaN);
675             Assert.fail("MathIllegalArgumentException expected");
676         } catch (MathIllegalArgumentException ex) {
677             // ignored
678         }
679         try {
680             randomData.nextUniform(Double.NaN, 0);
681             Assert.fail("MathIllegalArgumentException expected");
682         } catch (MathIllegalArgumentException ex) {
683             // ignored
684         }
685     }
686 
687     @Test
testNextUniformUniformPositiveBounds()688     public void testNextUniformUniformPositiveBounds() {
689         for (int i = 0; i < 5; i++) {
690             checkNextUniformUniform(0, 10);
691         }
692     }
693 
694     @Test
testNextUniformUniformNegativeToPositiveBounds()695     public void testNextUniformUniformNegativeToPositiveBounds() {
696         for (int i = 0; i < 5; i++) {
697             checkNextUniformUniform(-3, 5);
698         }
699     }
700 
701     @Test
testNextUniformUniformNegaiveBounds()702     public void testNextUniformUniformNegaiveBounds() {
703         for (int i = 0; i < 5; i++) {
704             checkNextUniformUniform(-7, -3);
705         }
706     }
707 
708     @Test
testNextUniformUniformMaximalInterval()709     public void testNextUniformUniformMaximalInterval() {
710         for (int i = 0; i < 5; i++) {
711             checkNextUniformUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
712         }
713     }
714 
checkNextUniformUniform(double min, double max)715     private void checkNextUniformUniform(double min, double max) {
716         // Set up bin bounds - min, binBound[0], ..., binBound[binCount-2], max
717         final int binCount = 5;
718         final double binSize = max / binCount - min/binCount; // Prevent overflow in extreme value case
719         final double[] binBounds = new double[binCount - 1];
720         binBounds[0] = min + binSize;
721         for (int i = 1; i < binCount - 1; i++) {
722             binBounds[i] = binBounds[i - 1] + binSize;  // + instead of * to avoid overflow in extreme case
723         }
724 
725         final Frequency freq = new Frequency();
726         for (int i = 0; i < smallSampleSize; i++) {
727             final double value = randomData.nextUniform(min, max);
728             Assert.assertTrue("nextUniform range", (value > min) && (value < max));
729             // Find bin
730             int j = 0;
731             while (j < binCount - 1 && value > binBounds[j]) {
732                 j++;
733             }
734             freq.addValue(j);
735         }
736 
737         final long[] observed = new long[binCount];
738         for (int i = 0; i < binCount; i++) {
739             observed[i] = freq.getCount(i);
740         }
741         final double[] expected = new double[binCount];
742         for (int i = 0; i < binCount; i++) {
743             expected[i] = 1d / binCount;
744         }
745 
746         TestUtils.assertChiSquareAccept(expected, observed, 0.01);
747     }
748 
749     /** test exclusive endpoints of nextUniform **/
750     @Test
testNextUniformExclusiveEndpoints()751     public void testNextUniformExclusiveEndpoints() {
752         for (int i = 0; i < 1000; i++) {
753             double u = randomData.nextUniform(0.99, 1);
754             Assert.assertTrue(u > 0.99 && u < 1);
755         }
756     }
757 
758     /** test failure modes and distribution of nextGaussian() */
759     @Test
testNextGaussian()760     public void testNextGaussian() {
761         try {
762             randomData.nextGaussian(0, 0);
763             Assert.fail("zero sigma -- MathIllegalArgumentException expected");
764         } catch (MathIllegalArgumentException ex) {
765             // ignored
766         }
767         double[] quartiles = TestUtils.getDistributionQuartiles(new NormalDistribution(0,1));
768         long[] counts = new long[4];
769         randomData.reSeed(1000);
770         for (int i = 0; i < 1000; i++) {
771             double value = randomData.nextGaussian(0, 1);
772             TestUtils.updateCounts(value, counts, quartiles);
773         }
774         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
775     }
776 
777     /** test failure modes and distribution of nextExponential() */
778     @Test
testNextExponential()779     public void testNextExponential() {
780         try {
781             randomData.nextExponential(-1);
782             Assert.fail("negative mean -- expecting MathIllegalArgumentException");
783         } catch (MathIllegalArgumentException ex) {
784             // ignored
785         }
786         try {
787             randomData.nextExponential(0);
788             Assert.fail("zero mean -- expecting MathIllegalArgumentException");
789         } catch (MathIllegalArgumentException ex) {
790             // ignored
791         }
792         double[] quartiles;
793         long[] counts;
794 
795         // Mean 1
796         quartiles = TestUtils.getDistributionQuartiles(new ExponentialDistribution(1));
797         counts = new long[4];
798         randomData.reSeed(1000);
799         for (int i = 0; i < 1000; i++) {
800             double value = randomData.nextExponential(1);
801             TestUtils.updateCounts(value, counts, quartiles);
802         }
803         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
804 
805         // Mean 5
806         quartiles = TestUtils.getDistributionQuartiles(new ExponentialDistribution(5));
807         counts = new long[4];
808         randomData.reSeed(1000);
809         for (int i = 0; i < 1000; i++) {
810             double value = randomData.nextExponential(5);
811             TestUtils.updateCounts(value, counts, quartiles);
812         }
813         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
814     }
815 
816     /** test reseeding, algorithm/provider games */
817     @Test
testConfig()818     public void testConfig() {
819         randomData.reSeed(1000);
820         double v = randomData.nextUniform(0, 1);
821         randomData.reSeed();
822         Assert.assertTrue("different seeds", FastMath.abs(v - randomData.nextUniform(0, 1)) > 10E-12);
823         randomData.reSeed(1000);
824         Assert.assertEquals("same seeds", v, randomData.nextUniform(0, 1), 10E-12);
825         randomData.reSeedSecure(1000);
826         String hex = randomData.nextSecureHexString(40);
827         randomData.reSeedSecure();
828         Assert.assertTrue("different seeds", !hex.equals(randomData
829                 .nextSecureHexString(40)));
830         randomData.reSeedSecure(1000);
831         Assert.assertTrue("same seeds", !hex
832                 .equals(randomData.nextSecureHexString(40)));
833 
834         /*
835          * remove this test back soon, since it takes about 4 seconds
836          *
837          * try { randomData.setSecureAlgorithm("SHA1PRNG","SUN"); } catch
838          * (NoSuchProviderException ex) { ; } Assert.assertTrue("different seeds",
839          * !hex.equals(randomData.nextSecureHexString(40))); try {
840          * randomData.setSecureAlgorithm("NOSUCHTHING","SUN");
841          * Assert.fail("expecting NoSuchAlgorithmException"); } catch
842          * (NoSuchProviderException ex) { ; } catch (NoSuchAlgorithmException
843          * ex) { ; }
844          *
845          * try { randomData.setSecureAlgorithm("SHA1PRNG","NOSUCHPROVIDER");
846          * Assert.fail("expecting NoSuchProviderException"); } catch
847          * (NoSuchProviderException ex) { ; }
848          */
849 
850         // test reseeding without first using the generators
851         RandomDataGenerator rd = new RandomDataGenerator();
852         rd.reSeed(100);
853         rd.nextLong(1, 2);
854         RandomDataGenerator rd2 = new RandomDataGenerator();
855         rd2.reSeedSecure(2000);
856         rd2.nextSecureLong(1, 2);
857         rd = new RandomDataGenerator();
858         rd.reSeed();
859         rd.nextLong(1, 2);
860         rd2 = new RandomDataGenerator();
861         rd2.reSeedSecure();
862         rd2.nextSecureLong(1, 2);
863     }
864 
865     /** tests for nextSample() sampling from Collection */
866     @Test
testNextSample()867     public void testNextSample() {
868         Object[][] c = { { "0", "1" }, { "0", "2" }, { "0", "3" },
869                 { "0", "4" }, { "1", "2" }, { "1", "3" }, { "1", "4" },
870                 { "2", "3" }, { "2", "4" }, { "3", "4" } };
871         long[] observed = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
872         double[] expected = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 };
873 
874         HashSet<Object> cPop = new HashSet<Object>(); // {0,1,2,3,4}
875         for (int i = 0; i < 5; i++) {
876             cPop.add(Integer.toString(i));
877         }
878 
879         Object[] sets = new Object[10]; // 2-sets from 5
880         for (int i = 0; i < 10; i++) {
881             HashSet<Object> hs = new HashSet<Object>();
882             hs.add(c[i][0]);
883             hs.add(c[i][1]);
884             sets[i] = hs;
885         }
886 
887         for (int i = 0; i < 1000; i++) {
888             Object[] cSamp = randomData.nextSample(cPop, 2);
889             observed[findSample(sets, cSamp)]++;
890         }
891 
892         /*
893          * Use ChiSquare dist with df = 10-1 = 9, alpha = .001 Change to 21.67
894          * for alpha = .01
895          */
896         Assert.assertTrue("chi-square test -- will fail about 1 in 1000 times",
897                 testStatistic.chiSquare(expected, observed) < 27.88);
898 
899         // Make sure sample of size = size of collection returns same collection
900         HashSet<Object> hs = new HashSet<Object>();
901         hs.add("one");
902         Object[] one = randomData.nextSample(hs, 1);
903         String oneString = (String) one[0];
904         if ((one.length != 1) || !oneString.equals("one")) {
905             Assert.fail("bad sample for set size = 1, sample size = 1");
906         }
907 
908         // Make sure we fail for sample size > collection size
909         try {
910             one = randomData.nextSample(hs, 2);
911             Assert.fail("sample size > set size, expecting MathIllegalArgumentException");
912         } catch (MathIllegalArgumentException ex) {
913             // ignored
914         }
915 
916         // Make sure we fail for empty collection
917         try {
918             hs = new HashSet<Object>();
919             one = randomData.nextSample(hs, 0);
920             Assert.fail("n = k = 0, expecting MathIllegalArgumentException");
921         } catch (MathIllegalArgumentException ex) {
922             // ignored
923         }
924     }
925 
926     @SuppressWarnings("unchecked")
findSample(Object[] u, Object[] samp)927     private int findSample(Object[] u, Object[] samp) {
928         for (int i = 0; i < u.length; i++) {
929             HashSet<Object> set = (HashSet<Object>) u[i];
930             HashSet<Object> sampSet = new HashSet<Object>();
931             for (int j = 0; j < samp.length; j++) {
932                 sampSet.add(samp[j]);
933             }
934             if (set.equals(sampSet)) {
935                 return i;
936             }
937         }
938         Assert.fail("sample not found:{" + samp[0] + "," + samp[1] + "}");
939         return -1;
940     }
941 
942     /** tests for nextPermutation */
943     @Test
testNextPermutation()944     public void testNextPermutation() {
945         int[][] p = { { 0, 1, 2 }, { 0, 2, 1 }, { 1, 0, 2 }, { 1, 2, 0 },
946                 { 2, 0, 1 }, { 2, 1, 0 } };
947         long[] observed = { 0, 0, 0, 0, 0, 0 };
948         double[] expected = { 100, 100, 100, 100, 100, 100 };
949 
950         for (int i = 0; i < 600; i++) {
951             int[] perm = randomData.nextPermutation(3, 3);
952             observed[findPerm(p, perm)]++;
953         }
954 
955         String[] labels = {"{0, 1, 2}", "{ 0, 2, 1 }", "{ 1, 0, 2 }",
956                 "{ 1, 2, 0 }", "{ 2, 0, 1 }", "{ 2, 1, 0 }"};
957         TestUtils.assertChiSquareAccept(labels, expected, observed, 0.001);
958 
959         // Check size = 1 boundary case
960         int[] perm = randomData.nextPermutation(1, 1);
961         if ((perm.length != 1) || (perm[0] != 0)) {
962             Assert.fail("bad permutation for n = 1, sample k = 1");
963 
964             // Make sure we fail for k size > n
965             try {
966                 perm = randomData.nextPermutation(2, 3);
967                 Assert.fail("permutation k > n, expecting MathIllegalArgumentException");
968             } catch (MathIllegalArgumentException ex) {
969                 // ignored
970             }
971 
972             // Make sure we fail for n = 0
973             try {
974                 perm = randomData.nextPermutation(0, 0);
975                 Assert.fail("permutation k = n = 0, expecting MathIllegalArgumentException");
976             } catch (MathIllegalArgumentException ex) {
977                 // ignored
978             }
979 
980             // Make sure we fail for k < n < 0
981             try {
982                 perm = randomData.nextPermutation(-1, -3);
983                 Assert.fail("permutation k < n < 0, expecting MathIllegalArgumentException");
984             } catch (MathIllegalArgumentException ex) {
985                 // ignored
986             }
987 
988         }
989     }
990 
991     // Disable until we have equals
992     //public void testSerial() {
993     //    Assert.assertEquals(randomData, TestUtils.serializeAndRecover(randomData));
994     //}
995 
findPerm(int[][] p, int[] samp)996     private int findPerm(int[][] p, int[] samp) {
997         for (int i = 0; i < p.length; i++) {
998             boolean good = true;
999             for (int j = 0; j < samp.length; j++) {
1000                 if (samp[j] != p[i][j]) {
1001                     good = false;
1002                 }
1003             }
1004             if (good) {
1005                 return i;
1006             }
1007         }
1008         Assert.fail("permutation not found");
1009         return -1;
1010     }
1011 
1012     @Test
testNextBeta()1013     public void testNextBeta() {
1014         double[] quartiles = TestUtils.getDistributionQuartiles(new BetaDistribution(2,5));
1015         long[] counts = new long[4];
1016         randomData.reSeed(1000);
1017         for (int i = 0; i < 1000; i++) {
1018             double value = randomData.nextBeta(2, 5);
1019             TestUtils.updateCounts(value, counts, quartiles);
1020         }
1021         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
1022     }
1023 
1024     @Test
testNextCauchy()1025     public void testNextCauchy() {
1026         double[] quartiles = TestUtils.getDistributionQuartiles(new CauchyDistribution(1.2, 2.1));
1027         long[] counts = new long[4];
1028         randomData.reSeed(1000);
1029         for (int i = 0; i < 1000; i++) {
1030             double value = randomData.nextCauchy(1.2, 2.1);
1031             TestUtils.updateCounts(value, counts, quartiles);
1032         }
1033         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
1034     }
1035 
1036     @Test
testNextChiSquare()1037     public void testNextChiSquare() {
1038         double[] quartiles = TestUtils.getDistributionQuartiles(new ChiSquaredDistribution(12));
1039         long[] counts = new long[4];
1040         randomData.reSeed(1000);
1041         for (int i = 0; i < 1000; i++) {
1042             double value = randomData.nextChiSquare(12);
1043             TestUtils.updateCounts(value, counts, quartiles);
1044         }
1045         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
1046     }
1047 
1048     @Test
testNextF()1049     public void testNextF() {
1050         double[] quartiles = TestUtils.getDistributionQuartiles(new FDistribution(12, 5));
1051         long[] counts = new long[4];
1052         randomData.reSeed(1000);
1053         for (int i = 0; i < 1000; i++) {
1054             double value = randomData.nextF(12, 5);
1055             TestUtils.updateCounts(value, counts, quartiles);
1056         }
1057         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
1058     }
1059 
1060     @Test
testNextGamma()1061     public void testNextGamma() {
1062         double[] quartiles;
1063         long[] counts;
1064 
1065         // Tests shape > 1, one case in the rejection sampling
1066         quartiles = TestUtils.getDistributionQuartiles(new GammaDistribution(4, 2));
1067         counts = new long[4];
1068         randomData.reSeed(1000);
1069         for (int i = 0; i < 1000; i++) {
1070             double value = randomData.nextGamma(4, 2);
1071             TestUtils.updateCounts(value, counts, quartiles);
1072         }
1073         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
1074 
1075         // Tests shape <= 1, another case in the rejection sampling
1076         quartiles = TestUtils.getDistributionQuartiles(new GammaDistribution(0.3, 3));
1077         counts = new long[4];
1078         randomData.reSeed(1000);
1079         for (int i = 0; i < 1000; i++) {
1080             double value = randomData.nextGamma(0.3, 3);
1081             TestUtils.updateCounts(value, counts, quartiles);
1082         }
1083         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
1084     }
1085 
1086     @Test
testNextT()1087     public void testNextT() {
1088         double[] quartiles = TestUtils.getDistributionQuartiles(new TDistribution(10));
1089         long[] counts = new long[4];
1090         randomData.reSeed(1000);
1091         for (int i = 0; i < 1000; i++) {
1092             double value = randomData.nextT(10);
1093             TestUtils.updateCounts(value, counts, quartiles);
1094         }
1095         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
1096     }
1097 
1098     @Test
testNextWeibull()1099     public void testNextWeibull() {
1100         double[] quartiles = TestUtils.getDistributionQuartiles(new WeibullDistribution(1.2, 2.1));
1101         long[] counts = new long[4];
1102         randomData.reSeed(1000);
1103         for (int i = 0; i < 1000; i++) {
1104             double value = randomData.nextWeibull(1.2, 2.1);
1105             TestUtils.updateCounts(value, counts, quartiles);
1106         }
1107         TestUtils.assertChiSquareAccept(expected, counts, 0.001);
1108     }
1109 
1110     @Test
testNextBinomial()1111     public void testNextBinomial() {
1112         BinomialDistributionTest testInstance = new BinomialDistributionTest();
1113         int[] densityPoints = testInstance.makeDensityTestPoints();
1114         double[] densityValues = testInstance.makeDensityTestValues();
1115         int sampleSize = 1000;
1116         int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues);
1117         BinomialDistribution distribution = (BinomialDistribution) testInstance.makeDistribution();
1118         double[] expectedCounts = new double[length];
1119         long[] observedCounts = new long[length];
1120         for (int i = 0; i < length; i++) {
1121             expectedCounts[i] = sampleSize * densityValues[i];
1122         }
1123         randomData.reSeed(1000);
1124         for (int i = 0; i < sampleSize; i++) {
1125           int value = randomData.nextBinomial(distribution.getNumberOfTrials(),
1126                   distribution.getProbabilityOfSuccess());
1127           for (int j = 0; j < length; j++) {
1128               if (value == densityPoints[j]) {
1129                   observedCounts[j]++;
1130               }
1131           }
1132         }
1133         TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001);
1134     }
1135 
1136     @Test
testNextHypergeometric()1137     public void testNextHypergeometric() {
1138         HypergeometricDistributionTest testInstance = new HypergeometricDistributionTest();
1139         int[] densityPoints = testInstance.makeDensityTestPoints();
1140         double[] densityValues = testInstance.makeDensityTestValues();
1141         int sampleSize = 1000;
1142         int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues);
1143         HypergeometricDistribution distribution = (HypergeometricDistribution) testInstance.makeDistribution();
1144         double[] expectedCounts = new double[length];
1145         long[] observedCounts = new long[length];
1146         for (int i = 0; i < length; i++) {
1147             expectedCounts[i] = sampleSize * densityValues[i];
1148         }
1149         randomData.reSeed(1000);
1150         for (int i = 0; i < sampleSize; i++) {
1151           int value = randomData.nextHypergeometric(distribution.getPopulationSize(),
1152                   distribution.getNumberOfSuccesses(), distribution.getSampleSize());
1153           for (int j = 0; j < length; j++) {
1154               if (value == densityPoints[j]) {
1155                   observedCounts[j]++;
1156               }
1157           }
1158         }
1159         TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001);
1160     }
1161 
1162     @Test
testNextPascal()1163     public void testNextPascal() {
1164         PascalDistributionTest testInstance = new PascalDistributionTest();
1165         int[] densityPoints = testInstance.makeDensityTestPoints();
1166         double[] densityValues = testInstance.makeDensityTestValues();
1167         int sampleSize = 1000;
1168         int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues);
1169         PascalDistribution distribution = (PascalDistribution) testInstance.makeDistribution();
1170         double[] expectedCounts = new double[length];
1171         long[] observedCounts = new long[length];
1172         for (int i = 0; i < length; i++) {
1173             expectedCounts[i] = sampleSize * densityValues[i];
1174         }
1175         randomData.reSeed(1000);
1176         for (int i = 0; i < sampleSize; i++) {
1177           int value = randomData.nextPascal(distribution.getNumberOfSuccesses(), distribution.getProbabilityOfSuccess());
1178           for (int j = 0; j < length; j++) {
1179               if (value == densityPoints[j]) {
1180                   observedCounts[j]++;
1181               }
1182           }
1183         }
1184         TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001);
1185     }
1186 
1187     @Test
testNextZipf()1188     public void testNextZipf() {
1189         ZipfDistributionTest testInstance = new ZipfDistributionTest();
1190         int[] densityPoints = testInstance.makeDensityTestPoints();
1191         double[] densityValues = testInstance.makeDensityTestValues();
1192         int sampleSize = 1000;
1193         int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues);
1194         ZipfDistribution distribution = (ZipfDistribution) testInstance.makeDistribution();
1195         double[] expectedCounts = new double[length];
1196         long[] observedCounts = new long[length];
1197         for (int i = 0; i < length; i++) {
1198             expectedCounts[i] = sampleSize * densityValues[i];
1199         }
1200         randomData.reSeed(1000);
1201         for (int i = 0; i < sampleSize; i++) {
1202           int value = randomData.nextZipf(distribution.getNumberOfElements(), distribution.getExponent());
1203           for (int j = 0; j < length; j++) {
1204               if (value == densityPoints[j]) {
1205                   observedCounts[j]++;
1206               }
1207           }
1208         }
1209         TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001);
1210     }
1211 
1212     @Test
1213     /**
1214      * MATH-720
1215      */
testReseed()1216     public void testReseed() {
1217         PoissonDistribution x = new PoissonDistribution(3.0);
1218         x.reseedRandomGenerator(0);
1219         final double u = x.sample();
1220         PoissonDistribution y = new PoissonDistribution(3.0);
1221         y.reseedRandomGenerator(0);
1222         Assert.assertEquals(u, y.sample(), 0);
1223     }
1224 
1225 }
1226