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 }