diff options
Diffstat (limited to 'tests/com/jsyn/util/TestPseudoRandom.java')
-rw-r--r-- | tests/com/jsyn/util/TestPseudoRandom.java | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/tests/com/jsyn/util/TestPseudoRandom.java b/tests/com/jsyn/util/TestPseudoRandom.java new file mode 100644 index 0000000..0ef2fa3 --- /dev/null +++ b/tests/com/jsyn/util/TestPseudoRandom.java @@ -0,0 +1,82 @@ +/* + * Copyright 2009 Phil Burk, Mobileer Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.jsyn.util; + +import junit.framework.TestCase; + +public class TestPseudoRandom extends TestCase { + PseudoRandom pseudoRandom; + private int[] bins; + private final static int BIN_SHIFTER = 8; + private final static int BIN_COUNT = 1 << BIN_SHIFTER; + private final static int BIN_MASK = BIN_COUNT - 1; + + @Override + protected void setUp() throws Exception { + super.setUp(); + pseudoRandom = new PseudoRandom(); + bins = new int[BIN_COUNT]; + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testMath() { + long seed = 3964771111L; + int positiveInt = (int) (seed & 0x7FFFFFFF); + assertTrue("masked random positive, " + positiveInt, (positiveInt >= 0)); + double rand = positiveInt * (1.0 / (1L << 31)); + assertTrue("not too low, " + rand, (rand >= 0.0)); + assertTrue("not too high, " + rand, (rand < 1.0)); + } + + public void testIntegerDistribution() { + int scaler = 10; + for (int i = 0; i < (bins.length * scaler); i++) { + int rand = pseudoRandom.nextRandomInteger(); + int positiveInt = rand & 0x7FFFFFFF; + assertTrue("masked random " + positiveInt, (positiveInt >= 0)); + int index = (rand >> (32 - BIN_SHIFTER)) & BIN_MASK; + bins[index] += 1; + } + checkDistribution(scaler); + } + + public void test01Distribution() { + int scaler = 10; + for (int i = 0; i < (bins.length * scaler); i++) { + double rand = pseudoRandom.random(); + assertTrue("not too low, #" + i + " = " + rand, (rand >= 0.0)); + assertTrue("not too high, #" + i + " = " + rand, (rand < 1.0)); + int index = (int) (rand * BIN_COUNT); + bins[index] += 1; + } + checkDistribution(scaler); + } + + private void checkDistribution(int scaler) { + // Generate running average that should stay near scaler + double average = scaler; + double coefficient = 0.9; + for (int i = 0; i < (bins.length); i++) { + average = (average * coefficient) + (bins[i] * (1.0 - coefficient)); + assertEquals("average at " + i, scaler, average, 0.2 * scaler); + } + } +} |