KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > math > random > ValueServer


1 /*
2  * Copyright 2003-2004 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
17 package org.apache.commons.math.random;
18 import java.io.BufferedReader JavaDoc;
19 import java.io.InputStreamReader JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.net.URL JavaDoc;
22 import java.net.MalformedURLException JavaDoc;
23
24 /**
25  * Generates values for use in simulation applications.
26  * <p>
27  * How values are generated is determined by the <code>mode</code>
28  * property.
29  * <p>
30  * Supported <code>mode</code> values are: <ul>
31  * <li> DIGEST_MODE -- uses an empirical distribution </li>
32  * <li> REPLAY_MODE -- replays data from <code>valuesFileURL</code></li>
33  * <li> UNIFORM_MODE -- generates uniformly distributed random values with
34  * mean = <code>mu</code> </li>
35  * <li> EXPONENTIAL_MODE -- generates exponentially distributed random values
36  * with mean = <code>mu</code></li>
37  * <li> GAUSSIAN_MODE -- generates Gaussian distributed random values with
38  * mean = <code>mu</code> and
39  * standard deviation = <code>sigma</code></li>
40  * <li> CONSTANT_MODE -- returns <code>mu</code> every time.</li></ul>
41  *
42  * @version $Revision$ $Date: 2005-05-21 22:25:44 -0700 (Sat, 21 May 2005) $
43  *
44  */

45 public class ValueServer {
46     /** mode determines how values are generated */
47     private int mode = 5;
48
49     /** URI to raw data values */
50     private URL JavaDoc valuesFileURL = null;
51
52     /** Mean for use with non-data-driven modes */
53     private double mu = 0.0;
54
55     /** Standard deviation for use with GAUSSIAN_MODE */
56     private double sigma = 0.0;
57
58     /** Empirical probability distribution for use with DIGEST_MODE */
59     private EmpiricalDistribution empiricalDistribution = null;
60
61     /** file pointer for REPLAY_MODE */
62     private BufferedReader JavaDoc filePointer = null;
63
64     /** RandomDataImpl to use for random data generation */
65     private RandomData randomData = new RandomDataImpl();
66
67     // Data generation modes ======================================
68

69     /** Use empirical distribution */
70     public static final int DIGEST_MODE = 0;
71
72     /** Replay data from valuesFilePath */
73     public static final int REPLAY_MODE = 1;
74
75     /** Uniform random deviates with mean = mu */
76     public static final int UNIFORM_MODE = 2;
77
78     /** Exponential random deviates with mean = mu */
79     public static final int EXPONENTIAL_MODE = 3;
80
81     /** Gaussian random deviates with mean = mu, std dev = sigma */
82     public static final int GAUSSIAN_MODE = 4;
83
84     /** Always return mu */
85     public static final int CONSTANT_MODE = 5;
86
87     /** Creates new ValueServer */
88     public ValueServer() {
89     }
90
91     /**
92      * Returns the next generated value, generated according
93      * to the mode value (see MODE constants).
94      *
95      * @return generated value
96      * @throws IOException in REPLAY_MODE if a file I/O error occurs
97      */

98     public double getNext() throws IOException JavaDoc {
99         switch (mode) {
100             case DIGEST_MODE: return getNextDigest();
101             case REPLAY_MODE: return getNextReplay();
102             case UNIFORM_MODE: return getNextUniform();
103             case EXPONENTIAL_MODE: return getNextExponential();
104             case GAUSSIAN_MODE: return getNextGaussian();
105             case CONSTANT_MODE: return mu;
106             default: throw new IllegalStateException JavaDoc
107                        ("Bad mode: " + mode);
108         }
109     }
110
111     /**
112      * Fills the input array with values generated using getNext() repeatedly.
113      *
114      * @param values array to be filled
115      * @throws IOException in REPLAY_MODE if a file I/O error occurs
116      */

117     public void fill(double[] values) throws IOException JavaDoc {
118         for (int i = 0; i < values.length; i++) {
119             values[i] = getNext();
120         }
121     }
122
123     /**
124      * Returns an array of length <code>length</code> with values generated
125      * using getNext() repeatedly.
126      *
127      * @param length length of output array
128      * @return array of generated values
129      * @throws IOException in REPLAY_MODE if a file I/O error occurs
130      */

131     public double[] fill(int length) throws IOException JavaDoc {
132         double[] out = new double[length];
133         for (int i = 0; i < length; i++) {
134             out[i] = getNext();
135         }
136         return out;
137     }
138
139     /**
140      * Computes the empirical distribution using values from the file
141      * in <code>valuesFileURL</code>, using the default number of bins.
142      * <p>
143      * <code>valuesFileURL</code> must exist and be
144      * readable by *this at runtime.
145      * <p>
146      * This method must be called before using <code>getNext()</code>
147      * with <code>mode = DISGEST_MODE</code>
148      *
149      * @throws IOException if an I/O error occurs reading the input file
150      */

151     public void computeDistribution() throws IOException JavaDoc {
152         empiricalDistribution = new EmpiricalDistributionImpl();
153         empiricalDistribution.load(valuesFileURL);
154     }
155
156     /**
157      * Computes the empirical distribution using values from the file
158      * in <code>valuesFileURL</code> and <code>binCount</code> bins.
159      * <p>
160      * <code>valuesFileURL</code> must exist and be
161      * readable by *this at runtime.
162      * <p>
163      * This method must be called before using <code>getNext()</code>
164      * with <code>mode = DISGEST_MODE</code>
165      *
166      * @param binCount the number of bins used in computing the empirical
167      * distribution
168      * @throws IOException if an error occurs reading the input file
169      */

170     public void computeDistribution(int binCount)
171             throws IOException JavaDoc {
172         empiricalDistribution = new EmpiricalDistributionImpl(binCount);
173         empiricalDistribution.load(valuesFileURL);
174         mu = empiricalDistribution.getSampleStats().getMean();
175         sigma = empiricalDistribution.getSampleStats().getStandardDeviation();
176     }
177
178     /** Getter for property mode.
179      * @return Value of property mode.
180      */

181     public int getMode() {
182         return mode;
183     }
184
185     /** Setter for property mode.
186      * @param mode New value of property mode.
187      */

188     public void setMode(int mode) {
189         this.mode = mode;
190     }
191
192     /**
193      * Getter for <code>valuesFileURL<code>
194      * @return Value of property valuesFileURL.
195      */

196     public URL JavaDoc getValuesFileURL() {
197         return valuesFileURL;
198     }
199
200     /**
201      * Sets the <code>valuesFileURL</code> using a string URL representation
202      * @param url String representation for new valuesFileURL.
203      * @throws MalformedURLException if url is not well formed
204      */

205     public void setValuesFileURL(String JavaDoc url) throws MalformedURLException JavaDoc {
206         this.valuesFileURL = new URL JavaDoc(url);
207     }
208
209     /**
210      * Sets the <code>valuesFileURL</code>
211      * @param url New value of property valuesFileURL.
212      */

213     public void setValuesFileURL(URL JavaDoc url) {
214         this.valuesFileURL = url;
215     }
216
217     /** Getter for property empiricalDistribution.
218      * @return Value of property empiricalDistribution.
219      */

220     public EmpiricalDistribution getEmpiricalDistribution() {
221         return empiricalDistribution;
222     }
223
224     /**
225      * Resets REPLAY_MODE file pointer to the beginning of the <code>valuesFileURL</code>.
226      *
227      * @throws IOException if an error occurs opening the file
228      */

229     public void resetReplayFile() throws IOException JavaDoc {
230         if (filePointer != null) {
231             try {
232                 filePointer.close();
233                 filePointer = null;
234             } catch (IOException JavaDoc ex) {
235                 // ignore
236
}
237         }
238         filePointer = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(valuesFileURL.openStream()));
239     }
240
241     /**
242      * Closes <code>valuesFileURL</code> after use in REPLAY_MODE.
243      *
244      * @throws IOException if an error occurs closing the file
245      */

