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