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