246     public void closeReplayFile() throws IOException JavaDoc {
247         if (filePointer != null) {
248             filePointer.close();
249             filePointer = null;
250         }
251     }
252
253     /** Getter for property mu.
254      * @return Value of property mu.
255      */

256     public double getMu() {
257         return mu;
258     }
259
260     /** Setter for property mu.
261      * @param mu New value of property mu.
262      */

263     public void setMu(double mu) {
264         this.mu = mu;
265     }
266
267     /** Getter for property sigma.
268      * @return Value of property sigma.
269      */

270     public double getSigma() {
271         return sigma;
272     }
273
274     /** Setter for property sigma.
275      * @param sigma New value of property sigma.
276      */

277     public void setSigma(double sigma) {
278         this.sigma = sigma;
279     }
280
281     //------------- private methods ---------------------------------
282

283     /**
284      * Gets a random value in DIGEST_MODE.
285      * <p>
286      * <strong>Preconditions</strong>: <ul>
287      * <li>Before this method is called, <code>computeDistribution()</code>
288      * must have completed successfully; otherwise an
289      * <code>IllegalStateException</code> will be thrown</li></ul>
290      *
291      * @return next random value from the empirical distribution digest
292      */

293     private double getNextDigest() {
294         if ((empiricalDistribution == null) ||
295             (empiricalDistribution.getBinStats().size() == 0)) {
296             throw new IllegalStateException JavaDoc("Digest not initialized");
297         }
298         return empiricalDistribution.getNextValue();
299     }
300
301     /**
302      * Gets next sequential value from the <code>valuesFileURL</code>.
303      * <p>
304      * Throws an IOException if the read fails.
305      * <p>
306      * This method will open the <code>valuesFileURL</code> if there is no
307      * replay file open.
308      * <p>
309      * The <code>valuesFileURL</code> will be closed and reopened to wrap around
310      * from EOF to BOF if EOF is encountered.
311      *
312      * @return next value from the replay file
313      * @throws IOException if there is a problem reading from the file
314      */

315     private double getNextReplay() throws IOException JavaDoc {
316         String JavaDoc str = null;
317         if (filePointer == null) {
318             resetReplayFile();
319         }
320         if ((str = filePointer.readLine()) == null) {
321             closeReplayFile();
322             resetReplayFile();
323             str = filePointer.readLine();
324         }
325         return new Double JavaDoc(str).doubleValue();
326     }
327
328     /**
329      * Gets a uniformly distributed random value with mean = mu.
330      *
331      * @return random uniform value
332      */

333     private double getNextUniform() {
334         return randomData.nextUniform(0, 2 * mu);
335     }
336
337     /**
338      * Gets an exponentially distributed random value with mean = mu.
339      *
340      * @return random exponential value
341      */

342     private double getNextExponential() {
343         return randomData.nextExponential(mu);
344     }
345
346     /**
347      * Gets a Gaussian distributed random value with mean = mu
348      * and standard deviation = sigma.
349      *
350      * @return random Gaussian value
351      */

352     private double getNextGaussian() {
353         return randomData.nextGaussian(mu, sigma);
354     }
355
356     /**
357      * Construct a ValueServer instance using a RandomData as its source
358      * of random data.
359      *
360      * @param randomData the RandomData instance used to source random data
361      * @since 1.1
362      */

363     public ValueServer(RandomData randomData) {
364         super();
365         this.randomData = randomData;
366     }
367 }
368
Popular Tags