KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > lang > math > RandomUtilsTest


1 /*
2  * Copyright 2002-2005 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.lang.math;
17
18 import java.util.Random JavaDoc;
19
20 import junit.framework.Test;
21 import junit.framework.TestCase;
22 import junit.framework.TestSuite;
23
24 /**
25  * Test cases for the {@link RandomUtils} class.
26  *
27  * @author <a HREF="mailto:phil@steitz.com">Phil Steitz</a>
28  * @version $Revision: 161244 $ $Date: 2005-04-14 02:16:36 -0400 (Thu, 14 Apr 2005) $
29  */

30
31 public final class RandomUtilsTest extends TestCase {
32
33     public RandomUtilsTest(String JavaDoc name) {
34         super(name);
35     }
36     
37     public void setUp() {
38     }
39     
40     public static Test suite() {
41         TestSuite suite = new TestSuite(RandomUtilsTest.class);
42         suite.setName("RandomUtils Tests");
43         return suite;
44     }
45     
46     /** test distribution of nextInt() */
47     public void testNextInt() {
48         tstNextInt(null);
49     }
50     
51     /** test distribution of nextInt(Random) */
52     public void testNextInt2() {
53         Random JavaDoc rnd = new Random JavaDoc();
54         rnd.setSeed(System.currentTimeMillis());
55         tstNextInt(rnd);
56     }
57     
58     /** test distribution of JVMRandom.nextInt() */
59     public void testJvmRandomNextInt() {
60         tstNextInt(RandomUtils.JVM_RANDOM);
61     }
62
63     
64     /**
65      * Generate 1000 values for nextInt(bound) and compare
66      * the observed frequency counts to expected counts using
67      * a chi-square test.
68      * @param rnd Random to use if not null
69      */

70     private void tstNextInt(Random JavaDoc rnd) {
71         int bound = 0;
72         int result = 0;
73         // test boundary condition: n = Integer.MAX_VALUE;
74
bound = Integer.MAX_VALUE;
75         if (rnd == null) {
76             result = RandomUtils.nextInt(bound);
77         } else {
78             result = RandomUtils.nextInt(rnd,bound);
79         }
80         assertTrue("result less than bound",result < bound);
81         assertTrue("result non-negative",result >= 0);
82         
83         // test uniformity -- use Chi-Square test at .01 level
84
bound = 4;
85         int[] expected = new int[] {250,250,250,250};
86         int[] observed = new int[] {0,0,0,0};
87         for (int i = 0; i < 1000; i ++) {
88             if (rnd == null) {
89                 result = RandomUtils.nextInt(bound);
90             } else {
91                 result = RandomUtils.nextInt(rnd,bound);
92             }
93             assertTrue(result < bound);
94             assertTrue(result >= 0);
95             observed[result]++;
96         }
97         /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
98          * Change to 11.34 for alpha = .01
99          */

100         assertTrue(
101             "chi-square test -- will fail about 1 in 1000 times",
102             chiSquare(expected,observed) < 16.27);
103     }
104     
105     /** test distribution of nextLong() */
106     public void testNextLong() {
107         tstNextLong(null);
108     }
109     
110     /** test distribution of nextLong(Random) BROKEN
111      * contract of nextLong(Random) is different from
112      * nextLong() */

113     public void testNextLong2() {
114         Random JavaDoc rnd = new Random JavaDoc();
115         rnd.setSeed(System.currentTimeMillis());
116         tstNextLong(rnd);
117     }
118      
119     /**
120      * Generate 1000 values for nextLong and check that
121      * p(value < long.MAXVALUE/2) ~ 0.5. Use chi-square test
122      * with df = 2-1 = 1
123      * @param rnd Random to use if not null
124      */

125     private void tstNextLong(Random JavaDoc rnd) {
126         int[] expected = new int[] {500,500};
127         int[] observed = new int[] {0,0};
128         long result = 0;
129         long midPoint = Long.MAX_VALUE/2;
130         for (int i = 0; i < 1000; i ++) {
131             if (rnd == null) {
132                 result = Math.abs(RandomUtils.nextLong());
133             } else {
134                 result = Math.abs(RandomUtils.nextLong(rnd));
135             }
136             if (result < midPoint) {
137                 observed[0]++;
138             } else {
139                 observed[1]++;
140             }
141         }
142         /* Use ChiSquare dist with df = 2-1 = 1, alpha = .001
143          * Change to 6.64 for alpha = .01
144          */

145         assertTrue(
146             "chi-square test -- will fail about 1 in 1000 times",
147             chiSquare(expected,observed) < 10.83);
148     }
149         
150     
151     /** test distribution of nextBoolean() */
152     public void testNextBoolean() {
153         tstNextBoolean(null);
154     }
155     
156     /** test distribution of nextBoolean(Random) */
157     public void testNextBoolean2() {
158         Random JavaDoc rnd = new Random JavaDoc();
159         rnd.setSeed(System.currentTimeMillis());
160         tstNextBoolean(rnd);
161     }
162     
163     /**
164      * Generate 1000 values for nextBoolean and check that
165      * p(value = false) ~ 0.5. Use chi-square test
166      * with df = 2-1 = 1
167      * @param rnd Random to use if not null
168      */

169     private void tstNextBoolean(Random JavaDoc rnd) {
170         int[] expected = new int[] {500,500};
171         int[] observed = new int[] {0,0};
172         boolean result = false;
173         for (int i = 0; i < 1000; i ++) {
174             if (rnd == null) {
175                 result = RandomUtils.nextBoolean();
176             } else {
177                 result = RandomUtils.nextBoolean(rnd);
178             }
179             if (result) {
180                 observed[0]++;
181             } else {
182                 observed[1]++;
183             }
184         }
185         /* Use ChiSquare dist with df = 2-1 = 1, alpha = .001
186          * Change to 6.64 for alpha = .01
187          */

188         assertTrue(
189             "chi-square test -- will fail about 1 in 1000 times",
190             chiSquare(expected,observed) < 10.83 );
191     }
192     
193     /** test distribution of nextFloat() */
194     public void testNextFloat() {
195         tstNextFloat(null);
196     }
197     
198     /** test distribution of nextFloat(Random) */
199     public void testNextFloat2() {
200         Random JavaDoc rnd = new Random JavaDoc();
201         rnd.setSeed(System.currentTimeMillis());
202         tstNextFloat(rnd);
203     }
204     
205     /**
206      * Generate 1000 values for nextFloat and check that
207      * p(value < 0.5) ~ 0.5. Use chi-square test
208      * with df = 2-1 = 1
209      * @param rnd Random to use if not null
210      */

211     private void tstNextFloat(Random JavaDoc rnd) {
212         int[] expected = new int[] {500,500};
213         int[] observed = new int[] {0,0};
214         float result = 0;
215         for (int i = 0; i < 1000; i ++) {
216             if (rnd == null) {
217                 result = RandomUtils.nextFloat();
218             } else {
219                 result = RandomUtils.nextFloat(rnd);
220             }
221             if (result < 0.5) {
222                 observed[0]++;
223             } else {
224                 observed[1]++;
225             }
226         }
227         /* Use ChiSquare dist with df = 2-1 = 1, alpha = .001
228          * Change to 6.64 for alpha = .01
229          */

230         assertTrue(
231             "chi-square test -- will fail about 1 in 1000 times",
232             chiSquare(expected,observed) < 10.83);
233     }
234     
235     /** test distribution of nextDouble() */
236     public void testNextDouble() {
237         tstNextDouble(null);
238     }
239     
240     /** test distribution of nextDouble(Random) */
241     public void testNextDouble2() {
242         Random JavaDoc rnd = new Random JavaDoc();
243         rnd.setSeed(System.currentTimeMillis());
244         tstNextDouble(rnd);
245     }
246     
247     /**
248      * Generate 1000 values for nextFloat and check that
249      * p(value < 0.5) ~ 0.5. Use chi-square test
250      * with df = 2-1 = 1
251      * @param rnd Random to use if not null
252      */

253     private void tstNextDouble(Random JavaDoc rnd) {
254         int[] expected = new int[] {500,500};
255         int[] observed = new int[] {0,0};
256         double result = 0;
257         for (int i = 0; i < 1000; i ++) {
258             if (rnd == null) {
259                 result = RandomUtils.nextDouble();
260             } else {
261                 result = RandomUtils.nextDouble(rnd);
262             }
263             if (result < 0.5) {
264                 observed[0]++;
265             } else {
266                 observed[1]++;
267             }
268         }
269         /* Use ChiSquare dist with df = 2-1 = 1, alpha = .001
270          * Change to 6.64 for alpha = .01
271          */

272         assertTrue(
273             "chi-square test -- will fail about 1 in 1000 times",
274             chiSquare(expected,observed) < 10.83);
275     }
276     
277     /** make sure that unimplemented methods fail */
278     public void testUnimplementedMethods() {
279
280         try {
281             RandomUtils.JVM_RANDOM.setSeed(1000);
282             fail("expecting UnsupportedOperationException");
283         } catch (UnsupportedOperationException JavaDoc ex) {
284             // empty
285
}
286
287         try {
288             RandomUtils.JVM_RANDOM.nextGaussian();
289             fail("expecting UnsupportedOperationException");
290         } catch (UnsupportedOperationException JavaDoc ex) {
291             // empty
292
}
293
294         try {
295             RandomUtils.JVM_RANDOM.nextBytes(null);
296             fail("expecting UnsupportedOperationException");
297         } catch (UnsupportedOperationException JavaDoc ex) {
298             // empty
299
}
300
301     }
302
303     /** make sure that illegal arguments fail */
304     public void testIllegalArguments() {
305
306         try {
307             RandomUtils.JVM_RANDOM.nextInt(-1);
308             fail("expecting IllegalArgumentException");
309         } catch (IllegalArgumentException JavaDoc ex) {
310             // empty
311
}
312
313         try {
314             JVMRandom.nextLong( -1L );
315             fail("expecting IllegalArgumentException");
316         } catch (IllegalArgumentException JavaDoc ex) {
317             // empty
318
}
319
320     }
321     
322     /**
323      * Computes Chi-Square statistic given observed and expected counts
324      * @param observed array of observed frequency counts
325      * @param expected array of expected frequency counts
326      */

327     private double chiSquare(int[] expected, int[] observed) {
328         double sumSq = 0.0d;
329         double dev = 0.0d;
330         for (int i = 0; i< observed.length; i++) {
331             dev = (double)(observed[i] - expected[i]);
332             sumSq += dev*dev/(double)expected[i];
333         }
334         return sumSq;
335     }
336
337 }
338
339
Popular Tags