From e4914557372fc1c166a34027d79c94e054b3ed9e Mon Sep 17 00:00:00 2001
From: Gilles
Date: Thu, 19 May 2016 18:32:08 +0200
Subject: [PATCH] MATH-1346
Class removed: similar functionality is available from "EmpiricalDistribution",
"RandomUtils.DataGenerator" and classes in package "o.a.c.m.distribution".
---
.../commons/math4/random/ValueServer.java | 445 ------------------
.../commons/math4/random/ValueServerTest.java | 242 ----------
2 files changed, 687 deletions(-)
delete mode 100644 src/main/java/org/apache/commons/math4/random/ValueServer.java
delete mode 100644 src/test/java/org/apache/commons/math4/random/ValueServerTest.java
diff --git a/src/main/java/org/apache/commons/math4/random/ValueServer.java b/src/main/java/org/apache/commons/math4/random/ValueServer.java
deleted file mode 100644
index 9e32035e7..000000000
--- a/src/main/java/org/apache/commons/math4/random/ValueServer.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * 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.math4.random;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.apache.commons.math4.exception.MathIllegalArgumentException;
-import org.apache.commons.math4.exception.MathIllegalStateException;
-import org.apache.commons.math4.exception.NullArgumentException;
-import org.apache.commons.math4.exception.ZeroException;
-import org.apache.commons.math4.exception.util.LocalizedFormats;
-
-/**
- * Generates values for use in simulation applications.
- *
- * How values are generated is determined by the mode
- * property.
- *
- * Supported mode
values are:
- * - DIGEST_MODE -- uses an empirical distribution
- * - REPLAY_MODE -- replays data from
valuesFileURL
- * - UNIFORM_MODE -- generates uniformly distributed random values with
- * mean =
mu
- * - EXPONENTIAL_MODE -- generates exponentially distributed random values
- * with mean =
mu
- * - GAUSSIAN_MODE -- generates Gaussian distributed random values with
- * mean =
mu
and
- * standard deviation = sigma
- * - CONSTANT_MODE -- returns
mu
every time.
- *
- *
- */
-public class ValueServer {
-
- /** Use empirical distribution. */
- public static final int DIGEST_MODE = 0;
-
- /** Replay data from valuesFilePath. */
- public static final int REPLAY_MODE = 1;
-
- /** Uniform random deviates with mean = μ. */
- public static final int UNIFORM_MODE = 2;
-
- /** Exponential random deviates with mean = μ. */
- public static final int EXPONENTIAL_MODE = 3;
-
- /** Gaussian random deviates with mean = μ, std dev = σ. */
- public static final int GAUSSIAN_MODE = 4;
-
- /** Always return mu */
- public static final int CONSTANT_MODE = 5;
-
- /** mode determines how values are generated. */
- private int mode = 5;
-
- /** URI to raw data values. */
- private URL valuesFileURL = null;
-
- /** Mean for use with non-data-driven modes. */
- private double mu = 0.0;
-
- /** Standard deviation for use with GAUSSIAN_MODE. */
- private double sigma = 0.0;
-
- /** Empirical probability distribution for use with DIGEST_MODE. */
- private EmpiricalDistribution empiricalDistribution = null;
-
- /** File pointer for REPLAY_MODE. */
- private BufferedReader filePointer = null;
-
- /** RandomDataImpl to use for random data generation. */
- private final RandomDataGenerator randomData;
-
- // Data generation modes ======================================
-
- /** Creates new ValueServer */
- public ValueServer() {
- randomData = new RandomDataGenerator();
- }
-
- /**
- * Construct a ValueServer instance using a RandomGenerator as its source
- * of random data.
- *
- * @since 3.1
- * @param generator source of random data
- */
- public ValueServer(RandomGenerator generator) {
- this.randomData = new RandomDataGenerator(generator);
- }
-
- /**
- * Returns the next generated value, generated according
- * to the mode value (see MODE constants).
- *
- * @return generated value
- * @throws IOException in REPLAY_MODE if a file I/O error occurs
- * @throws MathIllegalStateException if mode is not recognized
- * @throws MathIllegalArgumentException if the underlying random generator thwrows one
- */
- public double getNext() throws IOException, MathIllegalStateException, MathIllegalArgumentException {
- switch (mode) {
- case DIGEST_MODE: return getNextDigest();
- case REPLAY_MODE: return getNextReplay();
- case UNIFORM_MODE: return getNextUniform();
- case EXPONENTIAL_MODE: return getNextExponential();
- case GAUSSIAN_MODE: return getNextGaussian();
- case CONSTANT_MODE: return mu;
- default: throw new MathIllegalStateException(
- LocalizedFormats.UNKNOWN_MODE,
- mode,
- "DIGEST_MODE", DIGEST_MODE, "REPLAY_MODE", REPLAY_MODE,
- "UNIFORM_MODE", UNIFORM_MODE, "EXPONENTIAL_MODE", EXPONENTIAL_MODE,
- "GAUSSIAN_MODE", GAUSSIAN_MODE, "CONSTANT_MODE", CONSTANT_MODE);
- }
- }
-
- /**
- * Fills the input array with values generated using getNext() repeatedly.
- *
- * @param values array to be filled
- * @throws IOException in REPLAY_MODE if a file I/O error occurs
- * @throws MathIllegalStateException if mode is not recognized
- * @throws MathIllegalArgumentException if the underlying random generator thwrows one
- */
- public void fill(double[] values)
- throws IOException, MathIllegalStateException, MathIllegalArgumentException {
- for (int i = 0; i < values.length; i++) {
- values[i] = getNext();
- }
- }
-
- /**
- * Returns an array of length length
with values generated
- * using getNext() repeatedly.
- *
- * @param length length of output array
- * @return array of generated values
- * @throws IOException in REPLAY_MODE if a file I/O error occurs
- * @throws MathIllegalStateException if mode is not recognized
- * @throws MathIllegalArgumentException if the underlying random generator thwrows one
- */
- public double[] fill(int length)
- throws IOException, MathIllegalStateException, MathIllegalArgumentException {
- double[] out = new double[length];
- for (int i = 0; i < length; i++) {
- out[i] = getNext();
- }
- return out;
- }
-
- /**
- * Computes the empirical distribution using values from the file
- * in valuesFileURL
, using the default number of bins.
- *
- * valuesFileURL
must exist and be
- * readable by *this at runtime.
- *
- * This method must be called before using getNext()
- * with mode = DIGEST_MODE
- *
- * @throws IOException if an I/O error occurs reading the input file
- * @throws NullArgumentException if the {@code valuesFileURL} has not been set
- * @throws ZeroException if URL contains no data
- */
- public void computeDistribution() throws IOException, ZeroException, NullArgumentException {
- computeDistribution(EmpiricalDistribution.DEFAULT_BIN_COUNT);
- }
-
- /**
- * Computes the empirical distribution using values from the file
- * in valuesFileURL
and binCount
bins.
- *
- * valuesFileURL
must exist and be readable by this process
- * at runtime.
- *
- * This method must be called before using getNext()
- * with mode = DIGEST_MODE
- *
- * @param binCount the number of bins used in computing the empirical
- * distribution
- * @throws NullArgumentException if the {@code valuesFileURL} has not been set
- * @throws IOException if an error occurs reading the input file
- * @throws ZeroException if URL contains no data
- */
- public void computeDistribution(int binCount) throws NullArgumentException, IOException, ZeroException {
- empiricalDistribution = new EmpiricalDistribution(binCount);
- empiricalDistribution.load(valuesFileURL);
- mu = empiricalDistribution.getSampleStats().getMean();
- sigma = empiricalDistribution.getSampleStats().getStandardDeviation();
- }
-
- /**
- * Returns the data generation mode. See {@link ValueServer the class javadoc}
- * for description of the valid values of this property.
- *
- * @return Value of property mode.
- */
- public int getMode() {
- return mode;
- }
-
- /**
- * Sets the data generation mode.
- *
- * @param mode New value of the data generation mode.
- */
- public void setMode(int mode) {
- this.mode = mode;
- }
-
- /**
- * Returns the URL for the file used to build the empirical distribution
- * when using {@link #DIGEST_MODE}.
- *
- * @return Values file URL.
- */
- public URL getValuesFileURL() {
- return valuesFileURL;
- }
-
- /**
- * Sets the {@link #getValuesFileURL() values file URL} using a string
- * URL representation.
- *
- * @param url String representation for new valuesFileURL.
- * @throws MalformedURLException if url is not well formed
- */
- public void setValuesFileURL(String url) throws MalformedURLException {
- this.valuesFileURL = new URL(url);
- }
-
- /**
- * Sets the the {@link #getValuesFileURL() values file URL}.
- *
- * The values file must be an ASCII text file containing one
- * valid numeric entry per line.
- *
- * @param url URL of the values file.
- */
- public void setValuesFileURL(URL url) {
- this.valuesFileURL = url;
- }
-
- /**
- * Returns the {@link EmpiricalDistribution} used when operating in {@value #DIGEST_MODE}.
- *
- * @return EmpircalDistribution built by {@link #computeDistribution()}
- */
- public EmpiricalDistribution getEmpiricalDistribution() {
- return empiricalDistribution;
- }
-
- /**
- * Resets REPLAY_MODE file pointer to the beginning of the valuesFileURL
.
- *
- * @throws IOException if an error occurs opening the file
- * @throws NullPointerException if the {@code valuesFileURL} has not been set.
- */
- public void resetReplayFile() throws IOException {
- if (filePointer != null) {
- try {
- filePointer.close();
- filePointer = null;
- } catch (IOException ex) { //NOPMD
- // ignore
- }
- }
- filePointer = new BufferedReader(new InputStreamReader(valuesFileURL.openStream(), "UTF-8"));
- }
-
- /**
- * Closes {@code valuesFileURL} after use in REPLAY_MODE.
- *
- * @throws IOException if an error occurs closing the file
- */
- public void closeReplayFile() throws IOException {
- if (filePointer != null) {
- filePointer.close();
- filePointer = null;
- }
- }
-
- /**
- * Returns the mean used when operating in {@link #GAUSSIAN_MODE}, {@link #EXPONENTIAL_MODE}
- * or {@link #UNIFORM_MODE}. When operating in {@link #CONSTANT_MODE}, this is the constant
- * value always returned. Calling {@link #computeDistribution()} sets this value to the
- * overall mean of the values in the {@link #getValuesFileURL() values file}.
- *
- * @return Mean used in data generation.
- */
- public double getMu() {
- return mu;
- }
-
- /**
- * Sets the {@link #getMu() mean} used in data generation. Note that calling this method
- * after {@link #computeDistribution()} has been called will have no effect on data
- * generated in {@link #DIGEST_MODE}.
- *
- * @param mu new Mean value.
- */
- public void setMu(double mu) {
- this.mu = mu;
- }
-
- /**
- * Returns the standard deviation used when operating in {@link #GAUSSIAN_MODE}.
- * Calling {@link #computeDistribution()} sets this value to the overall standard
- * deviation of the values in the {@link #getValuesFileURL() values file}. This
- * property has no effect when the data generation mode is not
- * {@link #GAUSSIAN_MODE}.
- *
- * @return Standard deviation used when operating in {@link #GAUSSIAN_MODE}.
- */
- public double getSigma() {
- return sigma;
- }
-
- /**
- * Sets the {@link #getSigma() standard deviation} used in {@link #GAUSSIAN_MODE}.
- *
- * @param sigma New standard deviation.
- */
- public void setSigma(double sigma) {
- this.sigma = sigma;
- }
-
- /**
- * Reseeds the random data generator.
- *
- * @param seed Value with which to reseed the {@link RandomDataGenerator}
- * used to generate random data.
- */
- public void reSeed(long seed) {
- randomData.reSeed(seed);
- }
-
- //------------- private methods ---------------------------------
-
- /**
- * Gets a random value in DIGEST_MODE.
- *
- * Preconditions:
- * - Before this method is called,
computeDistribution()
- * must have completed successfully; otherwise an
- * IllegalStateException
will be thrown
- *
- * @return next random value from the empirical distribution digest
- * @throws MathIllegalStateException if digest has not been initialized
- */
- private double getNextDigest() throws MathIllegalStateException {
- if ((empiricalDistribution == null) ||
- (empiricalDistribution.getBinStats().size() == 0)) {
- throw new MathIllegalStateException(LocalizedFormats.DIGEST_NOT_INITIALIZED);
- }
- return empiricalDistribution.createSampler(randomData.getRandomProvider()).sample();
- }
-
- /**
- * Gets next sequential value from the valuesFileURL
.
- *
- * Throws an IOException if the read fails.
- *
- * This method will open the valuesFileURL
if there is no
- * replay file open.
- *
- * The valuesFileURL
will be closed and reopened to wrap around
- * from EOF to BOF if EOF is encountered. EOFException (which is a kind of
- * IOException) may still be thrown if the valuesFileURL
is
- * empty.
- *
- * @return next value from the replay file
- * @throws IOException if there is a problem reading from the file
- * @throws MathIllegalStateException if URL contains no data
- * @throws NumberFormatException if an invalid numeric string is
- * encountered in the file
- */
- private double getNextReplay() throws IOException, MathIllegalStateException {
- String str = null;
- if (filePointer == null) {
- resetReplayFile();
- }
- if ((str = filePointer.readLine()) == null) {
- // we have probably reached end of file, wrap around from EOF to BOF
- closeReplayFile();
- resetReplayFile();
- if ((str = filePointer.readLine()) == null) {
- throw new MathIllegalStateException(LocalizedFormats.URL_CONTAINS_NO_DATA,
- valuesFileURL);
- }
- }
- return Double.parseDouble(str);
- }
-
- /**
- * Gets a uniformly distributed random value with mean = mu.
- *
- * @return random uniform value
- * @throws MathIllegalArgumentException if the underlying random generator thwrows one
- */
- private double getNextUniform() throws MathIllegalArgumentException {
- return randomData.nextUniform(0, 2 * mu);
- }
-
- /**
- * Gets an exponentially distributed random value with mean = mu.
- *
- * @return random exponential value
- * @throws MathIllegalArgumentException if the underlying random generator thwrows one
- */
- private double getNextExponential() throws MathIllegalArgumentException {
- return randomData.nextExponential(mu);
- }
-
- /**
- * Gets a Gaussian distributed random value with mean = mu
- * and standard deviation = sigma.
- *
- * @return random Gaussian value
- * @throws MathIllegalArgumentException if the underlying random generator thwrows one
- */
- private double getNextGaussian() throws MathIllegalArgumentException {
- return randomData.nextGaussian(mu, sigma);
- }
-
-}
diff --git a/src/test/java/org/apache/commons/math4/random/ValueServerTest.java b/src/test/java/org/apache/commons/math4/random/ValueServerTest.java
deleted file mode 100644
index f9c63efc1..000000000
--- a/src/test/java/org/apache/commons/math4/random/ValueServerTest.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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.math4.random;
-
-import java.net.URL;
-import java.util.Arrays;
-
-import org.apache.commons.math4.RetryRunner;
-import org.apache.commons.math4.exception.MathIllegalStateException;
-import org.apache.commons.math4.exception.ZeroException;
-import org.apache.commons.math4.random.ValueServer;
-import org.apache.commons.math4.random.Well19937c;
-import org.apache.commons.math4.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 final 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.
- * 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 MathIllegalStateException");
- } catch (MathIllegalStateException 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.
- * 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 MathIllegalStateException");
- } catch (MathIllegalStateException 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());
- }
-
-}