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.math3.random;
018    
019    import org.apache.commons.math3.exception.NotStrictlyPositiveException;
020    import org.apache.commons.math3.util.FastMath;
021    
022    /** Base class for random number generators that generates bits streams.
023    
024     * @version $Id: BitsStreamGenerator.java 1416643 2012-12-03 19:37:14Z tn $
025     * @since 2.0
026    
027     */
028    public abstract class BitsStreamGenerator implements RandomGenerator {
029    
030        /** Next gaussian. */
031        private double nextGaussian;
032    
033        /** Creates a new random number generator.
034         */
035        public BitsStreamGenerator() {
036            nextGaussian = Double.NaN;
037        }
038    
039        /** {@inheritDoc} */
040        public abstract void setSeed(int seed);
041    
042        /** {@inheritDoc} */
043        public abstract void setSeed(int[] seed);
044    
045        /** {@inheritDoc} */
046        public abstract void setSeed(long seed);
047    
048        /** Generate next pseudorandom number.
049         * <p>This method is the core generation algorithm. It is used by all the
050         * public generation methods for the various primitive types {@link
051         * #nextBoolean()}, {@link #nextBytes(byte[])}, {@link #nextDouble()},
052         * {@link #nextFloat()}, {@link #nextGaussian()}, {@link #nextInt()},
053         * {@link #next(int)} and {@link #nextLong()}.</p>
054         * @param bits number of random bits to produce
055         * @return random bits generated
056         */
057        protected abstract int next(int bits);
058    
059        /** {@inheritDoc} */
060        public boolean nextBoolean() {
061            return next(1) != 0;
062        }
063    
064        /** {@inheritDoc} */
065        public void nextBytes(byte[] bytes) {
066            int i = 0;
067            final int iEnd = bytes.length - 3;
068            while (i < iEnd) {
069                final int random = next(32);
070                bytes[i]     = (byte) (random & 0xff);
071                bytes[i + 1] = (byte) ((random >>  8) & 0xff);
072                bytes[i + 2] = (byte) ((random >> 16) & 0xff);
073                bytes[i + 3] = (byte) ((random >> 24) & 0xff);
074                i += 4;
075            }
076            int random = next(32);
077            while (i < bytes.length) {
078                bytes[i++] = (byte) (random & 0xff);
079                random     = random >> 8;
080            }
081        }
082    
083        /** {@inheritDoc} */
084        public double nextDouble() {
085            final long high = ((long) next(26)) << 26;
086            final int  low  = next(26);
087            return (high | low) * 0x1.0p-52d;
088        }
089    
090        /** {@inheritDoc} */
091        public float nextFloat() {
092            return next(23) * 0x1.0p-23f;
093        }
094    
095        /** {@inheritDoc} */
096        public double nextGaussian() {
097    
098            final double random;
099            if (Double.isNaN(nextGaussian)) {
100                // generate a new pair of gaussian numbers
101                final double x = nextDouble();
102                final double y = nextDouble();
103                final double alpha = 2 * FastMath.PI * x;
104                final double r      = FastMath.sqrt(-2 * FastMath.log(y));
105                random       = r * FastMath.cos(alpha);
106                nextGaussian = r * FastMath.sin(alpha);
107            } else {
108                // use the second element of the pair already generated
109                random = nextGaussian;
110                nextGaussian = Double.NaN;
111            }
112    
113            return random;
114    
115        }
116    
117        /** {@inheritDoc} */
118        public int nextInt() {
119            return next(32);
120        }
121    
122        /**
123         * {@inheritDoc}
124         * <p>This default implementation is copied from Apache Harmony
125         * java.util.Random (r929253).</p>
126         *
127         * <p>Implementation notes: <ul>
128         * <li>If n is a power of 2, this method returns
129         * {@code (int) ((n * (long) next(31)) >> 31)}.</li>
130         *
131         * <li>If n is not a power of 2, what is returned is {@code next(31) % n}
132         * with {@code next(31)} values rejected (i.e. regenerated) until a
133         * value that is larger than the remainder of {@code Integer.MAX_VALUE / n}
134         * is generated. Rejection of this initial segment is necessary to ensure
135         * a uniform distribution.</li></ul></p>
136         */
137        public int nextInt(int n) throws IllegalArgumentException {
138            if (n > 0) {
139                if ((n & -n) == n) {
140                    return (int) ((n * (long) next(31)) >> 31);
141                }
142                int bits;
143                int val;
144                do {
145                    bits = next(31);
146                    val = bits % n;
147                } while (bits - val + (n - 1) < 0);
148                return val;
149            }
150            throw new NotStrictlyPositiveException(n);
151        }
152    
153        /** {@inheritDoc} */
154        public long nextLong() {
155            final long high  = ((long) next(32)) << 32;
156            final long  low  = ((long) next(32)) & 0xffffffffL;
157            return high | low;
158        }
159    
160        /**
161         * Clears the cache used by the default implementation of
162         * {@link #nextGaussian}.
163         */
164        public void clear() {
165            nextGaussian = Double.NaN;
166        }
167    
168    }