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.MathRuntimeException;
020    
021    /** Base class for random number generators that generates bits streams.
022    
023     * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $
024     * @since 2.0
025    
026     */
027    public abstract class BitsStreamGenerator implements RandomGenerator {
028    
029        /** Next gaussian. */
030        private double nextGaussian;
031    
032        /** Creates a new random number generator.
033         */
034        public BitsStreamGenerator() {
035            nextGaussian = Double.NaN;
036        }
037    
038        /** {@inheritDoc} */
039        public abstract void setSeed(int seed);
040    
041        /** {@inheritDoc} */
042        public abstract void setSeed(int[] seed);
043    
044        /** {@inheritDoc} */
045        public abstract void setSeed(long seed);
046    
047        /** Generate next pseudorandom number.
048         * <p>This method is the core generation algorithm. It is used by all the
049         * public generation methods for the various primitive types {@link
050         * #nextBoolean()}, {@link #nextBytes(byte[])}, {@link #nextDouble()},
051         * {@link #nextFloat()}, {@link #nextGaussian()}, {@link #nextInt()},
052         * {@link #next(int)} and {@link #nextLong()}.</p>
053         * @param bits number of random bits to produce
054         * @return random bits generated
055         */
056        protected abstract int next(int bits);
057    
058        /** {@inheritDoc} */
059        public boolean nextBoolean() {
060            return next(1) != 0;
061        }
062    
063        /** {@inheritDoc} */
064        public void nextBytes(byte[] bytes) {
065            int i = 0;
066            final int iEnd = bytes.length - 3;
067            while (i < iEnd) {
068                final int random = next(32);
069                bytes[i]     = (byte) (random & 0xff);
070                bytes[i + 1] = (byte) ((random >>  8) & 0xff);
071                bytes[i + 2] = (byte) ((random >> 16) & 0xff);
072                bytes[i + 3] = (byte) ((random >> 24) & 0xff);
073                i += 4;
074            }
075            int random = next(32);
076            while (i < bytes.length) {
077                bytes[i++] = (byte) (random & 0xff);
078                random     = random >> 8;
079            }
080        }
081    
082        /** {@inheritDoc} */
083        public double nextDouble() {
084            final long high = ((long) next(26)) << 26;
085            final int  low  = next(26);
086            return (high | low) * 0x1.0p-52d;
087        }
088    
089        /** {@inheritDoc} */
090        public float nextFloat() {
091            return next(23) * 0x1.0p-23f;
092        }
093    
094        /** {@inheritDoc} */
095        public double nextGaussian() {
096    
097            final double random;
098            if (Double.isNaN(nextGaussian)) {
099                // generate a new pair of gaussian numbers
100                final double x = nextDouble();
101                final double y = nextDouble();
102                final double alpha = 2 * Math.PI * x;
103                final double r      = Math.sqrt(-2 * Math.log(y));
104                random       = r * Math.cos(alpha);
105                nextGaussian = r * Math.sin(alpha);
106            } else {
107                // use the second element of the pair already generated
108                random = nextGaussian;
109                nextGaussian = Double.NaN;
110            }
111    
112            return random;
113    
114        }
115    
116        /** {@inheritDoc} */
117        public int nextInt() {
118            return next(32);
119        }
120    
121        /** {@inheritDoc} */
122        public int nextInt(int n) throws IllegalArgumentException {
123    
124            if (n < 1) {
125                throw MathRuntimeException.createIllegalArgumentException(
126                      "upper bound must be positive ({0})", n);
127            }
128    
129            // find bit mask for n
130            int mask = n;
131            mask |= mask >> 1;
132            mask |= mask >> 2;
133            mask |= mask >> 4;
134            mask |= mask >> 8;
135            mask |= mask >> 16;
136    
137            while (true) {
138                final int random = next(32) & mask;
139                if (random < n) {
140                    return random;
141                }
142            }
143    
144        }
145    
146        /** {@inheritDoc} */
147        public long nextLong() {
148            final long high  = ((long) next(32)) << 32;
149            final long  low  = ((long) next(32)) & 0xffffffffL;
150            return high | low;
151        }
152    
153    }