/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.commons.math3.random; import java.net.URL; import java.util.Arrays; import org.apache.commons.math3.RetryRunner; import org.apache.commons.math3.exception.MathIllegalStateException; import org.apache.commons.math3.exception.ZeroException; import org.apache.commons.math3.stat.descriptive.SummaryStatistics; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; /** * Test cases for the ValueServer class. * */ @RunWith(RetryRunner.class) public final class ValueServerTest { private ValueServer vs = new ValueServer(new Well19937c(100)); @Before public void setUp() { vs.setMode(ValueServer.DIGEST_MODE); URL url = getClass().getResource("testData.txt"); vs.setValuesFileURL(url); } /** * Generate 1000 random values and make sure they look OK.<br> * Note that there is a non-zero (but very small) probability that * these tests will fail even if the code is working as designed. */ @Test public void testNextDigest() throws Exception { double next = 0.0; double tolerance = 0.1; vs.computeDistribution(); Assert.assertTrue("empirical distribution property", vs.getEmpiricalDistribution() != null); SummaryStatistics stats = new SummaryStatistics(); for (int i = 1; i < 1000; i++) { next = vs.getNext(); stats.addValue(next); } Assert.assertEquals("mean", 5.069831575018909, stats.getMean(), tolerance); Assert.assertEquals("std dev", 1.0173699343977738, stats.getStandardDeviation(), tolerance); vs.computeDistribution(500); stats = new SummaryStatistics(); for (int i = 1; i < 1000; i++) { next = vs.getNext(); stats.addValue(next); } Assert.assertEquals("mean", 5.069831575018909, stats.getMean(), tolerance); Assert.assertEquals("std dev", 1.0173699343977738, stats.getStandardDeviation(), tolerance); } /** * Verify that when provided with fixed seeds, stochastic modes * generate fixed sequences. Verifies the fix for MATH-654. */ @Test public void testFixedSeed() throws Exception { ValueServer valueServer = new ValueServer(); URL url = getClass().getResource("testData.txt"); valueServer.setValuesFileURL(url); valueServer.computeDistribution(); checkFixedSeed(valueServer, ValueServer.DIGEST_MODE); checkFixedSeed(valueServer, ValueServer.EXPONENTIAL_MODE); checkFixedSeed(valueServer, ValueServer.GAUSSIAN_MODE); checkFixedSeed(valueServer, ValueServer.UNIFORM_MODE); } /** * Do the check for {@link #testFixedSeed()} * @param mode ValueServer mode */ private void checkFixedSeed(ValueServer valueServer, int mode) throws Exception { valueServer.reSeed(1000); valueServer.setMode(mode); double[][] values = new double[2][100]; for (int i = 0; i < 100; i++) { values[0][i] = valueServer.getNext(); } valueServer.reSeed(1000); for (int i = 0; i < 100; i++) { values[1][i] = valueServer.getNext(); } Assert.assertTrue(Arrays.equals(values[0], values[1])); } /** * Make sure exception thrown if digest getNext is attempted * before loading empiricalDistribution. */ @Test public void testNextDigestFail() throws Exception { try { vs.getNext(); Assert.fail("Expecting IllegalStateException"); } catch (IllegalStateException ex) {} } @Test public void testEmptyReplayFile() throws Exception { try { URL url = getClass().getResource("emptyFile.txt"); vs.setMode(ValueServer.REPLAY_MODE); vs.setValuesFileURL(url); vs.getNext(); Assert.fail("an exception should have been thrown"); } catch (MathIllegalStateException mise) { // expected behavior } } @Test public void testEmptyDigestFile() throws Exception { try { URL url = getClass().getResource("emptyFile.txt"); vs.setMode(ValueServer.DIGEST_MODE); vs.setValuesFileURL(url); vs.computeDistribution(); Assert.fail("an exception should have been thrown"); } catch (ZeroException ze) { // expected behavior } } /** * Test ValueServer REPLAY_MODE using values in testData file.<br> * Check that the values 1,2,1001,1002 match data file values 1 and 2. * the sample data file. */ @Test public void testReplay() throws Exception { double firstDataValue = 4.038625496201205; double secondDataValue = 3.6485326248346936; double tolerance = 10E-15; double compareValue = 0.0d; vs.setMode(ValueServer.REPLAY_MODE); vs.resetReplayFile(); compareValue = vs.getNext(); Assert.assertEquals(compareValue,firstDataValue,tolerance); compareValue = vs.getNext(); Assert.assertEquals(compareValue,secondDataValue,tolerance); for (int i = 3; i < 1001; i++) { compareValue = vs.getNext(); } compareValue = vs.getNext(); Assert.assertEquals(compareValue,firstDataValue,tolerance); compareValue = vs.getNext(); Assert.assertEquals(compareValue,secondDataValue,tolerance); vs.closeReplayFile(); // make sure no NPE vs.closeReplayFile(); } /** * Test other ValueServer modes */ @Test public void testModes() throws Exception { vs.setMode(ValueServer.CONSTANT_MODE); vs.setMu(0); Assert.assertEquals("constant mode test",vs.getMu(),vs.getNext(),Double.MIN_VALUE); vs.setMode(ValueServer.UNIFORM_MODE); vs.setMu(2); double val = vs.getNext(); Assert.assertTrue(val > 0 && val < 4); vs.setSigma(1); vs.setMode(ValueServer.GAUSSIAN_MODE); val = vs.getNext(); Assert.assertTrue("gaussian value close enough to mean", val < vs.getMu() + 100*vs.getSigma()); vs.setMode(ValueServer.EXPONENTIAL_MODE); val = vs.getNext(); Assert.assertTrue(val > 0); try { vs.setMode(1000); vs.getNext(); Assert.fail("bad mode, expecting IllegalStateException"); } catch (IllegalStateException ex) { // ignored } } /** * Test fill */ @Test public void testFill() throws Exception { vs.setMode(ValueServer.CONSTANT_MODE); vs.setMu(2); double[] val = new double[5]; vs.fill(val); for (int i = 0; i < 5; i++) { Assert.assertEquals("fill test in place",2,val[i],Double.MIN_VALUE); } double v2[] = vs.fill(3); for (int i = 0; i < 3; i++) { Assert.assertEquals("fill test in place",2,v2[i],Double.MIN_VALUE); } } /** * Test getters to make Clover happy */ @Test public void testProperties() throws Exception { vs.setMode(ValueServer.CONSTANT_MODE); Assert.assertEquals("mode test",ValueServer.CONSTANT_MODE,vs.getMode()); vs.setValuesFileURL("http://www.apache.org"); URL url = vs.getValuesFileURL(); Assert.assertEquals("valuesFileURL test","http://www.apache.org",url.toString()); } }