001: /*
002: * Copyright 2005 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.math.random;
017:
018: /**
019: * Abstract class implementing the {@link RandomGenerator} interface.
020: * Default implementations for all methods other than {@link #nextDouble()} and
021: * {@link #setSeed(long)} are provided.
022: * <p>
023: * All data generation methods are based on <code>nextDouble().</code>
024: * Concrete implementations <strong>must</strong> override
025: * this method and <strong>should</strong> provide better / more
026: * performant implementations of the other methods if the underlying PRNG
027: * supplies them.
028: *
029: * @since 1.1
030: * @version $Revision: 209144 $ $Date: 2005-07-04 16:30:05 -0700 (Mon, 04 Jul 2005) $
031: */
032: public abstract class AbstractRandomGenerator implements
033: RandomGenerator {
034:
035: /**
036: * Cached random normal value. The default implementation for
037: * {@link #nextGaussian} generates pairs of values and this field caches the
038: * second value so that the full algorithm is not executed for every
039: * activation. The value <code>Double.NaN</code> signals that there is
040: * no cached value. Use {@link #clear} to clear the cached value.
041: */
042: private double cachedNormalDeviate = Double.NaN;
043:
044: /**
045: * Construct a RandomGenerator.
046: */
047: public AbstractRandomGenerator() {
048: super ();
049:
050: }
051:
052: /**
053: * Clears the cache used by the default implementation of
054: * {@link #nextGaussian}. Implemementations that do not override the
055: * default implementation of <code>nextGaussian</code> should call this
056: * method in the implementation of {@link #setSeed(long)}
057: */
058: public void clear() {
059: cachedNormalDeviate = Double.NaN;
060: }
061:
062: /**
063: * Sets the seed of the underyling random number generator using a
064: * <code>long</code> seed. Sequences of values generated starting with the
065: * same seeds should be identical.
066: * <p>
067: * Implementations that do not override the default implementation of
068: * <code>nextGaussian</code> should include a call to {@link #clear} in the
069: * implementation of this method.
070: *
071: * @param seed the seed value
072: */
073: public abstract void setSeed(long seed);
074:
075: /**
076: * Generates random bytes and places them into a user-supplied
077: * byte array. The number of random bytes produced is equal to
078: * the length of the byte array.
079: * <p>
080: * The default implementation fills the array with bytes extracted from
081: * random integers generated using {@link #nextInt}.
082: *
083: * @param bytes the non-null byte array in which to put the
084: * random bytes
085: */
086: public void nextBytes(byte[] bytes) {
087: int bytesOut = 0;
088: while (bytesOut < bytes.length) {
089: int randInt = nextInt();
090: for (int i = 0; i < 3; i++) {
091: if (i > 0) {
092: randInt = randInt >> 8;
093: }
094: bytes[bytesOut++] = (byte) randInt;
095: if (bytesOut == bytes.length) {
096: return;
097: }
098: }
099: }
100: }
101:
102: /**
103: * Returns the next pseudorandom, uniformly distributed <code>int</code>
104: * value from this random number generator's sequence.
105: * All 2<font size="-1"><sup>32</sup></font> possible <tt>int</tt> values
106: * should be produced with (approximately) equal probability.
107: * <p>
108: * The default implementation provided here returns
109: * <pre>
110: * <code>(int) (nextDouble() * Integer.MAX_VALUE)</code>
111: * </pre>
112: *
113: * @return the next pseudorandom, uniformly distributed <code>int</code>
114: * value from this random number generator's sequence
115: */
116: public int nextInt() {
117: return (int) (nextDouble() * Integer.MAX_VALUE);
118: }
119:
120: /**
121: * Returns a pseudorandom, uniformly distributed <tt>int</tt> value
122: * between 0 (inclusive) and the specified value (exclusive), drawn from
123: * this random number generator's sequence.
124: * <p>
125: * The default implementation returns
126: * <pre>
127: * <code>(int) (nextDouble() * n</code>
128: * </pre>
129: *
130: * @param n the bound on the random number to be returned. Must be
131: * positive.
132: * @return a pseudorandom, uniformly distributed <tt>int</tt>
133: * value between 0 (inclusive) and n (exclusive).
134: * @throws IllegalArgumentException if n is not positive.
135: */
136: public int nextInt(int n) {
137: if (n <= 0) {
138: throw new IllegalArgumentException(
139: "upper bound must be positive");
140: }
141: int result = (int) (nextDouble() * n);
142: return result < n ? result : n - 1;
143: }
144:
145: /**
146: * Returns the next pseudorandom, uniformly distributed <code>long</code>
147: * value from this random number generator's sequence. All
148: * 2<font size="-1"><sup>64</sup></font> possible <tt>long</tt> values
149: * should be produced with (approximately) equal probability.
150: * <p>
151: * The default implementation returns
152: * <pre>
153: * <code>(long) (nextDouble() * Long.MAX_VALUE)</code>
154: * </pre>
155: *
156: * @return the next pseudorandom, uniformly distributed <code>long</code>
157: *value from this random number generator's sequence
158: */
159: public long nextLong() {
160: return (long) (nextDouble() * Long.MAX_VALUE);
161: }
162:
163: /**
164: * Returns the next pseudorandom, uniformly distributed
165: * <code>boolean</code> value from this random number generator's
166: * sequence.
167: * <p>
168: * The default implementation returns
169: * <pre>
170: * <code>nextDouble() <= 0.5</code>
171: * </pre>
172: *
173: * @return the next pseudorandom, uniformly distributed
174: * <code>boolean</code> value from this random number generator's
175: * sequence
176: */
177: public boolean nextBoolean() {
178: return nextDouble() <= 0.5;
179: }
180:
181: /**
182: * Returns the next pseudorandom, uniformly distributed <code>float</code>
183: * value between <code>0.0</code> and <code>1.0</code> from this random
184: * number generator's sequence.
185: * <p>
186: * The default implementation returns
187: * <pre>
188: * <code>(float) nextDouble() </code>
189: * </pre>
190: *
191: * @return the next pseudorandom, uniformly distributed <code>float</code>
192: * value between <code>0.0</code> and <code>1.0</code> from this
193: * random number generator's sequence
194: */
195: public float nextFloat() {
196: return (float) nextDouble();
197: }
198:
199: /**
200: * Returns the next pseudorandom, uniformly distributed
201: * <code>double</code> value between <code>0.0</code> and
202: * <code>1.0</code> from this random number generator's sequence.
203: * <p>
204: * This method provides the underlying source of random data used by the
205: * other methods.
206: *
207: * @return the next pseudorandom, uniformly distributed
208: * <code>double</code> value between <code>0.0</code> and
209: * <code>1.0</code> from this random number generator's sequence
210: */
211: public abstract double nextDouble();
212:
213: /**
214: * Returns the next pseudorandom, Gaussian ("normally") distributed
215: * <code>double</code> value with mean <code>0.0</code> and standard
216: * deviation <code>1.0</code> from this random number generator's sequence.
217: * <p>
218: * The default implementation uses the <em>Polar Method</em>
219: * due to G.E.P. Box, M.E. Muller and G. Marsaglia, as described in
220: * D. Knuth, <u>The Art of Computer Programming</u>, 3.4.1C.
221: * <p>
222: * The algorithm generates a pair of independent random values. One of
223: * these is cached for reuse, so the full algorithm is not executed on each
224: * activation. Implementations that do not override this method should
225: * make sure to call {@link #clear} to clear the cached value in the
226: * implementation of {@link #setSeed(long)}.
227: *
228: * @return the next pseudorandom, Gaussian ("normally") distributed
229: * <code>double</code> value with mean <code>0.0</code> and
230: * standard deviation <code>1.0</code> from this random number
231: * generator's sequence
232: */
233: public double nextGaussian() {
234: if (!Double.isNaN(cachedNormalDeviate)) {
235: double dev = cachedNormalDeviate;
236: cachedNormalDeviate = Double.NaN;
237: return dev;
238: }
239: double v1 = 0;
240: double v2 = 0;
241: double s = 1;
242: while (s >= 1) {
243: v1 = 2 * nextDouble() - 1;
244: v2 = 2 * nextDouble() - 1;
245: s = v1 * v1 + v2 * v2;
246: }
247: if (s != 0) {
248: s = Math.sqrt(-2 * Math.log(s) / s);
249: }
250: cachedNormalDeviate = v2 * s;
251: return v1 * s;
252: }
253: }
|