📄 valueserver.java
字号:
/* * 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.math.random;import java.io.BufferedReader;import java.io.EOFException;import java.io.InputStreamReader;import java.io.IOException;import java.net.URL;import java.net.MalformedURLException;/** * Generates values for use in simulation applications. * <p> * How values are generated is determined by the <code>mode</code> * property.</p> * <p> * Supported <code>mode</code> values are: <ul> * <li> DIGEST_MODE -- uses an empirical distribution </li> * <li> REPLAY_MODE -- replays data from <code>valuesFileURL</code></li> * <li> UNIFORM_MODE -- generates uniformly distributed random values with * mean = <code>mu</code> </li> * <li> EXPONENTIAL_MODE -- generates exponentially distributed random values * with mean = <code>mu</code></li> * <li> GAUSSIAN_MODE -- generates Gaussian distributed random values with * mean = <code>mu</code> and * standard deviation = <code>sigma</code></li> * <li> CONSTANT_MODE -- returns <code>mu</code> every time.</li></ul></p> * * @version $Revision: 617850 $ $Date: 2008-02-02 11:01:29 -0700 (Sat, 02 Feb 2008) $ * */public class ValueServer { /** 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 RandomData randomData = new RandomDataImpl(); // Data generation modes ====================================== /** 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 = mu */ public static final int UNIFORM_MODE = 2; /** Exponential random deviates with mean = mu */ public static final int EXPONENTIAL_MODE = 3; /** Gaussian random deviates with mean = mu, std dev = sigma */ public static final int GAUSSIAN_MODE = 4; /** Always return mu */ public static final int CONSTANT_MODE = 5; /** Creates new ValueServer */ public ValueServer() { } /** * 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 */ public double getNext() throws IOException { 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 IllegalStateException ("Bad mode: " + 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 */ public void fill(double[] values) throws IOException { for (int i = 0; i < values.length; i++) { values[i] = getNext(); } } /** * Returns an array of length <code>length</code> 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 */ public double[] fill(int length) throws IOException { 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 <code>valuesFileURL</code>, using the default number of bins. * <p> * <code>valuesFileURL</code> must exist and be * readable by *this at runtime.</p> * <p> * This method must be called before using <code>getNext()</code> * with <code>mode = DIGEST_MODE</code></p> * * @throws IOException if an I/O error occurs reading the input file */ public void computeDistribution() throws IOException { empiricalDistribution = new EmpiricalDistributionImpl(); empiricalDistribution.load(valuesFileURL); } /** * Computes the empirical distribution using values from the file * in <code>valuesFileURL</code> and <code>binCount</code> bins. * <p> * <code>valuesFileURL</code> must exist and be readable by this process * at runtime.</p> * <p> * This method must be called before using <code>getNext()</code> * with <code>mode = DIGEST_MODE</code></p> * * @param binCount the number of bins used in computing the empirical * distribution * @throws IOException if an error occurs reading the input file */ public void computeDistribution(int binCount) throws IOException { empiricalDistribution = new EmpiricalDistributionImpl(binCount); empiricalDistribution.load(valuesFileURL); mu = empiricalDistribution.getSampleStats().getMean(); sigma = empiricalDistribution.getSampleStats().getStandardDeviation(); } /** Getter for property mode. * @return Value of property mode. */ public int getMode() { return mode; } /** Setter for property mode. * @param mode New value of property mode. */ public void setMode(int mode) { this.mode = mode; } /** * Getter for <code>valuesFileURL<code> * @return Value of property valuesFileURL. */ public URL getValuesFileURL() { return valuesFileURL; } /** * Sets the <code>valuesFileURL</code> 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 <code>valuesFileURL</code> * @param url New value of property valuesFileURL. */ public void setValuesFileURL(URL url) { this.valuesFileURL = url; } /** Getter for property empiricalDistribution. * @return Value of property empiricalDistribution. */ public EmpiricalDistribution getEmpiricalDistribution() { return empiricalDistribution; } /** * Resets REPLAY_MODE file pointer to the beginning of the <code>valuesFileURL</code>. * * @throws IOException if an error occurs opening the file */ public void resetReplayFile() throws IOException { if (filePointer != null) { try { filePointer.close(); filePointer = null; } catch (IOException ex) { // ignore } } filePointer = new BufferedReader(new InputStreamReader(valuesFileURL.openStream())); } /** * Closes <code>valuesFileURL</code> 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; } } /** Getter for property mu. * @return Value of property mu. */ public double getMu() { return mu; } /** Setter for property mu. * @param mu New value of property mu. */ public void setMu(double mu) { this.mu = mu; } /** Getter for property sigma. * @return Value of property sigma. */ public double getSigma() { return sigma; } /** Setter for property sigma. * @param sigma New value of property sigma. */ public void setSigma(double sigma) { this.sigma = sigma; } //------------- private methods --------------------------------- /** * Gets a random value in DIGEST_MODE. * <p> * <strong>Preconditions</strong>: <ul> * <li>Before this method is called, <code>computeDistribution()</code> * must have completed successfully; otherwise an * <code>IllegalStateException</code> will be thrown</li></ul></p> * * @return next random value from the empirical distribution digest */ private double getNextDigest() { if ((empiricalDistribution == null) || (empiricalDistribution.getBinStats().size() == 0)) { throw new IllegalStateException("Digest not initialized"); } return empiricalDistribution.getNextValue(); } /** * Gets next sequential value from the <code>valuesFileURL</code>. * <p> * Throws an IOException if the read fails.</p> * <p> * This method will open the <code>valuesFileURL</code> if there is no * replay file open.</p> * <p> * The <code>valuesFileURL</code> 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 <code>valuesFileURL</code> is * empty.</p> * * @return next value from the replay file * @throws IOException if there is a problem reading from the file * @throws NumberFormatException if an invalid numeric string is * encountered in the file */ private double getNextReplay() throws IOException { 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 EOFException("URL " + valuesFileURL + " contains no data"); } } return Double.valueOf(str).doubleValue(); } /** * Gets a uniformly distributed random value with mean = mu. * * @return random uniform value */ private double getNextUniform() { return randomData.nextUniform(0, 2 * mu); } /** * Gets an exponentially distributed random value with mean = mu. * * @return random exponential value */ private double getNextExponential() { return randomData.nextExponential(mu); } /** * Gets a Gaussian distributed random value with mean = mu * and standard deviation = sigma. * * @return random Gaussian value */ private double getNextGaussian() { return randomData.nextGaussian(mu, sigma); } /** * Construct a ValueServer instance using a RandomData as its source * of random data. * * @param randomData the RandomData instance used to source random data * @since 1.1 */ public ValueServer(RandomData randomData) { super(); this.randomData = randomData; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -